Merge in ant and update from origin/master
diff --git a/ant/org.eclipse.ant.core/.classpath b/ant/org.eclipse.ant.core/.classpath
new file mode 100644
index 0000000..dc92c62
--- /dev/null
+++ b/ant/org.eclipse.ant.core/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry output="src_ant_bin" kind="src" path="src_ant/"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/ant/org.eclipse.ant.core/.externalToolBuilders/Build Ant Support JAR.launch b/ant/org.eclipse.ant.core/.externalToolBuilders/Build Ant Support JAR.launch
new file mode 100644
index 0000000..0f5d313
--- /dev/null
+++ b/ant/org.eclipse.ant.core/.externalToolBuilders/Build Ant Support JAR.launch
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
+<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,clean"/>
+<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.debug.ui.target_run_perspective" value="perspective_none"/>
+<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot; editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.core/src_ant&quot; type=&quot;2&quot;/&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.core/buildfiles/buildExtraJAR.xml&quot; type=&quot;1&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;&#10;}"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot; editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.core&quot; type=&quot;4&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;&#10;}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.ant.core/buildfiles/buildExtraJAR.xml}"/>
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_RUN_IN_BACKGROUND" value="false"/>
+</launchConfiguration>
diff --git a/ant/org.eclipse.ant.core/.project b/ant/org.eclipse.ant.core/.project
new file mode 100644
index 0000000..f37d1c5
--- /dev/null
+++ b/ant/org.eclipse.ant.core/.project
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.ant.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/Build Ant Support JAR.launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/ant/org.eclipse.ant.core/.settings/org.eclipse.pde.core.prefs b/ant/org.eclipse.ant.core/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..a490ecf
--- /dev/null
+++ b/ant/org.eclipse.ant.core/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,3 @@
+#Thu May 27 14:47:50 PDT 2004

+eclipse.preferences.version=1

+selfhosting.binExcludes=/org.eclipse.ant.core/src_ant_bin

diff --git a/ant/org.eclipse.ant.core/about.html b/ant/org.eclipse.ant.core/about.html
new file mode 100644
index 0000000..b3c0a26
--- /dev/null
+++ b/ant/org.eclipse.ant.core/about.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>October 8, 2009</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
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Third Party Content</h3>
+
+<p>The Content includes items that have been sourced from third parties as set out below. If you 
+did not receive this Content directly from the Eclipse Foundation, the following is provided 
+for informational purposes only, and you should look to the Redistributor&rsquo;s license for 
+terms and conditions of use.</p>
+
+<h4>Ant 1.7.1</h4>
+
+<p>The following classes in the plug-in JAR are based on Ant code  developed by The Apache Software Foundation and shall be defined as the &quot;Ant-Derived Work&quot;:</p>
+
+<ul>
+	<li>org.eclipse.ant.internal.core.ant.InternalAntRunner</li>
+	<li>org.eclipse.ant.internal.core.ant.InternalProject</li>
+</ul>
+
+<p>The binary code for the Ant-Derived Work is located in lib/antsupportlib.jar and the source code is located in lib/antsupportlibsrc.zip.</p>
+
+<p>Your use of the Ant-Derived Work is subject to the terms and conditions of the Apache Software License 2.0.  A copy of the license is contained
+in the file <a href="about_files/asl-v20.txt" target="_blank">about_files/asl-v20.txt</a> and is also available at <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>.
+
+<p>The names &quot;Ant&quot; and  &quot;Apache Software Foundation&quot; must not be used to endorse or promote products derived from this 
+software without prior written permission.  For written permission, please contact <a href="mailto:apache@apache.org">apache@apache.org</a>.</p>
+
+<p>The Apache attribution <a href="about_files/NOTICE" target="_blank">NOTICE</a> file is included with the Content in accordance with 4d of the Apache License, Version 2.0.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.core/about_files/NOTICE b/ant/org.eclipse.ant.core/about_files/NOTICE
new file mode 100644
index 0000000..1fb6dde
--- /dev/null
+++ b/ant/org.eclipse.ant.core/about_files/NOTICE
@@ -0,0 +1,15 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Apache Ant distribution.                      ==
+   =========================================================================
+
+   This product includes software developed by
+   The Apache Software Foundation (http://www.apache.org/).
+
+   This product includes also software developed by :
+     - the W3C consortium (http://www.w3c.org) ,
+     - the SAX project (http://www.saxproject.org)
+
+   Please read the different LICENSE files present in the root directory of
+   this distribution.
diff --git a/ant/org.eclipse.ant.core/about_files/asl-v20.txt b/ant/org.eclipse.ant.core/about_files/asl-v20.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/ant/org.eclipse.ant.core/about_files/asl-v20.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/ant/org.eclipse.ant.core/build.properties b/ant/org.eclipse.ant.core/build.properties
new file mode 100644
index 0000000..faf3b08
--- /dev/null
+++ b/ant/org.eclipse.ant.core/build.properties
@@ -0,0 +1,25 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+###############################################################################
+source.. =src/
+source.lib/antsupportlib.jar=src_ant/
+src.includes = about.html,\
+               schema/,\
+               about_files/
+bin.includes = plugin.xml,\
+               plugin.properties,\
+               about.html,\
+               .,\
+               lib/*.jar,\
+               META-INF/,\
+               about_files/
+jars.compile.order=.,lib/antsupportlib.jar
+jars.extra.classpath=platform:/plugin/org.apache.ant/lib/ant.jar,platform:/plugin/org.apache.ant/lib/ant-launcher.jar
+javadoc.packages=org.eclipse.*
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.core/buildfiles/exportplugin.xml b/ant/org.eclipse.ant.core/buildfiles/exportplugin.xml
new file mode 100644
index 0000000..f0df5c3
--- /dev/null
+++ b/ant/org.eclipse.ant.core/buildfiles/exportplugin.xml
@@ -0,0 +1,37 @@
+<!-- Export a jar of .class files for the org.eclipse.ant.core Eclipse plug-in
+     along with other important plugin files to the "plugin-export" subdirectory
+     of the target Eclipse installation -->
+<project name="Export ant.core" default="export" basedir="..">
+
+	<!-- Set the timestamp and important properties -->
+	<target name="init">
+		<tstamp/>
+		<property name="destdir" value="../../plugin-export" />
+		<property name="dest"  value="${destdir}/org.eclipse.ant.core_3.0.0" />
+	</target>
+
+	<!-- Create the jar of .class files, and copy other important files to export dir -->
+	<target name="export" depends="init">
+		<mkdir dir="${destdir}" />
+		<delete dir="${dest}" />
+		<mkdir dir="${dest}" />
+		<delete dir="${dest}/lib"/>
+		<mkdir dir="${dest}/lib"/>
+		<jar destfile="${dest}/antsupport.jar">
+			<fileset dir="bin">
+				<exclude name="org/eclipse/ant/internal/core/ant/*"/>
+			</fileset>
+		</jar>
+		<!-- Create the source zip -->
+		<zip destfile="${dest}/antsupportsrc.zip">
+			<fileset dir="src"/>
+		</zip>
+		<copy file="plugin.xml" todir="${dest}"/>
+		<copy file="plugin.properties" todir="${dest}"/>
+		<copy file=".classpath" todir="${dest}"/>
+		<copy file=".options" todir="${dest}"/>
+		<ant antfile="buildfiles/buildExtraJAR.xml" target="build"/>
+		<copy file="lib/antsupportlib.jar" todir="${dest}/lib"/>
+	</target>
+	
+</project>
diff --git a/ant/org.eclipse.ant.core/plugin.properties b/ant/org.eclipse.ant.core/plugin.properties
new file mode 100644
index 0000000..1d3d526
--- /dev/null
+++ b/ant/org.eclipse.ant.core/plugin.properties
@@ -0,0 +1,19 @@
+###############################################################################
+# 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
+###############################################################################
+
+pluginName = Ant Build Tool Core
+providerName = Eclipse.org
+classpathName = Extra Ant Classpath Entry Definitions
+tasksName = Ant Task Definitions
+typesName = Ant Type Definitions
+propertiesName = Ant Properties Definitions
+
+antBuildFileContentType.name= Ant Buildfile
diff --git a/ant/org.eclipse.ant.core/schema/antProperties.exsd b/ant/org.eclipse.ant.core/schema/antProperties.exsd
new file mode 100644
index 0000000..50a812d
--- /dev/null
+++ b/ant/org.eclipse.ant.core/schema/antProperties.exsd
@@ -0,0 +1,149 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.ant.core">

+<annotation>

+      <appInfo>

+         <meta.schema plugin="org.eclipse.ant.core" id="antProperties" name="Ant Properties"/>

+      </appInfo>

+      <documentation>

+         Allows plug-ins to define Ant properties for use in Ant build files.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <complexType>

+         <sequence>

+            <element ref="antProperty" minOccurs="0" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully qualified identifier of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional identifier of the extension instance

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name of the extension instance

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="antProperty">

+      <annotation>

+         <appInfo>

+            <meta.element labelAttribute="name"/>

+         </appInfo>

+      </annotation>

+      <complexType>

+         <attribute name="name" type="string" use="required">

+            <annotation>

+               <documentation>

+                  The name of the property.

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="value" type="string">

+            <annotation>

+               <documentation>

+                  The value of the property. If a value is provided here, the &quot;class&quot; attribute is ignored.

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string">

+            <annotation>

+               <documentation>

+                  If there is no &apos;value&apos; attribute provided, this class is called to return the dynamic value for the Ant property.  If &lt;code&gt;null&lt;/code&gt; is returned, the value is not set.

+               </documentation>

+               <appInfo>

+                  <meta.attribute kind="java" basedOn="org.eclipse.ant.core.IAntPropertyValueProvider"/>

+               </appInfo>

+            </annotation>

+         </attribute>

+         <attribute name="headless" type="boolean">

+            <annotation>

+               <documentation>

+                  indicates whether this property is suitable for use in a &quot;headless&quot; Ant environment. If running headless and the attribute is &quot;false&quot;, the property will not be set and any specified &lt;code&gt;org.eclipse.ant.core.IAntPropertyValueProvider&lt;/code&gt; will not be instantiated. The implied value is &lt;code&gt;true&lt;/code&gt;, when not specified.

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="eclipseRuntime" type="boolean">

+            <annotation>

+               <documentation>

+                  indicates whether this property should only be considered when run in the same VM as Eclipse. The implied value is &lt;code&gt;true&lt;/code&gt;, when not specified.

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="since"/>

+      </appInfo>

+      <documentation>

+         3.0

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="examples"/>

+      </appInfo>

+      <documentation>

+         The following is an example of an Ant properties extension point: 

+&lt;p&gt;

+&lt;pre&gt;

+   &lt;extension point=&quot;org.eclipse.ant.core.antProperties&quot;&gt;

+      &lt;antProperty name=&quot;eclipse.home&quot;

+           class=&quot;org.eclipse.ant.internal.core.AntPropertyValueProvider&quot;/&gt;

+      &lt;antProperty name=&quot;eclipse.running&quot;

+           value=&quot;true&quot;/&gt;

+   &lt;/extension&gt; 

+&lt;/pre&gt;

+&lt;/p&gt;

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="apiInfo"/>

+      </appInfo>

+      <documentation>

+         The class named in the &lt;samp&gt;class&lt;/samp&gt; property must implement the &lt;samp&gt;org.eclipse.ant.core.IAntPropertyValueProvider&lt;/samp&gt; interface.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="implementation"/>

+      </appInfo>

+      <documentation>

+         The platform uses this mechanism to set the Ant property eclipse.home to the Eclipse installation directory and to set the eclipse.running property.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="copyright"/>

+      </appInfo>

+      <documentation>

+         Copyright (c) 2000, 2006 IBM Corporation and others.&lt;br&gt;

+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 

+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;

+      </documentation>

+   </annotation>

+

+</schema>

diff --git a/ant/org.eclipse.ant.core/schema/antTypes.exsd b/ant/org.eclipse.ant.core/schema/antTypes.exsd
new file mode 100644
index 0000000..9c6d31d
--- /dev/null
+++ b/ant/org.eclipse.ant.core/schema/antTypes.exsd
@@ -0,0 +1,141 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.ant.core">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.ant.core" id="antTypes" name="Ant Types"/>
+      </appInfo>
+      <documentation>
+         Allows plug-ins to define arbitrary Ant datatypes for 
+use by the Ant infrastructure.  The standard Ant 
+infrastructure allows for the addition of arbitrary 
+datatypes.  Unfortunately, it is unlikely that the 
+Ant Core plug-in would have the classes required 
+by these datatypes on its classpath (or that of any 
+of its prerequisites).  To address this, clients 
+should define an extension which plugs into this 
+extension-point and maps a datatype name onto a class.  
+The Ant plug-in can then request that the declaring 
+plug-in load the specified class.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="antType" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified identifier of the target extension point
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  an optional identifier of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  an optional name of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="antType">
+      <annotation>
+         <appInfo>
+            <meta.element labelAttribute="name"/>
+         </appInfo>
+      </annotation>
+      <complexType>
+         <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  name of the type to be defined
+               </documentation>
+            </annotation>
+         </attribute>
+          <attribute name="uri" type="string">
+            <annotation>
+               <documentation>
+                   The uri that this definition should live in. Only used if using Ant newer than 1.6.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the fully qualified name of a Java class implementing 
+the datatype.  Generally this class must be a subclass of
+&lt;code&gt;org.apache.tools.ant.types.DataType&lt;/code&gt;.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.apache.tools.ant.types.DataType"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="library" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a path relative to the plug-in install location for the library containing the type.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="resource"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="headless" type="boolean">
+            <annotation>
+               <documentation>
+                  indicates whether this type is suitable for use in a &quot;headless&quot; Ant environment. If running headless and the attribute is &lt;code&gt;false&lt;/code&gt;, the type will not be loaded or defined. As well, the plugin class loader will not be added as a parent classloader to the Ant classloader. The implied value is &lt;code&gt;true&lt;/code&gt;, when not specified.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="eclipseRuntime" type="boolean">
+            <annotation>
+               <documentation>
+                  indicates whether this type requires an Eclipse runtime (i.e. must be run in the same VM as Eclipse). The implied value is &lt;code&gt;true&lt;/code&gt;, when not specified.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         The following is an example of an Ant types extension point: 
+&lt;p&gt;
+&lt;pre&gt;
+   &lt;extension point=&quot;org.eclipse.ant.core.antTypes&quot;&gt;
+      &lt;antType name=&quot;coolType&quot; class=&quot;com.example.CoolType&quot; library=&quot;lib/antSupport.jar&quot;/&gt;
+   &lt;/extension&gt; 
+&lt;/pre&gt;
+&lt;/p&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2000, 2006 IBM Corporation and others.&lt;br&gt;
+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 
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/ant/org.eclipse.ant.core/schema/extraClasspathEntries.exsd b/ant/org.eclipse.ant.core/schema/extraClasspathEntries.exsd
new file mode 100644
index 0000000..7557977
--- /dev/null
+++ b/ant/org.eclipse.ant.core/schema/extraClasspathEntries.exsd
@@ -0,0 +1,113 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.ant.core">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.ant.core" id="extraClasspathEntries" name="Extra Ant Classpath Entries"/>
+      </appInfo>
+      <documentation>
+         Allows plug-ins to define arbitrary JARs for use by the Ant infrastructure.
+These JARs are put into the Ant classpath at runtime.  Besides
+the JAR, the plug-in classloader of the plug-in providing the
+JAR is also added to the classpath.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="extraClasspathEntry" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified identifier of the target extension point
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  an optional identifier of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  an optional name of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="extraClasspathEntry">
+      <complexType>
+         <attribute name="library" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a path relative to the plug-in install location for the library.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="resource"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="headless" type="boolean">
+            <annotation>
+               <documentation>
+                  indicates whether this extra classpath entry is suitable for use in a &quot;headless&quot; Ant environment. If running headless and the attribute is &lt;code&gt;false&lt;/code&gt;, this entry will not be added to the Ant classpath. As well, the plugin class loader will not be added as a parent classloader to the Ant classloader. The implied value is &lt;code&gt;true&lt;/code&gt;, when not specified.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="eclipseRuntime" type="boolean">
+            <annotation>
+               <documentation>
+                  indicates whether this extra classpath entry should only be considered for builds run in the same VM as Eclipse. The implied value is true, when not specified.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         The following is an example of an extra classpath entries extension point:
+
+&lt;p&gt;
+&lt;pre&gt;
+ &lt;extension point=&quot;org.eclipse.ant.core.extraClasspathEntries&quot;&gt;
+  &lt;extraClasspathEntry library=&quot;myExtraLibrary.jar&quot;/&gt;
+ &lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         The platform itself supplies an Ant support jar (antsupportlib.jar).
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+           Copyright (c) 2000, 2005 IBM Corporation and others.&lt;br&gt;
+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 
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/AntCorePlugin.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/AntCorePlugin.java
new file mode 100644
index 0000000..7f26376
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/AntCorePlugin.java
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.core;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.ant.internal.core.AntClassLoader;
+import org.eclipse.ant.internal.core.AntCoreUtil;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The plug-in runtime class for the Ant Core plug-in.
+ * Clients may not instantiate or subclass this class.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class AntCorePlugin extends Plugin {
+
+	/**
+	 * Status code indicating an unexpected internal error.
+	 * @since 2.1
+	 */
+	public static final int INTERNAL_ERROR = 120;		
+	
+	/**
+	 * The single instance of this plug-in runtime class.
+	 */
+	private static AntCorePlugin plugin;
+
+	/**
+	 * The preferences class for this plug-in.
+	 */
+	private AntCorePreferences preferences;
+	
+	/**
+	 * Unique identifier constant (value <code>"org.eclipse.ant.core"</code>)
+	 * for the Ant Core plug-in.
+	 */
+	public static final String PI_ANTCORE = "org.eclipse.ant.core"; //$NON-NLS-1$
+
+	/**
+	 * Simple identifier constant (value <code>"antTasks"</code>)
+	 * for the Ant tasks extension point.
+	 */
+	public static final String PT_TASKS = "antTasks"; //$NON-NLS-1$
+
+	/**
+	 * Simple identifier constant (value <code>"extraClasspathEntries"</code>)
+	 * for the extra classpath entries extension point.
+	 */
+	public static final String PT_EXTRA_CLASSPATH = "extraClasspathEntries"; //$NON-NLS-1$
+
+	/**
+	 * Simple identifier constant (value <code>"antTypes"</code>)
+	 * for the Ant types extension point.
+	 */
+	public static final String PT_TYPES = "antTypes"; //$NON-NLS-1$
+	
+	/**
+	 * Simple identifier constant (value <code>"antProperties"</code>)
+	 * for the Ant properties extension point.
+	 * 
+	 * @since 3.0
+	 */
+	public static final String PT_PROPERTIES = "antProperties"; //$NON-NLS-1$
+	
+	/**
+	 * Simple identifier constant (value <code>"org.eclipse.ant.core.antBuildFile"</code>)
+	 * for the content type of an Ant BuildFile
+	 * 
+	 * @since 3.0
+	 */
+	public static final String ANT_BUILDFILE_CONTENT_TYPE = PI_ANTCORE + ".antBuildFile"; //$NON-NLS-1$
+
+	/**
+	 * Simple identifier constant (value <code>"class"</code>)
+	 * of a tag that appears in Ant extensions.
+	 */
+	public static final String CLASS = "class"; //$NON-NLS-1$
+
+	/**
+	 * Simple identifier constant (value <code>"name"</code>)
+	 * of a tag that appears in Ant extensions.
+	 */
+	public static final String NAME = "name"; //$NON-NLS-1$
+
+	/**
+	 * Simple identifier constant (value <code>"library"</code>)
+	 * of a tag that appears in Ant extensions.
+	 */
+	public static final String LIBRARY = "library"; //$NON-NLS-1$
+	
+	/**
+	 * Simple identifier constant (value <code>"headless"</code>) of a tag
+	 * that appears in Ant extensions.
+	 * @since 2.1
+	 */
+	public static final String HEADLESS = "headless"; //$NON-NLS-1$
+	
+	/**
+	 * Simple identifier constant (value <code>"eclipseRuntime"</code>) of a tag
+	 * that appears in Ant extensions.
+	 * @since 3.0
+	 */
+	public static final String ECLIPSE_RUNTIME = "eclipseRuntime"; //$NON-NLS-1$
+	
+	/**
+	 * Simple identifier constant (value <code>"uri"</code>) of a tag
+	 * that appears in Ant extensions.
+	 * @since 3.2
+	 */
+	public static final String URI = "uri"; //$NON-NLS-1$
+	
+	/**
+	 * Simple identifier constant (value <code>"value"</code>) of a tag
+	 * that appears in Ant extensions.
+	 * @since 3.0
+	 */
+	public static final String VALUE = "value"; //$NON-NLS-1$
+
+	/**
+	 * Key to access the <code>IProgressMonitor</code> reference. When a
+	 * progress monitor is passed to the <code>AntRunner.run(IProgressMonitor)</code>
+	 * method, the object is available as a reference for the current
+	 * Ant project.
+	 */
+	public static final String ECLIPSE_PROGRESS_MONITOR = "eclipse.progress.monitor"; //$NON-NLS-1$
+	
+	/**
+	 * Status code indicating an error occurred running a build.
+	 * @since 2.1
+	 */
+	public static final int ERROR_RUNNING_BUILD = 1;
+	
+	/**
+	 * Status code indicating an error occurred due to a malformed URL.
+	 * @since 2.1
+	 */
+	public static final int ERROR_MALFORMED_URL = 2;
+	
+	/**
+	 * Status code indicating an error occurred as a library was not specified
+	 * @since 2.1
+	 */
+	public static final int ERROR_LIBRARY_NOT_SPECIFIED = 3;
+
+	/** 
+	 * Constructs an instance of this plug-in runtime class.
+	 * <p>
+	 * An instance of this plug-in runtime class is automatically created 
+	 * when the facilities provided by the Ant Core plug-in are required.
+	 * <b>Clients must never explicitly instantiate a plug-in runtime class.</b>
+	 * </p>
+	 * @since 3.1
+	 * 
+	 */
+	public AntCorePlugin() {
+		plugin = this;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+	 * @since 3.1
+	 */
+	public void stop(BundleContext context) throws Exception {
+		super.stop(context);
+        AntCoreUtil.setBundleContext(null);
+		if (preferences != null) {
+			savePluginPreferences();
+		}
+	}
+    
+    /* (non-Javadoc)
+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+     * @since 3.1
+     */
+    public void start(BundleContext context) throws Exception {
+        super.start(context);
+        AntCoreUtil.setBundleContext(context);
+    }
+
+	/**
+	 * Given an extension point name, extract its extensions and return them
+	 * as a List.
+	 * @param pointName The name of the extension point
+	 * @return The list of the extensions
+	 */
+	private List extractExtensions(String pointName) {
+		IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(AntCorePlugin.PI_ANTCORE, pointName);
+		if (extensionPoint == null) {
+			return null;
+		}
+		IConfigurationElement[] extensions = extensionPoint.getConfigurationElements();
+		return Arrays.asList(extensions);
+	}
+
+	/**
+	 * Returns an object representing this plug-in's preferences.
+	 * 
+	 * @return the Ant core object representing the preferences for this plug-in.
+	 */
+	public AntCorePreferences getPreferences() {
+		if (preferences == null) {
+			preferences = new AntCorePreferences(extractExtensions(PT_TASKS), extractExtensions(PT_EXTRA_CLASSPATH), extractExtensions(PT_TYPES), extractExtensions(PT_PROPERTIES), false);
+		}
+		return preferences;
+	}
+	
+	/**
+	 * Set this plug-in's preferences for running headless based on the 
+	 * headless parameter.
+	 * This method is public for testing purposes only. It should not
+	 * be called outside of the Ant integration framework.
+	 * @param headless Whether or not to mark that the plug-in is running headless or not
+	 */
+	public void setRunningHeadless(boolean headless) {
+		preferences = new AntCorePreferences(extractExtensions(PT_TASKS), extractExtensions(PT_EXTRA_CLASSPATH), extractExtensions(PT_TYPES), extractExtensions(PT_PROPERTIES), headless);
+	}
+
+	/**
+	 * Returns this plug-in instance.
+	 *
+	 * @return the single instance of this plug-in runtime class
+	 */
+	public static AntCorePlugin getPlugin() {
+		return plugin;
+	}
+	
+	/**
+	 * Returns a new class loader to use when executing Ant builds.
+	 * 
+	 * @return the new class loader
+	 */
+	public ClassLoader getNewClassLoader() {
+	    AntCorePreferences corePreferences = getPreferences();
+		return getNewClassLoader(false, corePreferences.getURLs());
+	}
+	
+	/**
+	 * Returns a new class loader to use when executing Ant builds.
+	 * @param urls the URLs that define the classpath of the new classloader
+	 * @return the new class loader
+	 * @since 3.1
+	 */
+	public URLClassLoader getNewClassLoader(URL[] urls) {
+		return getNewClassLoader(false, urls);
+	}
+	
+	/**
+	 * Returns a new class loader to use when executing Ant builds or 
+	 * other applications such as parsing or code proposal determination.
+	 * 
+	 * @param allowLoading whether to allow plug-in classloaders associated 
+	 * with the new classloader to load Apache Ant classes or resources.
+	 * @return the new class loader
+	 */
+	public ClassLoader getNewClassLoader(boolean allowLoading) {
+		AntCorePreferences corePreferences = getPreferences();
+		URL[] urls = corePreferences.getURLs();
+		return getNewClassLoader(allowLoading, urls);
+	}
+		
+	/**
+	 * Returns a new class loader to use when executing Ant builds or 
+	 * other applications such as parsing or code proposal determination.
+	 *  
+	 * @param allowLoading whether to allow plug-in classloaders associated 
+	 * with the new classloader to load Apache Ant classes or resources.
+	 * @param urls the URLs that define the classpath of the new classloader
+	 * @return the new class loader
+	 * @since 3.1
+	 */
+	public URLClassLoader getNewClassLoader(boolean allowLoading, URL[] urls) {
+		AntCorePreferences corePreferences = getPreferences();
+		ClassLoader[] pluginLoaders = corePreferences.getPluginClassLoaders();
+		AntClassLoader loader= new AntClassLoader(urls, pluginLoaders);
+		loader.allowPluginClassLoadersToLoadAnt(allowLoading);
+		return loader;
+	}
+	
+	/**
+	 * Logs the specified throwable with this plug-in's log.
+	 * 
+	 * @param t throwable to log 
+	 * @since 2.1
+	 */
+	public static void log(Throwable t) {
+		IStatus status= new Status(IStatus.ERROR, PI_ANTCORE, INTERNAL_ERROR, "Error logged from Ant Core: ", t); //$NON-NLS-1$
+		getPlugin().getLog().log(status);
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/AntSecurityException.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/AntSecurityException.java
new file mode 100644
index 0000000..1f86741
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/AntSecurityException.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.core;
+
+
+/**
+ * A security exception that is thrown by the AntSecurityManager if
+ * an Ant task in some way attempts to halt or exit the Java Virtual Machine.
+ * 
+ * Clients may instantiate this class; it is not intended to be subclassed.
+ * @since 2.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class AntSecurityException extends SecurityException {
+
+	private static final long serialVersionUID = 1L;
+
+}
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/IAntClasspathEntry.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/IAntClasspathEntry.java
new file mode 100644
index 0000000..4420669
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/IAntClasspathEntry.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.core;
+
+import java.net.URL;
+
+/**
+ * Represents an Ant classpath entry.
+ * Clients may implement this interface.
+ *
+ * @since 3.0
+ */
+public interface IAntClasspathEntry {
+
+	/**
+	 * Returns the label for this classpath entry.
+	 * @return the label for this entry.
+	 */
+	public String getLabel();
+	
+	/**
+	 * Returns the URL for this classpath entry or <code>null</code>
+	 * if it cannot be resolved.
+	 * 
+	 * @return the url for this classpath entry.
+	 */
+	public URL getEntryURL();
+	
+	/**
+	 * Returns whether this classpath entry requires the Eclipse runtime to be 
+	 * relevant. Defaults value is <code>true</code>
+	 * 
+	 * @return whether this classpath entry requires the Eclipse runtime
+	 */
+	public boolean isEclipseRuntimeRequired();
+}
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/Task.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/Task.java
new file mode 100644
index 0000000..3d4eca5
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/Task.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.core;
+
+
+import org.eclipse.ant.internal.core.AntObject;
+
+/**
+ * Represents an Ant task.
+ * Clients may instantiate this class; it is not intended to be subclassed.
+ * @since 2.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Task extends AntObject {
+
+	/**
+	 * Returns the name of the task
+	 * @return the name of the task
+	 */
+	public String getTaskName() {
+		return fName;
+	}
+
+	/**
+	 * Sets the name of the task
+	 * @param taskName The taskName to set
+	 */
+	public void setTaskName(String taskName) {
+		fName= taskName;
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/Type.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/Type.java
new file mode 100644
index 0000000..429eacd
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/Type.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.core;
+
+
+import org.eclipse.ant.internal.core.AntObject;
+
+/**
+ * Represents an Ant type.
+ * Clients may instantiate this class; it is not intended to be subclassed.
+ * @since 2.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Type extends AntObject {
+
+	/**
+	 * Returns the type name
+	 * @return Returns a String
+	 */
+	public String getTypeName() {
+		return fName;
+	}
+
+	/**
+	 * Sets the taskName.
+	 * @param taskName The taskName to set
+	 */
+	public void setTypeName(String taskName) {
+		fName = taskName;
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/package.html b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/package.html
new file mode 100644
index 0000000..a931089
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/core/package.html
@@ -0,0 +1,14 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides support for running the Ant build tool in the platform.
+<h2>
+Package Specification</h2>
+This package defines a number of task and data types and various infrastructure
+pieces which make Ant in the platform easier and more powerful.
+</body>
+</html>
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AbstractEclipseBuildLogger.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AbstractEclipseBuildLogger.java
new file mode 100644
index 0000000..33c2299
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AbstractEclipseBuildLogger.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.core;
+
+import java.util.Map;
+
+import org.eclipse.ant.core.AntCorePlugin;
+
+public abstract class AbstractEclipseBuildLogger {
+    
+    /**
+     * Process identifier - used to link the Eclipse Ant build
+     * loggers to a process.
+     */
+    public static final String ANT_PROCESS_ID = AntCorePlugin.PI_ANTCORE + ".ANT_PROCESS_ID"; //$NON-NLS-1$
+    
+    protected String fProcessId= null;
+    
+    public void configure(Map userProperties) {
+        fProcessId= (String) userProperties.remove(ANT_PROCESS_ID);
+    } 
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AntClassLoader.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AntClassLoader.java
new file mode 100644
index 0000000..06a1dc2
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AntClassLoader.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *     Tom Tromey (tromey@redhat.com) - patch for bug 40972
+ *******************************************************************************/
+package org.eclipse.ant.internal.core;
+
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+public class AntClassLoader extends URLClassLoader {
+
+    private static final String ANT_PACKAGES_PREFIX = "org.apache.tools"; //$NON-NLS-1$
+    private static final String ANT_URL_PREFIX = "org/apache/tools";     //$NON-NLS-1$
+    
+    private boolean fAllowPluginLoading = false;
+
+    protected ClassLoader[] fPluginLoaders;
+
+    private ClassLoader fContextClassloader = null;
+    
+    public AntClassLoader(URL[] urls, ClassLoader[] pluginLoaders) {
+        super(urls, ClassLoader.getSystemClassLoader());
+        fPluginLoaders = pluginLoaders;
+    }
+
+    /*
+     * @see java.net.URLClassLoader#findClass(java.lang.String)
+     */
+    protected Class findClass(String name) throws ClassNotFoundException {
+        Class result = null;
+        //check whether to load the Apache Ant classes from the plug-in class loaders 
+        //or to only load from the URLs specified from the Ant runtime classpath preferences setting
+        if (fAllowPluginLoading || !(name.startsWith(ANT_PACKAGES_PREFIX))) {
+            result = loadClassPlugins(name);
+        } 
+        
+        if (result != null) {
+            return result;
+        }
+        
+        return super.findClass(name);
+    }
+
+    protected Class loadClassPlugins(String name) {
+        //remove this class loader as the context class loader
+        //when loading classes from plug-ins...see bug 94471
+        ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+        if (fContextClassloader != null) {
+            Thread.currentThread().setContextClassLoader(fContextClassloader);
+        }
+        try {
+            Class result = null;
+            if (fPluginLoaders != null) {
+                for (int i = 0; (i < fPluginLoaders.length) && (result == null); i++) {
+                    try {
+                        result = fPluginLoaders[i].loadClass(name);
+                    } catch (ClassNotFoundException e) {
+                        // Ignore exception now. If necessary we'll throw
+                        // a ClassNotFoundException in loadClass(String)
+                    }
+                }
+            }
+            return result;
+        } finally {
+            Thread.currentThread().setContextClassLoader(originalClassLoader);
+        }
+    }
+    
+    /*
+     * @see java.net.URLClassLoader#findResource(java.lang.String)
+     */
+    public URL findResource(String name) {
+    	 if (fAllowPluginLoading || !(name.startsWith(ANT_URL_PREFIX))) {
+             URL result = findResourcePlugins(name);
+             if (result != null) {
+            	 return result;
+             }
+         } 
+    	
+    	return super.findResource(name);
+    }
+    
+    private URL findResourcePlugins(String name) {
+    	//remove this class loader as the context class loader
+    	//when loading resources from plug-ins...see bug 94471
+    	ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+    	if (fContextClassloader != null) {
+    		Thread.currentThread().setContextClassLoader(fContextClassloader);
+    	}
+    	try {
+    		URL result = null;
+    		if (fPluginLoaders != null) {
+    			for (int i = 0; i < fPluginLoaders.length; i++) {
+    				result = fPluginLoaders[i].getResource(name);
+    				if (result != null) {
+    	    			return result;
+    	    		}
+    			}
+    		}
+    	} finally {
+    		Thread.currentThread().setContextClassLoader(originalClassLoader);
+    	}
+    	return null;
+    }
+    
+    /*
+     * @see java.net.URLClassLoader#findResources(java.lang.String)
+     */
+    public Enumeration findResources(String name) throws IOException {
+    	ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+    	if (fContextClassloader != null) {
+    		Thread.currentThread().setContextClassLoader(fContextClassloader);
+    	}
+    	List all = new ArrayList();
+    	try {
+    		if (fAllowPluginLoading || !(name.startsWith(ANT_URL_PREFIX) || name.startsWith(ANT_URL_PREFIX, 1))) {
+    			if (fPluginLoaders != null) {
+    				Enumeration result = null;
+    				for (int i = 0; i < fPluginLoaders.length; i++) {
+    					result = fPluginLoaders[i].getResources(name);
+    					while (result.hasMoreElements()) {
+    						all.add(result.nextElement());
+    					}
+    				}
+    			}
+    		}
+
+    		Enumeration superResources = super.findResources(name);
+    		if (all.isEmpty()) {
+    			return superResources;
+    		}
+
+    		while (superResources.hasMoreElements()) {
+    			all.add(superResources.nextElement());
+    		}
+    		return Collections.enumeration(all);
+    	} finally {
+    		Thread.currentThread().setContextClassLoader(originalClassLoader);
+    	}
+    }
+    
+    /**
+     * Sets whether this class loader will allow Apache Ant classes or resources to be found or
+     * loaded from its set of plug-in class loaders.
+     * 
+     * @param allowLoading whether or not to allow the plug-in class loaders
+     * to load the Apache Ant classes or resources
+     */
+    public void allowPluginClassLoadersToLoadAnt(boolean allowLoading) {
+        fAllowPluginLoading = allowLoading;
+    }
+    
+    public void setPluginContextClassloader(ClassLoader classLoader) {
+        fContextClassloader = classLoader;
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AntPropertyValueProvider.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AntPropertyValueProvider.java
new file mode 100644
index 0000000..cd28025
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AntPropertyValueProvider.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2006 BBDO Detroit 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:
+ *     Thierry Lach (thierry.lach@bbdodetroit.com) - initial API and implementation for bug 40502
+ *     IBM Corporation - added eclipse.running property, bug 65655
+ *******************************************************************************/
+package org.eclipse.ant.internal.core;
+
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.IAntPropertyValueProvider;
+import org.eclipse.core.runtime.FileLocator;
+
+/**
+ * Dynamic provider for Ant properties.
+ * 
+ * Provides the dynamic values for the following Ant properties:
+ * 
+ * <ul>
+ * <li><code>eclipse.home</code> - set to the Eclipse installation directory</li>
+ * </ul>
+ * * <ul>
+ * <li><code>eclipse.running</code> - set (to "true") when Eclipse is running</li>
+ * </ul>
+ * 
+ * @since 3.0
+ */
+public class AntPropertyValueProvider implements IAntPropertyValueProvider {
+	/**
+	 * Returns the dynamic property values for Ant properties.
+	 * 
+	 * @param propertyName The name of the property to resolve the value for
+	 * @return The resolved value for the property
+	 * @see org.eclipse.ant.core.IAntPropertyValueProvider#getAntPropertyValue(String)
+	 */
+	public String getAntPropertyValue(String propertyName) {
+		String value = null;
+		if ("eclipse.running".equals(propertyName)){ //$NON-NLS-1$
+			return "true"; //$NON-NLS-1$
+		} else if ("eclipse.home".equals(propertyName)) { //$NON-NLS-1$
+			try {
+				value = new File(FileLocator.resolve(new URL("platform:/base/")).getPath()).getAbsolutePath(); //$NON-NLS-1$
+				if (value.endsWith("/")) { //$NON-NLS-1$
+				    value = value.substring(0, value.length() - 1);
+				}
+			} catch (Exception e) {
+				AntCorePlugin.log(e);
+			}
+		}
+		return value;
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AntSecurityManager.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AntSecurityManager.java
new file mode 100644
index 0000000..fd79dde
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/AntSecurityManager.java
@@ -0,0 +1,373 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.core;
+
+
+import java.io.FileDescriptor;
+import java.net.InetAddress;
+import java.net.SocketPermission;
+import java.security.Permission;
+import java.util.PropertyPermission;
+import org.eclipse.ant.core.AntSecurityException;
+
+/**
+ * A security manager that always throws an <code>AntSecurityException</code>
+ * if the calling thread attempts to cause the Java Virtual Machine to 
+ * exit/halt or if the restricted thread attempts to set a System property.
+ * Otherwise this manager just delegates to the pre-existing manager
+ * passed in the constructor or mimics the default security manager behavior
+ */
+public class AntSecurityManager extends SecurityManager {
+
+	private SecurityManager fSecurityManager= null;
+	private Thread fRestrictedThread= null;
+	//ensure that the PropertyPermission class is loaded before we 
+	//start checking permissions: bug 85908
+	private static final PropertyPermission fgPropertyPermission= new PropertyPermission("*", "write"); //$NON-NLS-1$ //$NON-NLS-2$
+	
+	private boolean fAllowSettingSystemProperties= true;
+	
+	public AntSecurityManager(SecurityManager securityManager, Thread restrictedThread, boolean allowSettingProperties) {
+		fSecurityManager= securityManager;
+		fRestrictedThread= restrictedThread;
+		fAllowSettingSystemProperties= allowSettingProperties;
+	}
+	
+	public AntSecurityManager(SecurityManager securityManager, Thread restrictedThread) {
+		this(securityManager, restrictedThread, true);
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkExit(int)
+	 */
+	public void checkExit(int status) {
+		//no exit allowed from the restricted thread...System.exit is being called
+		//by some ant task...do not want Eclipse to exit if
+		//in the same VM.
+		if (Thread.currentThread() == fRestrictedThread) {
+			throw new AntSecurityException();
+		}
+		if (fSecurityManager != null) {
+			fSecurityManager.checkExit(status);
+		}
+	}
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkAccept(java.lang.String, int)
+	 */
+	public void checkAccept(String host, int port) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkAccept(host, port);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkAccess(java.lang.Thread)
+	 */
+	public void checkAccess(Thread t) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkAccess(t);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkAccess(java.lang.ThreadGroup)
+	 */
+	public void checkAccess(ThreadGroup g) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkAccess(g);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkAwtEventQueueAccess()
+	 */
+	public void checkAwtEventQueueAccess() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkAwtEventQueueAccess();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkConnect(java.lang.String, int, java.lang.Object)
+	 */
+	public void checkConnect(String host, int port, Object context) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkConnect(host, port, context);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkConnect(java.lang.String, int)
+	 */
+	public void checkConnect(String host, int port) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkConnect(host, port);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkCreateClassLoader()
+	 */
+	public void checkCreateClassLoader() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkCreateClassLoader();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkDelete(java.lang.String)
+	 */
+	public void checkDelete(String file) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkDelete(file);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkExec(java.lang.String)
+	 */
+	public void checkExec(String cmd) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkExec(cmd);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkLink(java.lang.String)
+	 */
+	public void checkLink(String lib) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkLink(lib);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkListen(int)
+	 */
+	public void checkListen(int port) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkListen(port);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkMemberAccess(java.lang.Class, int)
+	 */
+	public void checkMemberAccess(Class clazz, int which) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkMemberAccess(clazz, which);
+		}
+	}
+
+	/**
+	 * @see java.lang.SecurityManager#checkMulticast(java.net.InetAddress, byte)
+	 * @deprecated
+	 */
+	public void checkMulticast(InetAddress maddr, byte ttl) {
+		if (fSecurityManager != null) {
+			String host = maddr.getHostAddress();
+			if (!host.startsWith("[") && host.indexOf(':') != -1) { //$NON-NLS-1$
+	   			host = "[" + host + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+			}
+	    	checkPermission(new SocketPermission(host, "accept,connect")); //$NON-NLS-1$
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkMulticast(java.net.InetAddress)
+	 */
+	public void checkMulticast(InetAddress maddr) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkMulticast(maddr);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPackageAccess(java.lang.String)
+	 */
+	public void checkPackageAccess(String pkg) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPackageAccess(pkg);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPackageDefinition(java.lang.String)
+	 */
+	public void checkPackageDefinition(String pkg) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPackageDefinition(pkg);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPermission(java.security.Permission, java.lang.Object)
+	 */
+	public void checkPermission(Permission perm, Object context) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPermission(perm, context);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPermission(java.security.Permission)
+	 */
+	public void checkPermission(Permission perm) {
+		if (!fAllowSettingSystemProperties && fgPropertyPermission.implies(perm) && fRestrictedThread == Thread.currentThread()) {
+			//attempting to write a system property
+			throw new AntSecurityException();
+		}
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPermission(perm);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPrintJobAccess()
+	 */
+	public void checkPrintJobAccess() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPrintJobAccess();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPropertiesAccess()
+	 */
+	public void checkPropertiesAccess() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPropertiesAccess();
+		}
+		super.checkPropertiesAccess();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
+	 */
+	public void checkPropertyAccess(String key) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPropertyAccess(key);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkRead(java.io.FileDescriptor)
+	 */
+	public void checkRead(FileDescriptor fd) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkRead(fd);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkRead(java.lang.String, java.lang.Object)
+	 */
+	public void checkRead(String file, Object context) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkRead(file, context);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkRead(java.lang.String)
+	 */
+	public void checkRead(String file) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkRead(file);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkSecurityAccess(java.lang.String)
+	 */
+	public void checkSecurityAccess(String target) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkSecurityAccess(target);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkSetFactory()
+	 */
+	public void checkSetFactory() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkSetFactory();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkSystemClipboardAccess()
+	 */
+	public void checkSystemClipboardAccess() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkSystemClipboardAccess();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
+	 */
+	public boolean checkTopLevelWindow(Object window) {
+		if (fSecurityManager != null) {
+			return fSecurityManager.checkTopLevelWindow(window);
+		}
+		return super.checkTopLevelWindow(window);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)
+	 */
+	public void checkWrite(FileDescriptor fd) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkWrite(fd);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkWrite(java.lang.String)
+	 */
+	public void checkWrite(String file) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkWrite(file);
+		}
+	}
+
+	/**
+	 * @see java.lang.SecurityManager#getInCheck()
+	 * @deprecated
+	 */
+	public boolean getInCheck() {
+		if (fSecurityManager != null) {
+			return fSecurityManager.getInCheck();
+		}
+		return super.getInCheck();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#getSecurityContext()
+	 */
+	public Object getSecurityContext() {
+		if (fSecurityManager != null) {
+			return fSecurityManager.getSecurityContext();
+		}
+		return super.getSecurityContext();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#getThreadGroup()
+	 */
+	public ThreadGroup getThreadGroup() {
+		if (fSecurityManager != null) {
+			fSecurityManager.getThreadGroup();
+		}
+		return super.getThreadGroup();
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/InternalCoreAntMessages.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/InternalCoreAntMessages.java
new file mode 100644
index 0000000..22f65e6
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/InternalCoreAntMessages.java
@@ -0,0 +1,35 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.core;
+
+import org.eclipse.osgi.util.NLS;
+
+public class InternalCoreAntMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.core.InternalCoreAntMessages";//$NON-NLS-1$
+
+	public static String AntCorePreferences_Malformed_URL__1;
+	public static String AntCorePreferences_Library_not_specified_for___0__4;
+	public static String AntCorePreferences_No_library_for_task;
+	public static String AntCorePreferences_No_library_for_type;
+	public static String AntCorePreferences_8;
+	public static String AntCorePreferences_6;
+	public static String AntCorePreferences_0;
+	public static String AntCorePreferences_1;
+
+	public static String AntRunner_Could_not_find_one_or_more_classes__Please_check_the_Ant_classpath__1;
+	public static String AntRunner_Could_not_find_one_or_more_classes__Please_check_the_Ant_classpath__2;
+	public static String AntRunner_Build_Failed__3;
+	public static String AntRunner_Already_in_progess;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, InternalCoreAntMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/InternalCoreAntMessages.properties b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/InternalCoreAntMessages.properties
new file mode 100644
index 0000000..a3ffd92
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/InternalCoreAntMessages.properties
@@ -0,0 +1,24 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+###############################################################################
+
+AntCorePreferences_Malformed_URL__1=Malformed URL.
+AntCorePreferences_Library_not_specified_for___0__4=Library not specified for: {0}
+AntCorePreferences_No_library_for_task=The library \"{0}\" specified from \"{1}\" for the antTasks extension does not exist
+AntCorePreferences_No_library_for_type=The library \"{0}\" specified from \"{1}\" for the antTypes extension of does not exist
+AntCorePreferences_8=The library \"{0}\" specified from \"{1}\" for the antTasks or antTypes extension does not exist
+AntCorePreferences_6=The library \"{0}\" specified from \"{1}\" for the extraClasspathEntries extension does not exist
+AntCorePreferences_0=Exception parsing bundle manifest file.
+AntCorePreferences_1=Host not found for the fragment: {0}
+
+AntRunner_Could_not_find_one_or_more_classes__Please_check_the_Ant_classpath__1=Could not find one or more classes. Please check the Ant classpath.
+AntRunner_Could_not_find_one_or_more_classes__Please_check_the_Ant_classpath__2=Could not find one or more classes: \"{0}\". Please check the Ant classpath.
+AntRunner_Build_Failed__3=BUILD FAILED
+AntRunner_Already_in_progess=Ant build {0} already in progress. Concurrent Ant builds are possible if you specify to build in a separate JRE.
diff --git a/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/contentDescriber/AntBuildfileContentDescriber.java b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/contentDescriber/AntBuildfileContentDescriber.java
new file mode 100644
index 0000000..1cedf9d
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/contentDescriber/AntBuildfileContentDescriber.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 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
+ *     Philippe Ombredanne (pombredanne@nexb.com) - bug 125367
+ *******************************************************************************/
+package org.eclipse.ant.internal.core.contentDescriber;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.content.XMLContentDescriber;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * A content describer for Ant buildfiles.
+ * <p>
+ * If project top level element is found 
+ *      then if:
+ *          target sub-elements are found returns VALID
+ *          default attribute is found returns VALID
+ *          some other likely Ant element is found (classpath, import, macrodef, path, property, taskdef, typedef) returns VALID
+ *      else:
+ *          returns INDETERMINATE
+ * else
+ *      returns INDETERMINATE
+ * </p>
+ * 
+ * @since 3.1
+ */
+public final class AntBuildfileContentDescriber extends XMLContentDescriber implements IExecutableExtension {
+
+	/* (Intentionally not included in javadoc)
+	 * Determines the validation status for the given contents.
+	 * 
+	 * @param contents the contents to be evaluated
+	 * @return one of the following:<ul>
+	 * <li><code>VALID</code></li>,
+	 * <li><code>INVALID</code></li>,
+	 * <li><code>INDETERMINATE</code></li>
+	 * </ul>
+	 * @throws IOException
+	 */
+	private int checkCriteria(InputSource contents) throws IOException {
+		AntHandler antHandler = new AntHandler();
+		try {
+			if (!antHandler.parseContents(contents)) {
+				return INDETERMINATE;
+            }
+		} catch (SAXException e) {
+			// we may be handed any kind of contents... it is normal we fail to parse
+			return INDETERMINATE;
+		} catch (ParserConfigurationException e) {
+			// some bad thing happened - force this describer to be disabled
+			String message = "Internal Error: XML parser configuration error during content description for Ant buildfiles"; //$NON-NLS-1$
+			throw new RuntimeException(message);
+		}
+		// Check to see if we matched our criteria.
+		if (antHandler.hasRootProjectElement()) {
+			if (antHandler.hasProjectDefaultAttribute() || antHandler.hasTargetElement() || antHandler.hasAntElement()) {
+                //project and default attribute or project and target element(s) 
+				//or project and top level ant element(s) (classpath, import, macrodef, path, property, taskdef, typedef)
+                return VALID;
+            }
+            //only a top level project element...maybe an Ant buildfile
+            return INDETERMINATE;
+        } 
+			
+		return INDETERMINATE;
+	}
+
+	/* (Intentionally not included in javadoc)
+	 * @see IContentDescriber#describe(InputStream, IContentDescription)
+	 */
+	public int describe(InputStream contents, IContentDescription description) throws IOException {
+		// call the basic XML describer to do basic recognition
+		if (super.describe(contents, description) == INVALID) {
+			return INVALID;
+		}
+		// super.describe will have consumed some chars, need to rewind		
+		contents.reset();
+		// Check to see if we matched our criteria.		
+		return checkCriteria(new InputSource(contents));
+	}
+
+	/* (Intentionally not included in javadoc)
+	 * @see IContentDescriber#describe(Reader, IContentDescription)
+	 */
+	public int describe(Reader contents, IContentDescription description) throws IOException {
+		// call the basic XML describer to do basic recognition
+		if (super.describe(contents, description) == INVALID) {
+			return INVALID;
+		}
+		// super.describe will have consumed some chars, need to rewind
+		contents.reset();
+		// Check to see if we matched our criteria.
+		return checkCriteria(new InputSource(contents));
+	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+     */
+    public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.core/src_ant/META-INF/eclipse.inf b/ant/org.eclipse.ant.core/src_ant/META-INF/eclipse.inf
new file mode 100644
index 0000000..b4df3ab
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/META-INF/eclipse.inf
@@ -0,0 +1 @@
+jarprocessor.exclude.sign=true
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/DemuxInputStreamSetter.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/DemuxInputStreamSetter.java
new file mode 100644
index 0000000..78e824d
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/DemuxInputStreamSetter.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.core.ant;
+
+
+import org.apache.tools.ant.DemuxInputStream;
+import org.apache.tools.ant.Project;
+
+/**
+ * This class exists so that the Ant integration has backwards compatibility
+ * with Ant releases previous to 1.6. DemuxInputStream is a new class to Ant 1.6.
+ */
+class DemuxInputStreamSetter {
+
+	protected void remapSystemIn(Project project) {
+		System.setIn(new DemuxInputStream(project));
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseAntMain.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseAntMain.java
new file mode 100644
index 0000000..b50b591
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseAntMain.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.core.ant;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Main;
+import org.apache.tools.ant.Project;
+
+public class EclipseAntMain extends Main {
+
+	private Project fEclipseAntProject;
+
+	public EclipseAntMain(Project eclipseAntProject) {
+		super();
+		fEclipseAntProject = eclipseAntProject;
+	}
+
+	public static void run(String[] args, Project eclipseAntProject) {
+		Main projectHelpMain = new EclipseAntMain(eclipseAntProject);
+		projectHelpMain.startAnt(args, null, null);
+	}
+	
+	/*
+	 * @see org.apache.tools.ant.Main#exit(int)
+	 */
+	protected void exit(int exitCode) {
+		//disallow system exit
+	}
+	
+	/*
+	 * @see org.apache.tools.ant.Main#addBuildListeners(org.apache.tools.ant.Project)
+	 */
+	protected void addBuildListeners(Project project) {
+		Iterator listeners = fEclipseAntProject.getBuildListeners().iterator();
+		while (listeners.hasNext()) {
+			project.addBuildListener((BuildListener) listeners.next());
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseDefaultExecutor.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseDefaultExecutor.java
new file mode 100644
index 0000000..0daa35a
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseDefaultExecutor.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.core.ant;
+
+import java.util.Arrays;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.helper.DefaultExecutor;
+
+public class EclipseDefaultExecutor extends DefaultExecutor {
+
+    private static final EclipseSingleCheckExecutor SUB_EXECUTOR = new EclipseSingleCheckExecutor();
+    
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Executor#executeTargets(org.apache.tools.ant.Project, java.lang.String[])
+     */
+    public void executeTargets(Project project, String[] targetNames) throws BuildException {
+        Vector v= new Vector();
+        v.addAll(Arrays.asList(targetNames));
+        project.addReference("eclipse.ant.targetVector", v); //$NON-NLS-1$
+        super.executeTargets(project, targetNames);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Executor#getSubProjectExecutor()
+     */
+    public Executor getSubProjectExecutor() {
+       return SUB_EXECUTOR;
+    }
+}
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseMainHelper.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseMainHelper.java
new file mode 100644
index 0000000..6452502
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseMainHelper.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.core.ant;
+
+import org.apache.tools.ant.Project;
+
+public class EclipseMainHelper {
+
+	protected void runProjectHelp(String buildFileLocation, Project eclipseAntProject) {
+		EclipseAntMain.run(new String[]{"-f", buildFileLocation, "-p"}, eclipseAntProject); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+	
+	protected void runUsage(String buildFileLocation, Project eclipseAntProject) {
+		EclipseAntMain.run(new String[]{"-f", buildFileLocation, "-h"}, eclipseAntProject); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseSingleCheckExecutor.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseSingleCheckExecutor.java
new file mode 100644
index 0000000..e6549b6
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/EclipseSingleCheckExecutor.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.core.ant;
+
+import java.util.Arrays;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.helper.SingleCheckExecutor;
+
+public class EclipseSingleCheckExecutor extends SingleCheckExecutor {
+
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Executor#executeTargets(org.apache.tools.ant.Project, java.lang.String[])
+     */
+    public void executeTargets(Project project, String[] targetNames) throws BuildException {
+        Vector v= new Vector();
+        v.addAll(Arrays.asList(targetNames));
+        project.addReference("eclipse.ant.targetVector", v); //$NON-NLS-1$
+        super.executeTargets(project, targetNames);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Executor#getSubProjectExecutor()
+     */
+    public Executor getSubProjectExecutor() {
+        return this;
+    }
+}
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/ExecutorSetter.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/ExecutorSetter.java
new file mode 100644
index 0000000..03759f2
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/ExecutorSetter.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.core.ant;
+
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.Project;
+
+/**
+ * This class exists so that the Ant integration has backwards compatibility
+ * with Ant releases previous to 1.6.3. Executors are a new feature of Ant 1.6.3.
+ */
+public class ExecutorSetter {
+
+    protected void setExecutor(Project project) {
+        Executor executor= new EclipseDefaultExecutor();
+        project.setExecutor(executor);
+    }
+}
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/FailInputHandler.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/FailInputHandler.java
new file mode 100644
index 0000000..52155b3
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/FailInputHandler.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.core.ant;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.tools.ant.input.DefaultInputHandler;
+
+public class FailInputHandler extends DefaultInputHandler {
+	
+	protected InputStream getInputStream() {
+		//ensure any attempts to read input fail
+		return new InputStream(){
+			public int read() throws IOException {
+				throw new IOException();
+			}
+		};
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InputHandlerSetter.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InputHandlerSetter.java
new file mode 100644
index 0000000..42965b9
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InputHandlerSetter.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.core.ant;
+
+
+import java.text.MessageFormat; // can't use ICU in ant
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputHandler;
+
+/**
+ * This class exists so that the Ant integration has backwards compatibility
+ * with Ant releases previous to 1.5. InputHandlers are a new feature of Ant 1.5.
+ */
+class InputHandlerSetter {
+
+	protected void setInputHandler(Project project, String inputHandlerClassname) {
+		InputHandler handler = null;
+		if (inputHandlerClassname == null) {
+			handler = new DefaultInputHandler();
+		} else {
+			try {
+				handler = (InputHandler)(Class.forName(inputHandlerClassname).newInstance());
+			} catch (ClassCastException e) {
+				String msg = MessageFormat.format(InternalAntMessages.InternalAntRunner_handler_does_not_implement_InputHandler5, new String[]{inputHandlerClassname});
+				throw new BuildException(msg, e);
+			} catch (Exception e) {
+				String msg = MessageFormat.format(InternalAntMessages.InternalAntRunner_Unable_to_instantiate_input_handler_class, new String[]{inputHandlerClassname, e.getClass().getName()});
+				throw new BuildException(msg, e);
+			}
+		}
+		project.setInputHandler(handler);
+		project.setProjectReference(handler);
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InternalProject.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InternalProject.java
new file mode 100644
index 0000000..8a0aab2
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InternalProject.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2009 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 - derived implementation
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.core.ant;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat; // can't use ICU, ant build script
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * A subclass of Project to facilitate "faster" parsing with
+ * less garbage generated. This class is not used on Ant 1.6 and newer
+ * due to the improvements in lazy loading of these Ant versions.
+ * 
+ * Only three tasks are loaded (property, taskdef and 
+ * typedef: three tasks that can be defined outside of a target on Ant 1.5.1 or older).
+ *
+ * Datatypes are loaded if requested.
+ * 
+ * Derived from the original Ant Project class
+ */
+public class InternalProject extends Project {
+
+	private Hashtable typeNameToClass = null;
+	
+	public InternalProject() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.Project#init()
+	 */
+	public void init() throws BuildException {
+		setJavaVersionProperty();
+
+		try {
+			Class taskClass = Class.forName("org.apache.tools.ant.taskdefs.Property"); //$NON-NLS-1$
+			addTaskDefinition("property", taskClass); //$NON-NLS-1$
+			taskClass = Class.forName("org.apache.tools.ant.taskdefs.Typedef"); //$NON-NLS-1$
+			addTaskDefinition("typedef", taskClass); //$NON-NLS-1$
+			taskClass = Class.forName("org.apache.tools.ant.taskdefs.Taskdef"); //$NON-NLS-1$
+			addTaskDefinition("taskdef", taskClass); //$NON-NLS-1$
+		} catch (NoClassDefFoundError e) {
+			throw new BuildException(InternalAntMessages.InternalAntRunner_Missing_Class, e);
+		} catch (ClassNotFoundException c) {
+			throw new BuildException(InternalAntMessages.InternalAntRunner_Missing_Class, c);
+		}
+
+		setSystemProperties();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.Project#createDataType(java.lang.String)
+	 */
+	public Object createDataType(String typeName) throws BuildException {
+		if (typeNameToClass == null) {
+			initializeTypes();
+		}
+		Class typeClass = (Class) typeNameToClass.get(typeName);
+
+		if (typeClass == null) {
+			return null;
+		}
+
+		Throwable thrown = null;
+		try {
+			Constructor ctor = null;
+			boolean noArg = false;
+			// DataType can have a "no arg" constructor or take a single
+			// Project argument.
+			try {
+				ctor = typeClass.getConstructor(new Class[0]);
+				noArg = true;
+			} catch (NoSuchMethodException nse) {
+				ctor = typeClass.getConstructor(new Class[] { Project.class });
+				noArg = false;
+			}
+
+			Object o = null;
+			if (noArg) {
+				o = ctor.newInstance(new Object[0]);
+			} else {
+				o = ctor.newInstance(new Object[] { this });
+			}
+			if (o instanceof ProjectComponent) {
+				((ProjectComponent) o).setProject(this);
+			}
+			return o;
+		} catch (InvocationTargetException ite) {
+			thrown = ite.getTargetException();
+		} catch (IllegalArgumentException e) {
+			thrown = e;
+		} catch (InstantiationException e) {
+			thrown = e;
+		} catch (IllegalAccessException e) {
+			thrown = e;
+		} catch (NoSuchMethodException nse) {
+			thrown = nse;
+		} catch (NoClassDefFoundError ncdfe) {
+			thrown = ncdfe;
+		}
+		if (thrown != null) {
+			String message= MessageFormat.format(InternalAntMessages.InternalProject_could_not_create_type, new String[]{typeName, thrown.toString()});
+			throw new BuildException(message, thrown);
+		}
+		// this line is actually unreachable
+		return null;
+	}
+
+	/**
+	 * Initialize the mapping of data type name to data type classname
+	 */
+	private void initializeTypes() {
+		typeNameToClass = new Hashtable(18);
+		String dataDefs = "/org/apache/tools/ant/types/defaults.properties"; //$NON-NLS-1$
+		try {
+			Properties props = new Properties();
+			InputStream in = Project.class.getResourceAsStream(dataDefs);
+			if (in == null) {
+				return;
+			}
+			props.load(in);
+			in.close();
+
+			Enumeration enumeration = props.propertyNames();
+			while (enumeration.hasMoreElements()) {
+				String typeName = (String) enumeration.nextElement();
+				String className = props.getProperty(typeName);
+				try {
+					Class typeClass= Class.forName(className);
+					typeNameToClass.put(typeName, typeClass);
+				} catch (NoClassDefFoundError e) {
+					//ignore
+				} catch (ClassNotFoundException c) {
+					//ignore
+				}
+			}
+		} catch (IOException ioe) {
+			return;
+		}
+
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.Project#getDataTypeDefinitions()
+	 */
+	public Hashtable getDataTypeDefinitions() {
+		if (typeNameToClass == null) {
+			initializeTypes();
+		}
+		return typeNameToClass;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.Project#addDataTypeDefinition(java.lang.String, java.lang.Class)
+	 */
+	public void addDataTypeDefinition(String typeName, Class typeClass) {
+		getDataTypeDefinitions();
+		typeNameToClass.put(typeName, typeClass);
+	}
+}
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InternalProject2.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InternalProject2.java
new file mode 100644
index 0000000..85ae17f
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InternalProject2.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.core.ant;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+
+public class InternalProject2 extends Project {
+
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Project#createClassLoader(org.apache.tools.ant.types.Path)
+     */
+    public AntClassLoader createClassLoader(Path path) {
+    	AntClassLoader loader= super.createClassLoader(path);
+    	if (path == null) {
+    		//use the "fake" Eclipse runtime classpath for Ant
+    		loader.setClassPath(Path.systemClasspath);
+    	}
+        
+        return loader;
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/NullInputHandler.java b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/NullInputHandler.java
new file mode 100644
index 0000000..c660962
--- /dev/null
+++ b/ant/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/NullInputHandler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.core.ant;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.input.InputRequest;
+
+/**
+ * A input handler that does nothing with input requests
+ * Used to ensure we do not block while retrieving targets from an Ant buildfile
+ * that has an input task in the top level implicit target
+ */
+public class NullInputHandler implements InputHandler {
+
+	public NullInputHandler() {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.input.InputHandler#handleInput(org.apache.tools.ant.input.InputRequest)
+	 */
+	public void handleInput(InputRequest request) throws BuildException {
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/.classpath b/ant/org.eclipse.ant.launching/.classpath
new file mode 100644
index 0000000..a8eb00e
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" output="loggers_bin" path="loggers"/>
+	<classpathentry kind="src" output="common_bin" path="common"/>
+	<classpathentry kind="src" output="remote_bin" path="remote"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git "a/ant/org.eclipse.ant.launching/.externalToolBuilders/build common debug \133Builder\135.launch" "b/ant/org.eclipse.ant.launching/.externalToolBuilders/build common debug \133Builder\135.launch"
new file mode 100644
index 0000000..2f1ec55
--- /dev/null
+++ "b/ant/org.eclipse.ant.launching/.externalToolBuilders/build common debug \133Builder\135.launch"
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
+<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;launchConfigurationWorkingSet editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot; factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; id=&quot;1254539808328_112&quot; label=&quot;working set&quot; name=&quot;working set&quot;&gt;&#13;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.launching/lib&quot; type=&quot;2&quot;/&gt;&#13;&#10;&lt;/launchConfigurationWorkingSet&gt;}"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/org.eclipse.ant.launching/buildfiles/buildCommonDebug.xml"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.ant.launching"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;launchConfigurationWorkingSet editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot; factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; id=&quot;1254539834953_113&quot; label=&quot;workingSet&quot; name=&quot;workingSet&quot;&gt;&#13;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.launching/common&quot; type=&quot;2&quot;/&gt;&#13;&#10;&lt;/launchConfigurationWorkingSet&gt;}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.ant.launching/buildfiles/buildCommonDebug.xml}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+<stringAttribute key="process_factory_id" value="org.eclipse.ant.ui.remoteAntProcessFactory"/>
+</launchConfiguration>
diff --git "a/ant/org.eclipse.ant.launching/.externalToolBuilders/build loggers \133Builder\135.launch" "b/ant/org.eclipse.ant.launching/.externalToolBuilders/build loggers \133Builder\135.launch"
new file mode 100644
index 0000000..ec718d8
--- /dev/null
+++ "b/ant/org.eclipse.ant.launching/.externalToolBuilders/build loggers \133Builder\135.launch"
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
+<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
+<booleanAttribute key="org.eclipse.ant.uiSET_INPUTHANDLER" value="false"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;launchConfigurationWorkingSet editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot; factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; id=&quot;1254539604968_29&quot; label=&quot;working set&quot; name=&quot;working set&quot;&gt;&#13;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.launching/lib&quot; type=&quot;2&quot;/&gt;&#13;&#10;&lt;/launchConfigurationWorkingSet&gt;}"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/org.eclipse.ant.launching/buildfiles/buildLoggers.xml"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.ant.launching"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;launchConfigurationWorkingSet editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot; factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; id=&quot;1254539671875_56&quot; label=&quot;workingSet&quot; name=&quot;workingSet&quot;&gt;&#13;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.launching/loggers&quot; type=&quot;2&quot;/&gt;&#13;&#10;&lt;/launchConfigurationWorkingSet&gt;}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.ant.launching/buildfiles/buildLoggers.xml}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+<stringAttribute key="process_factory_id" value="org.eclipse.ant.ui.remoteAntProcessFactory"/>
+</launchConfiguration>
diff --git "a/ant/org.eclipse.ant.launching/.externalToolBuilders/build remote support \133Builder\135.launch" "b/ant/org.eclipse.ant.launching/.externalToolBuilders/build remote support \133Builder\135.launch"
new file mode 100644
index 0000000..c56eb96
--- /dev/null
+++ "b/ant/org.eclipse.ant.launching/.externalToolBuilders/build remote support \133Builder\135.launch"
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
+<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; id=&quot;1254617191468_44&quot; label=&quot;working set&quot; name=&quot;working set&quot;&gt;&#13;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.launching/lib&quot; type=&quot;2&quot;/&gt;&#13;&#10;&lt;/launchConfigurationWorkingSet&gt;}"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/org.eclipse.ant.launching/buildfiles/buildRemote.xml"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.ant.launching"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; id=&quot;1254617206453_45&quot; label=&quot;workingSet&quot; name=&quot;workingSet&quot;&gt;&#13;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.launching/remote&quot; type=&quot;2&quot;/&gt;&#13;&#10;&lt;/launchConfigurationWorkingSet&gt;}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.ant.launching/buildfiles/buildRemote.xml}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+<stringAttribute key="process_factory_id" value="org.eclipse.ant.ui.remoteAntProcessFactory"/>
+</launchConfiguration>
diff --git a/ant/org.eclipse.ant.launching/.project b/ant/org.eclipse.ant.launching/.project
new file mode 100644
index 0000000..5f704ef
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/.project
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.ant.launching</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>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<triggers>auto,full,incremental,</triggers>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/build loggers [Builder].launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<triggers>auto,full,incremental,</triggers>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/build common debug [Builder].launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<triggers>auto,full,incremental,</triggers>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/build remote support [Builder].launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/ant/org.eclipse.ant.launching/about.html b/ant/org.eclipse.ant.launching/about.html
new file mode 100644
index 0000000..5993925
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/about.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>October 8, 2009</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
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Third Party Content</h3>
+
+<p>The Content includes items that have been sourced from third parties as set out below. If you 
+did not receive this Content directly from the Eclipse Foundation, the following is provided 
+for informational purposes only, and you should look to the Redistributor&rsquo;s license for 
+terms and conditions of use.</p>
+
+<h4>Ant 1.7.1</h4>
+
+<p>The following classes in the plug-in JAR are based on Ant code developed by The Apache Software Foundation and shall be defined as the &quot;Ant-Derived Work&quot;:</p>
+
+<ul>
+	<li>org.eclipse.ant.internal.launching.remote.InternalAntRunner</li>
+</ul>
+
+<p>The object code for InternalAntRunner is located in lib/remote.jar and the source code is located in lib/remotesrc.zip.</p>
+
+<p>Your use of the Ant-Derived Work is subject to the terms and conditions of the Apache Software License 2.0.  A copy of the license is contained
+in the file <a href="about_files/asl-v20.txt" target="_blank">about_files/asl-v20.txt</a> and is also available at 
+<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>.</p>
+
+<p>The names &quot;Ant&quot; and  &quot;Apache Software Foundation&quot; must not be used to endorse or promote products derived from this 
+software without prior written permission.  For written permission, please contact <a href="mailto:apache@apache.org">apache@apache.org</a>.</p>
+
+<p>The Apache attribution <a href="about_files/NOTICE" target="_blank">NOTICE</a> file is included with the Content in accordance with 4d of the Apache License, Version 2.0.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/build.properties b/ant/org.eclipse.ant.launching/build.properties
new file mode 100644
index 0000000..f7a9d05
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/build.properties
@@ -0,0 +1,32 @@
+###############################################################################
+# Copyright (c) 2009 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
+###############################################################################
+source.. = src/                           
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               plugin.properties,\
+               lib/antdebug.jar,\
+               lib/loggers.jar,\
+               lib/remote.jar,\
+               about.html
+
+jars.compile.order = .,\
+				                     lib/antdebug.jar,\
+                     lib/loggers.jar,\
+                     lib/remote.jar
+source.lib/loggers.jar = loggers/
+output.lib/loggers.jar = loggers_bin/
+source.lib/antdebug.jar = common/
+output.lib/antdebug.jar = common_bin/
+source.lib/remote.jar = remote/
+output.lib/remote.jar = remote_bin/
+src.includes = about.html
diff --git a/ant/org.eclipse.ant.launching/buildfiles/buildCommonDebug.xml b/ant/org.eclipse.ant.launching/buildfiles/buildCommonDebug.xml
new file mode 100644
index 0000000..88b99eb
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/buildfiles/buildCommonDebug.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     Copyright (c) 2005, 2009 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
+ -->
+
+<project name="Build Ant common debug support JAR" default="build" basedir="..">
+	
+	<target name="build" description="Cleans, builds and refreshes" depends="clean, lib/antdebuglib.jar"/>
+
+	<target name="init">
+		<property name="temp.folder" value="${basedir}/temp.folder"/>
+		<property name="build.result.folder" value="${basedir}"/>
+	</target>
+	
+	<target name="lib/antdebuglib.jar" description= "Creates the antdebug.jar" depends="init">
+		<property name="destdir" value="${temp.folder}/lib/antdebug.jar.bin"/>
+		<delete dir="${destdir}"/>
+		<mkdir dir="${destdir}"/>
+		<!-- copy necessary class files resources -->
+		<copy todir="${destdir}">
+			<fileset dir="${basedir}/common_bin"/>
+		</copy>
+		<mkdir dir="${build.result.folder}/lib"/>
+		<jar destfile="${build.result.folder}/lib/antdebug.jar" basedir="${destdir}"/>
+		<delete dir="${temp.folder}"/>
+	</target>
+
+	<target name="clean" description="Deletes previous build remnants" depends="init">
+		<delete file="${build.result.folder}/lib/antdebug.jar"/>
+		<delete dir="${temp.folder}"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.launching/buildfiles/buildLoggers.xml b/ant/org.eclipse.ant.launching/buildfiles/buildLoggers.xml
new file mode 100644
index 0000000..1dbb04c
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/buildfiles/buildLoggers.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     Copyright (c) 2005, 2009 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
+ -->
+
+<project name="Build Ant loggers support JAR" default="build" basedir="..">
+	
+	<target name="build" description="Cleans, builds and refreshes" depends="clean, lib/loggerslib.jar"/>
+
+	<target name="init">
+		<property name="temp.folder" value="${basedir}/temp.folder"/>
+		<property name="build.result.folder" value="${basedir}"/>
+	</target>
+
+	<target name="lib/loggerslib.jar" description= "Creates the loggers.jar" depends="init">
+		<property name="destdir" value="${temp.folder}/lib/loggers.jar.bin"/>
+		<delete dir="${destdir}"/>
+		<mkdir dir="${destdir}"/>
+		<!-- copy necessary class files resources -->
+		<copy todir="${destdir}">
+			<fileset dir="${basedir}/loggers_bin/"/>
+		</copy>
+		<mkdir dir="${build.result.folder}/lib"/>
+		<jar destfile="${build.result.folder}/lib/loggers.jar" basedir="${destdir}"/>
+		<delete dir="${temp.folder}"/>
+	</target>
+
+	<target name="clean" description="Deletes previous build remnants" depends="init">
+		<delete file="${build.result.folder}/lib/loggers.jar"/>
+		<delete dir="${temp.folder}"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.launching/buildfiles/buildRemote.xml b/ant/org.eclipse.ant.launching/buildfiles/buildRemote.xml
new file mode 100644
index 0000000..2122e58
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/buildfiles/buildRemote.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+     Copyright (c) 2005, 2009 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
+ -->
+
+<project name="Build Ant remote support JAR" default="build" basedir="..">
+	
+	<target name="build" description="Cleans, builds and refreshes" depends="clean, lib/remotelib.jar"/>
+
+	<target name="init">
+		<property name="temp.folder" value="${basedir}/temp.folder"/>
+		<property name="build.result.folder" value="${basedir}"/>
+	</target>
+	
+	<target name="lib/remotelib.jar" description= "Creates the remote.jar" depends="init">
+		<property name="destdir" value="${temp.folder}/lib/remote.jar.bin"/>
+		<delete dir="${destdir}"/>
+		<mkdir dir="${destdir}"/>
+		<!-- copy necessary class files resources -->
+		<copy todir="${destdir}">
+			<fileset dir="${basedir}/remote_bin"/>
+		</copy>
+		<mkdir dir="${build.result.folder}/lib"/>
+		<jar destfile="${build.result.folder}/lib/remote.jar" basedir="${destdir}"/>
+		<delete dir="${temp.folder}"/>
+	</target>
+
+	<target name="clean" description="Deletes previous build remnants" depends="init">
+		<delete file="${build.result.folder}/lib/remote.jar"/>
+		<delete dir="${temp.folder}"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.launching/common/META-INF/eclipse.inf b/ant/org.eclipse.ant.launching/common/META-INF/eclipse.inf
new file mode 100644
index 0000000..b4df3ab
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/common/META-INF/eclipse.inf
@@ -0,0 +1 @@
+jarprocessor.exclude.sign=true
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/common/org/eclipse/ant/internal/launching/debug/IDebugBuildLogger.java b/ant/org.eclipse.ant.launching/common/org/eclipse/ant/internal/launching/debug/IDebugBuildLogger.java
new file mode 100644
index 0000000..9eb06c5
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/common/org/eclipse/ant/internal/launching/debug/IDebugBuildLogger.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug;
+
+
+public interface IDebugBuildLogger {
+
+	/**
+	 * Requests to suspend the build if the current debug state
+	 * indicates that suspension is required.
+	 */
+    public abstract void waitIfSuspended();
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/loggers/META-INF/eclipse.inf b/ant/org.eclipse.ant.launching/loggers/META-INF/eclipse.inf
new file mode 100644
index 0000000..b4df3ab
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/loggers/META-INF/eclipse.inf
@@ -0,0 +1 @@
+jarprocessor.exclude.sign=true
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/loggers/org/eclipse/ant/internal/launching/runtime/logger/NullBuildLogger.java b/ant/org.eclipse.ant.launching/loggers/org/eclipse/ant/internal/launching/runtime/logger/NullBuildLogger.java
new file mode 100644
index 0000000..8d50250
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/loggers/org/eclipse/ant/internal/launching/runtime/logger/NullBuildLogger.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.runtime.logger;
+
+
+import java.io.PrintStream;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildLogger;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.StringUtils;
+import org.eclipse.ant.core.AntSecurityException;
+import org.eclipse.ant.internal.core.AbstractEclipseBuildLogger;
+import org.eclipse.core.runtime.OperationCanceledException;
+
+public class NullBuildLogger extends AbstractEclipseBuildLogger implements BuildLogger{
+
+	protected int fMessageOutputLevel = Project.MSG_INFO;
+	private PrintStream fErr= null;
+	private PrintStream fOut= null;
+	protected boolean fEmacsMode= false;
+	
+	/**
+	 * An exception that has already been logged.
+	 */
+	protected Throwable fHandledException= null;
+	
+	/**
+	 * @see org.apache.tools.ant.BuildLogger#setMessageOutputLevel(int)
+	 */
+	public void setMessageOutputLevel(int level) {
+		fMessageOutputLevel= level;
+	}
+	
+	protected int getMessageOutputLevel() {
+		return fMessageOutputLevel;
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildLogger#setEmacsMode(boolean)
+	 */
+	public void setEmacsMode(boolean emacsMode) {
+		fEmacsMode= emacsMode;
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#buildStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void buildStarted(BuildEvent event) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#buildFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void buildFinished(BuildEvent event) {
+		String message= handleException(event);
+        if (message != null) {
+            logMessage(message, getMessageOutputLevel());
+        }
+		fHandledException= null;
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void targetStarted(BuildEvent event) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#targetFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void targetFinished(BuildEvent event) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#taskStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void taskStarted(BuildEvent event) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void taskFinished(BuildEvent event) {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.BuildListener#messageLogged(org.apache.tools.ant.BuildEvent)
+	 */
+	public void messageLogged(BuildEvent event) {
+		logMessage(event.getMessage(), event.getPriority());
+	}
+
+	protected PrintStream getErrorPrintStream() {
+		return fErr;
+	}
+	
+	protected PrintStream getOutputPrintStream() {
+		return fOut;
+	}
+	
+	/**
+	 * @see org.apache.tools.ant.BuildLogger#setErrorPrintStream(java.io.PrintStream)
+	 */
+	public void setErrorPrintStream(PrintStream err) {
+		//this build logger logs to "null" unless
+		//the user has explicitly set a logfile to use
+		if (err == System.err) {
+			fErr= null;
+		} else {
+			fErr= err;
+		}
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildLogger#setOutputPrintStream(java.io.PrintStream)
+	 */
+	public void setOutputPrintStream(PrintStream output) {
+		//this build logger logs to "null" unless
+		//the user has explicitly set a logfile to use
+		if (output == System.out) {
+			fOut= null;
+		} else {
+			fOut= output;
+		}
+	}
+	
+	protected void logMessage(String message, int priority) {
+		if (priority > getMessageOutputLevel()) {
+			return;
+		}
+		
+		if (priority == Project.MSG_ERR) {
+			if (getErrorPrintStream() != null && getErrorPrintStream() != System.err) {
+				//user has designated to log to a logfile
+				getErrorPrintStream().println(message);
+			}
+		} else {
+			if (getOutputPrintStream() != null && getOutputPrintStream() != System.out) {
+				//user has designated to log to a logfile
+				getOutputPrintStream().println(message);
+			} 
+		}
+	}
+	
+	protected String handleException(BuildEvent event) {
+		Throwable exception = event.getException();
+		if (exception == null || exception == fHandledException
+		|| exception instanceof OperationCanceledException
+		|| exception instanceof AntSecurityException) {
+			return null;
+		}
+		fHandledException= exception;
+        StringBuffer message= new StringBuffer();
+        message.append(StringUtils.LINE_SEP);
+        message.append(RuntimeMessages.NullBuildLogger_1);
+        message.append(StringUtils.LINE_SEP);
+        if (Project.MSG_VERBOSE <= fMessageOutputLevel || !(exception instanceof BuildException)) {
+            message.append(StringUtils.getStackTrace(exception));
+        } else {
+            if (exception instanceof BuildException) {
+                message.append(exception.toString()).append(StringUtils.LINE_SEP);
+            } else {
+                message.append(exception.getMessage()).append(StringUtils.LINE_SEP);
+            }
+        }
+        
+		return message.toString();	
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/loggers/org/eclipse/ant/internal/launching/runtime/logger/RuntimeMessages.java b/ant/org.eclipse.ant.launching/loggers/org/eclipse/ant/internal/launching/runtime/logger/RuntimeMessages.java
new file mode 100644
index 0000000..a1db558
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/loggers/org/eclipse/ant/internal/launching/runtime/logger/RuntimeMessages.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.runtime.logger;
+
+import org.eclipse.osgi.util.NLS;
+
+public class RuntimeMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.launching.runtime.logger.RuntimeMessages";//$NON-NLS-1$
+
+	public static String NullBuildLogger_1;
+	public static String AntProcessBuildLogger_Total_time;
+	public static String AntProcessBuildLogger__minutes_2;
+	public static String AntProcessBuildLogger__minute_3;
+	public static String AntProcessBuildLogger__seconds_4;
+	public static String AntProcessBuildLogger__second_5;
+	public static String AntProcessBuildLogger__milliseconds_6;
+	
+	public static String AntProcessDebugBuildLogger_1;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, RuntimeMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/loggers/org/eclipse/ant/internal/launching/runtime/logger/RuntimeMessages.properties b/ant/org.eclipse.ant.launching/loggers/org/eclipse/ant/internal/launching/runtime/logger/RuntimeMessages.properties
new file mode 100644
index 0000000..573188a
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/loggers/org/eclipse/ant/internal/launching/runtime/logger/RuntimeMessages.properties
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+###############################################################################
+
+NullBuildLogger_1=BUILD FAILED
+AntProcessBuildLogger_Total_time=Total time: 
+AntProcessBuildLogger__minutes_2=\ minutes
+AntProcessBuildLogger__minute_3=\ minute
+AntProcessBuildLogger__seconds_4=\ seconds
+AntProcessBuildLogger__second_5=\ second
+AntProcessBuildLogger__milliseconds_6=\ milliseconds
+
+AntProcessDebugBuildLogger_1=Build cancelled.
diff --git a/ant/org.eclipse.ant.launching/plugin.properties b/ant/org.eclipse.ant.launching/plugin.properties
new file mode 100644
index 0000000..650fb4f
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/plugin.properties
@@ -0,0 +1,24 @@
+###############################################################################
+# Copyright (c) 2009 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
+###############################################################################
+
+pluginName=Ant Launching Support
+providerName=Eclipse.org
+
+AntBuild = Ant Build
+AntLaunchDelegate.name=Eclipse Ant Launcher
+AntLaunchDelegate.description=The Eclipse Ant Launcher supports running and debugging Ant build files.
+
+AntBuilder.name=Ant Builder
+AntBuilderLaunchDelegate.name= Eclipse Ant Builder Launcher
+AntBuilderLaunchDelegate.description=The Eclipse Ant Builder Launcher supports running Ant build files.
+
+antBreakpointGroupName= Ant Breakpoints
+AntLineBreakpoint.name = Ant Line Breakpoint
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/remote/META-INF/eclipse.inf b/ant/org.eclipse.ant.launching/remote/META-INF/eclipse.inf
new file mode 100644
index 0000000..b4df3ab
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/META-INF/eclipse.inf
@@ -0,0 +1 @@
+jarprocessor.exclude.sign=true
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/AntSecurityException.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/AntSecurityException.java
new file mode 100644
index 0000000..294b248
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/AntSecurityException.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote;
+
+/**
+ * A security exception that is thrown by the AntSecurityManager if
+ * an Ant task in some way attempts to halt or exit the Java Virtual Machine.
+ * 
+ * @since 2.1
+ */
+public class AntSecurityException extends SecurityException {
+
+	private static final long serialVersionUID = 1L;
+
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/AntSecurityManager.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/AntSecurityManager.java
new file mode 100644
index 0000000..30f7ebb
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/AntSecurityManager.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote;
+
+
+import java.io.FileDescriptor;
+import java.net.InetAddress;
+import java.net.SocketPermission;
+import java.security.Permission;
+import java.util.PropertyPermission;
+
+/**
+ * A security manager that always throws an <code>AntSecurityException</code>
+ * if the calling thread attempts to cause the Java Virtual Machine to 
+ * exit/halt or if the restricted thread attempts to set a System property.
+ * Otherwise this manager just delegates to the pre-existing manager
+ * passed in the constructor or mimics the default security manager behavior
+ */
+public class AntSecurityManager extends SecurityManager {
+
+	private SecurityManager fSecurityManager= null;
+	private Thread fRestrictedThread= null;
+	//ensure that the PropertyPermission class is loaded before we 
+	//start checking permissions: bug 85908
+	private static final PropertyPermission fgPropertyPermission= new PropertyPermission("*", "write"); //$NON-NLS-1$ //$NON-NLS-2$
+	
+	private boolean fAllowSettingSystemProperties= true;
+	
+	public AntSecurityManager(SecurityManager securityManager, Thread restrictedThread, boolean allowSettingProperties) {
+		fSecurityManager= securityManager;
+		fRestrictedThread= restrictedThread;
+		fAllowSettingSystemProperties= allowSettingProperties;
+	}
+	
+	public AntSecurityManager(SecurityManager securityManager, Thread restrictedThread) {
+		this(securityManager, restrictedThread, true);
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkExit(int)
+	 */
+	public void checkExit(int status) {
+		//no exit allowed from the restricted thread...System.exit is being called
+		//by some ant task...disallow the exit
+		if (Thread.currentThread() == fRestrictedThread) {
+			throw new AntSecurityException();
+		}
+		if (fSecurityManager != null) {
+			fSecurityManager.checkExit(status);
+		}
+	}
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkAccept(java.lang.String, int)
+	 */
+	public void checkAccept(String host, int port) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkAccept(host, port);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkAccess(java.lang.Thread)
+	 */
+	public void checkAccess(Thread t) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkAccess(t);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkAccess(java.lang.ThreadGroup)
+	 */
+	public void checkAccess(ThreadGroup g) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkAccess(g);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkAwtEventQueueAccess()
+	 */
+	public void checkAwtEventQueueAccess() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkAwtEventQueueAccess();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkConnect(java.lang.String, int, java.lang.Object)
+	 */
+	public void checkConnect(String host, int port, Object context) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkConnect(host, port, context);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkConnect(java.lang.String, int)
+	 */
+	public void checkConnect(String host, int port) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkConnect(host, port);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkCreateClassLoader()
+	 */
+	public void checkCreateClassLoader() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkCreateClassLoader();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkDelete(java.lang.String)
+	 */
+	public void checkDelete(String file) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkDelete(file);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkExec(java.lang.String)
+	 */
+	public void checkExec(String cmd) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkExec(cmd);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkLink(java.lang.String)
+	 */
+	public void checkLink(String lib) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkLink(lib);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkListen(int)
+	 */
+	public void checkListen(int port) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkListen(port);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkMemberAccess(java.lang.Class, int)
+	 */
+	public void checkMemberAccess(Class clazz, int which) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkMemberAccess(clazz, which);
+		}
+	}
+
+	/**
+	 * @see java.lang.SecurityManager#checkMulticast(java.net.InetAddress, byte)
+	 * @deprecated
+	 */
+	public void checkMulticast(InetAddress maddr, byte ttl) {
+		if (fSecurityManager != null) {
+			String host = maddr.getHostAddress();
+			if (!host.startsWith("[") && host.indexOf(':') != -1) { //$NON-NLS-1$
+	   			host = "[" + host + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+			}
+	    	checkPermission(new SocketPermission(host, "accept,connect")); //$NON-NLS-1$
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkMulticast(java.net.InetAddress)
+	 */
+	public void checkMulticast(InetAddress maddr) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkMulticast(maddr);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPackageAccess(java.lang.String)
+	 */
+	public void checkPackageAccess(String pkg) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPackageAccess(pkg);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPackageDefinition(java.lang.String)
+	 */
+	public void checkPackageDefinition(String pkg) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPackageDefinition(pkg);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPermission(java.security.Permission, java.lang.Object)
+	 */
+	public void checkPermission(Permission perm, Object context) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPermission(perm, context);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPermission(java.security.Permission)
+	 */
+	public void checkPermission(Permission perm) {
+		if (!fAllowSettingSystemProperties && fgPropertyPermission.implies(perm) && fRestrictedThread == Thread.currentThread()) {
+			//attempting to write a system property
+			throw new AntSecurityException();
+		}
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPermission(perm);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPrintJobAccess()
+	 */
+	public void checkPrintJobAccess() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPrintJobAccess();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPropertiesAccess()
+	 */
+	public void checkPropertiesAccess() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPropertiesAccess();
+		}
+		super.checkPropertiesAccess();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
+	 */
+	public void checkPropertyAccess(String key) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkPropertyAccess(key);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkRead(java.io.FileDescriptor)
+	 */
+	public void checkRead(FileDescriptor fd) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkRead(fd);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkRead(java.lang.String, java.lang.Object)
+	 */
+	public void checkRead(String file, Object context) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkRead(file, context);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkRead(java.lang.String)
+	 */
+	public void checkRead(String file) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkRead(file);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkSecurityAccess(java.lang.String)
+	 */
+	public void checkSecurityAccess(String target) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkSecurityAccess(target);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkSetFactory()
+	 */
+	public void checkSetFactory() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkSetFactory();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkSystemClipboardAccess()
+	 */
+	public void checkSystemClipboardAccess() {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkSystemClipboardAccess();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
+	 */
+	public boolean checkTopLevelWindow(Object window) {
+		if (fSecurityManager != null) {
+			return fSecurityManager.checkTopLevelWindow(window);
+		}
+		return super.checkTopLevelWindow(window);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)
+	 */
+	public void checkWrite(FileDescriptor fd) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkWrite(fd);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#checkWrite(java.lang.String)
+	 */
+	public void checkWrite(String file) {
+		if (fSecurityManager != null) {
+			fSecurityManager.checkWrite(file);
+		}
+	}
+
+	/**
+	 * @see java.lang.SecurityManager#getInCheck()
+	 * @deprecated
+	 */
+	public boolean getInCheck() {
+		if (fSecurityManager != null) {
+			return fSecurityManager.getInCheck();
+		}
+		return super.getInCheck();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#getSecurityContext()
+	 */
+	public Object getSecurityContext() {
+		if (fSecurityManager != null) {
+			return fSecurityManager.getSecurityContext();
+		}
+		return super.getSecurityContext();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.SecurityManager#getThreadGroup()
+	 */
+	public ThreadGroup getThreadGroup() {
+		if (fSecurityManager != null) {
+			fSecurityManager.getThreadGroup();
+		}
+		return super.getThreadGroup();
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/DemuxInputStreamSetter.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/DemuxInputStreamSetter.java
new file mode 100644
index 0000000..9111611
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/DemuxInputStreamSetter.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote;
+
+
+import org.apache.tools.ant.DemuxInputStream;
+import org.apache.tools.ant.Project;
+
+/**
+ * This class exists so that the Ant integration has backwards compatibility
+ * with Ant releases previous to 1.6. DemuxInputStream is a new class to Ant 1.6.
+ */
+class DemuxInputStreamSetter {
+
+	protected void remapSystemIn(Project project) {
+		System.setIn(new DemuxInputStream(project));
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/EclipseDefaultExecutor.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/EclipseDefaultExecutor.java
new file mode 100644
index 0000000..6b86f5d
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/EclipseDefaultExecutor.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote;
+
+import java.util.Arrays;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.helper.DefaultExecutor;
+
+public class EclipseDefaultExecutor extends DefaultExecutor {
+
+    private static final EclipseSingleCheckExecutor SUB_EXECUTOR = new EclipseSingleCheckExecutor();
+    
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Executor#executeTargets(org.apache.tools.ant.Project, java.lang.String[])
+     */
+    public void executeTargets(Project project, String[] targetNames) throws BuildException {
+        Vector v= new Vector();
+        v.addAll(Arrays.asList(targetNames));
+        project.addReference("eclipse.ant.targetVector", v); //$NON-NLS-1$
+        super.executeTargets(project, targetNames);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Executor#getSubProjectExecutor()
+     */
+    public Executor getSubProjectExecutor() {
+       return SUB_EXECUTOR;
+    }
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/EclipseSingleCheckExecutor.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/EclipseSingleCheckExecutor.java
new file mode 100644
index 0000000..62ddd4f
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/EclipseSingleCheckExecutor.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote;
+
+import java.util.Arrays;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.helper.SingleCheckExecutor;
+
+public class EclipseSingleCheckExecutor extends SingleCheckExecutor {
+
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Executor#executeTargets(org.apache.tools.ant.Project, java.lang.String[])
+     */
+    public void executeTargets(Project project, String[] targetNames) throws BuildException {
+        Vector v= new Vector();
+        v.addAll(Arrays.asList(targetNames));
+        project.addReference("eclipse.ant.targetVector", v); //$NON-NLS-1$
+        super.executeTargets(project, targetNames);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.tools.ant.Executor#getSubProjectExecutor()
+     */
+    public Executor getSubProjectExecutor() {
+        return this;
+    }
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/ExecutorSetter.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/ExecutorSetter.java
new file mode 100644
index 0000000..ed9aba5
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/ExecutorSetter.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote;
+
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.Project;
+
+/**
+ * This class exists so that the Ant integration has backwards compatibility
+ * with Ant releases previous to 1.6.3. Executors are a new feature of Ant 1.6.3.
+ */
+public class ExecutorSetter {
+
+    protected void setExecutor(Project project) {
+        Executor executor= new EclipseDefaultExecutor();
+        project.setExecutor(executor);
+    }
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/InputHandlerSetter.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/InputHandlerSetter.java
new file mode 100644
index 0000000..21bdd1f
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/InputHandlerSetter.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote;
+
+
+import java.text.MessageFormat; // can't use ICU, used by ant
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputHandler;
+
+/**
+ * This class exists so that the Ant integration has backwards compatibility
+ * with Ant releases previous to 1.5. InputHandlers are a new feature of Ant 1.5.
+ */
+class InputHandlerSetter {
+
+	protected void setInputHandler(Project project, String inputHandlerClassname) {
+		InputHandler handler = null;
+		if (inputHandlerClassname == null) {
+			handler = new DefaultInputHandler();
+		} else {
+			try {
+				handler = (InputHandler)(Class.forName(inputHandlerClassname).newInstance());
+			} catch (ClassCastException e) {
+				String msg = MessageFormat.format(RemoteAntMessages.getString("InternalAntRunner.The_specified_input_handler_class_{0}_does_not_implement_the_org.apache.tools.ant.input.InputHandler_interface_5"), new String[]{inputHandlerClassname}); //$NON-NLS-1$
+				throw new BuildException(msg, e);
+			} catch (Exception e) {
+				String msg = MessageFormat.format(RemoteAntMessages.getString("InternalAntRunner.Unable_to_instantiate_specified_input_handler_class_{0}___{1}_6"), new String[]{inputHandlerClassname, e.getClass().getName()}); //$NON-NLS-1$
+				throw new BuildException(msg, e);
+			}
+		}
+		project.setInputHandler(handler);
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/RemoteAntMessages.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/RemoteAntMessages.java
new file mode 100644
index 0000000..5cb927e
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/RemoteAntMessages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote;
+
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class RemoteAntMessages {
+
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.launching.remote.RemoteAntMessages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+	private RemoteAntMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/RemoteAntMessages.properties b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/RemoteAntMessages.properties
new file mode 100644
index 0000000..a0c7332
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/RemoteAntMessages.properties
@@ -0,0 +1,76 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+###############################################################################
+
+InternalAntRunner.Build_file__{0}_1=Buildfile: {0}
+InternalAntRunner.Arguments__{0}_2=Arguments: {0}
+InternalAntRunner.Default_target__3=Default target:
+InternalAntRunner.Main_targets__4=Main targets:
+InternalAntRunner.Subtargets__5=Subtargets:
+InternalAntRunner.Unable_to_instantiate_logger__{0}_6=Unable to instantiate logger: {0}
+InternalAntRunner.Could_not_load_the_version_information._{0}_9=Could not load the version information. {0}
+InternalAntRunner.Could_not_load_the_version_information._10=Could not load the version information.
+InternalAntRunner.options_13=options
+InternalAntRunner.target_15=target
+InternalAntRunner.Options___21=Options: 
+InternalAntRunner.print_this_message_23=print this message
+InternalAntRunner.print_project_help_information_25=print project help information
+InternalAntRunner.print_the_version_information_and_exit_27=print the version information and exit
+InternalAntRunner.be_extra_quiet_29=be extra quiet
+InternalAntRunner.be_extra_verbose_31=be extra verbose
+InternalAntRunner.print_debugging_information_33=print debugging information
+InternalAntRunner.produce_logging_information_without_adornments_35=produce logging information without adornments
+InternalAntRunner.use_given_file_for_log_37=use given file for log
+InternalAntRunner.the_class_which_is_to_perform_logging_39=the class which is to perform logging
+InternalAntRunner.add_an_instance_of_class_as_a_project_listener_41=add an instance of class as a project listener
+InternalAntRunner.use_given_buildfile_43=use given buildfile
+InternalAntRunner.use_value_for_given_property_45=use value for given property
+InternalAntRunner.Using_{0}_file_as_build_log._1=Using {0} file as build log.
+InternalAntRunner.Could_not_write_to_the_specified_log_file__{0}._Make_sure_the_path_exists_and_you_have_write_permissions._2=Cannot write on the specified log file: {0}. Make sure the path exists and you have write permissions.
+InternalAntRunner.BUILD_SUCCESSFUL_1=BUILD SUCCESSFUL
+InternalAntRunner.Unknown_argument__{0}_2=Unknown argument: {0}
+InternalAntRunner.Buildfile__{0}_does_not_exist_!_1=Buildfile: {0} does not exist
+InternalAntRunner.{0}_which_was_specified_to_be_a_build_listener_is_not_an_instance_of_org.apache.tools.ant.BuildListener._1={0} which was specified to be a build listener is not an instance of org.apache.tools.ant.BuildListener.
+InternalAntRunner.{0}_which_was_specified_to_perform_logging_is_not_an_instance_of_org.apache.tools.ant.BuildLogger._2={0} which was specified to perform logging is not an instance of org.apache.tools.ant.BuildLogger.
+InternalAntRunner.You_must_specify_a_classname_when_using_the_-listener_argument_1=You must specify a classname when using the -listener argument
+InternalAntRunner.You_must_specify_a_log_file_when_using_the_-log_argument_3=You must specify a log file when using the -log argument
+InternalAntRunner.You_must_specify_a_buildfile_when_using_the_-buildfile_argument_4=You must specify a buildfile when using the -buildfile argument
+InternalAntRunner.12=print information that might be helpful to
+InternalAntRunner.13=\t\t\t\t\t\t\tdiagnose or report problems.
+InternalAntRunner.19=load all properties from file with -D
+InternalAntRunner.20=\t\t\t\t\t\t\tproperties taking precedence
+InternalAntRunner.22=the class which will handle input requests
+InternalAntRunner.1=\t\t\t\t\'
+InternalAntRunner.Only_one_logger_class_may_be_specified_1=Only one logger class may be specified
+InternalAntRunner.You_must_specify_a_classname_when_using_the_-inputhandler_argument_1=You must specify a classname when using the -inputhandler argument
+InternalAntRunner.Only_one_input_handler_class_may_be_specified._2=Only one input handler class may be specified.
+InternalAntRunner.You_must_specify_a_property_filename_when_using_the_-propertyfile_argument_3=You must specify a property filename when using the -propertyfile argument
+InternalAntRunner.Could_not_load_property_file_{0}__{1}_4=Could not load property file {0}: {1}
+InternalAntRunner.The_specified_input_handler_class_{0}_does_not_implement_the_org.apache.tools.ant.input.InputHandler_interface_5=The specified input handler class {0} does not implement the org.apache.tools.ant.input.InputHandler interface
+InternalAntRunner.Unable_to_instantiate_specified_input_handler_class_{0}___{1}_6=Unable to instantiate specified input handler class {0} : {1}
+InternalAntRunner.The_diagnositics_options_is_an_Ant_1.5.*_feature._Please_update_your_Ant_classpath_to_include_an_Ant_version_greater_than_this._4=The diagnostics options is an Ant 1.5.* feature. Please update your Ant classpath to include an Ant version greater than this.
+InternalAntRunner.Specifying_property_files_is_a_Ant_1.5.*_feature._Please_update_your_Ant_classpath._6=Specifying property files is a Ant 1.5.* feature. Please update your Ant classpath to include an Ant version greater than this.
+InternalAntRunner.ANT_HOME_must_be_set_to_use_Ant_diagnostics_2=ANT_HOME must be set to use Ant diagnostics
+InternalAntRunner.Buildfile__{0}_is_not_a_file_1=Buildfile: {0} is not a file
+InternalAntRunner.-find_not_supported=-find not supported.\nCan be emulated using Run As > Ant Build located\nin the Run > External Tools menu
+InternalAntRunner.157=-lib not supported\nConfigure the Ant runtime classpath using either the\nglobal Ant runtime classpath or the Ant runtime classpath\n for this particular build
+InternalAntRunner.158=\t\t\tdo not allow interactive input
+InternalAntRunner.159=\t\texecute all targets that do not depend
+InternalAntRunner.160=\t\t\t\t\t\ton failed target(s)
+InternalAntRunner.161=Class {0} not found for task {1}
+InternalAntRunner.162=Class {0} not found for type {1}
+
+RemoteAntBuildLogger.1=BUILD FAILED
+RemoteAntBuildLogger.Total_time=Total time: 
+RemoteAntBuildLogger._minutes_2=\ minutes
+RemoteAntBuildLogger._minute_3=\ minute
+RemoteAntBuildLogger._seconds_4=\ seconds
+RemoteAntBuildLogger._second_5=\ second
+RemoteAntBuildLogger._milliseconds_6=\ milliseconds
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/inputhandler/FailInputHandler.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/inputhandler/FailInputHandler.java
new file mode 100644
index 0000000..63341f4
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/inputhandler/FailInputHandler.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.launching.remote.inputhandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.tools.ant.input.DefaultInputHandler;
+
+public class FailInputHandler extends DefaultInputHandler {
+	
+	protected InputStream getInputStream() {
+		//ensure any attempts to read input fail
+		return new InputStream(){
+			public int read() throws IOException {
+				throw new IOException();
+			}
+		};
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/logger/MessageIds.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/logger/MessageIds.java
new file mode 100644
index 0000000..1c0741a
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/logger/MessageIds.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote.logger;
+
+
+public class MessageIds {
+
+	public final static String PROCESS_ID=   "processID"; //$NON-NLS-1$
+	public final static String BUILD_CANCELLED= "cancelled"; //$NON-NLS-1$
+    //constants need to start greater than the Project.MSG_* constants
+	public final static String TASK= "6"; //$NON-NLS-1$
+	public final static String TARGET= "7"; //$NON-NLS-1$
+}
diff --git a/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/logger/RemoteAntBreakpoint.java b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/logger/RemoteAntBreakpoint.java
new file mode 100644
index 0000000..f371516
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/remote/org/eclipse/ant/internal/launching/remote/logger/RemoteAntBreakpoint.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.remote.logger;
+
+import java.io.File;
+
+import org.eclipse.ant.internal.launching.debug.model.DebugMessageIds;
+
+public class RemoteAntBreakpoint {
+	
+    private File fFile;
+	private int fLineNumber;
+	private String fFileName;
+	
+	public RemoteAntBreakpoint(String breakpointRepresentation) {
+		String[] data= breakpointRepresentation.split(DebugMessageIds.MESSAGE_DELIMITER);
+		String fileName= data[1];
+		String lineNumber= data[2];
+		fFileName= fileName;
+		fFile= new File(fileName);
+		fLineNumber= Integer.parseInt(lineNumber);
+	}
+
+	public boolean isAt(String fileName, int lineNumber) {
+		return fLineNumber == lineNumber && fileName != null && fFile.equals(new File(fileName));
+	}
+	
+	public String toMarshallString() {
+		StringBuffer buffer= new StringBuffer(DebugMessageIds.BREAKPOINT);
+		buffer.append(DebugMessageIds.MESSAGE_DELIMITER);
+		buffer.append(fFileName);
+		buffer.append(DebugMessageIds.MESSAGE_DELIMITER);
+		buffer.append(fLineNumber);
+		return buffer.toString();
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object obj) {
+		if (!(obj instanceof RemoteAntBreakpoint)) {
+			return false;
+		}
+		RemoteAntBreakpoint other= (RemoteAntBreakpoint) obj;
+		return other.getLineNumber() == fLineNumber && other.getFile().equals(fFile);
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode() {
+		return fFileName.hashCode() + fLineNumber;
+	}
+	
+	public int getLineNumber() {
+		return fLineNumber;
+	}
+
+	public String getFileName() {
+		return fFileName;
+	}
+	
+	public File getFile() {
+	    return fFile;
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntCoreModelMessages.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntCoreModelMessages.java
new file mode 100644
index 0000000..fa78e74
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntCoreModelMessages.java
@@ -0,0 +1,25 @@
+/**********************************************************************
+ * Copyright (c) 2000, 2009 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.launching;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntCoreModelMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.launching.launchConfigurations.AntCoreModelMessages";//$NON-NLS-1$
+	
+	public static String AntUtil_6;
+	public static String AntUtil_7;
+	public static String AntUtil_2;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntCoreModelMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntCoreModelMessages.properties b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntCoreModelMessages.properties
new file mode 100644
index 0000000..6bad54f
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntCoreModelMessages.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+###############################################################################
+
+AntUtil_6=Invalid property file entry: {0}
+AntUtil_7=Unable to generate Ant classpath
+AntUtil_2=Error reading launch configuration
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunch.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunch.java
new file mode 100644
index 0000000..81c4143
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunch.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.Launch;
+import org.eclipse.debug.core.model.ISourceLocator;
+
+/**
+ * Stores link descriptors for Launch for further use of TaskLinkManager
+ */
+public class AntLaunch extends Launch {
+	List linkDescriptors;
+
+	public AntLaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
+		super(launchConfiguration, mode, locator);
+		linkDescriptors = new ArrayList();
+	}
+
+	public void addLinkDescriptor(String line, String fileName, int lineNumber, int offset, int length) {
+		if (fileName!= null && fileName.trim().length() > 0) {
+			synchronized (linkDescriptors) {
+				linkDescriptors.add(new LinkDescriptor(line, fileName, lineNumber, offset, length));
+			}
+		}
+	}
+
+	public void removeLinkDescriptor(LinkDescriptor ld) {
+		synchronized (linkDescriptors) {
+			linkDescriptors.remove(ld);
+		}
+	}
+
+	public List getLinkDescriptors() {
+		synchronized (linkDescriptors) {
+			return new ArrayList(linkDescriptors);
+		}
+	}
+
+	public void clearLinkDescriptors() {
+		synchronized (linkDescriptors) {
+			linkDescriptors.clear();
+		}
+	}
+
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingPreferenceInitializer.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingPreferenceInitializer.java
new file mode 100644
index 0000000..54d5964
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingPreferenceInitializer.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+
+public class AntLaunchingPreferenceInitializer extends
+		AbstractPreferenceInitializer {
+
+	public AntLaunchingPreferenceInitializer() {
+		super();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seeorg.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#
+	 * initializeDefaultPreferences()
+	 */
+	public void initializeDefaultPreferences() {
+
+		IEclipsePreferences node = new DefaultScope()
+				.getNode(AntLaunching.getUniqueIdentifier());
+		node.put(IAntLaunchingPreferenceConstants.ANT_COMMUNICATION_TIMEOUT,
+				"20000"); //$NON-NLS-1$
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/IAntLaunchingPreferenceConstants.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/IAntLaunchingPreferenceConstants.java
new file mode 100644
index 0000000..9acd581
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/IAntLaunchingPreferenceConstants.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching;
+
+/**
+ * Constants used to identify user preferences.
+ */
+public interface IAntLaunchingPreferenceConstants {
+
+	 /**
+     * int preference identifier constant which specifies the length of time to wait
+     * to connect with the socket that communicates with the separate JRE to capture the output
+     */
+    public static final String ANT_COMMUNICATION_TIMEOUT= "timeout"; //$NON-NLS-1$
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/LinkDescriptor.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/LinkDescriptor.java
new file mode 100644
index 0000000..baba206
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/LinkDescriptor.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching;
+
+/**
+ * Stores detailed data of Link. Used to create linked messages.
+ */
+public class LinkDescriptor {
+	String line;
+	String fileName;
+	int lineNumber;
+	int offset;
+	int length;
+
+	public LinkDescriptor(String line, String fileName, int lineNumber,
+			int offset, int length) {
+		super();
+		this.line = line;
+		this.fileName = fileName;
+		this.lineNumber = lineNumber;
+		this.offset = offset;
+		this.length = length;
+	}
+
+	public String getLine() {
+		return line;
+	}
+
+	public void setLine(String line) {
+		this.line = line;
+	}
+
+	public String getFileName() {
+		return fileName;
+	}
+
+	public void setFileName(String fileName) {
+		this.fileName = fileName;
+	}
+
+	public int getLineNumber() {
+		return lineNumber;
+	}
+
+	public void setLineNumber(int lineNumber) {
+		this.lineNumber = lineNumber;
+	}
+
+	public int getOffset() {
+		return offset;
+	}
+
+	public void setOffset(int offset) {
+		this.offset = offset;
+	}
+
+	public int getLength() {
+		return length;
+	}
+
+	public void setLength(int length) {
+		this.length = length;
+	}
+
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntDebugMessages.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntDebugMessages.java
new file mode 100644
index 0000000..396c1c4
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntDebugMessages.java
@@ -0,0 +1,23 @@
+/**********************************************************************
+ * Copyright (c) 2005, 2009 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.launching.debug;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntDebugMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.launching.debug.AntDebugMessages";//$NON-NLS-1$
+    
+	public static String AntSourceContainer_0;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntDebugMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntDebugMessages.properties b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntDebugMessages.properties
new file mode 100644
index 0000000..78c11d9
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntDebugMessages.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2005, 2009 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
+###############################################################################
+
+AntSourceContainer_0=Ant Source Container
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourceContainer.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourceContainer.java
new file mode 100644
index 0000000..579b66f
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourceContainer.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.launching.debug;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+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.debug.core.sourcelookup.ISourceContainerType;
+import org.eclipse.debug.core.sourcelookup.containers.AbstractSourceContainer;
+import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
+
+public class AntSourceContainer extends AbstractSourceContainer {
+
+	private IWorkspaceRoot fRoot;
+
+	public AntSourceContainer() {
+		fRoot = ResourcesPlugin.getWorkspace().getRoot();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.sourcelookup.ISourceContainer#findSourceElements(java.lang.String)
+	 */
+	public Object[] findSourceElements(String path) throws CoreException {
+		ArrayList sources = new ArrayList();
+		File osFile = new File(path);
+		if (osFile.exists()) {
+			try {
+				IPath canonicalPath = new Path(osFile.getCanonicalPath());
+				IFile[] files = fRoot.findFilesForLocation(canonicalPath);
+				if (files.length > 0) {
+					for (int i = 0; i < files.length; i++) {
+						sources.add(files[i]);
+					}
+				} else {
+					sources.add(new LocalFileStorage(osFile));
+				}
+			} catch (IOException e) {
+			}
+		}
+		return sources.toArray();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.sourcelookup.ISourceContainer#getName()
+	 */
+	public String getName() {
+		return AntDebugMessages.AntSourceContainer_0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.sourcelookup.ISourceContainer#getType()
+     * Not persisted via the launch configuration
+	 */
+	public ISourceContainerType getType() {
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourceLookupDirector.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourceLookupDirector.java
new file mode 100644
index 0000000..e0de3dd
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourceLookupDirector.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector;
+import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
+
+/**
+ * Ant source lookup director. For Ant source lookup there is one source
+ * lookup participant. 
+ */
+public class AntSourceLookupDirector extends AbstractSourceLookupDirector {
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#initializeParticipants()
+	 */
+	public void initializeParticipants() {
+		addParticipants(new ISourceLookupParticipant[]{new AntSourceLookupParticipant()});
+	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.model.IPersistableSourceLocator#getMemento()
+     */
+    public String getMemento() throws CoreException {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourceLookupParticipant.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourceLookupParticipant.java
new file mode 100644
index 0000000..73e0409
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourceLookupParticipant.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug;
+
+import org.eclipse.ant.internal.launching.debug.model.AntStackFrame;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant;
+
+/**
+ * The Ant source lookup participant knows how to translate a 
+ * Ant stack frame into a source file name 
+ */
+public class AntSourceLookupParticipant extends AbstractSourceLookupParticipant {
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#getSourceName(java.lang.Object)
+	 */
+	public String getSourceName(Object object) throws CoreException {
+		if (object instanceof AntStackFrame) {
+			return ((AntStackFrame)object).getFilePath();
+		}
+        if (object instanceof String) {
+            // assume it's a file name
+            return (String)object;
+        }
+		return null;
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourcePathComputerDelegate.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourcePathComputerDelegate.java
new file mode 100644
index 0000000..67e216f
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/AntSourcePathComputerDelegate.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.sourcelookup.ISourceContainer;
+import org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate;
+
+/**
+ * Computes the default source lookup path for an Ant launch configuration.
+ * The default source lookup is a container that knows how to map the 
+ * fully qualified file system paths to either the <code>IFile</code> within the workspace or
+ * a <code>LocalFileStorage</code> for buildfiles not in the workspace.
+ */
+public class AntSourcePathComputerDelegate implements ISourcePathComputerDelegate {
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate#computeSourceContainers(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public ISourceContainer[] computeSourceContainers(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {
+		return new ISourceContainer[] {new AntSourceContainer()};
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/IAntDebugConstants.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/IAntDebugConstants.java
new file mode 100644
index 0000000..c53e121
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/IAntDebugConstants.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.launching.debug;
+
+public interface IAntDebugConstants {
+	
+	/**
+	 * Unique identifier for the Ant debug model (value 
+	 * <code>org.eclipse.ant.ui.debug</code>).
+	 */
+	public static final String ID_ANT_DEBUG_MODEL = "org.eclipse.ant.ui.debug"; //$NON-NLS-1$
+	
+	/**
+	 * Unique identifier for the Ant line breakpoint markers 
+	 * (value <code>org.eclipse.ant.ui.antLineBreakpointMarker</code>).
+	 */
+	public static final String ID_ANT_LINE_BREAKPOINT_MARKER= "org.eclipse.ant.ui.antLineBreakpointMarker"; //$NON-NLS-1$
+    
+    /**
+     * Unique identifier for the Ant run to line breakpoints 
+     * (value <code>org.eclipse.ant.ui.runToLineBreakpoint</code>).
+     */
+    public static final String ANT_RUN_TO_LINE= "org.eclipse.ant.ui.runToLineBreakpoint"; //$NON-NLS-1$
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntDebugElement.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntDebugElement.java
new file mode 100644
index 0000000..07a9528
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntDebugElement.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug.model;
+
+
+import org.eclipse.ant.internal.launching.AntLaunching;
+import org.eclipse.ant.internal.launching.debug.IAntDebugConstants;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.DebugElement;
+
+/**
+ * Common function of Ant debug model elements
+ */
+public abstract class AntDebugElement extends DebugElement {
+	
+	/**
+	 * Constructs a new debug element contained in the given
+	 * debug target.
+	 * 
+	 * @param target debug target
+	 */
+	public AntDebugElement(AntDebugTarget target) {
+		super(target);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier()
+	 */
+	public String getModelIdentifier() {
+		return IAntDebugConstants.ID_ANT_DEBUG_MODEL;
+	}
+    
+	/**
+     * Throws a debug exception with the given message, error code, and underlying
+     * exception.
+     */
+    protected void throwDebugException(String message) throws DebugException {
+        throw new DebugException(new Status(IStatus.ERROR, AntLaunching.getUniqueIdentifier(),
+            DebugException.TARGET_REQUEST_FAILED, message, null));
+    }
+    
+    protected AntDebugTarget getAntDebugTarget() {
+        return (AntDebugTarget)super.getDebugTarget();
+    }
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntLineBreakpoint.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntLineBreakpoint.java
new file mode 100644
index 0000000..2a96b5b
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntLineBreakpoint.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug.model;
+
+import com.ibm.icu.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.ant.internal.launching.debug.IAntDebugConstants;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.LineBreakpoint;
+
+/**
+ * Ant line breakpoint
+ */
+public class AntLineBreakpoint extends LineBreakpoint {
+	
+	/**
+	 * Default constructor is required for the breakpoint manager
+	 * to re-create persisted breakpoints. After instantiating a breakpoint,
+	 * the <code>setMarker(...)</code> method is called to restore
+	 * this breakpoint's attributes.
+	 */
+	public AntLineBreakpoint() {
+	}
+	
+	/**
+	 * Constructs a line breakpoint on the given resource at the given
+	 * line number. The line number is 1-based (i.e. the first line of a
+	 * file is line number 1).
+	 * 
+	 * @param resource file on which to set the breakpoint
+	 * @param lineNumber 1-based line number of the breakpoint
+	 * @throws CoreException if unable to create the breakpoint
+	 */
+	public AntLineBreakpoint(IResource resource, int lineNumber) throws CoreException {
+	    this(resource, lineNumber, new HashMap(), true);
+	}
+	
+	/**
+	 * Constructs a line breakpoint on the given resource at the given
+	 * line number. The line number is 1-based (i.e. the first line of a
+	 * file is line number 1).
+	 * 
+	 * @param resource file on which to set the breakpoint
+	 * @param lineNumber 1-based line number of the breakpoint
+	 * @param attributes the marker attributes to set
+	 * @param register whether to add this breakpoint to the breakpoint manager
+	 * @throws CoreException if unable to create the breakpoint
+	 */
+	public AntLineBreakpoint(final IResource resource, final int lineNumber, final Map attributes, final boolean register) throws CoreException {
+	    IWorkspaceRunnable wr= new IWorkspaceRunnable() {
+			public void run(IProgressMonitor monitor) throws CoreException {
+			    IMarker marker = resource.createMarker(IAntDebugConstants.ID_ANT_LINE_BREAKPOINT_MARKER);
+			    setMarker(marker);
+			    attributes.put(IBreakpoint.ENABLED, Boolean.TRUE);
+			    attributes.put(IMarker.LINE_NUMBER, new Integer(lineNumber));
+			    attributes.put(IBreakpoint.ID, IAntDebugConstants.ID_ANT_DEBUG_MODEL);
+                attributes.put(IMarker.MESSAGE, MessageFormat.format(DebugModelMessages.AntLineBreakpoint_0, new String[] {Integer.toString(lineNumber)}));
+			    ensureMarker().setAttributes(attributes);
+                
+                register(register);
+			}
+	    };
+	    run(getMarkerRule(resource), wr);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IBreakpoint#getModelIdentifier()
+	 */
+	public String getModelIdentifier() {
+		return IAntDebugConstants.ID_ANT_DEBUG_MODEL;
+	}
+
+    /**
+     * @return whether this breakpoint is a run to line breakpoint
+     */
+    public boolean isRunToLine() {
+        try {
+            return ensureMarker().getAttribute(IAntDebugConstants.ANT_RUN_TO_LINE, false);
+        } catch (DebugException e) {
+           return false;
+        }
+    }
+    
+    /**
+     * Add this breakpoint to the breakpoint manager,
+     * or sets it as unregistered.
+     */
+    private void register(boolean register) throws CoreException {
+        if (register) {
+            DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(this);
+        } else {
+            setRegistered(false);
+        }
+    }
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntProperties.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntProperties.java
new file mode 100644
index 0000000..4f93fec
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntProperties.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug.model;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+
+public class AntProperties extends AntDebugElement implements IVariable {
+	
+	private IValue fValue;
+	private String fName;
+    private boolean fValid= true;
+
+	public AntProperties(AntDebugTarget target, String name) {
+		super(target);
+		fName= name;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IVariable#getValue()
+	 */
+	public synchronized IValue getValue() throws DebugException {
+        int attempts= 0;
+        while (!fValid && !getDebugTarget().isTerminated()) {
+            try {
+                wait(50);
+            } catch (InterruptedException e) {
+            }
+            if (attempts == 20 && !fValid && !getDebugTarget().isTerminated()) {
+                throwDebugException(DebugModelMessages.AntProperties_1);
+            }
+            attempts++;
+        }
+ 		return fValue;
+	}
+    
+    public IValue getLastValue() {
+        return fValue;
+    }
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IVariable#getName()
+	 */
+	public String getName() {
+		return fName;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IVariable#getReferenceTypeName()
+	 */
+	public String getReferenceTypeName() {
+		return ""; //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IVariable#hasValueChanged()
+	 */
+	public boolean hasValueChanged() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValueModification#setValue(java.lang.String)
+	 */
+	public void setValue(String expression) {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValueModification#setValue(org.eclipse.debug.core.model.IValue)
+	 */
+	public void setValue(IValue value) {
+		fValue= value;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValueModification#supportsValueModification()
+	 */
+	public boolean supportsValueModification() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValueModification#verifyValue(java.lang.String)
+	 */
+	public boolean verifyValue(String expression) {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValueModification#verifyValue(org.eclipse.debug.core.model.IValue)
+	 */
+	public boolean verifyValue(IValue value) {
+		return false;
+	}
+
+    public synchronized void setValid(boolean valid) {
+        fValid= valid;        
+        notifyAll();
+    }
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntPropertiesValue.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntPropertiesValue.java
new file mode 100644
index 0000000..2ec303c
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntPropertiesValue.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *     Brock Janiczak (brockj@tpg.com.au) - bug 154907
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+
+public class AntPropertiesValue extends AntDebugElement implements IValue {
+	
+	private List fProperties= new ArrayList();
+	
+	public AntPropertiesValue(AntDebugTarget target) {
+		super(target);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValue#getReferenceTypeName()
+	 */
+	public String getReferenceTypeName() {
+		return ""; //$NON-NLS-1$
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValue#getValueString()
+	 */
+	public String getValueString() {
+		return ""; //$NON-NLS-1$
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValue#isAllocated()
+	 */
+	public boolean isAllocated() {
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValue#getVariables()
+	 */
+	public IVariable[] getVariables() {
+		Collections.sort(fProperties);
+		return (IVariable[])fProperties.toArray(new IVariable[fProperties.size()]);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IValue#hasVariables()
+	 */
+	public boolean hasVariables() {
+		return true;
+	}
+	
+	protected void addProperties(List properties) {
+		fProperties.addAll(properties);
+	}
+
+	public List getProperties() {
+		return fProperties;
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntProperty.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntProperty.java
new file mode 100644
index 0000000..9a699da
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntProperty.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *     Brock Janiczak (brockj@tpg.com.au) - bug 154907
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug.model;
+
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+
+/**
+ * A property in an Ant build.
+ */
+public class AntProperty extends AntDebugElement implements IVariable, Comparable {
+
+	private String fName;
+	private AntValue fValue;
+    private String fLabel;
+	
+	/**
+	 * Constructs a variable associated with the debug target
+	 * with the given name and value.
+	 * 
+	 * @param target the debug target
+	 * @param name property name
+	 * @param value property value
+	 */
+	public AntProperty(AntDebugTarget target, String name, String value) {
+		super(target);
+		fName = name;
+		fValue= new AntValue(target, value);
+	}
+	
+	/*
+	 * @see org.eclipse.debug.core.model.IVariable#getValue()
+	 */
+	public IValue getValue() {
+		return fValue;
+	}
+	
+	/*
+	 * @see org.eclipse.debug.core.model.IVariable#getName()
+	 */
+	public String getName() {
+		return fName;
+	}
+	
+	/*
+	 * @see org.eclipse.debug.core.model.IVariable#getReferenceTypeName()
+	 */
+	public String getReferenceTypeName() {
+		return ""; //$NON-NLS-1$
+	}
+	
+	/*
+	 * @see org.eclipse.debug.core.model.IVariable#hasValueChanged()
+	 */
+	public boolean hasValueChanged() {
+		return false;
+	}
+	
+	/*
+	 * @see org.eclipse.debug.core.model.IValueModification#setValue(java.lang.String)
+	 */
+	public void setValue(String expression) {
+	}
+	
+	/*
+	 * @see org.eclipse.debug.core.model.IValueModification#setValue(org.eclipse.debug.core.model.IValue)
+	 */
+	public void setValue(IValue value) {
+	}
+	
+	/*
+	 * @see org.eclipse.debug.core.model.IValueModification#supportsValueModification()
+	 */
+	public boolean supportsValueModification() {
+		return false;
+	}
+	
+	/*
+	 * @see org.eclipse.debug.core.model.IValueModification#verifyValue(java.lang.String)
+	 */
+	public boolean verifyValue(String expression) {
+		return false;
+	}
+	
+	/*
+	 * @see org.eclipse.debug.core.model.IValueModification#verifyValue(org.eclipse.debug.core.model.IValue)
+	 */
+	public boolean verifyValue(IValue value) {
+		return false;
+	}
+
+    /**
+     * @return the text used to render this property
+     */
+    public String getText() {
+        if (fLabel == null) {
+            StringBuffer buffer= new StringBuffer(getName());
+            buffer.append("= "); //$NON-NLS-1$
+            buffer.append(fValue.getValueString());          
+            fLabel=  buffer.toString();
+        } 
+        return fLabel;
+    }
+    
+    /*
+     * @see java.lang.Comparable#compareTo(java.lang.Object)
+     */
+    public int compareTo(Object other) {
+    	AntProperty otherProperty = (AntProperty) other;
+    	return fName.compareToIgnoreCase(otherProperty.getName());
+    }
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntStackFrame.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntStackFrame.java
new file mode 100644
index 0000000..a72a712
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntStackFrame.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug.model;
+
+import org.eclipse.ant.internal.launching.AntLaunchingUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IRegisterGroup;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.IVariable;
+
+/**
+ * Ant stack frame.
+ */
+public class AntStackFrame extends AntDebugElement implements IStackFrame {
+	
+	private AntThread fThread;
+	private String fName;
+	private int fLineNumber;
+	private String fFilePath;
+	private int fId;
+    private String fFullPath;
+	
+	/**
+	 * Constructs a stack frame in the given thread with the given id.
+	 * 
+	 * @param antThread
+	 * @param id stack frame id (0 is the top of the stack)
+	 */
+	public AntStackFrame(AntThread antThread, int id, String name, String fullPath, int lineNumber) {
+		super((AntDebugTarget) antThread.getDebugTarget());
+		fId = id;
+		fThread = antThread;
+		fLineNumber= lineNumber;
+		fName= name;
+		setFilePath(fullPath);
+	}
+	
+	public void setId(int id) {
+		fId= id;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStackFrame#getThread()
+	 */
+	public IThread getThread() {
+		return fThread;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStackFrame#getVariables()
+	 */
+	public IVariable[] getVariables() throws DebugException {
+	   return fThread.getVariables();
+	}
+
+    /* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStackFrame#hasVariables()
+	 */
+	public boolean hasVariables() {
+		return isSuspended();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStackFrame#getLineNumber()
+	 */
+	public int getLineNumber() {
+		return fLineNumber;
+	}
+	
+	public void setLineNumber(int lineNumber) {
+		fLineNumber= lineNumber;
+	}
+	
+	public void setFilePath(String fullPath) {
+        fFullPath= fullPath;
+        IFile file= AntLaunchingUtil.getFileForLocation(fullPath, null);
+        if (file != null) {
+            fFilePath= file.getProjectRelativePath().toString();
+        } else {
+            fFilePath= new Path(fullPath).lastSegment();
+        }
+	}
+	
+	public String getFilePath() {
+		return fFullPath;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStackFrame#getCharStart()
+	 */
+	public int getCharStart() {
+		return -1;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStackFrame#getCharEnd()
+	 */
+	public int getCharEnd() {
+		return -1;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStackFrame#getName()
+	 */
+	public String getName() {
+		return fName;
+	}
+	
+	public void setName(String name) {
+		fName= name;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStackFrame#getRegisterGroups()
+	 */
+	public IRegisterGroup[] getRegisterGroups() {
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStackFrame#hasRegisterGroups()
+	 */
+	public boolean hasRegisterGroups() {
+		return false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStep#canStepInto()
+	 */
+	public boolean canStepInto() {
+		return getThread().canStepInto();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStep#canStepOver()
+	 */
+	public boolean canStepOver() {
+		return getThread().canStepOver();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStep#canStepReturn()
+	 */
+	public boolean canStepReturn() {
+		return getThread().canStepReturn();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStep#isStepping()
+	 */
+	public boolean isStepping() {
+		return getThread().isStepping();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStep#stepInto()
+	 */
+	public void stepInto() throws DebugException {
+		getThread().stepInto();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStep#stepOver()
+	 */
+	public void stepOver() throws DebugException {
+		getThread().stepOver();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStep#stepReturn()
+	 */
+	public void stepReturn() throws DebugException {
+		getThread().stepReturn();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
+	 */
+	public boolean canResume() {
+		return getThread().canResume();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
+	 */
+	public boolean canSuspend() {
+		return getThread().canSuspend();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
+	 */
+	public boolean isSuspended() {
+		return getThread().isSuspended();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.ISuspendResume#resume()
+	 */
+	public void resume() throws DebugException {
+		getThread().resume();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
+	 */
+	public void suspend() throws DebugException {
+		getThread().suspend();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
+	 */
+	public boolean canTerminate() {
+		return getThread().canTerminate();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
+	 */
+	public boolean isTerminated() {
+		return getThread().isTerminated();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.ITerminate#terminate()
+	 */
+	public void terminate() throws DebugException {
+		getThread().terminate();
+	}
+	
+	/**
+	 * Returns the name of the buildfile this stack frame is associated
+	 * with.
+	 * 
+	 * @return the name of the buildfile this stack frame is associated
+	 * with
+	 */
+	public String getSourceName() {
+		return fFilePath;
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object obj) {
+		if (obj instanceof AntStackFrame) {
+			AntStackFrame sf = (AntStackFrame)obj;
+			if (getSourceName() != null) {
+				return getSourceName().equals(sf.getSourceName()) &&
+					sf.getLineNumber() == getLineNumber() &&
+					sf.fId == fId;
+			} 
+			return sf.fId == fId;
+		}
+		return false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode() {
+	    if (getSourceName() == null) {
+	        return fId;
+	    }
+	    return getSourceName().hashCode() + fId;
+	}
+	
+	/**
+	 * Returns this stack frame's unique identifier within its thread
+	 * 
+	 * @return this stack frame's unique identifier within its thread
+	 */
+	protected int getIdentifier() {
+		return fId;
+	}
+    
+    /**
+     * Returns the system, user or runtime property
+     * name, or <code>null</code> if unable to resolve a property with the name.
+     *
+     * @param propertyName the name of the variable to search for
+     * @return a property, or <code>null</code> if none
+     */
+    public AntProperty findProperty(String propertyName) {
+        try {
+            IVariable[] groups= getVariables();
+            for (int i = 0; i < groups.length; i++) {
+                AntProperties propertiesGrouping = (AntProperties) groups[i];
+                AntPropertiesValue value= (AntPropertiesValue) propertiesGrouping.getValue();
+                IVariable[] properties= value.getVariables();
+                for (int j = 0; j < properties.length; j++) {
+                    AntProperty property = (AntProperty) properties[j];
+                    if (property.getName().equals(propertyName)) {
+                        return property;
+                    }
+                }
+            }
+        } catch (DebugException e) {
+        }
+        return null;
+    } 
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntValue.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntValue.java
new file mode 100644
index 0000000..2285279
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/AntValue.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug.model;
+
+import org.eclipse.ant.internal.launching.debug.IAntDebugConstants;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+
+public class AntValue extends AntDebugElement implements IValue  {
+
+    private String fValueString;
+    protected static final IVariable[] EMPTY = new IVariable[0];
+    
+    /**
+     * @param target
+     */
+    public AntValue(AntDebugTarget target, String value) {
+        super(target);
+        fValueString= value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.model.IValue#getReferenceTypeName()
+     */
+    public String getReferenceTypeName() {
+        return ""; //$NON-NLS-1$
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.model.IValue#getValueString()
+     */
+    public String getValueString() {
+        return fValueString;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.model.IValue#isAllocated()
+     */
+    public boolean isAllocated() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.model.IValue#getVariables()
+     */
+    public IVariable[] getVariables() {
+        return EMPTY;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.model.IValue#hasVariables()
+     */
+    public boolean hasVariables() {
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier()
+     */
+    public String getModelIdentifier() {
+        return IAntDebugConstants.ID_ANT_DEBUG_MODEL;
+    }
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/DebugMessageIds.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/DebugMessageIds.java
new file mode 100644
index 0000000..fcc8f3e
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/DebugMessageIds.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.debug.model;
+
+
+public class DebugMessageIds {
+	
+	public final static String MESSAGE_DELIMITER= ","; //$NON-NLS-1$
+	
+	public final static String BUILD_STARTED=   "build_started"; //$NON-NLS-1$
+	public final static String TARGET_STARTED= "target_started"; //$NON-NLS-1$
+	public final static String TARGET_FINISHED= "target_finished"; //$NON-NLS-1$
+	public final static String TASK_STARTED= "task_started"; //$NON-NLS-1$
+	public final static String TASK_FINISHED= "task_finished"; //$NON-NLS-1$
+	
+	public final static String STEP= "step"; //$NON-NLS-1$
+	public final static String STEP_OVER= "step_over"; //$NON-NLS-1$
+	public final static String STEP_INTO= "step_into"; //$NON-NLS-1$
+	
+	public final static String TERMINATE= "terminate"; //$NON-NLS-1$
+	public final static String TERMINATED= "terminated"; //$NON-NLS-1$
+	public final static String SUSPEND= "suspend"; //$NON-NLS-1$
+	public final static String SUSPENDED= "suspended"; //$NON-NLS-1$
+	public final static String RESUME= "resume"; //$NON-NLS-1$
+	
+	public final static String STACK= "stack"; //$NON-NLS-1$
+	
+	public final static String ADD_BREAKPOINT= "add"; //$NON-NLS-1$
+	public final static String REMOVE_BREAKPOINT= "remove"; //$NON-NLS-1$
+	
+	public final static String CLIENT_REQUEST= "client"; //$NON-NLS-1$
+	public final static String BREAKPOINT= "breakpoint"; //$NON-NLS-1$
+	
+	public final static String PROPERTIES= "prop"; //$NON-NLS-1$
+	public final static String PROPERTY_VALUE= "value"; //$NON-NLS-1$
+	public final static int PROPERTY_USER= 0;
+	public final static int PROPERTY_SYSTEM= 1;
+	public final static int PROPERTY_RUNTIME= 2;
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/DebugModelMessages.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/DebugModelMessages.java
new file mode 100644
index 0000000..acadad6
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/DebugModelMessages.java
@@ -0,0 +1,32 @@
+/**********************************************************************
+ * Copyright (c) 2004, 2009 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.launching.debug.model;
+
+import org.eclipse.osgi.util.NLS;
+
+public class DebugModelMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.launching.debug.model.DebugModelMessages";//$NON-NLS-1$
+
+	public static String AntDebugTarget_0;
+
+	public static String AntLineBreakpoint_0;
+	public static String AntThread_0;
+	public static String AntThread_1;
+	public static String AntThread_2;
+    public static String AntThread_3;
+    public static String AntThread_4;
+    
+    public static String AntProperties_1;
+    
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, DebugModelMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/DebugModelMessages.properties b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/DebugModelMessages.properties
new file mode 100644
index 0000000..31cf843
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/debug/model/DebugModelMessages.properties
@@ -0,0 +1,21 @@
+###############################################################################
+# Copyright (c) 2004, 2009 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
+###############################################################################
+
+AntDebugTarget_0=Ant Build
+
+AntLineBreakpoint_0=Ant breakpoint [line: {0}]
+AntThread_0=User Properties
+AntThread_1=System Properties
+AntThread_2=Runtime Properties
+AntThread_3=Request to retrieve Ant stack frames failed
+AntThread_4=Request to retrieve Ant properties failed
+
+AntProperties_1=Request to Ant properties value failed
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntClasspathProvider.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntClasspathProvider.java
new file mode 100644
index 0000000..e4f8b36
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntClasspathProvider.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jdt.launching.StandardClasspathProvider;
+
+public class AntClasspathProvider extends StandardClasspathProvider {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.launching.IRuntimeClasspathProvider#computeUnresolvedClasspath(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public IRuntimeClasspathEntry[] computeUnresolvedClasspath(ILaunchConfiguration configuration) throws CoreException {
+		boolean useDefault = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
+		if (useDefault) {
+			List rtes = new ArrayList(10);
+			IRuntimeClasspathEntry jreEntry = null;
+			try {
+				jreEntry = JavaRuntime.computeJREEntry(configuration);
+			} catch (CoreException e) {
+				// not a java project
+			}
+			if (jreEntry == null) {
+				jreEntry = JavaRuntime.newRuntimeContainerClasspathEntry(
+						JavaRuntime.newDefaultJREContainerPath(), IRuntimeClasspathEntry.STANDARD_CLASSES);
+			}
+			rtes.add(jreEntry);
+			rtes.add(new AntHomeClasspathEntry());
+			rtes.add(new ContributedClasspathEntriesEntry());
+			return (IRuntimeClasspathEntry[]) rtes.toArray(new IRuntimeClasspathEntry[rtes.size()]);
+		}
+		return super.computeUnresolvedClasspath(configuration);
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntHomeClasspathEntry.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntHomeClasspathEntry.java
new file mode 100644
index 0000000..1a8a9bf
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntHomeClasspathEntry.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.IAntClasspathEntry;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.jdt.internal.launching.AbstractRuntimeClasspathEntry;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.ibm.icu.text.MessageFormat;
+
+/**
+ * A classpath entry that contains a set of archives for a particular
+ * ANT_HOME.
+ * 
+ * @since 3.0 
+ */
+public class AntHomeClasspathEntry extends AbstractRuntimeClasspathEntry {
+	
+	public static final String TYPE_ID = "org.eclipse.ant.ui.classpathentry.antHome"; //$NON-NLS-1$
+	
+	/**
+	 * Local path on disk where Ant Home is located or <code>null</code>
+	 * to indicate the use of the default Ant Home.
+	 */
+	private String antHomeLocation = null;
+	
+	/**
+	 * Creates an AntHome entry for the default AntHome installation.
+	 */
+	public AntHomeClasspathEntry() {
+		antHomeLocation = null;
+	}
+	
+	/**
+	 * Constructs an AntHome entry for the Ant installed at the specified
+	 * root directory.
+	 * 
+	 * @param antHome path in the local file system to an Ant installation
+	 */
+	public AntHomeClasspathEntry(String antHome) {
+		antHomeLocation = antHome;
+	}
+		
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.launching.AbstractRuntimeClasspathEntry#buildMemento(org.w3c.dom.Document, org.w3c.dom.Element)
+	 */
+	protected void buildMemento(Document document, Element memento) throws CoreException {
+		if (antHomeLocation == null) {
+			memento.setAttribute("default", "true");  //$NON-NLS-1$//$NON-NLS-2$
+		} else {
+			memento.setAttribute("antHome", new Path(antHomeLocation).toString()); //$NON-NLS-1$
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.launching.IRuntimeClasspathEntry2#initializeFrom(org.w3c.dom.Element)
+	 */
+	public void initializeFrom(Element memento) throws CoreException {
+		String antHome = memento.getAttribute("antHome"); //$NON-NLS-1$
+		if (antHome != null && (antHome.length() > 0)) {
+			IPath path = new Path(antHome);
+			antHomeLocation = path.toOSString();
+		} else {
+			antHomeLocation = null;
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getTypeId()
+	 */
+	public String getTypeId() {
+		return TYPE_ID;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getRuntimeClasspathEntries(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public IRuntimeClasspathEntry[] getRuntimeClasspathEntries(ILaunchConfiguration configuration) throws CoreException {
+		List libs = new ArrayList(40);
+		AntCorePreferences preferences = AntCorePlugin.getPlugin().getPreferences();
+		if (antHomeLocation == null) {
+			IAntClasspathEntry[] entries = preferences.getAntHomeClasspathEntries();
+			for (int i = 0; i < entries.length; i++) {
+				IAntClasspathEntry entry = entries[i];
+				libs.add(JavaRuntime.newStringVariableClasspathEntry(entry.getLabel()));
+			}
+		} else {
+			File lib= resolveAntHome();
+			IPath libDir = new Path(antHomeLocation).append("lib"); //$NON-NLS-1$
+			String[] fileNames = lib.list();
+			for (int i = 0; i < fileNames.length; i++) {
+				String name = fileNames[i];
+				IPath path = new Path(name);
+				String fileExtension = path.getFileExtension();
+				if ("jar".equalsIgnoreCase(fileExtension)) { //$NON-NLS-1$
+					libs.add(JavaRuntime.newArchiveRuntimeClasspathEntry(libDir.append(path)));
+				}
+			}
+		}
+		return (IRuntimeClasspathEntry[]) libs.toArray(new IRuntimeClasspathEntry[libs.size()]);
+	}
+	
+	public File resolveAntHome() throws CoreException {
+		if (antHomeLocation == null) { //using the default ant home
+			return null;
+		}
+		IPath libDir= new Path(antHomeLocation).append("lib"); //$NON-NLS-1$
+		File lib= libDir.toFile();
+		File parentDir= lib.getParentFile();
+		if (parentDir == null || !parentDir.exists()) {
+			abort(MessageFormat.format(AntLaunchConfigurationMessages.AntHomeClasspathEntry_10, new String[] {antHomeLocation}), null);
+		}
+		if (!lib.exists() || !lib.isDirectory()) {
+			abort(MessageFormat.format(AntLaunchConfigurationMessages.AntHomeClasspathEntry_11, new String[] {antHomeLocation}), null);
+		}
+		return lib;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getName()
+	 */
+	public String getName() {
+		if (antHomeLocation == null) {
+			return AntLaunchConfigurationMessages.AntHomeClasspathEntry_8;
+		}
+		return MessageFormat.format(AntLaunchConfigurationMessages.AntHomeClasspathEntry_9, new String[]{antHomeLocation});
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getType()
+	 */
+	public int getType() {
+		return IRuntimeClasspathEntry.OTHER;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#isComposite()
+	 */
+	public boolean isComposite() {
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object obj) {
+		return obj instanceof AntHomeClasspathEntry &&
+		  equalsOrNull(antHomeLocation, ((AntHomeClasspathEntry)obj).antHomeLocation);
+	}
+	
+	/**
+	 * Return whether s1 is equivalent to s2.
+	 * 
+	 * @param s1
+	 * @param s2
+	 * @return whether s1 is equivalent to s2
+	 */
+	private boolean equalsOrNull(String s1, String s2) {
+		if (s1 == null || s2 == null) {
+			return s1 == s2;
+		} 
+		return s1.equalsIgnoreCase(s2);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode() {
+		return getClass().hashCode();
+	}	
+	
+	/**
+	 * Sets the ant home to use.
+	 * 
+	 * @param path path to toor of an ant home installation
+	 */
+	public void setAntHome(String path) {
+		antHomeLocation = path;
+	}
+	
+	/**
+	 * Returns the ant home location
+	 * 
+	 * @return path to root ant installation directory
+	 */
+	public String getAntHome() {
+		if (antHomeLocation == null) {
+			return AntCorePlugin.getPlugin().getPreferences().getAntHome();
+		}
+		return antHomeLocation;
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntJavaLaunchDelegate.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntJavaLaunchDelegate.java
new file mode 100644
index 0000000..ac08c65
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntJavaLaunchDelegate.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.JavaLaunchDelegate;
+
+/**
+ * Used by the AntLaunchDelegate for Ant builds in a separate VM
+ * The subclassing is needed to be able to launch an Ant build from a non-Java project
+ */
+public class AntJavaLaunchDelegate extends JavaLaunchDelegate {
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate2#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public boolean preLaunchCheck(ILaunchConfiguration configuration,String mode, IProgressMonitor monitor) throws CoreException {
+		try {
+			return super.preLaunchCheck(configuration, mode, monitor);
+		} catch (CoreException ce) {
+			//likely dealing with a non-Java project
+		}
+		//no need to check for breakpoints as always in run mode
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate#getProgramArguments(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException {
+		try {
+			return super.getProgramArguments(configuration);
+		} catch (CoreException ce) {
+		}
+		return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, ""); //$NON-NLS-1$
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntLaunchConfigurationMessages.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntLaunchConfigurationMessages.java
new file mode 100644
index 0000000..30c7df3
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntLaunchConfigurationMessages.java
@@ -0,0 +1,37 @@
+/**********************************************************************
+ * Copyright (c) 2000, 2009 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 - Initial API and implementation
+ * dakshinamurthy.karra@gmail.com - bug 165371
+ **********************************************************************/
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntLaunchConfigurationMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.launching.launchConfigurations.AntLaunchConfigurationMessages";//$NON-NLS-1$
+
+	public static String AntLaunchDelegate_Launching__0__1;
+	public static String AntLaunchDelegate_Running__0__2;
+	public static String AntLaunchDelegate_Build_In_Progress;
+	public static String AntLaunchDelegate_Failure;
+	public static String AntLaunchDelegate_22;
+	public static String AntLaunchDelegate_23;
+	public static String AntLaunchDelegate_28;
+
+	public static String AntHomeClasspathEntry_8;
+	public static String AntHomeClasspathEntry_9;
+	public static String AntHomeClasspathEntry_10;
+	public static String AntHomeClasspathEntry_11;
+
+	public static String ContributedClasspathEntriesEntry_1;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntLaunchConfigurationMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntLaunchConfigurationMessages.properties b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntLaunchConfigurationMessages.properties
new file mode 100644
index 0000000..e661655
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntLaunchConfigurationMessages.properties
@@ -0,0 +1,26 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+#     dakshinamurthy.karra@gmail.com - bug 165371
+###############################################################################
+
+AntLaunchDelegate_Launching__0__1=Launching {0}
+AntLaunchDelegate_Running__0__2=Running {0}
+AntLaunchDelegate_Build_In_Progress=Ant build {0} already in progress. Concurrent Ant builds are possible if you specify to build in a separate JRE.
+AntLaunchDelegate_Failure=Failure of Background Ant Build
+AntLaunchDelegate_22=&Do not show error dialog when Ant build fails
+AntLaunchDelegate_23=Ant Build Failed
+AntLaunchDelegate_28=Waiting for virtual machine to exit...
+
+AntHomeClasspathEntry_8=Ant Home (Default)
+AntHomeClasspathEntry_9=Ant Home ({0})
+AntHomeClasspathEntry_10=Ant Home {0} does not exist
+AntHomeClasspathEntry_11=Ant Home {0} does not contain a "lib" directory
+
+ContributedClasspathEntriesEntry_1=Additional Tasks & Support
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntMigrationDelegate.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntMigrationDelegate.java
new file mode 100644
index 0000000..bd56832
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntMigrationDelegate.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+import org.eclipse.ant.internal.launching.AntLaunchingUtil;
+import org.eclipse.core.externaltools.internal.IExternalToolConstants;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.variables.IStringVariableManager;
+import org.eclipse.core.variables.VariablesPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationMigrationDelegate;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+
+/**
+ * Delegate for migrating Ant launch configurations.
+ * The migration process involves a resource mapping being created such that launch configurations
+ * can be filtered from the launch configuration dialog based on resource availability.
+ * 
+ * @since 3.2
+ */
+public class AntMigrationDelegate implements ILaunchConfigurationMigrationDelegate {
+	
+	/**
+	 * Method to get the file for the specified launch configuration that should be mapped to the launch configuration  
+	 * 
+	 * @param candidate the launch configuration that the file will be mapped to.
+	 * @return the buildfile or <code>null</code> if not in the workspace
+	 */
+	protected IFile getFileForCandidate(ILaunchConfiguration candidate) {
+		IFile file= null;
+		String expandedLocation= null;
+		String location= null;
+		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
+		try {
+			location= candidate.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String)null);
+			if (location != null) {
+				expandedLocation= manager.performStringSubstitution(location);
+				if (expandedLocation != null) {
+					file= AntLaunchingUtil.getFileForLocation(expandedLocation, null);
+				}
+			}
+		} catch (CoreException e) {
+		}
+		return file;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.ILaunchConfigurationMigrationDelegate#isCandidate()
+	 */
+	public boolean isCandidate(ILaunchConfiguration candidate) throws CoreException {
+		IResource[] mappedResources = candidate.getMappedResources();
+		if (mappedResources != null && mappedResources.length > 0) {
+			return false;
+		}
+		return getFileForCandidate(candidate) != null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.ILaunchConfigurationMigrationDelegate#migrate(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public void migrate(ILaunchConfiguration candidate) throws CoreException {
+		IFile file = getFileForCandidate(candidate);
+		ILaunchConfigurationWorkingCopy wc = candidate.getWorkingCopy();
+		wc.setMappedResources(new IResource[] {file});
+		wc.doSave();
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntStreamMonitor.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntStreamMonitor.java
new file mode 100644
index 0000000..cf6199f
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntStreamMonitor.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.debug.core.IStreamListener;
+import org.eclipse.debug.core.model.IFlushableStreamMonitor;
+
+/**
+ * Stream monitor implementation for an Ant build process.
+ */
+public class AntStreamMonitor implements IFlushableStreamMonitor {
+
+	private StringBuffer fContents = new StringBuffer();
+	private ListenerList fListeners = new ListenerList(1);
+	private boolean fBuffered = true;
+	
+	/**
+	 * @see org.eclipse.debug.core.model.IStreamMonitor#addListener(org.eclipse.debug.core.IStreamListener)
+	 */
+	public void addListener(IStreamListener listener) {
+		fListeners.add(listener);
+	}
+
+	/**
+	 * @see org.eclipse.debug.core.model.IStreamMonitor#getContents()
+	 */
+	public String getContents() {
+		return fContents.toString();
+	}
+
+	/**
+	 * @see org.eclipse.debug.core.model.IStreamMonitor#removeListener(org.eclipse.debug.core.IStreamListener)
+	 */
+	public void removeListener(IStreamListener listener) {
+		fListeners.remove(listener);
+	}
+
+	/**
+	 * Appends the given message to this stream, and notifies listeners.
+	 * 
+	 * @param message
+	 */
+	public void append(String message) {
+		if (isBuffered()) {
+			fContents.append(message);
+		}
+		Object[] listeners = fListeners.getListeners();
+		for (int i = 0; i < listeners.length; i++) {
+			IStreamListener listener = (IStreamListener)listeners[i];
+			listener.streamAppended(message, this);
+		}
+	}
+	/**
+	 * @see org.eclipse.debug.core.model.IFlushableStreamMonitor#flushContents()
+	 */
+	public void flushContents() {
+		fContents.setLength(0);
+	}
+
+	/**
+	 * @see org.eclipse.debug.core.model.IFlushableStreamMonitor#isBuffered()
+	 */
+	public boolean isBuffered() {
+		return fBuffered;
+	}
+
+	/**
+	 * @see org.eclipse.debug.core.model.IFlushableStreamMonitor#setBuffered(boolean)
+	 */
+	public void setBuffered(boolean buffer) {
+		fBuffered = buffer;
+	}
+}
+
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntStreamsProxy.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntStreamsProxy.java
new file mode 100644
index 0000000..66a5e09
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/AntStreamsProxy.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+
+import org.eclipse.ant.internal.launching.AntLaunching;
+import org.eclipse.debug.core.model.IStreamMonitor;
+import org.eclipse.debug.core.model.IStreamsProxy;
+
+/**
+ * 
+ */
+public class AntStreamsProxy implements IStreamsProxy {
+	
+	private AntStreamMonitor fErrorMonitor = new AntStreamMonitor();
+	private AntStreamMonitor fOutputMonitor = new AntStreamMonitor();
+	
+	public static final String ANT_DEBUG_STREAM = AntLaunching.PLUGIN_ID + ".ANT_DEBUG_STREAM"; //$NON-NLS-1$
+	public static final String ANT_VERBOSE_STREAM = AntLaunching.PLUGIN_ID + ".ANT_VERBOSE_STREAM"; //$NON-NLS-1$
+	public static final String ANT_WARNING_STREAM = AntLaunching.PLUGIN_ID + ".ANT_WARNING_STREAM"; //$NON-NLS-1$
+	
+	private AntStreamMonitor fDebugMonitor = new AntStreamMonitor();
+	private AntStreamMonitor fVerboseMonitor = new AntStreamMonitor();
+	private AntStreamMonitor fWarningMonitor = new AntStreamMonitor();
+
+	/**
+	 * @see org.eclipse.debug.core.model.IStreamsProxy#getErrorStreamMonitor()
+	 */
+	public IStreamMonitor getErrorStreamMonitor() {
+		return fErrorMonitor;
+	}
+
+	/**
+	 * @see org.eclipse.debug.core.model.IStreamsProxy#getOutputStreamMonitor()
+	 */
+	public IStreamMonitor getOutputStreamMonitor() {
+		return fOutputMonitor;
+	}
+
+	/**
+	 * @see org.eclipse.debug.core.model.IStreamsProxy#write(java.lang.String)
+	 */
+	public void write(String input) {
+	}
+
+	public IStreamMonitor getWarningStreamMonitor() {
+		return fWarningMonitor;
+	}
+	
+	public IStreamMonitor getDebugStreamMonitor() {
+		return fDebugMonitor;
+	}	
+	
+	public IStreamMonitor getVerboseStreamMonitor() {
+		return fVerboseMonitor;
+	}	
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/MessageIds.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/MessageIds.java
new file mode 100644
index 0000000..119e18a
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/MessageIds.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+public class MessageIds {
+
+	public final static String PROCESS_ID=   "processID"; //$NON-NLS-1$
+	public final static String BUILD_CANCELLED= "cancelled"; //$NON-NLS-1$
+	//constants need to start greater than the Project.MSG_* constants
+    public final static String TASK= "6"; //$NON-NLS-1$
+    public final static String TARGET= "7"; //$NON-NLS-1$
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/RemoteAntProcessFactory.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/RemoteAntProcessFactory.java
new file mode 100644
index 0000000..013c13e
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/RemoteAntProcessFactory.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.ant.launching.IAntLaunchConstants;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.IProcessFactory;
+import org.eclipse.debug.core.model.IProcess;
+
+public class RemoteAntProcessFactory implements IProcessFactory {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.IProcessFactory#newProcess(org.eclipse.debug.core.ILaunch, java.lang.Process, java.lang.String, java.util.Map)
+	 */
+	public IProcess newProcess(ILaunch launch, Process process, String label, Map attributes) {
+		if (attributes == null) {
+			attributes= new HashMap(1);
+		}
+		attributes.put(IProcess.ATTR_PROCESS_TYPE, IAntLaunchConstants.ID_ANT_PROCESS_TYPE);
+		return new RemoteAntRuntimeProcess(launch, process, label, attributes);
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/RemoteAntRuntimeProcess.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/RemoteAntRuntimeProcess.java
new file mode 100644
index 0000000..4a0bba2
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/launchConfigurations/RemoteAntRuntimeProcess.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.launching.launchConfigurations;
+
+import java.util.Map;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IStreamsProxy;
+import org.eclipse.debug.core.model.RuntimeProcess;
+
+public class RemoteAntRuntimeProcess extends RuntimeProcess {
+
+	/**
+	 * Constructs a RuntimeProcess on the given system process
+	 * with the given name, adding this process to the given
+	 * launch.
+	 * Sets the streams proxy to an AntStreamsProxy if output is captured.
+	 */
+	public RemoteAntRuntimeProcess(ILaunch launch, Process process, String name, Map attributes) {
+		super(launch, process, name, attributes);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.RuntimeProcess#createStreamsProxy()
+	 */
+	protected IStreamsProxy createStreamsProxy() {
+		return new AntStreamsProxy();
+	}
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/launching/IAntLaunchConstants.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/launching/IAntLaunchConstants.java
new file mode 100644
index 0000000..ec8ae33
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/launching/IAntLaunchConstants.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.launching;
+
+import org.eclipse.core.externaltools.internal.IExternalToolConstants;
+
+/**
+ * Constant definitions for Ant launch configurations.
+ * 
+ * @since 1.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IAntLaunchConstants {
+
+	/**
+	 * Ant launch configuration type identifier.
+	 */
+	public static final String ID_ANT_LAUNCH_CONFIGURATION_TYPE = "org.eclipse.ant.AntLaunchConfigurationType"; //$NON-NLS-1$
+
+	public static final String MAIN_TYPE_NAME= "org.eclipse.ant.internal.launching.remote.InternalAntRunner"; //$NON-NLS-1$
+	
+	/**
+	 * Ant builder launch configuration type identifier. Ant project builders
+	 * are of this type.
+	 */
+	public static final String ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE = "org.eclipse.ant.AntBuilderLaunchConfigurationType"; //$NON-NLS-1$
+
+	/**
+	 * String attribute indicating the Ant targets to execute. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 */
+	public static final String ATTR_ANT_TARGETS = IExternalToolConstants.UI_PLUGIN_ID + ".ATTR_ANT_TARGETS"; //$NON-NLS-1$
+
+	/**
+	 * String attribute indicating the Ant targets to execute after a clean
+	 * (full build) for an Ant builder. Default value is <code>null</code> which
+	 * indicates that the default target is to be executed. Format is a comma
+	 * separated listing of targets.
+	 */
+	public static final String ATTR_ANT_AFTER_CLEAN_TARGETS = "org.eclipse.ant.ui.ATTR_ANT_AFTER_CLEAN_TARGETS"; //$NON-NLS-1$
+
+	/**
+	 * String attribute indicating the Ant targets to execute during a manual
+	 * build for an Ant builder. Default value is <code>null</code> which
+	 * indicates that the default target is to be executed. Format is a comma
+	 * separated listing of targets.
+	 */
+	public static final String ATTR_ANT_MANUAL_TARGETS = "org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS"; //$NON-NLS-1$
+
+	/**
+	 * String attribute indicating the Ant targets to execute during an auto
+	 * build for an Ant builder. Default value is <code>null</code> which
+	 * indicates that the default target is to be executed. Format is a comma
+	 * separated listing of targets.
+	 */
+	public static final String ATTR_ANT_AUTO_TARGETS = "org.eclipse.ant.ui.ATTR_ANT_AUTO_TARGETS"; //$NON-NLS-1$
+
+	/**
+	 * String attribute indicating the Ant targets to execute during a clean for
+	 * an Ant builder. Default value is <code>null</code> which indicates that
+	 * the default target is to be executed. Format is a comma separated listing
+	 * of targets.
+	 */
+	public static final String ATTR_ANT_CLEAN_TARGETS = "org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS"; //$NON-NLS-1$
+
+	/**
+	 * Boolean attribute indicating whether or not target specification for an
+	 * Ant builder has been updated for 3.1
+	 */
+	public static final String ATTR_TARGETS_UPDATED = "org.eclipse.ant.ui.ATTR_TARGETS_UPDATED"; //$NON-NLS-1$
+
+	/**
+	 * Map attribute indicating the Ant properties to be defined during the
+	 * build. Default value is <code>null</code> which indicates no additional
+	 * properties will be defined.
+	 */
+	public static final String ATTR_ANT_PROPERTIES = IExternalToolConstants.UI_PLUGIN_ID + ".ATTR_ANT_PROPERTIES"; //$NON-NLS-1$					
+
+	/**
+	 * String attribute indicating the Ant targets to execute. Default value is
+	 * <code>null</code> which indicates that no additional property files will
+	 * be defined. Format is a comma separated listing of property files.
+	 */
+	public static final String ATTR_ANT_PROPERTY_FILES = IExternalToolConstants.UI_PLUGIN_ID + ".ATTR_ANT_PROPERTY_FILES"; //$NON-NLS-1$
+
+	/**
+	 * Boolean attribute indicating whether or not internal targets (targets
+	 * with no description) should be hidden from the user in the launch
+	 * configuration dialog. Default value is <code>false</code> which indicates
+	 * that all targets will be displayed.
+	 */
+	public static final String ATTR_HIDE_INTERNAL_TARGETS = IExternalToolConstants.UI_PLUGIN_ID + ".ATTR_HIDE_INTERNAL_TARGETS"; //$NON-NLS-1$
+
+	/**
+	 * Integer attribute indicating which column targets should be sorted on. A
+	 * value of 0 indicates target name, 1 indicates target description, and -1
+	 * indicates no sort. Default value is -1.
+	 */
+	public static final String ATTR_SORT_TARGETS = IExternalToolConstants.UI_PLUGIN_ID + "ATTR_SORT_TARGETS"; //$NON-NLS-1$
+
+	/**
+	 * Boolean attribute indicating if the default VM install should be used for
+	 * the separate JRE build Default value is <code>false</code> for backwards
+	 * compatibility
+	 */
+	public static final String ATTR_DEFAULT_VM_INSTALL = "org.eclipse.ant.ui.DEFAULT_VM_INSTALL"; //$NON-NLS-1$
+
+	/**
+	 * Identifier for Ant processes (value
+	 * <code>org.eclipse.ant.ui.antProcess</code>). This identifier is set as
+	 * the value for the <code>IProcess.ATTR_PROCESS_TYPE</code> attribute in
+	 * processes created by the Ant launch delegate.
+	 */
+	public static final String ID_ANT_PROCESS_TYPE = "org.eclipse.ant.ui.antProcess"; //$NON-NLS-1$
+
+}
diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/launching/package.html b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/launching/package.html
new file mode 100644
index 0000000..55fd484
--- /dev/null
+++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/launching/package.html
@@ -0,0 +1,13 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides support for Ant launching.
+<h2>
+Package Specification</h2>
+This package defines constants for Ant launch configuration attributes. 
+</body>
+</html>
diff --git a/ant/org.eclipse.ant.tests.core/.classpath b/ant/org.eclipse.ant.tests.core/.classpath
new file mode 100644
index 0000000..2ed1e9c
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="test plugin"/>
+	<classpathentry kind="src" path="tests"/>
+	<classpathentry kind="src" output="test_support_bin" path="test support"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/ant/org.eclipse.ant.tests.core/.externalToolBuilders/Ant Test Support Lib Builder.launch b/ant/org.eclipse.ant.tests.core/.externalToolBuilders/Ant Test Support Lib Builder.launch
new file mode 100644
index 0000000..601d4a0
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/.externalToolBuilders/Ant Test Support Lib Builder.launch
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
+<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,clean"/>
+<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot; editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.tests.core/test support/org&quot; type=&quot;2&quot;/&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.tests.core/buildfiles/buildAntTestsSupportJAR.xml&quot; type=&quot;1&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;&#10;}"/>
+<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot; editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.tests.core&quot; type=&quot;4&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;&#10;}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.ant.tests.core/buildfiles/buildAntTestsSupportJAR.xml}"/>
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_RUN_IN_BACKGROUND" value="false"/>
+</launchConfiguration>
diff --git a/ant/org.eclipse.ant.tests.core/.project b/ant/org.eclipse.ant.tests.core/.project
new file mode 100644
index 0000000..8d670cd
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/.project
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.ant.tests.core</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>		
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/Ant Test Support Lib Builder.launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/ant/org.eclipse.ant.tests.core/.settings/org.eclipse.pde.core.prefs b/ant/org.eclipse.ant.tests.core/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..f01a374
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,3 @@
+#Thu May 27 14:48:43 PDT 2004

+eclipse.preferences.version=1

+selfhosting.binExcludes=/org.eclipse.ant.tests.core/test_support_bin

diff --git a/ant/org.eclipse.ant.tests.core/.settings/org.eclipse.pde.prefs b/ant/org.eclipse.ant.tests.core/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..b307715
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,29 @@
+#Mon Dec 14 11:40:48 CST 2009

+compilers.f.unresolved-features=1

+compilers.f.unresolved-plugins=1

+compilers.incompatible-environment=1

+compilers.p.build=1

+compilers.p.build.missing.output=1

+compilers.p.deprecated=1

+compilers.p.discouraged-class=1

+compilers.p.illegal-att-value=0

+compilers.p.internal=1

+compilers.p.missing-packages=2

+compilers.p.missing-version-export-package=2

+compilers.p.missing-version-import-package=2

+compilers.p.missing-version-require-bundle=2

+compilers.p.no-required-att=0

+compilers.p.not-externalized-att=1

+compilers.p.unknown-attribute=0

+compilers.p.unknown-class=1

+compilers.p.unknown-element=0

+compilers.p.unknown-identifier=1

+compilers.p.unknown-resource=1

+compilers.p.unresolved-ex-points=0

+compilers.p.unresolved-import=0

+compilers.p.unused-element-or-attribute=1

+compilers.s.create-docs=false

+compilers.s.doc-folder=doc

+compilers.s.open-tags=1

+compilers.use-project=true

+eclipse.preferences.version=1

diff --git a/ant/org.eclipse.ant.tests.core/about.html b/ant/org.eclipse.ant.tests.core/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</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
+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/ant/org.eclipse.ant.tests.core/build.properties b/ant/org.eclipse.ant.tests.core/build.properties
new file mode 100644
index 0000000..3d4cff0
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/build.properties
@@ -0,0 +1,28 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+###############################################################################
+bin.includes = plugin.xml,\
+               plugin.properties,\
+               test.xml,\
+               about.html,\
+               testbuildfiles/,\
+               testresources/,\
+               testlib/,\
+               lib/,\
+               lib/*.jar,\
+               *.jar,\
+               META-INF/
+               
+source.anttestscore.jar = test plugin/,\
+                          tests/
+source.lib/antTestsSupport.jar = test support/
+jars.compile.order=anttestscore.jar,lib/antTestsSupport.jar
+output.lib/antTestsSupport.jar = test_support_bin/
+output.anttestscore.jar = bin/
diff --git a/ant/org.eclipse.ant.tests.core/buildfiles/buildAntTestsSupportJAR.xml b/ant/org.eclipse.ant.tests.core/buildfiles/buildAntTestsSupportJAR.xml
new file mode 100644
index 0000000..8b57ae7
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/buildfiles/buildAntTestsSupportJAR.xml
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.core/plugin.properties b/ant/org.eclipse.ant.tests.core/plugin.properties
new file mode 100644
index 0000000..f1e9e46
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# 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
+###############################################################################
+
+pluginName=Ant Core Test Plugin
+providerName=Eclipse.org
diff --git a/ant/org.eclipse.ant.tests.core/plugin.xml b/ant/org.eclipse.ant.tests.core/plugin.xml
new file mode 100644
index 0000000..bdadd4a
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/plugin.xml
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntFileRunner.java b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntFileRunner.java
new file mode 100644
index 0000000..539e802
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntFileRunner.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.testplugin;
+
+
+import org.eclipse.ant.core.AntRunner;
+import org.eclipse.ant.tests.core.AbstractAntTest;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Responsible for running test ant build files.
+ */
+public class AntFileRunner {
+	
+	private static final String BASE_DIR_PREFIX = "-Dbasedir="; //$NON-NLS-1$
+
+	public void run(IFile buildFile, String[] targets, String[] args, String baseDir, boolean captureOutput) throws CoreException {
+	
+		AntRunner runner = new AntRunner();
+
+		String[] runnerArgs = args;
+
+		if (baseDir.length() > 0) {
+			// Ant requires the working directory to be specified
+			// as one of the arguments, so it needs to be appended.
+			int length = 1;
+			if (args != null) {
+				length = args.length + 1;
+			} 
+			
+			runnerArgs = new String[length];
+			if (args != null) {
+				System.arraycopy(args, 0, runnerArgs, 0, args.length);
+			}
+			runnerArgs[length - 1] = BASE_DIR_PREFIX + baseDir;
+		}
+		runner.setArguments(runnerArgs);
+
+		if (buildFile != null) {
+			runner.setBuildFileLocation(buildFile.getLocation().toFile().toString());
+		}
+		if (targets != null && targets.length > 0) {
+			runner.setExecutionTargets(targets);
+		}
+		if (captureOutput) {
+			runner.addBuildLogger(AbstractAntTest.ANT_TEST_BUILD_LOGGER);
+		}
+
+		runner.run(null);
+	}
+	
+	public void run(String[] args, String baseDir) throws Exception {
+	
+		AntRunner runner = new AntRunner();
+
+		String[] runnerArgs = args;
+
+		if (baseDir.length() > 0) {
+			// Ant requires the working directory to be specified
+			// as one of the arguments, so it needs to be appended.
+			runnerArgs = new String[args.length + 1];
+			System.arraycopy(args, 0, runnerArgs, 0, args.length);
+			runnerArgs[args.length] = BASE_DIR_PREFIX + baseDir;
+		}
+		runner.setArguments(runnerArgs);
+
+		runner.run(args);
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntTestChecker.java b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntTestChecker.java
new file mode 100644
index 0000000..1f449e5
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntTestChecker.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.testplugin;
+
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+public class AntTestChecker {
+	
+	private static AntTestChecker deflt= null;
+	
+	private int taskStartedCount;
+	
+	private int taskFinishedCount;
+	
+	private int targetsStartedCount;
+	
+	private int targetsFinishedCount;
+	
+	private int buildsStartedCount;
+	
+	private int buildsFinishedCount;
+	
+	private List messages= new ArrayList();
+	
+	private List targets= new ArrayList();
+	
+	private List tasks= new ArrayList();
+	
+	private List projects= new ArrayList();
+	
+	private Hashtable userProperties;
+	
+	private List nameOfListeners= new ArrayList();
+	
+	private AntTestChecker()  {
+	}
+	
+	/**
+	 * Returns the singleton AntTestChecker
+	 */
+	public static AntTestChecker getDefault() {
+		if (deflt == null) {
+			deflt= new AntTestChecker();
+		}
+		return deflt;
+	}
+	
+	/**
+	 * Resets the singleton AntTestChecker
+	 */
+	public static void reset() {
+		if (deflt != null) {
+			deflt.resetState();
+		}
+	}
+	/**
+	 * @see org.apache.tools.ant.BuildListener#buildFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void buildFinished() {
+		buildsFinishedCount++;
+	}
+
+	
+	public void buildStarted(String projectName) {
+		buildsStartedCount++;
+		projects.add(projectName);
+	}
+
+	
+	public void messageLogged(String message) {
+		messages.add(message);
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#targetFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void targetFinished() {
+		targetsFinishedCount++;
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void targetStarted(String targetName) {
+		targetsStartedCount++;
+		targets.add(targetName);
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void taskFinished() {
+		taskFinishedCount++;
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#taskStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void taskStarted(String taskName) {
+		taskStartedCount++;
+		tasks.add(taskName);
+	}
+	
+	/**
+	 * Returns the buildsFinishedCount.
+	 * @return int
+	 */
+	public int getBuildsFinishedCount() {
+		return buildsFinishedCount;
+	}
+
+	/**
+	 * Returns the buildsStartedCount.
+	 * @return int
+	 */
+	public int getBuildsStartedCount() {
+		return buildsStartedCount;
+	}
+
+	/**
+	 * Returns the messagesLoggedCount.
+	 * @return int
+	 */
+	public int getMessagesLoggedCount() {
+		return messages.size();
+	}
+
+	/**
+	 * Returns the targetsFinishedCount.
+	 * @return int
+	 */
+	public int getTargetsFinishedCount() {
+		return targetsFinishedCount;
+	}
+
+	/**
+	 * Returns the targetsStartedCount.
+	 * @return int
+	 */
+	public int getTargetsStartedCount() {
+		return targetsStartedCount;
+	}
+
+	/**
+	 * Returns the taskFinishedCount.
+	 * @return int
+	 */
+	public int getTaskFinishedCount() {
+		return taskFinishedCount;
+	}
+
+	/**
+	 * Returns the taskStartedCount.
+	 * @return int
+	 */
+	public int getTaskStartedCount() {
+		return taskStartedCount;
+	}
+	
+	protected void resetState() {
+		taskStartedCount= 0;
+		taskFinishedCount= 0;
+		targetsStartedCount= 0;
+		targetsFinishedCount= 0;
+		buildsStartedCount= 0;
+		buildsFinishedCount= 0;
+		messages= new ArrayList();
+		tasks= new ArrayList();
+		targets= new ArrayList();
+		projects= new ArrayList();
+		userProperties= null;
+		nameOfListeners= new ArrayList();
+	}
+	
+	/**
+     * Return the message n from the last:
+     * e.g. getLoggedMessage(0) returns the most recent message
+     * 
+	 * @param n message index
+	 * @return the nth last message
+	 */
+    public String getLoggedMessage(int n) {
+        n = messages.size() - (n + 1);
+        if ((n < 0) || (n >= messages.size())) {
+            return null;
+        }
+        return (String) messages.get(n);
+    }
+
+    public String getLastMessageLogged() {
+        return getLoggedMessage(0);
+    }
+	
+	public void setUserProperties(Hashtable userProperties) {
+		this.userProperties= userProperties;
+	}
+
+	public String getUserProperty(String name) {
+		return (String)userProperties.get(name);
+	}
+	
+	public List getMessages() {
+		return messages;
+	}
+	
+	public List getListeners() {
+		return nameOfListeners;
+	}
+	
+	public String getLastListener() {
+		return (String)nameOfListeners.get(nameOfListeners.size() - 1);
+	}
+
+
+	public void addNameOfListener(String nameOfListener) {
+		this.nameOfListeners.add(nameOfListener);
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntTestPlugin.java b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntTestPlugin.java
new file mode 100644
index 0000000..3e58103
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntTestPlugin.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.testplugin;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceDescription;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.Bundle;
+
+
+public class AntTestPlugin extends AbstractUIPlugin {
+	
+	private static AntTestPlugin deflt;
+	
+	public AntTestPlugin() {
+		super();
+		deflt= this;
+	}
+	
+	public static AntTestPlugin getDefault() {
+		return deflt;
+	}
+	
+	public static IWorkspace getWorkspace() {
+		return ResourcesPlugin.getWorkspace();
+	}
+	
+	public static void enableAutobuild(boolean enable) throws CoreException {
+		// disable auto build
+		IWorkspace workspace= AntTestPlugin.getWorkspace();
+		IWorkspaceDescription desc= workspace.getDescription();
+		desc.setAutoBuilding(enable);
+		workspace.setDescription(desc);
+	}
+	
+	public File getFileInPlugin(IPath path) {
+		try {
+			Bundle bundle = getDefault().getBundle();
+			URL installURL= new URL(bundle.getEntry("/"), path.toString());
+			URL localURL= FileLocator.toFileURL(installURL);
+			return new File(localURL.getFile());
+		} catch (IOException e) {
+			return null;
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntTestPropertyValueProvider.java b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntTestPropertyValueProvider.java
new file mode 100644
index 0000000..2786e96
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/AntTestPropertyValueProvider.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.testplugin;
+
+import org.eclipse.ant.core.IAntPropertyValueProvider;
+
+public class AntTestPropertyValueProvider implements IAntPropertyValueProvider {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.core.IAntPropertyValueProvider#getAntPropertyValue(java.lang.String)
+	 */
+	public String getAntPropertyValue(String antPropertyName) {
+		return "AntTestPropertyValueProvider";
+	}
+
+}
diff --git a/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/ProjectHelper.java b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/ProjectHelper.java
new file mode 100644
index 0000000..4389ed7
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test plugin/org/eclipse/ant/tests/core/testplugin/ProjectHelper.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.testplugin;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.wizards.datatransfer.*;
+
+/**
+ * Helper methods to set up an IProject.
+ */
+public class ProjectHelper {
+	
+	public static final IPath TEST_BUILDFILES_DIR= new Path("testbuildfiles");
+	public static final IPath TEST_RESOURCES_DIR= new Path("testresources");	
+	public static final IPath TEST_LIB_DIR= new Path("testlib");
+	
+	/**
+	 * Creates a IProject.
+	 */	
+	public static IProject createProject(String projectName) throws CoreException {
+		IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
+		IProject project= root.getProject(projectName);
+		if (!project.exists()) {
+			project.create(null);
+		} else {
+			project.refreshLocal(IResource.DEPTH_INFINITE, null);
+		}
+		
+		if (!project.isOpen()) {
+			project.open(null);
+		}
+		
+		return project;
+	}
+	
+	/**
+	 * Removes an IProject.
+	 */		
+	public static void delete(IProject project) throws CoreException {
+		project.delete(true, true, null);
+	}
+
+
+	/**
+	 * Adds a folder to an IProject.
+	 */		
+	public static IFolder addFolder(IProject project, String containerName) throws CoreException {
+		
+			IFolder folder= project.getFolder(containerName);
+			if (!folder.exists()) {
+				folder.create(false, true, null);
+			}
+		
+		return folder;
+		
+	}
+	
+	public static void importFilesFromDirectory(File rootDir, IPath destPath, IProgressMonitor monitor) throws InvocationTargetException, IOException {		
+		IImportStructureProvider structureProvider = FileSystemStructureProvider.INSTANCE;
+		List files = new ArrayList(100);
+		addFiles(rootDir, files);
+		try {
+			ImportOperation op= new ImportOperation(destPath, rootDir, structureProvider, new ImportOverwriteQuery(), files);
+			op.setCreateContainerStructure(false);
+			op.run(monitor);
+		} catch (InterruptedException e) {
+			// should not happen
+		}
+	}	
+	
+	private static void addFiles(File dir, List collection) throws IOException {
+		File[] files = dir.listFiles();
+		List subDirs = new ArrayList(2);
+		for (int i = 0; i < files.length; i++) {
+			if (files[i].isFile()) {
+				collection.add(files[i]);
+			} else if (files[i].isDirectory()) {
+				subDirs.add(files[i]);
+			}
+		}
+		Iterator iter = subDirs.iterator();
+		while (iter.hasNext()) {
+			File subDir = (File)iter.next();
+			addFiles(subDir, collection);
+		}
+	}
+	
+	private static class ImportOverwriteQuery implements IOverwriteQuery {
+		public String queryOverwrite(String file) {
+			return ALL;
+		}	
+	}
+
+	public static final String PROJECT_NAME = "AntTests";
+	public static final String BUILDFILES_FOLDER = "buildfiles";
+	public static final String RESOURCES_FOLDER = "resources";
+	public static final String LIB_FOLDER = "lib";			
+}
diff --git a/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/inputHandlers/AntTestInputHandler.java b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/inputHandlers/AntTestInputHandler.java
new file mode 100644
index 0000000..e6be8dc
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/inputHandlers/AntTestInputHandler.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.support.inputHandlers;
+
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputRequest;
+
+/**
+ * A test input handler when using Ant within Eclipse.
+ * This is the class that will respond to <input> requests from
+ * within an Ant build file.
+ * If the build is occurring in Ant 1.6.0 and the -noinput option has been specified
+ * this input handler will fail.
+ */
+public class AntTestInputHandler extends DefaultInputHandler {
+	
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.input.InputHandler#handleInput(org.apache.tools.ant.input.InputRequest)
+	 */
+	public void handleInput(InputRequest request) throws BuildException {
+		if (System.getProperty("eclipse.ant.noInput") != null) { //$NON-NLS-1$
+			throw new BuildException("Unable to respond to input request likely as a result of specifying the -noinput command");
+		}
+		request.setInput("testing handling input requests");
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/tasks/AntTestTask.java b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/tasks/AntTestTask.java
new file mode 100644
index 0000000..57372f0
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/tasks/AntTestTask.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.support.tasks;
+
+
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Echo;
+
+
+public class AntTestTask extends Task {
+	
+	public AntTestTask() {
+		super();
+	}
+	
+	/**
+	 * @see org.apache.tools.ant.Task#execute()
+	 */
+	public void execute() throws BuildException {
+		Echo echo= new Echo();
+		echo.setProject(getProject());
+		echo.setMessage("Testing Ant in Eclipse with a custom task");
+		echo.execute();
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/tasks/AntTestTask2.java b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/tasks/AntTestTask2.java
new file mode 100644
index 0000000..2f44be2
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/tasks/AntTestTask2.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.support.tasks;
+
+
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Echo;
+
+
+public class AntTestTask2 extends Task {
+	
+	public AntTestTask2() {
+		super();
+	}
+	
+	/**
+	 * @see org.apache.tools.ant.Task#execute()
+	 */
+	public void execute() throws BuildException {
+		Echo echo= new Echo();
+		echo.setProject(getProject());
+		echo.setMessage("Testing Ant in Eclipse with a custom task");
+		echo.execute();
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/testloggers/TestBuildListener.java b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/testloggers/TestBuildListener.java
new file mode 100644
index 0000000..7744880
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/testloggers/TestBuildListener.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.support.testloggers;
+
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildListener;
+import org.eclipse.ant.tests.core.testplugin.AntTestChecker;
+
+
+public class TestBuildListener implements BuildListener {
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#buildFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void buildFinished(BuildEvent event) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#buildStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void buildStarted(BuildEvent event) {
+		AntTestChecker.getDefault().addNameOfListener(this.getClass().getName());
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#messageLogged(org.apache.tools.ant.BuildEvent)
+	 */
+	public void messageLogged(BuildEvent event) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#targetFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void targetFinished(BuildEvent event) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void targetStarted(BuildEvent event) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void taskFinished(BuildEvent event) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#taskStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void taskStarted(BuildEvent event) {
+	}
+
+}
diff --git a/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/testloggers/TestBuildLogger.java b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/testloggers/TestBuildLogger.java
new file mode 100644
index 0000000..3b9d8aa
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/testloggers/TestBuildLogger.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.support.testloggers;
+
+
+import java.io.PrintStream;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildLogger;
+import org.apache.tools.ant.Project;
+import org.eclipse.ant.core.AntSecurityException;
+import org.eclipse.ant.tests.core.testplugin.AntTestChecker;
+import org.eclipse.core.runtime.OperationCanceledException;
+
+public class TestBuildLogger implements BuildLogger {
+
+	private int fMessageOutputLevel= Project.MSG_INFO;
+	private PrintStream fErr= null;
+	private PrintStream fOut= null;
+    private boolean fSetProperties= true;
+	
+	/**
+	 * An exception that has already been logged.
+	 */
+	private Throwable fHandledException= null;
+	
+	
+	public TestBuildLogger() {
+	}
+	
+	/**
+	 * @see org.apache.tools.ant.BuildLogger#setMessageOutputLevel(int)
+	 */
+	public void setMessageOutputLevel(int level) {
+		fMessageOutputLevel= level;
+	}
+	
+	protected int getMessageOutputLevel() {
+		return fMessageOutputLevel;
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildLogger#setEmacsMode(boolean)
+	 */
+	public void setEmacsMode(boolean emacsMode) {
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#buildStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void buildStarted(BuildEvent event) {
+		AntTestChecker.getDefault().buildStarted(event.getProject().getName());
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#buildFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void buildFinished(BuildEvent event) {
+		handleException(event);
+		fHandledException= null;
+		AntTestChecker.getDefault().buildFinished();
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void targetStarted(BuildEvent event) {
+		AntTestChecker.getDefault().targetStarted(event.getTarget().getName());
+        if (fSetProperties) {
+            fSetProperties= false;
+            AntTestChecker.getDefault().setUserProperties(event.getProject().getProperties());
+        }
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#targetFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void targetFinished(BuildEvent event) {
+		handleException(event);
+		AntTestChecker.getDefault().targetFinished();
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#taskStarted(org.apache.tools.ant.BuildEvent)
+	 */
+	public void taskStarted(BuildEvent event) {
+		AntTestChecker.getDefault().taskStarted(event.getTask().getTaskName());
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent)
+	 */
+	public void taskFinished(BuildEvent event) {
+		handleException(event);
+		AntTestChecker.getDefault().targetFinished();
+	}
+
+	/**
+	 * @see BuildListener#messageLogged(BuildEvent)
+	 */
+	public void messageLogged(BuildEvent event) {
+		if (event.getPriority() > getMessageOutputLevel()) {
+			return;
+		}
+		logMessage(event.getMessage(), event.getPriority());
+		AntTestChecker.getDefault().messageLogged(event.getMessage());
+	}
+
+	protected PrintStream getErrorPrintStream() {
+		return fErr;
+	}
+	
+	protected PrintStream getOutputPrintStream() {
+		return fOut;
+	}
+	
+	/**
+	 * @see org.apache.tools.ant.BuildLogger#setErrorPrintStream(java.io.PrintStream)
+	 */
+	public void setErrorPrintStream(PrintStream err) {
+		//this build logger logs to "null" unless
+		//the user has explicitly set a logfile to use
+		if (err == System.err) {
+			fErr= null;
+		} else {
+			fErr= err;
+		}
+	}
+
+	/**
+	 * @see org.apache.tools.ant.BuildLogger#setOutputPrintStream(java.io.PrintStream)
+	 */
+	public void setOutputPrintStream(PrintStream output) {
+		//this build logger logs to "null" unless
+		//the user has explicitly set a logfile to use
+		if (output == System.out) {
+			fOut= null;
+		} else {
+			fOut= output;
+		}
+	}
+	
+	protected void logMessage(String message, int priority) {
+		if (priority > getMessageOutputLevel()) {
+			return;
+		}
+		
+		if (priority == Project.MSG_ERR) {
+			if (getErrorPrintStream() != null && getErrorPrintStream() != System.err) {
+				//user has designated to log to a logfile
+				getErrorPrintStream().println(message);
+			}
+		} else {
+			if (getOutputPrintStream() != null && getOutputPrintStream() != System.out) {
+				//user has designated to log to a logfile
+				getOutputPrintStream().println(message);
+			} 
+		}
+	}
+	
+	protected void handleException(BuildEvent event) {
+		Throwable exception = event.getException();
+		if (exception == null || exception == fHandledException
+		|| exception instanceof OperationCanceledException
+		|| exception instanceof AntSecurityException) {
+			return;
+		}
+		fHandledException= exception;
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/types/AntTestPath.java b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/types/AntTestPath.java
new file mode 100644
index 0000000..e5e9bf2
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test support/org/eclipse/ant/tests/core/support/types/AntTestPath.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.support.types;
+
+
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+
+public class AntTestPath extends Path {
+	
+	String message;
+	
+	public AntTestPath(Project project) {
+		super(project);
+	}
+	
+	public void setMessage(String message) {
+		this.message= message;
+	}
+	
+	public String getMessage() {
+		return message;
+	}
+	
+}
diff --git a/ant/org.eclipse.ant.tests.core/test.xml b/ant/org.eclipse.ant.tests.core/test.xml
new file mode 100644
index 0000000..4f6daa5
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/test.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+
+<project name="testsuite" default="run" basedir=".">
+  <!-- sets the properties eclipse-home, and library-file -->
+  <!-- The property ${eclipse-home} should be passed into this script -->
+  <!-- Set a meaningful default value for when it is not. -->
+  <property name="eclipse-home" value="${basedir}\..\.."/>
+<property name="plugin-name" value="org.eclipse.ant.tests.core"/>
+  <property name="library-file"
+            value="${eclipse-home}/plugins/org.eclipse.test/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">
+    <property name="jdt-folder" 
+              value="${eclipse-home}/jdt_folder"/>
+    <delete dir="${jdt-folder}" quiet="true"/>
+    <ant target="core-test" antfile="${library-file}" dir="${eclipse-home}">
+      <property name="data-dir" value="${jdt-folder}"/>
+      <property name="plugin-name" value="${plugin-name}"/>
+      <property name="classname" 
+                value="org.eclipse.ant.tests.core.AutomatedSuite"/>
+    </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>
+
+  <!-- This target runs the performance test suites. -->
+  <target name="performance">
+  </target>	
+	
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug32551.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug32551.xml
new file mode 100644
index 0000000..e543997
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug32551.xml
@@ -0,0 +1,15 @@
+<project name="bug" default="all">
+ <path id="myclasspath">
+ 	<fileset dir="..\lib">
+  		<include name="antTestsSupport.jar" /> 
+  	</fileset>
+  </path>
+  
+ <taskdef name="hello" classname="org.eclipse.ant.tests.core.support.tasks.AntTestTask">
+  	<classpath refid="myclasspath" /> 
+  </taskdef>
+  
+ <target name="all">
+  	<hello /> 
+  </target>
+  </project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug34663.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug34663.xml
new file mode 100644
index 0000000..2479f90
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug34663.xml
@@ -0,0 +1,8 @@
+<project name="34663.xml" default="echoP">
+
+<taskdef file="${ROOTDIR}/taskdefs.properties" />
+ 
+ <target name="echoP">
+ 	<myEchoProperties/>
+ </target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug42926.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug42926.xml
new file mode 100644
index 0000000..3bb86a2
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug42926.xml
@@ -0,0 +1,12 @@
+<project default="all">
+	<path id="someclasspath">
+		<fileset dir="${ant.home}/lib" includes="sometask.jar"/>
+	</path>
+
+	<taskdef name="sometask" classname="com.foo.SomeTask"
+classpathref="someclasspath"/>
+
+	<target name="all">
+		<echo>Hello ${ant.home}</echo>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug73602.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug73602.xml
new file mode 100644
index 0000000..505a2bd
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/Bug73602.xml
@@ -0,0 +1,13 @@
+<project name="main" default="all">
+    <taskdef resource="taskdefs.properties"/>
+    <hello/>
+    <target name="all">
+        <echo>Hello</echo>
+    </target>
+	<target name="all3">
+	        <echo>Hello</echo>
+	    </target>
+	<target name="all4">
+	        <echo>Hello</echo>
+	    </target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/ClasspathOrdering.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/ClasspathOrdering.xml
new file mode 100644
index 0000000..c99b65e
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/ClasspathOrdering.xml
@@ -0,0 +1,6 @@
+<project name="ClasspathOrdering" default="ordered" basedir="..">
+
+	<target name="ordered">
+		<java classname= "ClasspathOrdering"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/CustomTask.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/CustomTask.xml
new file mode 100644
index 0000000..53525c8
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/CustomTask.xml
@@ -0,0 +1,13 @@
+<project name="Custom Task" default="Custom Task" basedir=".">
+	<target name="init">
+		<tstamp/>
+	</target>
+
+	<target name="Custom Task" description= "Test adding a custom task" depends="init">
+		<AntTestTask/>
+	</target>
+	
+	<target name="Custom Task from Entry" description= "Test adding a custom task">
+		<AntTestTask2/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/CustomType.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/CustomType.xml
new file mode 100644
index 0000000..1ae1ef5
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/CustomType.xml
@@ -0,0 +1,16 @@
+<project name="Custom Type" default="Custom Type" basedir=".">
+
+	<anttestpath id="compile.classpath">
+      <fileset dir="lib">
+        <include name="**/*.jar"/>
+      </fileset>
+    </anttestpath>
+    
+	<target name="init">
+		<tstamp/>
+	</target>
+
+	<target name="Custom Type" description= "Test adding a custom type" depends="init">
+		<echo message="Test adding a custom type"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/ExtensionPointTask.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/ExtensionPointTask.xml
new file mode 100644
index 0000000..b8c6bb4
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/ExtensionPointTask.xml
@@ -0,0 +1,16 @@
+<!--
+     Copyright (c) 2005, 2006 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
+ -->
+<project name="Extension Point Task" default="Extension Point Task" basedir=".">
+	<target name="Extension Point Task" description= "Ensure that an extension point defined task is present">
+		<coolTask/>
+		<my:coolTask xmlns:my="testing"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/ExtensionPointType.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/ExtensionPointType.xml
new file mode 100644
index 0000000..abaaaec
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/ExtensionPointType.xml
@@ -0,0 +1,12 @@
+<project name="Extension Point Type" default="Extension Point Type" basedir=".">
+
+	<coolType id="compile.classpath">
+      <fileset dir="lib">
+        <include name="**/*.jar"/>
+      </fileset>
+    </coolType>
+    
+	<target name="Extension Point Type" description= "Ensure that an extension point defined type is present">
+		<echo message="Ensure that an extension point defined type is present"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/NoDefault.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/NoDefault.xml
new file mode 100644
index 0000000..77c914a
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/NoDefault.xml
@@ -0,0 +1,5 @@
+<project name= "Testing">
+	<target name= "test">
+		<echo message="testing"/>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/TestForEcho.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/TestForEcho.xml
new file mode 100644
index 0000000..2213e5e
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/TestForEcho.xml
@@ -0,0 +1,11 @@
+<project name="Echo Test" default="Test for Echo" basedir=".">
+	<target name="init">
+		<tstamp/>
+	</target>
+
+	<target name="Test for Echo" description= "Calls other echos" depends="init">
+		<ant antfile="buildfiles/echoing.xml" dir="../../AntTests" target="echo1"/>
+		<ant antfile="buildfiles/echoing.xml" dir="../../AntTests" target="echo2"/>
+		<ant antfile="buildfiles/echoing.xml" dir="../../AntTests" target="echo3"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/build.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/build.xml
new file mode 100644
index 0000000..7638a53
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/build.xml
@@ -0,0 +1,14 @@
+<project name="Eching" default="echo1" basedir="..">
+
+	<target name="echo1">
+		<echo message="echo1"/>
+	</target>
+	
+	<target name="echo2">
+		<echo message="echo2"/>
+	</target>
+	
+	<target name="echo3" description= "An echo3!">
+		<echo message="echo3"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/echoing.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/echoing.xml
new file mode 100644
index 0000000..5cdd64d
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/echoing.xml
@@ -0,0 +1,14 @@
+<project name="Echoing" default="echo1" basedir="..">
+
+	<target name="echo1">
+		<echo message="echo1"/>
+	</target>
+	
+	<target name="echo2">
+		<echo message="echo2"/>
+	</target>
+	
+	<target name="echo3" description= "An echo3!">
+		<echo message="echo3"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/failingTarget.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/failingTarget.xml
new file mode 100644
index 0000000..04418e0
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/failingTarget.xml
@@ -0,0 +1,9 @@
+<project default="all">
+	<target name="all" depends="fails, echos"/>
+	<target name="fails">
+		<jar jarfile="jar16.jar" basedir="doesNotExist"/>
+	</target>
+	<target name="echos">
+		<echo>Still echo on failure</echo>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/input.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/input.xml
new file mode 100644
index 0000000..8d70ab5
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/input.xml
@@ -0,0 +1,7 @@
+<project name="input testing" default= "input test">
+	<target name="input test">
+		<input message="Enter for echo" addproperty= "inputTest">
+		</input>
+		<echo message="${inputTest}"/>
+	</target>	
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.core/testbuildfiles/javac.xml b/ant/org.eclipse.ant.tests.core/testbuildfiles/javac.xml
new file mode 100644
index 0000000..42f0225
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testbuildfiles/javac.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="org.eclipse.ant.core" default="build" basedir="..">
+
+	
+	<target name="init" depends="properties">
+		<property name="plugin" value="AntTests"/>
+		<property name="temp.folder" value="${basedir}/temp.folder"/>
+		<property name="plugin.destination" value="${basedir}"/>
+		<property name="build.result.folder" value="${basedir}"/>
+	</target>
+	
+	<target name="properties" if="use.eclipse.JDTCompiler">
+		<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+	</target>
+	
+	<target name="build" depends="init">
+		<property name="destdir" value="${temp.folder}/javac.bin"/>
+		<delete dir="${temp.folder}/javac.bin"/>
+		<mkdir dir="${temp.folder}/javac.bin"/>
+		<!-- compile the source code -->
+		<javac destdir="${temp.folder}/javac.bin" failonerror="false" verbose="false" debug="on" includeAntRuntime="yes">
+			<src path="resources"/>
+		</javac>
+	</target>
+	
+	<target name="clean" depends="init">
+		<delete dir="${temp.folder}"/>
+	</target>
+
+	<target name="refresh" depends="init" if="eclipse.running">
+		<eclipse.refreshLocal resource="${plugin}" depth="infinite"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.core/testlib/classpathOrdering1.jar b/ant/org.eclipse.ant.tests.core/testlib/classpathOrdering1.jar
new file mode 100644
index 0000000..b10cb7f
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testlib/classpathOrdering1.jar
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.core/testlib/classpathOrdering2.jar b/ant/org.eclipse.ant.tests.core/testlib/classpathOrdering2.jar
new file mode 100644
index 0000000..6816741
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testlib/classpathOrdering2.jar
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.core/testlib/taskFolder/org/eclipse/ant/tests/core/support/tasks/AntTestTask2.class b/ant/org.eclipse.ant.tests.core/testlib/taskFolder/org/eclipse/ant/tests/core/support/tasks/AntTestTask2.class
new file mode 100644
index 0000000..6a37eb5
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testlib/taskFolder/org/eclipse/ant/tests/core/support/tasks/AntTestTask2.class
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.core/testresources/AntTestTask.java b/ant/org.eclipse.ant.tests.core/testresources/AntTestTask.java
new file mode 100644
index 0000000..4f3f09c
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testresources/AntTestTask.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Echo;
+
+
+public class AntTestTask extends Task {
+	
+	public AntTestTask() {
+		super();
+	}
+	
+	/**
+	 * @see org.apache.tools.ant.Task#execute()
+	 */
+	public void execute() throws BuildException {
+		Echo echo= new Echo();
+		echo.setProject(getProject());
+		echo.setMessage("Testing Ant in Eclipse with a custom task");
+		echo.execute();
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.core/testresources/taskdefs.properties b/ant/org.eclipse.ant.tests.core/testresources/taskdefs.properties
new file mode 100644
index 0000000..47fdd3a
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testresources/taskdefs.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2004, 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
+###############################################################################
+myEchoProperties=org.apache.tools.ant.taskdefs.optional.EchoProperties
+hello=org.eclipse.ant.tests.core.support.tasks.AntTestTask
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.core/testresources/test.properties b/ant/org.eclipse.ant.tests.core/testresources/test.properties
new file mode 100644
index 0000000..8a043f8
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/testresources/test.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# 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
+###############################################################################
+AntTests=testing from properties file
+eclipse.is.cool=Yep
diff --git a/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/AbstractAntTest.java b/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/AbstractAntTest.java
new file mode 100644
index 0000000..be5f9c3
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/AbstractAntTest.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core;
+
+
+import java.io.File;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.AntRunner;
+import org.eclipse.ant.core.IAntClasspathEntry;
+import org.eclipse.ant.core.Property;
+import org.eclipse.ant.core.TargetInfo;
+import org.eclipse.ant.core.Task;
+import org.eclipse.ant.core.Type;
+import org.eclipse.ant.tests.core.testplugin.AntFileRunner;
+import org.eclipse.ant.tests.core.testplugin.AntTestChecker;
+import org.eclipse.ant.tests.core.testplugin.AntTestPlugin;
+import org.eclipse.ant.tests.core.testplugin.ProjectHelper;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+ 
+/**
+ * Tests for Ant core
+ */
+public abstract class AbstractAntTest extends TestCase {
+	
+	protected static final String BUILD_SUCCESSFUL= "BUILD SUCCESSFUL";
+	public static final String ANT_TEST_BUILD_LOGGER = "org.eclipse.ant.tests.core.support.testloggers.TestBuildLogger"; //$NON-NLS-1$
+	public static final String ANT_TEST_BUILD_LISTENER= "org.eclipse.ant.tests.core.support.testloggers.TestBuildListener";
+	
+	/* (non-Javadoc)
+	 * @see junit.framework.TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		super.setUp();
+		assertProject();
+	}
+	
+	/**
+	 * Asserts that the test project has been created and all testing resources have been 
+	 * loaded each time the {@link #setUp()} method is called
+	 * @throws Exception
+	 * @since 3.5
+	 */
+	protected void assertProject() throws Exception {
+		// delete any pre-existing project
+		IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ProjectHelper.PROJECT_NAME);
+		if (!pro.exists()) {
+			// create project and import build files and support files
+			IProject project = ProjectHelper.createProject(ProjectHelper.PROJECT_NAME);
+			IFolder folder = ProjectHelper.addFolder(project, ProjectHelper.BUILDFILES_FOLDER);
+			File root = AntTestPlugin.getDefault().getFileInPlugin(ProjectHelper.TEST_BUILDFILES_DIR);
+			ProjectHelper.importFilesFromDirectory(root, folder.getFullPath(), null);
+			
+			folder = ProjectHelper.addFolder(project, ProjectHelper.RESOURCES_FOLDER);
+			root = AntTestPlugin.getDefault().getFileInPlugin(ProjectHelper.TEST_RESOURCES_DIR);
+			ProjectHelper.importFilesFromDirectory(root, folder.getFullPath(), null);
+			
+			folder = ProjectHelper.addFolder(project, ProjectHelper.LIB_FOLDER);
+			root = AntTestPlugin.getDefault().getFileInPlugin(ProjectHelper.TEST_LIB_DIR);
+			ProjectHelper.importFilesFromDirectory(root, folder.getFullPath(), null);
+		}
+	}
+	
+	/**
+	 * Returns the 'AntTests' project.
+	 * 
+	 * @return the test project
+	 */
+	protected IProject getProject() {
+		return ResourcesPlugin.getWorkspace().getRoot().getProject(ProjectHelper.PROJECT_NAME);
+	}
+	
+	public AbstractAntTest(String name) {
+		super(name);
+	}
+	
+	protected IFile getBuildFile(String buildFileName) {
+		IFile file = getProject().getFolder(ProjectHelper.BUILDFILES_FOLDER).getFile(buildFileName);
+		assertTrue("Could not find build file named: " + buildFileName, file.exists());
+		return file;
+	}
+	
+	protected IFolder getWorkingDirectory(String workingDirectoryName) {
+		IFolder folder = getProject().getFolder(workingDirectoryName);
+		assertTrue("Could not find the working directory named: " + workingDirectoryName, folder.exists());
+		return folder;
+	}
+	
+	protected IFile checkFileExists(String fileName) throws CoreException {
+		getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+		IFile file = getProject().getFolder(ProjectHelper.BUILDFILES_FOLDER).getFile(fileName);
+		assertTrue("Could not find file named: " + fileName, file.exists());
+		return file;
+	}
+	
+	public void run(String buildFileName) throws CoreException {
+		run(buildFileName, null, false);
+	}
+	
+	public void run(String buildFileName, String[] args) throws CoreException {
+		run(buildFileName, args, false);
+	}
+	
+	public void run(String buildFileName, String[] args, boolean retrieveTargets) throws CoreException {
+		run(buildFileName, args, retrieveTargets, "");
+	}
+	
+	public void run(String buildFileName, String[] args, boolean retrieveTargets, String workingDir) throws CoreException {
+		AntTestChecker.reset();
+		IFile buildFile= null;
+		if (buildFileName != null) {
+			buildFile= getBuildFile(buildFileName);
+		}
+		AntFileRunner runner= new AntFileRunner();
+		String[] targets= null;
+		if (retrieveTargets) {
+			targets= getTargetNames(buildFileName);
+		}
+		if (workingDir.length() > 0) {
+			workingDir= getWorkingDirectory(workingDir).getLocation().toFile().getAbsolutePath();
+		} 
+		runner.run(buildFile, targets, args, workingDir, true);
+		assertTrue("Build starts did not equal build finishes", AntTestChecker.getDefault().getBuildsStartedCount() == AntTestChecker.getDefault().getBuildsFinishedCount());
+	}
+	
+	protected TargetInfo[] getTargets(String buildFileName) throws CoreException {
+		IFile buildFile= getBuildFile(buildFileName);
+		
+		AntRunner runner = new AntRunner();
+		runner.setBuildFileLocation(buildFile.getLocation().toFile().getAbsolutePath());
+	 	return runner.getAvailableTargets();
+	}
+	
+	protected String[] getTargetNames(String buildFileName) throws CoreException {
+		TargetInfo[] infos= getTargets(buildFileName);
+		String[] names= new String[infos.length];
+		for (int i = 0; i < infos.length; i++) {
+			TargetInfo info = infos[i];
+			names[i]= info.getName();
+		}
+		return names;
+	}
+	
+	protected String[] getTargetDescriptions(String buildFileName) throws CoreException {
+		TargetInfo[] infos= getTargets(buildFileName);
+		String[] descriptions= new String[infos.length];
+		for (int i = 0; i < infos.length; i++) {
+			TargetInfo info = infos[i];
+			descriptions[i]= info.getDescription();
+		}
+		return descriptions;
+	}
+	
+	/**
+	 * Returns the name of the project containing the given target in the given build file or
+	 * <code>null</code> if no project name can be found.
+	 */
+	protected String getProjectName(String buildFileName, String targetName) throws CoreException {
+		TargetInfo info= getTarget(buildFileName, targetName);
+		if (info != null) {
+			return info.getProject().getName();
+		}
+		return null;
+	}
+	
+	/**
+	 * Returns the dependencies of the target with the given name in the given build file or <code>null</code>
+	 * if no such target can be found.
+	 */
+	protected String[] getDependencies(String buildFileName, String targetName) throws CoreException {
+		TargetInfo info= getTarget(buildFileName, targetName);
+		if (info != null) {
+			return info.getDependencies();
+		}
+		return null;
+	}
+	
+	/**
+	 * Returns the target with the given name in the given build file or <code>null</code>
+	 * if no such target can be found.
+	 */
+	protected TargetInfo getTarget(String buildFileName, String targetName) throws CoreException {
+		TargetInfo[] infos= getTargets(buildFileName);
+		for (int i= 0, numTargets= infos.length; i < numTargets; i++) {
+			if (infos[i].getName().equals(targetName)) {
+				return infos[i];
+			}
+		}
+		return null;
+	}
+    
+    /**
+     * Return the log message n from the last:
+     * e.g. getLoggedMessage(0) returns the most recent message
+     * 
+     * @param n message index
+     * @return the nth last message
+     */
+    protected String getLoggedMessage(int n) {
+        return AntTestChecker.getDefault().getLoggedMessage(n);
+    }
+	
+	protected String getLastMessageLogged() {
+		return getLoggedMessage(0);
+	}
+	
+	protected void assertSuccessful() {
+		List messages= AntTestChecker.getDefault().getMessages();
+		String success= (String)messages.get(messages.size() - 1);
+		assertEquals("Build was not flagged as successful: " + success, BUILD_SUCCESSFUL, success);
+	}
+	
+	protected String getPropertyFileName() {
+		return getProject().getFolder(ProjectHelper.RESOURCES_FOLDER).getFile("test.properties").getLocation().toFile().getAbsolutePath();
+	}
+	
+	protected void restorePreferenceDefaults() {
+		AntCorePreferences prefs= AntCorePlugin.getPlugin().getPreferences();
+		IAntClasspathEntry toolsEntry= prefs.getToolsJarEntry();
+		IAntClasspathEntry[] additionalEntries;
+		if (toolsEntry == null) {
+			additionalEntries= new IAntClasspathEntry[]{};
+		} else {
+			additionalEntries= new IAntClasspathEntry[] {toolsEntry};
+		}
+		prefs.setAdditionalClasspathEntries(additionalEntries);
+		prefs.setAntHomeClasspathEntries(prefs.getDefaultAntHomeEntries());
+		prefs.setCustomTasks(new Task[]{});
+		prefs.setCustomTypes(new Type[]{});
+		prefs.setCustomPropertyFiles(new String[]{});
+		prefs.setCustomProperties(new Property[]{});
+		prefs.setAntHome(prefs.getDefaultAntHome());
+	}
+	
+	protected String getAntHome() {
+		AntCorePreferences prefs= AntCorePlugin.getPlugin().getPreferences();
+		IAntClasspathEntry[] entries= prefs.getAntHomeClasspathEntries();
+		IAntClasspathEntry antjar= entries[0];
+		IPath antHomePath= new Path(antjar.getEntryURL().getFile());
+		antHomePath= antHomePath.removeLastSegments(1);
+		return antHomePath.toFile().getAbsolutePath();
+	}
+}
+
diff --git a/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/tests/ProjectTests.java b/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/tests/ProjectTests.java
new file mode 100644
index 0000000..c3694fa
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/tests/ProjectTests.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.tests;
+
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.tests.core.AbstractAntTest;
+import org.eclipse.ant.tests.core.testplugin.AntTestChecker;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+
+
+public class ProjectTests extends AbstractAntTest {
+	
+	public ProjectTests(String name) {
+		super(name);
+	}
+	
+	/**
+	 * Tests that the three properties that should always be set are correct
+	 */
+	public void testBasePropertiesSet() throws CoreException {
+		String buildFileName="TestForEcho.xml"; 
+		run(buildFileName);
+		IFile buildFile= getBuildFile(buildFileName);
+		String fullName= buildFile.getLocation().toFile().getAbsolutePath();
+		assertEquals("eclipse.running should have been set as true", "true", AntTestChecker.getDefault().getUserProperty("eclipse.running"));
+		assertEquals("ant.file should have been set as the build file name", fullName, AntTestChecker.getDefault().getUserProperty("ant.file"));
+		assertNotNull("ant.java.version should have been set", AntTestChecker.getDefault().getUserProperty("ant.java.version"));
+		assertNotNull("ant.version should have been set", AntTestChecker.getDefault().getUserProperty("ant.version"));
+		assertNotNull("eclipse.home should have been set", AntTestChecker.getDefault().getUserProperty("eclipse.home"));
+	}
+
+	public void testValue() throws CoreException {
+		String buildFileName="TestForEcho.xml"; 
+		run(buildFileName);
+		assertEquals("property.testing should have been set as true", "true", AntTestChecker.getDefault().getUserProperty("property.testing"));
+	}
+
+	public void testValueWithClass() throws CoreException {
+		
+		String buildFileName="TestForEcho.xml"; 
+		run(buildFileName);
+		assertEquals("property.testing2 should have been set as hey", "hey", AntTestChecker.getDefault().getUserProperty("property.testing2"));
+	}
+
+	public void testClass() throws CoreException {
+		String buildFileName="TestForEcho.xml"; 
+		run(buildFileName);
+		assertEquals("property.testing3 should have been set as AntTestPropertyProvider", "AntTestPropertyValueProvider", AntTestChecker.getDefault().getUserProperty("property.testing3"));
+	}
+	
+	public void testHeadless() throws CoreException {
+		try {
+			AntCorePlugin.getPlugin().setRunningHeadless(true);
+			String buildFileName="TestForEcho.xml"; 
+			run(buildFileName);
+			assertNull("property.headless should not have been set as AntTestPropertyProvider", AntTestChecker.getDefault().getUserProperty("property.headless"));
+		} finally {
+			AntCorePlugin.getPlugin().setRunningHeadless(false);
+		}
+	}
+	
+	public void testNotHeadless() throws CoreException {
+		String buildFileName="TestForEcho.xml"; 
+		run(buildFileName);
+		assertEquals("property.headless should have been set as AntTestPropertyProvider", "headless", AntTestChecker.getDefault().getUserProperty("property.headless"));
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/tests/TaskTests.java b/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/tests/TaskTests.java
new file mode 100644
index 0000000..24ae812
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/tests/TaskTests.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.tests;
+
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.IAntClasspathEntry;
+import org.eclipse.ant.core.Property;
+import org.eclipse.ant.core.Task;
+import org.eclipse.ant.internal.core.AntClasspathEntry;
+import org.eclipse.ant.tests.core.AbstractAntTest;
+import org.eclipse.ant.tests.core.testplugin.AntTestChecker;
+import org.eclipse.ant.tests.core.testplugin.ProjectHelper;
+import org.eclipse.core.runtime.CoreException;
+
+public class TaskTests extends AbstractAntTest {
+
+	
+	public TaskTests(String name) {
+		super(name);
+	}
+	
+	/**
+	 * Testing the old deprecated API
+	 * @throws CoreException
+	 */
+	public void testAddTaskSettingLibrary() throws CoreException {
+		AntCorePreferences prefs =AntCorePlugin.getPlugin().getPreferences();
+		URL[] urls= prefs.getExtraClasspathURLs();
+		Task newTask= new Task();
+		newTask.setLibrary(urls[0]);
+		newTask.setTaskName("AntTestTask");
+		newTask.setClassName("org.eclipse.ant.tests.core.support.tasks.AntTestTask");
+		prefs.setCustomTasks(new Task[]{newTask});
+		
+		prefs.updatePluginPreferences();
+		
+		run("CustomTask.xml", new String[0], false);
+		String msg= (String)AntTestChecker.getDefault().getMessages().get(1);
+		assertEquals("Message incorrect: " + msg, "Testing Ant in Eclipse with a custom task", msg);
+		assertSuccessful();
+	}
+	
+	public void testAddTaskSettingLibraryEntry() throws CoreException {
+		AntCorePreferences prefs =AntCorePlugin.getPlugin().getPreferences();
+		URL[] urls= prefs.getExtraClasspathURLs();
+		Task newTask= new Task();
+		newTask.setLibraryEntry(new AntClasspathEntry(urls[0]));
+		newTask.setTaskName("AntTestTask2");
+		newTask.setClassName("org.eclipse.ant.tests.core.support.tasks.AntTestTask");
+		prefs.setCustomTasks(new Task[]{newTask});
+		
+		prefs.updatePluginPreferences();
+		
+		run("CustomTask.xml", new String[] {"Custom Task from Entry"}, false);
+		String msg= (String)AntTestChecker.getDefault().getMessages().get(1);
+		assertEquals("Message incorrect: " + msg, "Testing Ant in Eclipse with a custom task", msg);
+		assertSuccessful();
+	}
+	
+	public void testRemoveTask() {
+		AntCorePreferences prefs =AntCorePlugin.getPlugin().getPreferences();
+		prefs.setCustomTasks(new Task[]{});
+		try {
+			run("CustomTask.xml");
+		} catch (CoreException ce) {
+			assertTrue("Exception from undefined task is incorrect", ce.getMessage().trim().endsWith("Action: Check that any <presetdef>/<macrodef> declarations have taken place."));
+			return;
+		} finally {
+			restorePreferenceDefaults();	
+		}
+		assertTrue("Build should have failed as task no longer defined", false);
+	}
+	
+	public void testAddTaskFromFolder() throws CoreException {
+		try {
+			AntCorePreferences prefs =AntCorePlugin.getPlugin().getPreferences();
+			Task newTask= new Task();
+			String path= getProject().getFolder(ProjectHelper.LIB_FOLDER).getFile("taskFolder").getLocation().toFile().getAbsolutePath();
+			IAntClasspathEntry entry= new AntClasspathEntry(path + File.separatorChar);
+			IAntClasspathEntry entries[] = prefs.getAdditionalClasspathEntries();
+			IAntClasspathEntry newEntries[] = new IAntClasspathEntry[entries.length + 1];
+			System.arraycopy(entries, 0, newEntries, 0, entries.length);
+			newEntries[entries.length] = entry;
+			prefs.setAdditionalClasspathEntries(newEntries);
+		
+			newTask.setLibraryEntry(entry);
+			newTask.setTaskName("AntTestTask");
+			newTask.setClassName("org.eclipse.ant.tests.core.support.tasks.AntTestTask2");
+			prefs.setCustomTasks(new Task[]{newTask});
+		
+			prefs.updatePluginPreferences();
+		
+			run("CustomTask.xml", new String[0], false);
+			String msg= (String)AntTestChecker.getDefault().getMessages().get(1);
+			assertEquals("Message incorrect: " + msg, "Testing Ant in Eclipse with a custom task", msg);
+			assertSuccessful();
+		} finally {
+			restorePreferenceDefaults();
+		}
+	}
+		
+	public void testTasksDefinedInPropertyFile() throws CoreException {
+		try {
+			AntCorePreferences prefs =AntCorePlugin.getPlugin().getPreferences();
+			Property newProp= new Property("ROOTDIR", "..//resources");
+			prefs.setCustomProperties(new Property[]{newProp});
+			run("Bug34663.xml");
+		} finally {
+			restorePreferenceDefaults();
+		}
+	}
+	
+	public void testTaskDefinedInExtensionPoint() throws CoreException {
+		run("ExtensionPointTask.xml");
+		String msg= (String)AntTestChecker.getDefault().getMessages().get(1);
+		assertEquals("Message incorrect: " + msg, "Testing Ant in Eclipse with a custom task", msg);
+		assertSuccessful();
+	}
+		
+	public void testTaskDefinedInExtensionPointHeadless() {
+		AntCorePlugin.getPlugin().setRunningHeadless(true);
+		try {
+			run("ExtensionPointTask.xml");
+		} catch (CoreException ce) {
+			assertTrue("Exception from undefined task is incorrect", ce.getMessage().trim().endsWith("Action: Check that any <presetdef>/<macrodef> declarations have taken place."));
+			return;
+		} finally {
+			AntCorePlugin.getPlugin().setRunningHeadless(false);
+		}
+		assertTrue("Build should have failed as task was not defined to run in headless", false);
+	}
+	
+	public void testTaskDefinedInExtensionPointWithURI() throws CoreException {
+		run("ExtensionPointTask.xml");
+		String msg= (String)AntTestChecker.getDefault().getMessages().get(2);
+		assertEquals("Message incorrect: " + msg, "Testing Ant in Eclipse with a custom task", msg);
+		assertSuccessful();
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/tests/TypeTests.java b/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/tests/TypeTests.java
new file mode 100644
index 0000000..2e30fcc
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.core/tests/org/eclipse/ant/tests/core/tests/TypeTests.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.core.tests;
+
+
+import java.net.URL;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.Type;
+import org.eclipse.ant.internal.core.AntClasspathEntry;
+import org.eclipse.ant.tests.core.AbstractAntTest;
+import org.eclipse.ant.tests.core.testplugin.AntTestChecker;
+import org.eclipse.core.runtime.CoreException;
+
+public class TypeTests extends AbstractAntTest {
+
+	public TypeTests(String name) {
+		super(name);
+	}
+	
+	public void testAddType() throws CoreException {
+		AntCorePreferences prefs =AntCorePlugin.getPlugin().getPreferences();
+		URL[] urls= prefs.getExtraClasspathURLs();
+		Type newType= new Type();
+		newType.setLibraryEntry(new AntClasspathEntry(urls[0]));
+		newType.setTypeName("anttestpath");
+		newType.setClassName("org.eclipse.ant.tests.core.support.types.AntTestPath");
+		prefs.setCustomTypes(new Type[]{newType});
+		
+		run("CustomType.xml");
+		String msg= (String)AntTestChecker.getDefault().getMessages().get(1);
+		assertEquals("Message incorrect: " + msg, "Test adding a custom type", msg);
+		assertSuccessful();
+	}
+	
+	public void testRemoveType() {
+		AntCorePreferences prefs =AntCorePlugin.getPlugin().getPreferences();
+		prefs.setCustomTypes(new Type[]{});
+		try {
+			run("CustomType.xml");
+		} catch (CoreException ce) {
+			assertTrue("Exception from undefined type is incorrect: "+ ce.getMessage(), ce.getMessage().trim().endsWith("Action: Check that any <presetdef>/<macrodef> declarations have taken place."));
+			return;
+		} finally {
+			restorePreferenceDefaults();	
+		}
+		assertTrue("Build should have failed as type no longer defined", false);
+		
+	}
+	
+	public void testTypeDefinedInExtensionPoint() throws CoreException {
+		run("ExtensionPointType.xml");
+		String msg= (String)AntTestChecker.getDefault().getMessages().get(1);
+		assertEquals("Message incorrect: " + msg, "Ensure that an extension point defined type is present", msg);
+		assertSuccessful();
+	}
+	
+	public void testTypeDefinedInExtensionPointHeadless() {
+		AntCorePlugin.getPlugin().setRunningHeadless(true);
+		try {
+			run("ExtensionPointType.xml");
+		} catch (CoreException ce) {
+			assertTrue("Exception from undefined type is incorrect: " + ce.getMessage(), ce.getMessage().trim().endsWith("Action: Check that any <presetdef>/<macrodef> declarations have taken place."));
+			return;
+		} finally {
+			AntCorePlugin.getPlugin().setRunningHeadless(false);
+		}
+		assertTrue("Build should have failed as type was not defined to run in headless", false);
+	}	
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/.classpath b/ant/org.eclipse.ant.tests.ui/.classpath
new file mode 100644
index 0000000..3b2694c
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="Ant Editor Tests"/>
+	<classpathentry kind="src" path="Ant Debug Tests"/>
+	<classpathentry kind="src" path="test plugin"/>
+	<classpathentry kind="src" path="Ant Tests"/>
+	<classpathentry kind="src" path="External Tools"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="src" output="test_support_bin" path="test support"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/ant/org.eclipse.ant.tests.ui/.externalToolBuilders/Build Test Support JAR.launch b/ant/org.eclipse.ant.tests.ui/.externalToolBuilders/Build Test Support JAR.launch
new file mode 100644
index 0000000..71fd1f3
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/.externalToolBuilders/Build Test Support JAR.launch
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
+<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
+<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot; editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.tests.ui/buildfiles/buildAntTestsSupportJAR.xml&quot; type=&quot;1&quot;/&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.tests.ui/test support&quot; type=&quot;2&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;&#10;}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,clean"/>
+<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot; editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.tests.ui&quot; type=&quot;4&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;&#10;}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.ant.tests.ui/buildfiles/buildAntTestsSupportJAR.xml}"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+</launchConfiguration>
diff --git a/ant/org.eclipse.ant.tests.ui/.project b/ant/org.eclipse.ant.tests.ui/.project
new file mode 100644
index 0000000..3c759b0
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/.project
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.ant.tests.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>		
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/Build Test Support JAR.launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/ant/org.eclipse.ant.tests.ui/.settings/org.eclipse.pde.core.prefs b/ant/org.eclipse.ant.tests.ui/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..0f654cf
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,3 @@
+#Thu May 27 14:48:38 PDT 2004

+eclipse.preferences.version=1

+selfhosting.binExcludes=/org.eclipse.ant.tests.ui/test_support_bin

diff --git a/ant/org.eclipse.ant.tests.ui/.settings/org.eclipse.pde.prefs b/ant/org.eclipse.ant.tests.ui/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..facd8d2
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,29 @@
+#Mon Dec 14 11:41:00 CST 2009

+compilers.f.unresolved-features=1

+compilers.f.unresolved-plugins=1

+compilers.incompatible-environment=1

+compilers.p.build=1

+compilers.p.build.missing.output=1

+compilers.p.deprecated=1

+compilers.p.discouraged-class=1

+compilers.p.illegal-att-value=0

+compilers.p.internal=1

+compilers.p.missing-packages=2

+compilers.p.missing-version-export-package=2

+compilers.p.missing-version-import-package=2

+compilers.p.missing-version-require-bundle=2

+compilers.p.no-required-att=0

+compilers.p.not-externalized-att=1

+compilers.p.unknown-attribute=0

+compilers.p.unknown-class=1

+compilers.p.unknown-element=0

+compilers.p.unknown-identifier=1

+compilers.p.unknown-resource=1

+compilers.p.unresolved-ex-points=0

+compilers.p.unresolved-import=0

+compilers.p.unused-element-or-attribute=1

+compilers.s.create-docs=false

+compilers.s.doc-folder=doc

+compilers.s.open-tags=1

+compilers.use-project=true

+eclipse.preferences.version=1

diff --git a/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/BreakpointTests.java b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/BreakpointTests.java
new file mode 100644
index 0000000..28e5214
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/BreakpointTests.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.debug;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.ant.internal.launching.debug.model.AntDebugTarget;
+import org.eclipse.ant.internal.launching.debug.model.AntThread;
+import org.eclipse.ant.launching.IAntLaunchConstants;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+
+/**
+ * Tests Ant breakpoints.
+ */
+public class BreakpointTests extends AbstractAntDebugTest {
+	
+	public BreakpointTests(String name) {
+		super(name);
+	}
+
+	public void testDeferredBreakpoints() throws Exception {
+		deferredBreakpoints(false);		
+	}
+
+	public void testDeferredBreakpointsSepVM() throws Exception {
+		deferredBreakpoints(true);		
+	}
+
+	private void deferredBreakpoints(boolean sepVM) throws Exception, CoreException, DebugException {
+		String fileName = "breakpoints";
+		IFile file= getIFile(fileName + ".xml");
+		List bps = new ArrayList();
+		bps.add(createLineBreakpoint(5, file));
+		bps.add(createLineBreakpoint(14, file));
+		AntThread thread= null;
+		try {
+			thread= launchToBreakpoint(fileName, true, sepVM);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+			while (!bps.isEmpty()) {
+				IBreakpoint hit = getBreakpoint(thread);
+				assertNotNull("suspended, but not by breakpoint", hit);
+				assertTrue("hit un-registered breakpoint", bps.contains(hit));
+				assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint);
+				ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
+				int lineNumber = breakpoint.getLineNumber();
+				int stackLine = thread.getTopStackFrame().getLineNumber();
+				assertEquals("line numbers of breakpoint and stack frame do not match", lineNumber, stackLine);
+				bps.remove(breakpoint);
+				breakpoint.delete();
+				if (!bps.isEmpty()) {
+                    if (sepVM) {
+                        waitForTarget();
+                    }
+					thread = resume(thread);
+				}
+			}
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testDisabledBreakpoint() throws Exception {
+        disabledBreakpoint(false);				
+	}
+
+	public void testDisabledBreakpointSepVM() throws Exception {
+        disabledBreakpoint(true);				
+	}
+
+	private void disabledBreakpoint(boolean separateVM) throws Exception, CoreException {
+		String fileName = "breakpoints";
+		ILineBreakpoint bp = createLineBreakpoint(5, fileName + ".xml");
+		bp.setEnabled(false);
+		AntDebugTarget debugTarget = null;
+		try {
+			debugTarget= launchAndTerminate(fileName, separateVM);
+		} finally {
+			terminateAndRemove(debugTarget);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testEnableDisableBreakpoint() throws Exception {
+        enableDisableBreapoint(false);				
+	}
+
+	public void testEnableDisableBreakpointSepVM() throws Exception {
+        enableDisableBreapoint(true);				
+	}
+
+	private void enableDisableBreapoint(boolean sepVM) throws Exception, CoreException {
+		
+		String fileName = "breakpoints";
+		ILineBreakpoint bp = createLineBreakpoint(5, fileName + ".xml");
+		bp.setEnabled(true);
+		AntThread thread = null;
+		try {
+			if (sepVM) {
+				fileName+= "SepVM";
+			}
+            ILaunchConfiguration config= getLaunchConfiguration(fileName);
+            ILaunchConfigurationWorkingCopy copy= config.getWorkingCopy();
+            copy.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, "entry1,entry2");
+			thread= launchToLineBreakpoint(copy, bp);
+			bp.setEnabled(false);
+            if (sepVM) {
+                waitForTarget();
+            }
+			resumeAndExit(thread);
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+    private synchronized void waitForTarget() {
+        try {
+            //wait for the target to get updated for the new breakpoint state 
+            wait(1000);
+        } catch (InterruptedException ie) {
+        }
+    }
+	
+	public void testSkipLineBreakpoint() throws Exception {
+        skipLineBreakpoint(false);			    
+	}
+	
+	public void testSkipLineBreakpointSepVM() throws Exception {
+        skipLineBreakpoint(true);			    
+	}
+
+	private void skipLineBreakpoint(boolean sepVM) throws Exception {
+		String fileName = "breakpoints";
+		IFile file= getIFile(fileName + ".xml");
+		ILineBreakpoint bp = createLineBreakpoint(5, file);
+		createLineBreakpoint(15, file);
+		AntThread thread = null;
+		try {
+			if (sepVM) {
+				fileName+= "SepVM";
+			}
+		    thread= launchToLineBreakpoint(fileName, bp);
+		    getBreakpointManager().setEnabled(false);
+		    resumeAndExit(thread);
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+			getBreakpointManager().setEnabled(true);
+		}
+	}
+	
+	public void testBreakpoint() throws Exception {
+		breakpoints(false, "default", 5, 15);
+	}
+	
+	public void testBreakpointSepVM() throws Exception {
+		breakpoints(true, "default", 5, 15);
+	}
+
+	public void testTargetBreakpoint() throws Exception {
+		breakpoints(false, "entry2", 4, 24);
+	}
+    
+    public void testTaskOutOfTargetBreakpoint() throws Exception {
+        breakpoints(false, "entry2", 36, 5);
+    }
+    
+    public void testTaskOutOfTargetBreakpointSepVm() throws Exception {
+        breakpoints(true, "entry2", 36, 5);
+    }
+	
+	public void testTargetBreakpointSepVM() throws Exception {
+		breakpoints(true, "entry2", 4, 24);
+	}
+	
+	private void breakpoints(boolean sepVM, String defaultTargetName, int firstLineNumber, int secondLineNumber) throws CoreException {
+		String fileName = "breakpoints";
+		IFile file= getIFile(fileName + ".xml");
+		ILineBreakpoint bp = createLineBreakpoint(firstLineNumber, file);
+		AntThread thread = null;
+		try {
+			if (sepVM) {
+				fileName+= "SepVM";
+			}
+			ILaunchConfiguration config= getLaunchConfiguration(fileName);
+			ILaunchConfigurationWorkingCopy copy= config.getWorkingCopy();
+			copy.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, defaultTargetName);
+            if (!sepVM) {
+                Thread.sleep(3000); //TODO bug 121207: wait for previous launch to fully terminate
+            }
+		    thread= launchToLineBreakpoint(copy, bp);
+			bp= createLineBreakpoint(secondLineNumber, file);
+		    resumeToLineBreakpoint(thread, bp);
+		} catch (InterruptedException e) {
+           
+        } finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/DebugElementEventWaiter.java b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/DebugElementEventWaiter.java
new file mode 100644
index 0000000..768a87d
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/DebugElementEventWaiter.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.debug;
+
+import org.eclipse.ant.tests.ui.testplugin.DebugEventWaiter;
+import org.eclipse.debug.core.DebugEvent;
+
+/**
+ * Waits for an event on a specific element
+ */
+
+public class DebugElementEventWaiter extends DebugEventWaiter {
+	
+	protected Object fElement;
+	
+	public DebugElementEventWaiter(int kind, Object element) {
+		super(kind);
+		fElement = element;
+	}
+	
+	public boolean accept(DebugEvent event) {
+		return super.accept(event) && fElement == event.getSource();
+	}
+
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/DebugElementKindEventDetailWaiter.java b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/DebugElementKindEventDetailWaiter.java
new file mode 100644
index 0000000..93d96ae
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/DebugElementKindEventDetailWaiter.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.debug;
+
+import org.eclipse.ant.tests.ui.testplugin.DebugElementKindEventWaiter;
+import org.eclipse.debug.core.DebugEvent;
+
+/**
+ * Wait for the specified event with the specified from the specified element.
+ */
+public class DebugElementKindEventDetailWaiter extends DebugElementKindEventWaiter {
+
+	protected int fDetail;
+
+	public DebugElementKindEventDetailWaiter(int eventKind, Class elementClass, int detail) {
+		super(eventKind, elementClass);
+		fDetail = detail;
+	}
+	
+	public boolean accept(DebugEvent event) {
+		return super.accept(event) && fDetail == event.getDetail();
+	}
+	
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/StackTests.java b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/StackTests.java
new file mode 100644
index 0000000..61f5a5d
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/StackTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.debug;
+
+import org.eclipse.ant.internal.launching.debug.model.AntThread;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.debug.core.model.IStackFrame;
+
+public class StackTests extends AbstractAntDebugTest {
+
+    public StackTests(String name) {
+        super(name);
+    }
+
+    public void testStackForAntCall() throws Exception {
+        antCallStack(false);
+    }
+    
+    public void testStackForAntCallVM() throws Exception {
+        antCallStack(true);
+    }
+    
+    private void antCallStack(boolean sepVM) throws CoreException {
+        String fileName = "85769";
+        IFile file= getIFile(fileName + ".xml");
+        ILineBreakpoint bp = createLineBreakpoint(18, file);
+        AntThread thread = null;
+        try {
+            if (sepVM) {
+                fileName+= "SepVM";
+            }
+            thread= launchToLineBreakpoint(fileName, bp);
+            
+            
+            IStackFrame[] frames= thread.getStackFrames();
+           
+            assertTrue(frames.length == 3);
+            IStackFrame frame = frames[0];
+            frame.getName().equals("");
+        } finally {
+            terminateAndRemove(thread);
+            removeAllBreakpoints();
+        }
+    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/SteppingTests.java b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/SteppingTests.java
new file mode 100644
index 0000000..e76d1a5
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Debug Tests/org/eclipse/ant/tests/ui/debug/SteppingTests.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.debug;
+
+import org.eclipse.ant.internal.launching.debug.model.AntStackFrame;
+import org.eclipse.ant.internal.launching.debug.model.AntThread;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.debug.core.model.IStackFrame;
+
+public class SteppingTests extends AbstractAntDebugTest {
+
+    public SteppingTests(String name) {
+        super(name);
+    }
+    
+    /**
+     * bug 84400
+     */
+    public void testStepBackFromAntCall() throws Exception {
+		antCallStack(false, 12, DebugEvent.STEP_OVER, "default: echo", 7);
+    }
+    
+    /**
+     * bug 84400
+     */
+    public void testStepBackFromAntCallSepVM() throws Exception {
+		antCallStack(true, 12, DebugEvent.STEP_OVER, "default: echo", 7);
+    }
+	
+	 /**
+     * bug 88218, 85769
+     */
+    public void testStepIntoAntCall() throws Exception {
+        AntThread thread= null;
+        try {
+            thread= antCallStack(false, 5, DebugEvent.STEP_INTO, "pre-call: echo", 16, false);
+            IStackFrame[] frames= thread.getStackFrames();
+            assertFrame("call", 10, (AntStackFrame)frames[1]);
+        } finally {
+            terminateAndRemove(thread);
+            removeAllBreakpoints();
+        }
+    }
+    
+    /**
+     * bug 88218, 85769
+     */
+    public void testStepIntoAntCallSepVM() throws Exception {
+        AntThread thread= null;
+        try {
+            thread= antCallStack(true, 5, DebugEvent.STEP_INTO, "pre-call: echo", 16, false);
+            IStackFrame[] frames= thread.getStackFrames();
+            assertFrame("call", 10, (AntStackFrame)frames[1]);
+        } finally {
+            terminateAndRemove(thread);
+            removeAllBreakpoints();
+        }
+    }
+	
+	 public void testStepOverAntCall() throws Exception {
+		 antCallStack(false, 5, DebugEvent.STEP_OVER, "default: echo", 7);
+	 }
+	 
+	 public void testStepOverAntCallSepVM() throws Exception {
+		 antCallStack(true, 5, DebugEvent.STEP_OVER, "default: echo", 7);
+	 }
+     
+     /**
+      * bug 96022
+      */
+     public void testStepOverAntCallPastOtherAntCalls() throws Exception {
+         debugStack(false, 7, DebugEvent.STEP_OVER, "default: echo", 9, "96022", true);
+     }
+     /**
+      * bug 96022
+      */
+     public void testStepOverAntCallPastOtherAntCallsSepVm() throws Exception {
+        debugStack(true, 7, DebugEvent.STEP_OVER, "default: echo", 9, "96022", true);
+     }
+	 
+	 public void testStepOverAntCallHitBreakpoint() throws Exception {
+		 String fileName = "debugAntCall";
+		 createLineBreakpoint(12, fileName + ".xml");
+		 antCallStack(false, 5, DebugEvent.BREAKPOINT, "call: sleep", 12);
+	 }
+	 
+	 public void testStepOverAntCallHitBreakpointSepVM() throws Exception {
+		 String fileName = "debugAntCall";
+		 createLineBreakpoint(12, fileName + ".xml");
+		 antCallStack(true, 5, DebugEvent.BREAKPOINT, "call: sleep", 12);
+	 }
+    
+	private AntThread antCallStack(boolean sepVM, int lineNumber, int kind, String frameName, int frameLineNumber) throws CoreException {
+        return antCallStack(sepVM, lineNumber, kind, frameName, frameLineNumber, true);
+	}
+    
+	private AntThread antCallStack(boolean sepVM, int lineNumber, int kind, String frameName, int frameLineNumber, boolean terminate) throws CoreException {
+        String fileName = "debugAntCall";
+        return debugStack(sepVM, lineNumber, kind, frameName, frameLineNumber, fileName, terminate);
+    }
+
+	private AntThread debugStack(boolean sepVM, int lineNumber, int kind, String frameName, int frameLineNumber, String fileName, boolean terminate) throws CoreException, DebugException {
+		ILineBreakpoint bp = createLineBreakpoint(lineNumber, fileName + ".xml");
+		AntThread thread= null;
+		try {
+			if (sepVM) {
+				fileName+="SepVM";
+			}
+			ILaunchConfiguration config= getLaunchConfiguration(fileName);
+			thread= launchToLineBreakpoint(config, bp); 
+			debugFrame(kind, frameName, frameLineNumber, thread);
+			return thread;
+        } finally {
+			if (terminate) {
+				terminateAndRemove(thread);
+				removeAllBreakpoints();
+			}
+		}
+	}
+
+	private void debugFrame(int kind, String frameName, int frameLineNumber, AntThread thread) throws DebugException {
+		AntStackFrame frame = (AntStackFrame)thread.getTopStackFrame();
+		assertNotNull(frame);
+		switch (kind) {
+			case DebugEvent.BREAKPOINT: 
+				stepOverToHitBreakpoint(frame);
+				break;
+			case DebugEvent.STEP_OVER:
+				stepOver(frame);
+				break;
+			case DebugEvent.STEP_INTO:
+				stepInto(frame);
+				break;
+		}
+		assertFrame(thread, frameName, frameLineNumber);
+	}
+	
+    private AntStackFrame assertFrame(AntThread thread, String frameName, int lineNumber) throws DebugException {
+        AntStackFrame frame = (AntStackFrame)thread.getTopStackFrame();
+        return assertFrame(frameName, lineNumber, frame);
+    }
+
+    private AntStackFrame assertFrame(String frameName, int lineNumber, AntStackFrame frame) {
+        String actualFrameName= frame.getName();
+        int actualLineNumber= frame.getLineNumber();
+        assertTrue("Name of stack frame incorrect. Expected " + frameName + " was: " + actualFrameName, frameName.equals(actualFrameName));
+        assertTrue("Line number of stack frame incorrect. Expected " + lineNumber + " was: " + actualLineNumber, lineNumber == actualLineNumber);
+        return frame;
+    }
+    
+    /**
+     * bug 85309
+     * @throws CoreException
+     */
+    public void testStepOutOfMacrodef() throws CoreException {
+    	String fileName = "macrodef";
+		debugStack(false, 8 , DebugEvent.STEP_OVER, "type: eclipseMacro", 16, fileName, true);
+    }
+    
+    /**
+     * bug 85309
+     * @throws CoreException
+     */
+    public void testStepOutOfMacrodefSepVM() throws CoreException {
+    	String fileName = "macrodef";
+		debugStack(true, 8 , DebugEvent.STEP_OVER, "type: eclipseMacro", 16, fileName, true);
+    }
+    
+    /**
+     * bug 94769
+     * @throws CoreException
+     */
+    public void testStepIntoMacrodef() throws CoreException {
+    	testMacroDef(false);
+    }
+    
+ /**
+     * bug 94769
+     * @throws CoreException
+     */
+    public void testStepIntoMacrodefSepVM() throws CoreException {
+    	testMacroDef(true);
+    }
+
+    private void testMacroDef(boolean sepVM) throws CoreException, DebugException {
+    	AntThread thread= null;
+    	try {
+    		String fileName = "macrodef";
+    		thread= debugStack(sepVM, 16 , DebugEvent.STEP_INTO, "type: sequential", 0, fileName, false);
+    		debugFrame(DebugEvent.STEP_INTO, "type: echo", 8, thread);
+    		debugFrame(DebugEvent.STEP_OVER, "type: eclipseMacro", 17, thread);
+    	} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+    
+//    public void testStepBackFromAnt() throws Exception {
+//        antCallStack(false);
+//    }
+//    
+//    public void testStepBackFromAntSepVM() throws Exception {
+//        antCallStack(false);
+//    }
+//
+//    
+//    public void testStepIntoAnt() throws Exception {
+//        antCallStack(false);
+//    }
+//    
+//    public void testStepIntoAntSepVM() throws Exception {
+//        antCallStack(false);
+//    }
+//
+//    public void testStepOverAnt() throws Exception {
+//        antCallStack(false);
+//    }
+//    
+//    public void testStepOverAntSepVM() throws Exception {
+//        antCallStack(false);
+//    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/dtd/dumper.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/dtd/dumper.java
new file mode 100644
index 0000000..b6d6d16
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/dtd/dumper.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *     Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.dtd;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.eclipse.ant.internal.ui.dtd.IDfm;
+import org.eclipse.ant.internal.ui.dtd.IElement;
+import org.eclipse.ant.internal.ui.dtd.IModel;
+import org.eclipse.ant.internal.ui.dtd.ISchema;
+import org.eclipse.ant.internal.ui.dtd.ParseError;
+import org.eclipse.ant.internal.ui.dtd.Parser;
+
+/**
+ * This class is intended to be used from the command line (hence the
+ * uncapitalized class name).
+ * @author Bob Foster
+ */
+public class dumper {
+
+	public static int main(String[] args) {
+
+		if (args.length <= 0) {
+			System.out.println("Usage: java DTDMerger URL");
+			return 0;
+		}
+		String document = args[0];
+
+		Parser parser = new Parser();
+		
+		ISchema schema;
+		try {
+			schema = parser.parse(document);
+		} catch (ParseError e) {
+			System.out.println(e.getMessage());
+			e.printStackTrace();
+			return 1;
+		} catch (IOException e) {
+			e.printStackTrace();
+			return 1;
+		}
+		System.out.println("DTD successfully parsed");
+		dumpSchema(schema);
+		return 0;
+	}
+	
+	/**
+	 * Write schema contents to standard output.
+	 */
+	private static void dumpSchema(ISchema schema) {
+		IElement[] elements = schema.getElements();
+		System.out.println(""+elements.length+" elements defined");
+		for (int i = 0; i < elements.length; i++) {
+			IElement element = elements[i];
+			IModel model = element.getContentModel();
+			System.out.println("ELEMENT "+element.getName()
+				+'"'+model.stringRep()+'"');
+			dumpDfm(element.getDfm());
+		}
+	}
+
+	/**
+	 * Dump dfm as a series of states.
+	 * <pre>
+	 * S0  a=>S1 b=>S2 
+	 * S1  c=>S2
+	 * S2* d=>S2
+	 * </pre>
+	 * Where * indicates accepting state.
+	 * @param dfm to dump
+	 */
+	private static void dumpDfm(IDfm dfm) {
+		HashMap map = new HashMap();
+		dumpDfm(dfm, map, 0);
+		LinkedList list = new LinkedList();
+		Iterator it = map.entrySet().iterator();
+		while (it.hasNext()) {
+			Map.Entry entry = (Map.Entry) it.next();
+			list.add(new State((IDfm)entry.getKey(), (Integer)entry.getValue()));
+		}
+		State[] states = (State[]) list.toArray(new State[list.size()]);
+		Arrays.sort(states);
+		for (int i = 0; i < states.length; i++) {
+			print(states[i], map);
+		}
+	}
+
+	private static void print(State state, HashMap map) {
+		System.out.print("  S"+state.n.intValue()
+			+(state.dfm.isAccepting() ? "*  " : "  "));
+		String[] accepts = state.dfm.getAccepts();
+		for (int i = 0; i < accepts.length; i++) {
+			String accept = accepts[i];
+			IDfm next = state.dfm.advance(accept);
+			int n = ((Integer)map.get(next)).intValue();
+			System.out.print(" "+accept+"=>S"+n);
+		}
+		System.out.println();
+	}
+	
+	private static int dumpDfm(IDfm dfm, HashMap map, int num) {
+		if (!map.containsKey(dfm)) {
+			map.put(dfm, new Integer(num++));
+			String[] accepts = dfm.getAccepts();
+			for (int i = 0; i < accepts.length; i++) {
+				IDfm next = dfm.advance(accepts[i]);
+				num = dumpDfm(next, map, num);
+			}
+		}
+		return num;
+	}
+	
+	private static class State implements Comparable {
+		public IDfm dfm;
+		public Integer n;
+		public State(IDfm dfm, Integer n) {
+			this.dfm = dfm;
+			this.n = n;
+		}
+		/**
+		 * @see java.lang.Comparable#compareTo(java.lang.Object)
+		 */
+		public int compareTo(Object o) {
+			State other = (State) o;
+			return n.intValue() < other.n.intValue()
+				? -1 
+				: (n.intValue() == other.n.intValue() 
+					? 0 
+					: 1);
+		}
+
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/TaskDescriptionProviderTest.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/TaskDescriptionProviderTest.java
new file mode 100644
index 0000000..a0c094e
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/TaskDescriptionProviderTest.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 GEBIT Gesellschaft fuer EDV-Beratung
+ * und Informatik-Technologien mbH, 
+ * Berlin, Duesseldorf, Frankfurt (Germany).
+ * 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:
+ *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.editor;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
+import org.eclipse.ant.internal.ui.editor.TaskDescriptionProvider;
+
+/**
+ * Tests the tasks description provider.
+ * 
+ */
+public class TaskDescriptionProviderTest extends AbstractAntUITest {
+
+    public TaskDescriptionProviderTest(String name) {
+        super(name);
+    }
+
+    /** 
+     * Tests getting the description of a task.
+     */
+    public void testGettingTaskDescription() {
+        TaskDescriptionProvider provider = TaskDescriptionProvider.getDefault();
+        String description = provider.getDescriptionForTask("apply");
+        assertNotNull(description);
+        assertTrue(description.length() > 0);
+    }
+
+    /**
+     * Tests getting the description of an attribute.
+     */
+    public void testGettingAttribute() {
+        TaskDescriptionProvider provider = TaskDescriptionProvider.getDefault();
+        String description = provider.getDescriptionForTaskAttribute("apply", "executable");
+        assertNotNull(description);
+        assertTrue(description.length() > 0);
+    }
+    
+    /**
+     * Tests getting the required value of an attribute.
+     */
+    public void testGettingRequired() {
+        TaskDescriptionProvider provider = TaskDescriptionProvider.getDefault();
+        String required = provider.getRequiredAttributeForTaskAttribute("apply", "executable");
+        assertNotNull(required);
+        assertEquals("yes", required);
+    }
+
+    public static Test suite() {
+		return new TestSuite(TaskDescriptionProviderTest.class);
+    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/FormattingPreferencesTest.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/FormattingPreferencesTest.java
new file mode 100644
index 0000000..946a69b
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/FormattingPreferencesTest.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 John-Mason P. Shackelford 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:
+ *     John-Mason P. Shackelford - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.editor.formatter;
+
+import org.eclipse.ant.internal.ui.editor.formatter.FormattingPreferences;
+import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
+
+public class FormattingPreferencesTest extends AbstractAntUITest {
+
+    public FormattingPreferencesTest(String name) {
+        super(name);
+    }
+
+    public final void testGetCanonicalIndent() {
+     
+        FormattingPreferences prefs;
+        
+        // test spaces 
+        prefs = new FormattingPreferences(){
+            public int getTabWidth() {                
+                return 3;
+            }
+            public boolean useSpacesInsteadOfTabs() {
+                return true;
+            }
+        };        
+        assertEquals("   ",prefs.getCanonicalIndent());
+        
+        // ensure the value is not hard coded
+        prefs = new FormattingPreferences(){
+            public int getTabWidth() {                
+                return 7;
+            }
+            public boolean useSpacesInsteadOfTabs() {
+                return true;
+            }
+        };        
+        assertEquals("       ",prefs.getCanonicalIndent());
+        
+        // use tab character
+        prefs = new FormattingPreferences(){
+            public int getTabWidth() {                
+                return 7;
+            }
+            public boolean useSpacesInsteadOfTabs() {
+                return false;
+            }
+        };        
+        assertEquals("\t",prefs.getCanonicalIndent());
+    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/XmlDocumentFormatterTest.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/XmlDocumentFormatterTest.java
new file mode 100644
index 0000000..0a007aa
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/XmlDocumentFormatterTest.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 John-Mason P. Shackelford 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:
+ *     John-Mason P. Shackelford - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.editor.formatter;
+
+import org.eclipse.ant.internal.ui.editor.formatter.FormattingPreferences;
+import org.eclipse.ant.internal.ui.editor.formatter.XmlDocumentFormatter;
+import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
+
+public class XmlDocumentFormatterTest extends AbstractAntUITest {
+
+    public XmlDocumentFormatterTest(String name) {
+        super(name);
+    }
+
+    /**
+     * General Test 
+     */
+    public final void testGeneralFormat() throws Exception {
+        FormattingPreferences prefs = new FormattingPreferences(){
+            public int getTabWidth() {                
+                return 3;
+            }
+            public boolean useSpacesInsteadOfTabs() {
+                return true;
+            }
+        };
+        simpleTest("formatTest_source01.xml","formatTest_target01.xml",prefs);        
+    }
+
+    /**
+     * Insure that tab width is not hard coded
+     */
+    public final void testTabWidth() throws Exception {
+        FormattingPreferences prefs = new FormattingPreferences(){
+            public int getTabWidth() {                
+                return 7;
+            }
+            public boolean useSpacesInsteadOfTabs() {
+                return true;
+            }
+        };
+        simpleTest("formatTest_source01.xml","formatTest_target02.xml",prefs);        
+    }
+
+    
+    /**
+     * Test with tab characters instead of spaces.
+     */
+    public final void testTabsInsteadOfSpaces() throws Exception {
+        FormattingPreferences prefs = new FormattingPreferences(){
+            public int getTabWidth() {                
+                return 3;
+            }
+            public boolean useSpacesInsteadOfTabs() {
+                return false;
+            }
+        };
+        simpleTest("formatTest_source01.xml","formatTest_target03.xml",prefs);        
+    }
+    
+    /**
+     * @param sourceFileName - file to format
+     * @param targetFileName - the source file after a properly executed format
+     * @param prefs - given the included preference instructions
+     * @throws Exception
+     */
+    private void simpleTest(String sourceFileName, String targetFileName, FormattingPreferences prefs) throws Exception {
+        
+        XmlDocumentFormatter xmlFormatter = new XmlDocumentFormatter();
+        xmlFormatter.setDefaultLineDelimiter(System.getProperty("line.separator"));
+        String result = xmlFormatter.format(getFileContentAsString(getBuildFile(sourceFileName)),prefs);
+        String expectedResult = getFileContentAsString(getBuildFile(targetFileName));
+        
+        assertEquals(expectedResult, result);
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/XmlFormatterTest.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/XmlFormatterTest.java
new file mode 100644
index 0000000..acd8fcb
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/XmlFormatterTest.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 John-Mason P. Shackelford 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:
+ *     John-Mason P. Shackelford - initial API and implementation
+ *     IBM Corporation - bug 84342
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.editor.formatter;
+
+import junit.framework.TestCase;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.editor.formatter.FormattingPreferences;
+import org.eclipse.ant.internal.ui.editor.formatter.XmlFormatter;
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.core.runtime.Preferences;
+
+public class XmlFormatterTest extends TestCase {
+
+    public final void testFormatUsingPreferenceStore() {
+        Preferences prefs = AntUIPlugin.getDefault().getPluginPreferences();
+        prefs.setValue(AntEditorPreferenceConstants.FORMATTER_WRAP_LONG, true);
+        prefs.setValue(AntEditorPreferenceConstants.FORMATTER_MAX_LINE_LENGTH, 40);
+        prefs.setValue(AntEditorPreferenceConstants.FORMATTER_ALIGN, false);
+        prefs.setValue(AntEditorPreferenceConstants.FORMATTER_TAB_CHAR, true);
+        prefs.setValue(AntEditorPreferenceConstants.FORMATTER_TAB_SIZE, 4);
+        String lineSep= System.getProperty("line.separator");
+        String xmlDoc = "<project default=\"go\"><target name=\"go\" description=\"Demonstrate the wrapping of long tags.\"><echo>hi</echo></target></project>";
+        String formattedDoc = XmlFormatter.format(xmlDoc);
+        String expected = "<project default=\"go\">" + lineSep + "\t<target name=\"go\"" + lineSep + "\t        description=\"Demonstrate the wrapping of long tags.\">" + lineSep + "\t\t<echo>hi</echo>" + lineSep + "\t</target>" + lineSep + "</project>";
+        assertEquals(expected, formattedDoc);
+    }
+
+    public final void testFormatWithPreferenceParameter() {
+        FormattingPreferences prefs = new FormattingPreferences() {
+            public boolean wrapLongTags() { return true;}
+            public int getMaximumLineWidth() { return 40;}
+            public boolean alignElementCloseChar() { return false;}
+            public boolean useSpacesInsteadOfTabs() { return true;}
+            public int getTabWidth() { return 6;}
+        };
+        String lineSep= System.getProperty("line.separator");
+        String xmlDoc = "<project default=\"go\"><target name=\"go\" description=\"Demonstrate the wrapping of long tags.\"><echo>hi</echo></target></project>";
+        String formattedDoc = XmlFormatter.format(xmlDoc, prefs);
+        String expected = "<project default=\"go\">" + lineSep + "      <target name=\"go\"" + lineSep + "              description=\"Demonstrate the wrapping of long tags.\">" + lineSep + "            <echo>hi</echo>" + lineSep + "      </target>" + lineSep + "</project>";
+        assertEquals(expected, formattedDoc);
+    }
+    
+    /**
+     * Bug 84342
+     */
+    public final void testFormatMaintainingLineSeparators() {
+        FormattingPreferences prefs = new FormattingPreferences() {
+            public boolean wrapLongTags() { return true;}
+            public int getMaximumLineWidth() { return 40;}
+            public boolean alignElementCloseChar() { return false;}
+            public boolean useSpacesInsteadOfTabs() { return true;}
+            public int getTabWidth() { return 6;}
+        };
+        String lineSep= System.getProperty("line.separator");
+        String xmlDoc = "<project default=\"go\"><target name=\"go\" description=\"Demonstrate the wrapping of long tags.\"><echo>hi</echo></target>" + lineSep + lineSep + "</project>";
+        String formattedDoc = XmlFormatter.format(xmlDoc, prefs);
+        String expected = "<project default=\"go\">" + lineSep + "      <target name=\"go\"" + lineSep + "              description=\"Demonstrate the wrapping of long tags.\">" + lineSep + "            <echo>hi</echo>" + lineSep + "      </target>" + lineSep + lineSep + "</project>";
+        assertEquals(expected, formattedDoc);
+    }
+
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/XmlTagFormatterTest.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/XmlTagFormatterTest.java
new file mode 100644
index 0000000..abd3e29
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/formatter/XmlTagFormatterTest.java
@@ -0,0 +1,378 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 John-Mason P. Shackelford 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:
+ *     John-Mason P. Shackelford - initial API and implementation
+ *     IBM Corporation - Bug 84342
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.editor.formatter;
+
+import java.util.List;
+
+import org.eclipse.ant.internal.ui.editor.formatter.XmlTagFormatter;
+import org.eclipse.ant.internal.ui.editor.formatter.FormattingPreferences;
+import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
+
+public class XmlTagFormatterTest extends AbstractAntUITest {
+
+    // TODO This test is too low level and too tightly coupled to internals.
+
+    /* ---------------- Test Fixture ---------------- */
+    // In case anyone wonders why many people recommend against testing
+    // privates, I produce this example...
+    private static class InnerClassFactory extends XmlTagFormatter {
+
+        public static class ParseException extends XmlTagFormatter.ParseException {
+
+			private static final long serialVersionUID = 1L;
+
+			public ParseException(String message) {
+                super(message);
+            }
+        }
+
+        public static class Tag extends XmlTagFormatter.Tag {
+        }
+
+        public static class TagFormatter extends XmlTagFormatter.TagFormatter {
+
+            public boolean lineRequiresWrap(String line, int lineWidth,
+                    int tabWidth) {
+                return super.lineRequiresWrap(line, lineWidth, tabWidth);
+            }
+
+            public int tabExpandedLineWidth(String line, int tabWidth) {
+                return super.tabExpandedLineWidth(line, tabWidth);
+            }
+
+            public String wrapTag(Tag tag, FormattingPreferences prefs,
+                    String indent, String lineDelimiter) {
+                return super.wrapTag(tag, prefs, indent, lineDelimiter);
+            }
+        }
+
+        public static class TagParser extends XmlTagFormatter.TagParser {
+
+            public String getElementName(String tagText)
+                    throws XmlTagFormatter.ParseException {
+                return super.getElementName(tagText);
+            }
+
+            public List getAttibutes(String elementText)
+                    throws XmlTagFormatter.ParseException {
+                return super.getAttibutes(elementText);
+            }
+        }
+
+        public static Tag createTag() {
+            return new Tag();
+        }
+
+        public static TagFormatter createTagFormatter() {
+            return new TagFormatter();
+        }
+
+        public static TagParser createTagParser() {
+            return new TagParser();
+        }
+
+        public static void validateAttributePair(Object attributePair, String attribute, String value) {
+            XmlTagFormatter.AttributePair pair = (XmlTagFormatter.AttributePair) attributePair;
+            assertEquals(attribute, pair.getAttribute());
+            assertEquals(value, pair.getValue());
+        }
+    }
+
+    public XmlTagFormatterTest(String name) {
+        super(name);
+    }
+
+    private FormattingPreferences getPreferences(final boolean wrapLongTags,
+            final boolean alignCloseChar, final int maxLineWidth) {
+
+        return new FormattingPreferences() {
+
+            public boolean alignElementCloseChar() {
+                return alignCloseChar;
+            }
+
+            public boolean wrapLongTags() {
+                return wrapLongTags;
+            }
+
+            public int getMaximumLineWidth() {
+                return maxLineWidth;
+            }
+        };
+    }
+
+    private void simpleTest(String source, String target,
+            FormattingPreferences prefs, String indent, String lineDelimiter) throws Exception {
+    	
+        String result = XmlTagFormatter.format(source, prefs, indent, lineDelimiter);
+        assertEquals(target, result);
+    }
+
+    /* ---------------- Test Methods ---------------- */
+
+    public void testParserGetElementName() throws Exception {
+
+        InnerClassFactory.TagParser tagParser = InnerClassFactory
+                .createTagParser();
+
+        String elementFixture1 = "<myElement attribute1=\"value1\" attribute2=\"value2\" />"; //$NON-NLS-1$
+        assertEquals("myElement", tagParser.getElementName(elementFixture1)); //$NON-NLS-1$
+
+        String elementFixture2 = "<myElement\t\nattribute1=\"value1\" attribute2=\"value2\" />"; //$NON-NLS-1$
+        assertEquals("myElement", tagParser.getElementName(elementFixture2)); //$NON-NLS-1$
+
+        assertEquals("x", tagParser.getElementName("<x/>")); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("x", tagParser.getElementName("<x>")); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("x:y", tagParser.getElementName("<x:y/>")); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("x:y", tagParser.getElementName("<x:y abc/>")); //$NON-NLS-1$ //$NON-NLS-2$
+
+        Exception e1 = null;
+        try {
+            tagParser.getElementName("<>"); //$NON-NLS-1$
+        } catch (Exception e) {
+            e1 = e;
+        }
+        assertNotNull(e1);
+        assertTrue(e1.getClass().isAssignableFrom(
+                InnerClassFactory.ParseException.class));
+
+        Exception e2 = null;
+        try {
+            tagParser.getElementName("<>"); //$NON-NLS-1$
+        } catch (Exception e) {
+            e2 = e;
+        }
+        assertNotNull(e2);
+        assertTrue(e2.getClass().isAssignableFrom(
+                InnerClassFactory.ParseException.class));
+
+    }
+
+    public void testParserGetAttributes() throws Exception {
+        InnerClassFactory.TagParser tagParser = InnerClassFactory
+                .createTagParser();
+
+        List attributePairs;
+
+        // test normal situation
+        attributePairs = tagParser
+                .getAttibutes("<myElement attribute1=\"value1\" attribute2=\"value2\" />"); //$NON-NLS-1$
+
+        assertEquals(2, attributePairs.size());
+        InnerClassFactory.validateAttributePair(attributePairs.get(0),
+                "attribute1", "value1"); //$NON-NLS-1$ //$NON-NLS-2$
+        InnerClassFactory.validateAttributePair(attributePairs.get(1),
+                "attribute2", "value2"); //$NON-NLS-1$ //$NON-NLS-2$
+
+        
+        // test with extra whitespace and funny quotes
+        attributePairs = tagParser
+                .getAttibutes("<myElement \nattribute1 =  'value1\"'\nattribute2\t=\"value2'\" />"); //$NON-NLS-1$
+
+        assertEquals(2, attributePairs.size());
+        InnerClassFactory.validateAttributePair(attributePairs.get(0),
+                "attribute1", "value1\""); //$NON-NLS-1$ //$NON-NLS-2$
+        InnerClassFactory.validateAttributePair(attributePairs.get(1),
+                "attribute2", "value2'"); //$NON-NLS-1$ //$NON-NLS-2$
+
+// TODO attributes which contain whitespace should throw a parse error
+//       
+//        // test parse errors - whitespace in attribute name
+//        Exception e1 = null;
+//        try {
+//            attributePairs = tagParser
+//                    .getAttibutes("<myElement at tribute1 = \"value1\" attribute2=\"value2\" />");
+//        } catch (Exception e) {
+//            e1 = e;
+//        }
+//        assertNotNull(e1);
+//        assertTrue(e1.getClass().isAssignableFrom(
+//                InnerClassFactory.ParseException.class));
+        
+        
+        // test parse errors - equals in the wrong place
+        Exception e2 = null;
+        try {
+            attributePairs = tagParser
+                    .getAttibutes("<myElement attribute1=\"value1\" = attribute2=\"value2\" />"); //$NON-NLS-1$
+        } catch (Exception e) {
+            e2 = e;
+        }
+        assertNotNull(e2);
+        assertTrue(e2.getClass().isAssignableFrom(
+                InnerClassFactory.ParseException.class));
+        
+        
+        // test parse errors - quotes in the wrong place
+        Exception e3 = null;
+        try {
+            attributePairs = tagParser
+                    .getAttibutes("<myElement attribute1=\"\"value1\"  attribute2=\"value2\" />"); //$NON-NLS-1$
+        } catch (Exception e) {
+            e3 = e;
+        }
+        assertNotNull(e3);
+        assertTrue(e3.getClass().isAssignableFrom(InnerClassFactory.ParseException.class));
+    }
+
+    public void testFormat01() throws Exception {
+    	String lineSep= System.getProperty("line.separator");
+        String indent = "\t"; //$NON-NLS-1$
+        String source = "<target name=\"myTargetName\" depends=\"a,b,c,d,e,f,g\" description=\"This is a very long element which ought to be wrapped.\">"; //$NON-NLS-1$
+        String target = "<target name=\"myTargetName\"" + lineSep //$NON-NLS-1$
+                + indent
+                + "        depends=\"a,b,c,d,e,f,g\"" + lineSep //$NON-NLS-1$
+                + indent
+                + "        description=\"This is a very long element which ought to be wrapped.\">"; //$NON-NLS-1$
+
+        simpleTest(source, target, getPreferences(true, false, 60), indent, lineSep);
+    }
+
+    public void testFormat02() throws Exception {
+    	String lineSep= System.getProperty("line.separator");
+        String indent = "\t"; //$NON-NLS-1$
+        String source = "<target name=\"myTargetName\" depends=\"a,b,c,d,e,f,g\" description=\"This is a very long element which ought to be wrapped.\">"; //$NON-NLS-1$
+        String target = "<target name=\"myTargetName\"" + lineSep //$NON-NLS-1$
+                + indent
+                + "        depends=\"a,b,c,d,e,f,g\"" + lineSep //$NON-NLS-1$
+                + indent
+                + "        description=\"This is a very long element which ought to be wrapped.\"" + lineSep //$NON-NLS-1$
+                + indent + ">"; //$NON-NLS-1$
+
+        simpleTest(source, target, getPreferences(true, true, 60), indent, lineSep);
+    }
+    
+    public void testBug73411() throws Exception {
+    	String lineSep= System.getProperty("line.separator");
+        String indent = "\t"; //$NON-NLS-1$
+        String source = "<target name='myTargetName' depends=\"a,b,c,d,e,f,g\" description=\'This is a very long element which ought to be \"wrapped\".'>"; //$NON-NLS-1$
+        String target = "<target name='myTargetName'" + lineSep //$NON-NLS-1$
+                + indent
+                + "        depends=\"a,b,c,d,e,f,g\"" + lineSep //$NON-NLS-1$
+                + indent
+                + "        description='This is a very long element which ought to be \"wrapped\".'" + lineSep //$NON-NLS-1$
+                + indent + ">"; //$NON-NLS-1$
+
+        simpleTest(source, target, getPreferences(true, true, 60), indent, lineSep);
+    }
+
+    public void testLineRequiresWrap() throws Exception {
+
+        InnerClassFactory.TagFormatter tagFormatter = InnerClassFactory.createTagFormatter();
+
+        boolean shouldWrap = tagFormatter.lineRequiresWrap(
+                        "\t\t  <myElement attribute1=\"value1\" attribute2=\"value2\" />", //$NON-NLS-1$
+                        70, 8);
+        boolean shouldNotWrap = tagFormatter.lineRequiresWrap(
+                        "\t\t <myElement attribute1=\"value1\" attribute2=\"value2\" />", //$NON-NLS-1$
+                        70, 8);
+        assertTrue(shouldWrap);
+        assertTrue(!shouldNotWrap);
+
+    }
+
+    public void testTabExpandedLineWidth() throws Exception {
+
+        InnerClassFactory.TagFormatter tagFormatter = InnerClassFactory.createTagFormatter();
+
+        assertEquals(20, tagFormatter.tabExpandedLineWidth("\t  1234567890", 8)); //$NON-NLS-1$
+        assertEquals(10, tagFormatter.tabExpandedLineWidth("1234567890", 8)); //$NON-NLS-1$
+        assertEquals(19, tagFormatter.tabExpandedLineWidth("\t1\t2	34567890", 3)); //$NON-NLS-1$
+    }
+
+    public void testTabToStringAndMinimumLength() throws Exception {
+        InnerClassFactory.Tag tag = InnerClassFactory.createTag();
+
+        tag.setElementName("myElement"); //$NON-NLS-1$
+        tag.setClosed(false);
+        assertEquals("<myElement>", tag.toString()); //$NON-NLS-1$
+        assertEquals(tag.toString().length(), tag.minimumLength());
+
+        tag.setClosed(true);
+        assertEquals("<myElement />", tag.toString()); //$NON-NLS-1$
+        assertEquals(tag.toString().length(), tag.minimumLength());
+
+        tag.addAttribute("attribute1", "value1", '"'); //$NON-NLS-1$ //$NON-NLS-2$
+        tag.addAttribute("attribute2", "value2", '"'); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals(
+                "<myElement attribute1=\"value1\" attribute2=\"value2\" />", //$NON-NLS-1$
+                tag.toString());
+        assertEquals(tag.toString().length(), tag.minimumLength());
+
+        tag.setClosed(false);
+        assertEquals("<myElement attribute1=\"value1\" attribute2=\"value2\">", //$NON-NLS-1$
+                tag.toString());
+        assertEquals(tag.toString().length(), tag.minimumLength());
+    }
+
+    public void testWrapTag() throws Exception {
+
+        InnerClassFactory.Tag tag = InnerClassFactory.createTag();
+
+        InnerClassFactory.TagFormatter tagFormatter = InnerClassFactory
+                .createTagFormatter();
+
+        FormattingPreferences dontAlignCloseChar = new FormattingPreferences() {
+
+            public boolean alignElementCloseChar() {
+                return false;
+            }
+        };
+        FormattingPreferences doAlignCloseChar = new FormattingPreferences() {
+
+            public boolean alignElementCloseChar() {
+                return true;
+            }
+        };
+
+        tag.setElementName("myElement"); //$NON-NLS-1$
+        tag.addAttribute("attribute1", "value1", '"'); //$NON-NLS-1$ //$NON-NLS-2$
+        tag.addAttribute("attribute2", "value2", '"'); //$NON-NLS-1$ //$NON-NLS-2$
+
+        tag.setClosed(true);
+
+        String lineSep= System.getProperty("line.separator");
+        assertEquals("<myElement attribute1=\"value1\"" + lineSep //$NON-NLS-1$
+                + "\t\t             attribute2=\"value2\" />", tagFormatter //$NON-NLS-1$
+                .wrapTag(tag, dontAlignCloseChar, "\t\t  ", lineSep)); //$NON-NLS-1$
+
+        assertEquals("<myElement attribute1=\"value1\"" + lineSep //$NON-NLS-1$
+                + "\t\t             attribute2=\"value2\"" + lineSep + "\t\t  />", //$NON-NLS-1$
+                tagFormatter.wrapTag(tag, doAlignCloseChar, "\t\t  ", lineSep)); //$NON-NLS-1$
+
+        tag.setClosed(false);
+
+        assertEquals("<myElement attribute1=\"value1\"" + lineSep //$NON-NLS-1$
+                + "\t\t             attribute2=\"value2\">", tagFormatter //$NON-NLS-1$
+                .wrapTag(tag, dontAlignCloseChar, "\t\t  ", lineSep)); //$NON-NLS-1$
+
+        assertEquals("<myElement attribute1=\"value1\"" + lineSep //$NON-NLS-1$
+                + "\t\t             attribute2=\"value2\"" + lineSep + "\t\t  >", //$NON-NLS-1$
+                tagFormatter.wrapTag(tag, doAlignCloseChar, "\t\t  ", lineSep)); //$NON-NLS-1$
+
+    }
+
+    public void testBug63558() throws Exception {
+		
+		// Ordinarily the double space after the element name would be repaired
+		// but if the formatter is working correctly these examples will be
+		// considered malformed and will be passed through untouched.
+    	 String lineSep= System.getProperty("line.separator");
+		String source1 = "<echo  file=\"foo\">" + lineSep + "&lt;html>&lt;body>&lt;pre>" //$NON-NLS-1$
+				+ "${compilelog}&lt;/pre>&lt;/body>&lt;/html>"; //$NON-NLS-1$
+		FormattingPreferences prefs = getPreferences(true, false, 60); //$NON-NLS-1$
+		simpleTest(source1, source1, prefs, "\t", lineSep);
+	
+		String source2 = "<echo  file=\"foo\"/bar/baz></echo>"; //$NON-NLS-1$		
+		simpleTest(source2, source2, prefs, "\t", lineSep);
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/performance/EditorTestHelper.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/performance/EditorTestHelper.java
new file mode 100644
index 0000000..5196cd7
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/performance/EditorTestHelper.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.editor.performance;
+
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.jobs.IJobManager;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+
+/**
+ * @since 3.1
+ */
+public class EditorTestHelper {
+
+	public static IEditorPart openInEditor(IFile file, boolean runEventLoop) throws PartInitException {
+		IEditorPart part= IDE.openEditor(getActivePage(), file);
+		if (runEventLoop)
+			runEventQueue(part);
+		return part;
+	}
+
+	public static IEditorPart openInEditor(IFile file, String editorId, boolean runEventLoop) throws PartInitException {
+		IEditorPart part= IDE.openEditor(getActivePage(), file, editorId);
+		if (runEventLoop)
+			runEventQueue(part);
+		return part;
+	}
+
+	public static IDocument getDocument(ITextEditor editor) {
+		IDocumentProvider provider= editor.getDocumentProvider();
+		IEditorInput input= editor.getEditorInput();
+		return provider.getDocument(input);
+	}
+
+	public static void revertEditor(ITextEditor editor, boolean runEventQueue) {
+		editor.doRevertToSaved();
+		if (runEventQueue)
+			runEventQueue(editor);
+	}
+	
+	public static void closeAllEditors() {
+		IWorkbenchPage page= getActivePage();
+		if (page != null)
+			page.closeAllEditors(false);
+	}
+	
+	public static void runEventQueue() {
+		IWorkbenchWindow window= getActiveWorkbenchWindow();
+		if (window != null)
+			runEventQueue(window.getShell());
+	}
+	
+	public static void runEventQueue(IWorkbenchPart part) {
+		runEventQueue(part.getSite().getShell());
+	}
+	
+	public static void runEventQueue(Shell shell) {
+		while (shell.getDisplay().readAndDispatch());
+	}
+	
+	public static void runEventQueue(long minTime) {
+		long nextCheck= System.currentTimeMillis() + minTime;
+		while (System.currentTimeMillis() < nextCheck) {
+			runEventQueue();
+			sleep(1);
+		}
+	}
+	
+	public static IWorkbenchWindow getActiveWorkbenchWindow() {
+		return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+	}
+
+	public static IWorkbenchPage getActivePage() {
+		IWorkbenchWindow window= getActiveWorkbenchWindow();
+		return window != null ? window.getActivePage() : null;
+	}
+
+	public static Display getActiveDisplay() {
+		IWorkbenchWindow window= getActiveWorkbenchWindow();
+		return window != null ? window.getShell().getDisplay() : null;
+	}
+
+	public static boolean calmDown(long minTime, long maxTime, long intervalTime) {
+		long startTime= System.currentTimeMillis() + minTime;
+		runEventQueue();
+		while (System.currentTimeMillis() < startTime)
+			runEventQueue(intervalTime);
+		
+		long endTime= maxTime > 0 ? System.currentTimeMillis() + maxTime : Long.MAX_VALUE;
+		boolean calm= isCalm();
+		while (!calm && System.currentTimeMillis() < endTime) {
+			runEventQueue(intervalTime);
+			calm= isCalm();
+		}
+//		System.out.println("--------------------------------------------------");
+		return calm;
+	}
+
+	public static void sleep(int intervalTime) {
+		try {
+			Thread.sleep(intervalTime);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public static boolean isCalm() {
+		IJobManager jobManager= Job.getJobManager();
+		Job[] jobs= jobManager.find(null);
+		for (int i= 0; i < jobs.length; i++) {
+			Job job= jobs[i];
+			int state= job.getState();
+//			System.out.println(job.getName() + ": " + getStateName(state));
+			if (state == Job.RUNNING || state == Job.WAITING) {
+//				System.out.println();
+				return false;
+			}
+		}
+//		System.out.println();
+		return true;
+	}
+
+	public static void bringToTop() {
+		getActiveWorkbenchWindow().getShell().forceActive();
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/performance/NonInitialTypingTest.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/performance/NonInitialTypingTest.java
new file mode 100644
index 0000000..ec9b947
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/performance/NonInitialTypingTest.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.editor.performance;
+
+import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
+
+/**
+ * Measures the time to type in one single target into a large buildfile
+ * @since 3.1
+ */
+public class NonInitialTypingTest extends AbstractAntUITest {
+	
+	public NonInitialTypingTest(String name) {
+		super(name);
+	}
+
+//	private ITextEditor fEditor;
+//	
+//	private static final char[] TARGET= ("<target name=\"newTarget\" >\r" +
+//			"<echo>\"New Target\"</echo>\r" +
+//			"</target>\r").toCharArray();
+//
+//	private PerformanceMeter fMeter;
+//
+//	private KeyboardProbe fKeyboardProbe;
+//
+//	protected void setUp() throws PartInitException, BadLocationException {
+//		EditorTestHelper.runEventQueue();
+//		IFile file= getProject().getFolder("buildfiles").getFolder("performance").getFile("build.xml");	
+//		fEditor= (ITextEditor) EditorTestHelper.openInEditor(file, true);
+//		// dirty editor to avoid initial dirtying / validate edit costs
+//		dirtyEditor();
+//		Performance performance= Performance.getDefault();
+//		fMeter= performance.createPerformanceMeter(performance.getDefaultScenarioId(this));
+//		fKeyboardProbe= new KeyboardProbe();
+//
+//		int offset= getInsertPosition();
+//		fEditor.getSelectionProvider().setSelection(new TextSelection(offset, 0));
+//		EditorTestHelper.runEventQueue();
+//		sleep(1000);
+//	}
+//	
+//	private void dirtyEditor() {
+//		fEditor.getSelectionProvider().setSelection(new TextSelection(0, 0));
+//		EditorTestHelper.runEventQueue();
+//		sleep(1000);
+//		
+//		Display display= EditorTestHelper.getActiveDisplay();
+//		fKeyboardProbe.pressChar('{', display);
+//		SWTEventHelper.pressKeyCode(display, SWT.BS);
+//		sleep(1000);
+//	}
+//
+//	protected void tearDown() throws Exception {
+//		sleep(1000);
+//		EditorTestHelper.revertEditor(fEditor, true);
+//		EditorTestHelper.closeAllEditors();
+//		
+//		fMeter.commit();
+//	}
+//
+//	public void testTypeAMethod() {
+//		Display display= EditorTestHelper.getActiveDisplay();
+//		
+//		fMeter.start();
+//		for (int i= 0; i < TARGET.length; i++) {
+//			fKeyboardProbe.pressChar(TARGET[i], display);
+//		}
+//		fMeter.stop();
+//	}
+//
+//	private synchronized void sleep(int time) {
+//		try {
+//			wait(time);
+//		} catch (InterruptedException e) {
+//		}
+//	}
+//	
+//	private int getInsertPosition() throws BadLocationException {
+//		IDocument document= EditorTestHelper.getDocument(fEditor);
+//		int lines= document.getNumberOfLines();
+//		int offset= document.getLineOffset(lines - 2);
+//		return offset;
+//	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/support/TestLocationProvider.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/support/TestLocationProvider.java
new file mode 100644
index 0000000..7f7c608
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/support/TestLocationProvider.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.editor.support;
+
+import java.io.File;
+
+import org.eclipse.ant.internal.ui.model.LocationProvider;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+
+public class TestLocationProvider extends LocationProvider {
+
+	private File buildFile;
+	
+	public TestLocationProvider(File buildFile) {
+		super(null);
+		this.buildFile= buildFile;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.ILocationProvider#getLocation()
+	 */
+	public IPath getLocation() {
+		return new Path(buildFile.getAbsolutePath());
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/support/TestProblemRequestor.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/support/TestProblemRequestor.java
new file mode 100644
index 0000000..db678da
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/support/TestProblemRequestor.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.editor.support;
+
+import org.eclipse.ant.internal.ui.model.IProblem;
+import org.eclipse.ant.internal.ui.model.IProblemRequestor;
+
+public class TestProblemRequestor implements IProblemRequestor {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblemRequestor#acceptProblem(org.eclipse.ant.internal.ui.editor.outline.IProblem)
+	 */
+	public void acceptProblem(IProblem problem) {
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblemRequestor#beginReporting()
+	 */
+	public void beginReporting() {
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblemRequestor#endReporting()
+	 */
+	public void endReporting() {
+
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/support/TestTextCompletionProcessor.java b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/support/TestTextCompletionProcessor.java
new file mode 100644
index 0000000..5b611ad
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Editor Tests/org/eclipse/ant/tests/ui/editor/support/TestTextCompletionProcessor.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.editor.support;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Assert;
+
+import org.eclipse.ant.internal.ui.editor.AntEditor;
+import org.eclipse.ant.internal.ui.editor.AntEditorCompletionProcessor;
+import org.eclipse.ant.internal.ui.model.AntModel;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.ICompletionListener;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistantExtension2;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.w3c.dom.Element;
+
+public class TestTextCompletionProcessor extends AntEditorCompletionProcessor {
+
+	public final static int TEST_PROPOSAL_MODE_NONE = AntEditorCompletionProcessor.PROPOSAL_MODE_NONE;
+	public final static int TEST_PROPOSAL_MODE_BUILDFILE = AntEditorCompletionProcessor.PROPOSAL_MODE_BUILDFILE;
+	public final static int TEST_PROPOSAL_MODE_TASK_PROPOSAL = AntEditorCompletionProcessor.PROPOSAL_MODE_TASK_PROPOSAL;
+	public final static int TEST_PROPOSAL_MODE_PROPERTY_PROPOSAL = AntEditorCompletionProcessor.PROPOSAL_MODE_PROPERTY_PROPOSAL;
+	public final static int TEST_PROPOSAL_MODE_ATTRIBUTE_PROPOSAL = AntEditorCompletionProcessor.PROPOSAL_MODE_ATTRIBUTE_PROPOSAL;
+	public final static int TEST_PROPOSAL_MODE_TASK_PROPOSAL_CLOSING = AntEditorCompletionProcessor.PROPOSAL_MODE_TASK_PROPOSAL_CLOSING;
+	public final static int TEST_PROPOSAL_MODE_ATTRIBUTE_VALUE_PROPOSAL = AntEditorCompletionProcessor.PROPOSAL_MODE_ATTRIBUTE_VALUE_PROPOSAL;
+	
+	private File fEditedFile;
+	private ISourceViewer fViewer;
+    private boolean fNeedsToDispose= true;
+    
+    
+
+	public TestTextCompletionProcessor(AntModel model) {
+		super(model);
+        fContentAssistant= new IContentAssistantExtension2() {
+            public void setEmptyMessage(String message) {
+            }
+        
+            public void setStatusMessage(String message) {
+            }
+        
+            public void setStatusLineVisible(boolean show) {
+            }
+        
+            public void setShowEmptyList(boolean showEmpty) {
+            }
+        
+            public void setRepeatedInvocationMode(boolean cycling) {
+            }
+        
+            public void removeCompletionListener(ICompletionListener listener) {
+            }
+        
+            public void addCompletionListener(ICompletionListener listener) {
+        
+            }        
+        };
+	}
+	
+	public TestTextCompletionProcessor(AntEditor editor) {
+		this(editor.getAntModel());
+		fViewer= editor.getViewer();
+        fNeedsToDispose= false;
+	}
+	
+	public TestTextCompletionProcessor() {
+		this((AntModel)null);
+	}
+	
+    public ICompletionProposal[] getAttributeProposals(String taskName, String prefix) {
+    	if (cursorPosition == -1) {
+    		cursorPosition= taskName.length();
+    	}
+        return super.getAttributeProposals(taskName, prefix);
+    }
+
+    public Element findChildElementNamedOf(Element anElement, String childElementName) {
+        return super.findChildElementNamedOf(anElement, childElementName);
+    }
+
+    public ICompletionProposal[] getTaskProposals(String text, String parentName, String prefix) {
+    	cursorPosition= Math.max(0, text.length() - 1);
+        return super.getTaskProposals(new Document(text), parentName, prefix);
+    }
+    
+    public ICompletionProposal[] getTaskProposals(IDocument document, String parentName, String aPrefix) {
+    	cursorPosition= Math.max(0, document.getLength() - 1);
+    	return super.getTaskProposals(document, parentName, aPrefix);
+    }
+
+    public int determineProposalMode(String text, int theCursorPosition, String prefix) {
+        return super.determineProposalMode(new Document(text), theCursorPosition, prefix);
+    }
+
+    public String getParentName(String text, int aLineNumber, int aColumnNumber) {
+        return super.getParentName(new Document(text), aLineNumber, aColumnNumber);
+    }
+    
+    public String getParentName(IDocument doc, int aLineNumber, int aColumnNumber) {
+    	return super.getParentName(doc, aLineNumber, aColumnNumber);
+    }
+
+    public String getPrefixFromDocument(String aDocumentText, int anOffset) {
+        String prefix= super.getPrefixFromDocument(aDocumentText, anOffset);
+        currentPrefix= null;
+        return prefix;
+    }
+
+    public ICompletionProposal[] getPropertyProposals(IDocument document, String prefix, int cursorPos) {
+        return super.getPropertyProposals(document, prefix, cursorPos);
+    }
+
+    /**
+     * Returns the edited File that org.eclipse.ant.internal.ui.editor.AntEditorCompletionProcessor sets or a temporary 
+     * file, which only serves as a dummy.
+     * @see org.eclipse.ant.internal.ui.editor.AntEditorCompletionProcessor#getEditedFile()
+     */
+	public File getEditedFile() {
+		if (fEditedFile != null){
+			return fEditedFile;
+		}
+		File tempFile = null;
+        try {
+            tempFile = File.createTempFile("test", null);
+        } catch (IOException e) {
+            Assert.fail(e.getMessage());
+        }
+        tempFile.deleteOnExit();
+        return tempFile;
+    }
+
+	public void setLineNumber(int aLineNumber) {
+    	lineNumber = aLineNumber;
+    }
+
+	public void setColumnNumber(int aColumnNumber) {
+    	columnNumber = aColumnNumber;
+    }
+	
+	public void setCursorPosition(int cursorPosition) {
+		this.cursorPosition = cursorPosition;
+	}
+    
+	public void setEditedFile(File aFile) {
+		fEditedFile= aFile;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.AntEditorCompletionProcessor#getTargetAttributeValueProposals(org.eclipse.jface.text.IDocument, java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public ICompletionProposal[] getTargetAttributeValueProposals(IDocument document, String textToSearch, String prefix, String attributeName) {
+		return super.getTargetAttributeValueProposals(document, textToSearch, prefix, attributeName);
+	}
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.ant.internal.ui.editor.AntEditorCompletionProcessor#getAntCallAttributeValueProposals(org.eclipse.jface.text.IDocument, java.lang.String, java.lang.String)
+     */
+    public ICompletionProposal[] getAntCallAttributeValueProposals(IDocument document, String prefix, String attributeName) {
+        return super.getAntCallAttributeValueProposals(document, prefix, attributeName);
+    }
+	/**
+	 * Since the testing occurs without necessarily having an associated viewer, return
+	 * a dummy value.
+	 */
+	protected char getPreviousChar() {
+		return '?';
+	}
+	
+	 /**
+     * Returns whether the specified task name is known.
+     */
+    protected boolean isKnownElement(String elementName) {
+    	if (antModel != null) {
+    		return super.isKnownElement(elementName);
+    	} 
+    	return getDtd().getElement(elementName) != null ;
+    }
+    
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.AntEditorCompletionProcessor#getProposalsFromDocument(org.eclipse.jface.text.IDocument, java.lang.String)
+	 */
+	public ICompletionProposal[] getProposalsFromDocument(IDocument document, String prefix) {
+		return super.getProposalsFromDocument(document, prefix);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.AntEditorCompletionProcessor#getBuildFileProposals(org.eclipse.jface.text.IDocument, java.lang.String)
+	 */
+	public ICompletionProposal[] getBuildFileProposals(String text, String prefix) {
+		return super.getBuildFileProposals(new Document(text), prefix);
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.AntEditorCompletionProcessor#determineTemplateProposals(org.eclipse.jface.text.ITextViewer, int)
+	 */
+	public ICompletionProposal[] determineTemplateProposals() {
+		return super.determineTemplateProposals(fViewer, cursorPosition);
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
+	 */
+	public ICompletionProposal[] computeCompletionProposals(int documentOffset) {
+		return super.computeCompletionProposals(fViewer, documentOffset);
+	}
+    
+    public void dispose() {
+        if (fNeedsToDispose && antModel != null) {
+            //not working with an editor
+            antModel.dispose();
+        }
+    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/AbstractAntUIBuildPerformanceTest.java b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/AbstractAntUIBuildPerformanceTest.java
new file mode 100644
index 0000000..9747920
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/AbstractAntUIBuildPerformanceTest.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.test.performance.Dimension;
+import org.eclipse.test.performance.Performance;
+import org.eclipse.test.performance.PerformanceMeter;
+
+public class AbstractAntUIBuildPerformanceTest extends AbstractAntUIBuildTest {
+
+	protected PerformanceMeter fPerformanceMeter;
+
+	/**
+	 * Constructs a performance test case with the given name.
+	 * @param name the name of the performance test case
+	 */
+	public AbstractAntUIBuildPerformanceTest(String name) {
+		super(name);
+	}
+	
+	/**
+	 * Overridden to create a default performance meter for this test case.
+	 * @throws Exception
+	 */
+	protected void setUp() throws Exception {
+		super.setUp();
+		Performance performance= Performance.getDefault();
+		fPerformanceMeter= performance.createPerformanceMeter(performance.getDefaultScenarioId(this));
+	}
+
+	/**
+	 * Overridden to dispose of the performance meter.
+	 * @throws Exception
+	 */
+	protected void tearDown() throws Exception {
+		fPerformanceMeter.dispose();
+	}
+
+	/**
+	 * Mark the scenario of this test case
+	 * to be included into the global performance summary. The summary shows
+	 * the given dimension of the scenario and labels the scenario with the short name.
+	 * 
+	 * @param shortName a short (shorter than 40 characters) descritive name of the scenario
+	 * @param dimension the dimension to show in the summary
+	 */
+	public void tagAsGlobalSummary(String shortName, Dimension dimension) {
+		Performance performance= Performance.getDefault();
+		performance.tagAsGlobalSummary(fPerformanceMeter, shortName, new Dimension[] { dimension } );
+	}
+	
+	/**
+	 * Mark the scenario of this test case
+	 * to be included into the performance summary. The summary shows
+	 * the given dimension of the scenario and labels the scenario with the short name.
+	 * 
+	 * @param shortName a short (shorter than 40 characters) descriptive name of the scenario
+	 * @param dimension the dimension to show in the summary
+	 */
+	public void tagAsSummary(String shortName, Dimension dimension) {
+		Performance performance= Performance.getDefault();
+		performance.tagAsSummary(fPerformanceMeter, shortName, new Dimension[] { dimension } );
+	}
+
+	/**
+	 * Mark the scenario represented by the given PerformanceMeter
+	 * to be included into the global performance summary. The summary shows
+	 * the given dimensions of the scenario and labels the scenario with the short name.
+	 * 
+	 * @param shortName a short (shorter than 40 characters) descriptive name of the scenario
+	 * @param dimensions an array of dimensions to show in the summary
+	 */
+	public void tagAsGlobalSummary(String shortName, Dimension[] dimensions) {
+		Performance performance= Performance.getDefault();
+		performance.tagAsGlobalSummary(fPerformanceMeter, shortName, dimensions );
+	}
+	
+	/**
+	 * Called from within a test case immediately before the code to measure is run.
+	 * It starts capturing of performance data.
+	 * Must be followed by a call to {@link PerformanceTestCase#stopMeasuring()} before subsequent calls
+	 * to this method or {@link PerformanceTestCase#commitMeasurements()}.
+	 */
+	protected void startMeasuring() {
+		fPerformanceMeter.start();
+	}
+	
+	protected void stopMeasuring() {
+		fPerformanceMeter.stop();
+	}
+	
+	protected void commitMeasurements() {
+		fPerformanceMeter.commit(); 
+	}
+
+	/**
+	 * Asserts default properties of the measurements captured for this test case.
+	 * 
+	 * @throws RuntimeException if the properties do not hold
+	 */
+	protected void assertPerformance() {
+		Performance.getDefault().assertPerformance(fPerformanceMeter);
+	}
+
+	/**
+	 * Asserts that the measurement specified by the given dimension
+	 * is within a certain range with respect to some reference value.
+	 * If the specified dimension isn't available, the call has no effect.
+	 * 
+	 * @param dim the Dimension to check
+	 * @param lowerPercentage a negative number indicating the percentage the measured value is allowed to be smaller than some reference value
+	 * @param upperPercentage a positive number indicating the percentage the measured value is allowed to be greater than some reference value
+	 * @throws RuntimeException if the properties do not hold
+	 */
+	protected void assertPerformanceInRelativeBand(Dimension dim, int lowerPercentage, int upperPercentage) {
+		Performance.getDefault().assertPerformanceInRelativeBand(fPerformanceMeter, dim, lowerPercentage, upperPercentage);
+	}
+	
+	/**
+	 * Launches the Ant build for this config.
+	 * Waits for all of the lines to be appended to the console.
+	 * 
+	 * @param config the launch configuration to execute
+	 * @param i the number of times to perform the launch
+	 */
+	protected void launch(ILaunchConfiguration config, int i) throws CoreException {
+		startMeasuring();
+		for (int j = 0; j < i; j++) {
+		    super.launch(config);    
+        }
+		stopMeasuring();
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/AbstractAntUIBuildTest.java b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/AbstractAntUIBuildTest.java
new file mode 100644
index 0000000..8e4eca7
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/AbstractAntUIBuildTest.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui;
+
+import junit.framework.TestResult;
+
+import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.console.IHyperlink;
+
+
+public abstract class AbstractAntUIBuildTest extends AbstractAntUITest {
+
+	/**
+	 * Flag that indicates test are in progress
+	 */
+	protected boolean testing = true;
+		
+	public AbstractAntUIBuildTest(String name) {
+		super(name);
+	}
+	
+	/**
+	 * Runs the test and collects the result in a TestResult without blocking
+	 * the UI thread.
+	 */
+	public void run(final TestResult result) {
+		final Display display = Display.getCurrent();
+		Thread thread = null;
+		try {
+			Runnable r = new Runnable() {
+				public void run() {
+					AbstractAntUIBuildTest.super.run(result);		
+					testing = false;
+					display.wake();
+				}
+			};
+			thread = new Thread(r);
+			thread.start();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		while (testing) {
+			try {
+				if (!display.readAndDispatch())
+					display.sleep();
+			} catch (Throwable e) {
+				e.printStackTrace();
+			}			
+		}		
+	}
+	
+	/**
+	 * Launches the Ant build with the buildfile name (no extension).
+	 * Waits for all of the lines to be appended to the console.
+	 * 
+	 * @param buildFileName the buildfile to execute
+	 * @return thread in which the first suspend event occurred
+	 */
+	protected void launch(String buildFileName) throws CoreException {
+		super.launch(buildFileName);
+	}
+	
+	/**
+	 * Launches the launch configuration
+	 * Waits for all of the lines to be appended to the console.
+	 * 
+	 * @param config the config to execute
+	 * @return thread in which the first suspend event occurred
+	 */
+	protected void launch(ILaunchConfiguration config) throws CoreException {
+	    launchAndTerminate(config, 20000);
+	}
+	
+	protected void activateLink(final IHyperlink link) {
+		Display.getDefault().asyncExec(new Runnable() {
+			public void run() {
+				link.linkActivated();
+			}
+		});
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest#launch(java.lang.String, java.lang.String)
+	 */
+	protected void launch(String buildFileName, String arguments) throws CoreException {
+		super.launch(buildFileName, arguments);
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/AntUtilTests.java b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/AntUtilTests.java
new file mode 100644
index 0000000..5f8933c
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/AntUtilTests.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.ant.internal.ui.AntUtil;
+import org.eclipse.ant.internal.ui.model.AntTargetNode;
+import org.eclipse.ant.launching.IAntLaunchConstants;
+import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
+import org.eclipse.core.externaltools.internal.IExternalToolConstants;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+
+public class AntUtilTests extends AbstractAntUITest {
+
+    public AntUtilTests(String name) {
+        super(name);
+    }
+    
+    public void testGetTargetsLaunchConfiguration() throws CoreException {
+       String buildFileName= "echoing";
+       File buildFile= getBuildFile(buildFileName + ".xml");
+       String arguments= null;
+       Map properties= null;
+       String propertyFiles= null;
+       AntTargetNode[] targets= AntUtil.getTargets(buildFile.getAbsolutePath(), getLaunchConfiguration(buildFileName, arguments, properties, propertyFiles));
+       assertTrue(targets != null);
+       assertTrue("Incorrect number of targets retrieved; should be 4 was: " + targets.length, targets.length == 4);
+       assertContains("echo3", targets);
+    }
+    
+    public void testGetTargetsLaunchConfigurationMinusD() throws CoreException {
+        String buildFileName= "importRequiringUserProp";
+        File buildFile= getBuildFile(buildFileName + ".xml");
+        String arguments= "-DimportFileName=toBeImported.xml";
+        Map properties= null;
+        String propertyFiles= null;
+        AntTargetNode[] targets= AntUtil.getTargets(buildFile.getAbsolutePath(), getLaunchConfiguration(buildFileName, arguments, properties, propertyFiles));
+        assertTrue(targets != null);
+        assertTrue("Incorrect number of targets retrieved; should be 3 was: " + targets.length, targets.length == 3);
+        assertContains("import-default", targets);
+     }
+    
+    public void testGetTargetsLaunchConfigurationMinusDAndProperty() throws CoreException {
+        String buildFileName= "importRequiringUserProp";
+        File buildFile= getBuildFile(buildFileName + ".xml");
+        String arguments= "-DimportFileName=toBeImported.xml";
+        //arguments should win
+        Map properties= new HashMap();
+        properties.put("importFileName", "notToBeImported.xml");
+        String propertyFiles= null;
+        AntTargetNode[] targets= AntUtil.getTargets(buildFile.getAbsolutePath(), getLaunchConfiguration(buildFileName, arguments, properties, propertyFiles));
+        assertTrue(targets != null);
+        assertTrue("Incorrect number of targets retrieved; should be 3 was: " + targets.length, targets.length == 3);
+        assertContains("import-default", targets);
+     }
+    
+    
+    public void testGetTargetsLaunchConfigurationProperty() throws CoreException {
+        String buildFileName= "importRequiringUserProp";
+        File buildFile= getBuildFile(buildFileName + ".xml");
+        String arguments= null;
+        Map properties= new HashMap();
+        properties.put("importFileName", "toBeImported.xml");
+        String propertyFiles= null;
+        AntTargetNode[] targets= AntUtil.getTargets(buildFile.getAbsolutePath(), getLaunchConfiguration(buildFileName, arguments, properties, propertyFiles));
+        assertTrue(targets != null);
+        assertTrue("Incorrect number of targets retrieved; should be 3 was: " + targets.length, targets.length == 3);
+        assertContains("import-default", targets);
+     }
+    
+    public void testGetTargetsLaunchConfigurationPropertyFile() throws CoreException {
+        String buildFileName= "importRequiringUserProp";
+        File buildFile= getBuildFile(buildFileName + ".xml");
+        String arguments= null;
+        Map properties= null;
+        String propertyFiles= "buildtest1.properties";
+        AntTargetNode[] targets= AntUtil.getTargets(buildFile.getAbsolutePath(), getLaunchConfiguration(buildFileName, arguments, properties, propertyFiles));
+        assertTrue(targets != null);
+        assertTrue("Incorrect number of targets retrieved; should be 3 was: " + targets.length, targets.length == 3);
+        assertContains("import-default", targets);
+     }
+    
+    protected ILaunchConfiguration getLaunchConfiguration(String buildFileName, String arguments, Map properties, String propertyFiles) throws CoreException {
+        ILaunchConfiguration config = getLaunchConfiguration(buildFileName);
+		assertNotNull("Could not locate launch configuration for " + buildFileName, config);
+		ILaunchConfigurationWorkingCopy copy= config.getWorkingCopy();
+		if (arguments != null) {
+		    copy.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, arguments);
+		}
+		if (properties != null) {
+		    copy.setAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTIES, properties);
+		}
+		if (propertyFiles != null) {
+		    copy.setAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTY_FILES, propertyFiles);
+		}
+		return copy;
+    }
+
+    /**
+ 	 * Asserts that <code>displayString</code> is in one of the 
+ 	 * completion proposals.
+ 	 */
+    private void assertContains(String targetName, AntTargetNode[] targets) {
+        boolean found = false;
+        for (int i = 0; i < targets.length; i++) {
+            AntTargetNode target = targets[i];
+            String foundName = target.getTargetName();
+            if(targetName.equals(foundName)) {
+                found = true;
+                break;
+            }
+        }
+        assertEquals("Did not find target: " + targetName, true, found);
+    }        
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/performance/AbstractAntPerformanceTest.java b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/performance/AbstractAntPerformanceTest.java
new file mode 100644
index 0000000..b9fcd6e
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/performance/AbstractAntPerformanceTest.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ *  Copyright (c) 2005, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.performance;
+
+import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
+import org.eclipse.test.performance.PerformanceTestCase;
+
+/**
+ * Abstract class for ant performance tests, ensures the test project is created 
+ * and ready in the test workspace.
+ * 
+ * @since 3.5
+ */
+public abstract class AbstractAntPerformanceTest extends PerformanceTestCase {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.test.performance.PerformanceTestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		super.setUp();
+		AbstractAntUITest.assertProject();
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/performance/OpenLaunchConfigurationDialogTests.java b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/performance/OpenLaunchConfigurationDialogTests.java
new file mode 100644
index 0000000..e367813
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/performance/OpenLaunchConfigurationDialogTests.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.performance;
+
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.tests.ui.editor.performance.EditorTestHelper;
+import org.eclipse.ant.tests.ui.testplugin.AbstractAntUITest;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.test.performance.Dimension;
+import org.eclipse.test.performance.PerformanceTestCase;
+import org.eclipse.ui.externaltools.internal.model.IExternalToolConstants;
+
+public class OpenLaunchConfigurationDialogTests extends PerformanceTestCase {
+
+    public static String fgIdentifier= IExternalToolConstants.ID_EXTERNAL_TOOLS_LAUNCH_GROUP;
+    
+    public void testOpenAntLaunchConfigurationDialog1() {
+        //cold run
+        ILaunchConfiguration configuration= getLaunchConfiguration("big");
+		IStructuredSelection selection= new StructuredSelection(configuration);
+		for (int i = 0; i < 10; i++) {
+		    openLCD(selection, fgIdentifier, 20); 
+        }
+		
+		commitMeasurements();
+		assertPerformance();
+    }
+    
+    public void testOpenAntLaunchConfigurationDialog2() {
+        //warm run
+        ILaunchConfiguration configuration= getLaunchConfiguration("big");
+		IStructuredSelection selection= new StructuredSelection(configuration);
+		tagAsSummary("Open LCD on Targets tab", Dimension.ELAPSED_PROCESS);
+		for (int i = 0; i < 10; i++) {
+		    openLCD(selection, fgIdentifier, 20); 
+        }
+		
+		commitMeasurements();
+		assertPerformance();
+    }
+
+    private ILaunchConfiguration getLaunchConfiguration(String buildFileName) {
+        IFile file = AbstractAntUITest.getJavaProject().getProject().getFolder("launchConfigurations").getFile(buildFileName + ".launch");
+		ILaunchConfiguration config = AbstractAntUITest.getLaunchManager().getLaunchConfiguration(file);
+		assertTrue("Could not find launch configuration for " + buildFileName, config.exists());
+		return config;
+    }
+
+    private void openLCD(final IStructuredSelection selection, final String groupIdentifier, int numberOfOpens) {
+        startMeasuring();
+        for (int i = 0; i < numberOfOpens; i++) {
+	        //set a status to go to the targets tab
+		    IStatus status = new Status(IStatus.INFO, IAntUIConstants.PLUGIN_ID, IAntUIConstants.STATUS_INIT_RUN_ANT, "", null); //$NON-NLS-1$
+			LaunchConfigurationsDialog dialog= new LaunchConfigurationsDialog(DebugUIPlugin.getShell(), DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(groupIdentifier));
+			dialog.setBlockOnOpen(false);
+			dialog.setOpenMode(LaunchConfigurationsDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION);
+			dialog.setInitialSelection(selection);
+			dialog.setInitialStatus(status);
+			
+			dialog.open();
+            EditorTestHelper.runEventQueue(dialog.getShell());
+			dialog.close();
+        }
+		stopMeasuring();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.test.performance.PerformanceTestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+       super.setUp();
+       IPreferenceStore debugPreferenceStore = DebugUIPlugin.getDefault().getPreferenceStore();
+       debugPreferenceStore.setValue(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_CLOSED, false);
+       debugPreferenceStore.setValue(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_DELETED, false);
+       debugPreferenceStore.setValue(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_TYPES, false);       
+       debugPreferenceStore.setValue(IInternalDebugUIConstants.PREF_FILTER_WORKING_SETS, false);
+       EditorTestHelper.runEventQueue();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.test.performance.PerformanceTestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        IPreferenceStore debugPreferenceStore = DebugUIPlugin.getDefault().getPreferenceStore();
+        debugPreferenceStore.setToDefault(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_CLOSED);
+        debugPreferenceStore.setToDefault(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_DELETED);
+        debugPreferenceStore.setToDefault(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_TYPES);       
+        debugPreferenceStore.setToDefault(IInternalDebugUIConstants.PREF_FILTER_WORKING_SETS);
+    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/performance/SeparateVMTests.java b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/performance/SeparateVMTests.java
new file mode 100644
index 0000000..66af71c
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/Ant Tests/org/eclipse/ant/tests/ui/performance/SeparateVMTests.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.performance;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.ant.tests.ui.AbstractAntUIBuildPerformanceTest;
+import org.eclipse.core.externaltools.internal.IExternalToolConstants;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.IDebugUIConstants;
+
+public class SeparateVMTests extends AbstractAntUIBuildPerformanceTest {
+		
+    public SeparateVMTests(String name) {
+        super(name);
+    }
+    
+	public static Test suite() {
+		return new TestSuite(SeparateVMTests.class);
+	}
+
+    /**
+     * Performance test for launching Ant in a separate vm.
+     */
+	public void testBuild() throws CoreException {
+    	//tagAsSummary("Separate JRE Build", Dimension.ELAPSED_PROCESS);
+    	ILaunchConfiguration config= getLaunchConfiguration("echoingSepVM");
+    	//possible first time hit of the SWT pieces getting written from the JAR to the 
+    	//metadata area
+    	launchAndTerminate(config, 20000);
+    	for (int i = 0; i < 10; i++) {
+    		launch(config, 10);
+		}
+    	commitMeasurements();
+		assertPerformance(); 	
+    }
+	
+	 /**
+     * Performance test for launching Ant in a separate vm with no console output.
+     */
+	public void testBuildNoConsole() throws CoreException {
+    	//tagAsSummary("Separate JRE Build; capture output off", Dimension.ELAPSED_PROCESS);
+    	ILaunchConfiguration config = getLaunchConfiguration("echoingSepVM");
+		assertNotNull("Could not locate launch configuration for " + "echoingSepVM", config);
+		ILaunchConfigurationWorkingCopy copy= config.getWorkingCopy();
+		copy.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, false);
+		copy.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, false);
+		//possible first time hit of the SWT pieces getting written from the JAR to the 
+    	//metadata area
+		launchAndTerminate(copy, 20000);
+		for (int i = 0; i < 10; i++) {
+    		launch(copy, 10);
+        }
+    	commitMeasurements();
+		assertPerformance(); 	
+    }
+    
+    /**
+     * Performance test for launching Ant in a separate vm with debug information.
+     */
+    public void testBuildMinusDebug() throws CoreException {
+    	//tagAsSummary("Separate JRE Build; -debug", Dimension.ELAPSED_PROCESS);
+    	ILaunchConfiguration config = getLaunchConfiguration("echoingSepVM");
+		assertNotNull("Could not locate launch configuration for " + "echoingSepVM", config);
+		ILaunchConfigurationWorkingCopy copy= config.getWorkingCopy();
+		copy.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, "-debug");
+		//possible first time hit of the SWT pieces getting written from the JAR to the 
+    	//metadata area
+		launchAndTerminate(copy, 20000);
+    	for (int i = 0; i < 10; i++) {
+    		launch(copy, 10);
+        }
+    	commitMeasurements();
+		assertPerformance();
+	}  	
+    
+     /**
+     * Performance test for launching Ant in a separate vm with lots of links
+     */
+    public void testBuildWithLotsOfLinks() throws CoreException {
+        //tagAsSummary("Separate JRE Build; links", Dimension.ELAPSED_PROCESS);
+        ILaunchConfiguration config = getLaunchConfiguration("echoPropertiesSepVM");
+        //possible first time hit of the SWT pieces getting written from the JAR to the 
+        //metadata area
+        launchAndTerminate(config, 20000);
+        for (int i = 0; i < 10; i++) {
+            launch(config, 10);
+        }
+        commitMeasurements();
+        assertPerformance();
+    }   
+}
diff --git a/ant/org.eclipse.ant.tests.ui/about.html b/ant/org.eclipse.ant.tests.ui/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</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
+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/ant/org.eclipse.ant.tests.ui/build.properties b/ant/org.eclipse.ant.tests.ui/build.properties
new file mode 100644
index 0000000..03e042d
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/build.properties
@@ -0,0 +1,30 @@
+###############################################################################
+# Copyright (c) 2004, 2009 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
+###############################################################################
+bin.includes = plugin.xml,\
+               plugin.properties,\
+               test.xml,\
+               about.html,\
+               testbuildfiles/,\
+               lib/,\
+               lib/*.jar,\
+               *.jar,\
+               META-INF/
+               
+source.anttestsui.jar = test plugin/,\
+                        Ant Editor Tests/,\
+                        Ant Debug Tests/,\
+                        External Tools/,\
+                        Ant Tests/
+						
+source.lib/antUITestsSupport.jar = test support/
+jars.compile.order=anttestsui.jar,lib/antUITestsSupport.jar
+output.lib/antUITestsSupport.jar = test_support_bin/
+output.anttestsui.jar = bin/
diff --git a/ant/org.eclipse.ant.tests.ui/buildfiles/buildAntTestsSupportJAR.xml b/ant/org.eclipse.ant.tests.ui/buildfiles/buildAntTestsSupportJAR.xml
new file mode 100644
index 0000000..bde5127
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/buildfiles/buildAntTestsSupportJAR.xml
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.ui/icons/ant.gif b/ant/org.eclipse.ant.tests.ui/icons/ant.gif
new file mode 100644
index 0000000..6da365c
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/icons/ant.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.ui/plugin.properties b/ant/org.eclipse.ant.tests.ui/plugin.properties
new file mode 100644
index 0000000..4a08e07
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2003, 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
+###############################################################################
+
+pluginName=Ant UI Test Plugin
+providerName=Eclipse.org
diff --git a/ant/org.eclipse.ant.tests.ui/plugin.xml b/ant/org.eclipse.ant.tests.ui/plugin.xml
new file mode 100644
index 0000000..d41961f
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/plugin.xml
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/AbstractAntUITest.java b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/AbstractAntUITest.java
new file mode 100644
index 0000000..e6cc839
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/AbstractAntUITest.java
@@ -0,0 +1,483 @@
+/*******************************************************************************
+ *  Copyright (c) 2003, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.testplugin;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import junit.framework.TestCase;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
+import org.eclipse.ant.internal.ui.model.AntModel;
+import org.eclipse.ant.tests.ui.editor.support.TestLocationProvider;
+import org.eclipse.ant.tests.ui.editor.support.TestProblemRequestor;
+import org.eclipse.core.externaltools.internal.IExternalToolConstants;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.ui.console.IHyperlink;
+import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition;
+import org.eclipse.ui.internal.console.IOConsolePartition;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Abstract Ant UI test class
+ */
+public abstract class AbstractAntUITest extends TestCase {
+    
+    public static String ANT_EDITOR_ID= "org.eclipse.ant.ui.internal.editor.AntEditor";
+    
+    private IDocument currentDocument;
+
+    /**
+     * Constructor
+     * @param name
+     */
+    public AbstractAntUITest(String name) {
+        super(name);
+    }
+        
+    /**
+     * Returns the {@link IFile} for the given build file name
+     * @param buildFileName
+     * @return the associated {@link IFile} for the given build file name
+     */
+    protected IFile getIFile(String buildFileName) {
+        return getProject().getFolder("buildfiles").getFile(buildFileName); 
+    }
+    
+    /**
+     * Returns the {@link File} for the given build file name
+     * @param buildFileName
+     * @return the {@link File} for the given build file name
+     */
+    protected File getBuildFile(String buildFileName) {
+        IFile file = getIFile(buildFileName);
+        assertTrue("Could not find build file named: " + buildFileName, file.exists());
+        return file.getLocation().toFile();
+    }
+    
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+    	super.setUp();
+    	assertProject();
+    }
+    
+    /**
+     * Asserts that the testing project has been setup in the test workspace
+     * @throws Exception
+     * 
+     * @since 3.5
+     */
+    public static void assertProject() throws Exception {
+		IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ProjectHelper.PROJECT_NAME);
+		if (!pro.exists()) {
+			// create project and import build files and support files
+			IProject project = ProjectHelper.createProject(ProjectHelper.PROJECT_NAME);
+			IFolder folder = ProjectHelper.addFolder(project, "buildfiles");
+			ProjectHelper.addFolder(project, "launchConfigurations");
+			File root = AntUITestPlugin.getDefault().getFileInPlugin(ProjectHelper.TEST_BUILDFILES_DIR);
+			ProjectHelper.importFilesFromDirectory(root, folder.getFullPath(), null);
+			
+			ProjectHelper.createLaunchConfigurationForBoth("echoing");
+			ProjectHelper.createLaunchConfigurationForBoth("102282");
+			ProjectHelper.createLaunchConfigurationForBoth("74840");
+            ProjectHelper.createLaunchConfigurationForBoth("failingTarget");
+			ProjectHelper.createLaunchConfiguration("build");
+			ProjectHelper.createLaunchConfiguration("bad");
+			ProjectHelper.createLaunchConfiguration("importRequiringUserProp");
+            ProjectHelper.createLaunchConfigurationForSeparateVM("echoPropertiesSepVM", "echoProperties");
+			ProjectHelper.createLaunchConfigurationForSeparateVM("extensionPointSepVM", null);
+			ProjectHelper.createLaunchConfigurationForSeparateVM("extensionPointTaskSepVM", null);
+			ProjectHelper.createLaunchConfigurationForSeparateVM("extensionPointTypeSepVM", null);
+			ProjectHelper.createLaunchConfigurationForSeparateVM("input", null);
+			ProjectHelper.createLaunchConfigurationForSeparateVM("environmentVar", null);
+            
+            ProjectHelper.createLaunchConfigurationForBoth("breakpoints");
+            ProjectHelper.createLaunchConfigurationForBoth("debugAntCall");
+            ProjectHelper.createLaunchConfigurationForBoth("96022");
+            ProjectHelper.createLaunchConfigurationForBoth("macrodef");
+            ProjectHelper.createLaunchConfigurationForBoth("85769");
+			
+			ProjectHelper.createLaunchConfiguration("big", ProjectHelper.PROJECT_NAME + "/buildfiles/performance/build.xml");
+			
+			//do not show the Ant build failed error dialog
+			AntUIPlugin.getDefault().getPreferenceStore().setValue(IAntUIPreferenceConstants.ANT_ERROR_DIALOG, false);
+		}
+    }
+
+    /**
+     * Returns the 'AntUITests' project.
+     * 
+     * @return the test project
+     */
+    protected static IProject getProject() {
+        return ResourcesPlugin.getWorkspace().getRoot().getProject(ProjectHelper.PROJECT_NAME);
+    }
+    
+    /**
+     * Returns the underlying {@link IDocument} for the given file name
+     * @param fileName
+     * @return the underlying {@link IDocument} for the given file name
+     */
+    protected IDocument getDocument(String fileName) {
+        File file = getBuildFile(fileName);
+        InputStream in;
+        try {
+            in = new FileInputStream(file);
+        } catch (FileNotFoundException e) {
+            return null;
+        }
+        String initialContent= getStreamContentAsString(in);
+        return new Document(initialContent);
+    }
+
+    /**
+     * Returns the contents of the given {@link InputStream} as a {@link String}
+     * @param inputStream
+     * @return the {@link InputStream} as a {@link String}
+     */
+    protected String getStreamContentAsString(InputStream inputStream) {
+        InputStreamReader reader;
+        try {
+            reader = new InputStreamReader(inputStream, ResourcesPlugin.getEncoding());
+        } catch (UnsupportedEncodingException e) {
+            AntUIPlugin.log(e);
+            return ""; //$NON-NLS-1$
+        }
+        BufferedReader tempBufferedReader = new BufferedReader(reader);
+
+        return getReaderContentAsString(tempBufferedReader);
+    }
+    
+    /**
+     * Returns the contents of the given {@link BufferedReader} as a {@link String}
+     * @param bufferedReader
+     * @return the contents of the given {@link BufferedReader} as a {@link String}
+     */
+    protected String getReaderContentAsStringNew(BufferedReader bufferedReader) {
+        StringBuffer result = new StringBuffer();
+        try {
+            char[] readBuffer= new char[2048];
+            int n= bufferedReader.read(readBuffer);
+            while (n > 0) {
+                result.append(readBuffer, 0, n);
+                n= bufferedReader.read(readBuffer);
+            }
+        } catch (IOException e) {
+            AntUIPlugin.log(e);
+            return null;
+        }
+
+        return result.toString();
+    }
+    
+    /**
+     * Returns the contents of the given {@link BufferedReader} as a {@link String}
+     * @param bufferedReader
+     * @return the contents of the given {@link BufferedReader} as a {@link String}
+     */
+    protected String getReaderContentAsString(BufferedReader bufferedReader) {
+        StringBuffer result = new StringBuffer();
+        try {
+            String line= bufferedReader.readLine();
+
+            while(line != null) {
+                if(result.length() != 0) {
+                    result.append(System.getProperty("line.separator")); //$NON-NLS-1$
+                }
+                result.append(line);
+                line = bufferedReader.readLine();
+            }
+        } catch (IOException e) {
+            AntUIPlugin.log(e);
+            return null;
+        }
+
+        return result.toString();
+    }
+        
+    /**
+     * Returns the {@link AntModel} for the given file name
+     * @param fileName
+     * @return the {@link AntModel} for the given file name
+     */
+    protected AntModel getAntModel(String fileName) {
+        currentDocument= getDocument(fileName);
+        AntModel model= new AntModel(currentDocument, new TestProblemRequestor(), new TestLocationProvider(getBuildFile(fileName)));
+        model.reconcile();
+        return model;
+    }
+    
+    /**
+     * @return the current {@link IDocument} context
+     */
+    public IDocument getCurrentDocument() {
+        return currentDocument;
+    }
+
+    /**
+     * Allows the current {@link IDocument} context to be set. This method accepts <code>null</code>
+     * @param currentDocument
+     */
+    public void setCurrentDocument(IDocument currentDocument) {
+        this.currentDocument = currentDocument;
+    }
+    
+    /**
+     * Launches the Ant build with the build file name (no extension).
+     * 
+     * @param buildFileName the ant build file name
+     */
+    protected void launch(String buildFileName) throws CoreException {
+        ILaunchConfiguration config = getLaunchConfiguration(buildFileName);
+        assertNotNull("Could not locate launch configuration for " + buildFileName, config);
+        launchAndTerminate(config, 20000);
+    }
+    
+    /**
+     * Launches the Ant build with the build file name (no extension).
+     * 
+     * @param buildFileName the build file
+     * @param arguments the ant arguments
+     */
+    protected void launch(String buildFileName, String arguments) throws CoreException {
+        ILaunchConfiguration config = getLaunchConfiguration(buildFileName);
+        assertNotNull("Could not locate launch configuration for " + buildFileName, config);
+        ILaunchConfigurationWorkingCopy copy= config.getWorkingCopy();
+        copy.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, arguments);
+        launchAndTerminate(copy, 20000);
+    }
+    
+    /**
+    * Launches the Ant build in debug output mode with the build file name (no extension).
+    * 
+    * @param mainTypeName the program to launch
+    * @return thread in which the first suspend event occurred
+    */
+    protected void launchWithDebug(String buildFileName) throws CoreException {
+        ILaunchConfiguration config = getLaunchConfiguration(buildFileName);
+        assertNotNull("Could not locate launch configuration for " + buildFileName, config);
+        ILaunchConfigurationWorkingCopy copy= config.getWorkingCopy();
+        copy.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, "-debug");
+        launchAndTerminate(copy, 10000);
+    }
+    
+    /**
+     * Returns the launch configuration for the given build file
+     * 
+     * @param buildFileName build file to launch
+     * @see ProjectCreationDecorator
+     */
+    protected ILaunchConfiguration getLaunchConfiguration(String buildFileName) {
+        IFile file = getJavaProject().getProject().getFolder("launchConfigurations").getFile(buildFileName + ".launch");
+        ILaunchConfiguration config = getLaunchManager().getLaunchConfiguration(file);
+        assertTrue("Could not find launch configuration for " + buildFileName, config.exists());
+        return config;
+    }
+
+    /**
+     * Returns the content of the specified file as <code>String</code>.
+     */
+    protected String getFileContentAsString(File aFile) throws FileNotFoundException {
+        InputStream stream = new FileInputStream(aFile);
+        InputStreamReader reader = new InputStreamReader(stream);
+        BufferedReader bufferedReader = new BufferedReader(reader);
+    
+        return getReaderContentAsString(bufferedReader);
+    }
+    
+    /**
+     * @return a new SAX parser instrance
+     */
+    protected SAXParser getSAXParser() {
+        SAXParser parser = null;
+        try {
+            parser = SAXParserFactory.newInstance().newSAXParser();
+        } catch (ParserConfigurationException e) {
+            AntUIPlugin.log(e);
+        } catch (SAXException e) {
+            AntUIPlugin.log(e);
+        }
+        return parser;
+    }
+
+    
+    /**
+     * Parses the given input stream with the given parser using the given handler
+     * @param stream
+     * @param parser
+     * @param handler
+     * @param editedFile
+     */
+    protected void parse(InputStream stream, SAXParser parser, DefaultHandler handler, File editedFile) {
+        InputSource inputSource= new InputSource(stream);
+        if (editedFile != null) {
+            //needed for resolving relative external entities
+            inputSource.setSystemId(editedFile.getAbsolutePath());
+        }
+
+        try {
+            parser.parse(inputSource, handler);
+        } catch (SAXException e) {
+        } catch (IOException e) {
+        }
+    }
+    
+    /**
+     * Returns the launch manager
+     * 
+     * @return launch manager
+     */
+    public static ILaunchManager getLaunchManager() {
+        return DebugPlugin.getDefault().getLaunchManager();
+    }
+    
+    /**
+     * Returns the 'AntUITests' project.
+     * 
+     * @return the test project
+     */
+    public static IJavaProject getJavaProject() {
+        return JavaCore.create( getProject());
+    }
+    
+    /**
+     * Launches the given configuration and waits for the terminated event or the length of the given timeout, 
+     * whichever comes first 
+     * @param config
+     * @param timeout
+     * @throws CoreException
+     */
+    protected void launchAndTerminate(ILaunchConfiguration config, int timeout) throws CoreException {
+        DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.TERMINATE, IProcess.class);
+        waiter.setTimeout(timeout);
+
+        Object terminatee = launchAndWait(config, waiter);      
+        assertNotNull("Program did not terminate.", terminatee);
+        assertTrue("terminatee is not an IProcess", terminatee instanceof IProcess);
+        IProcess process = (IProcess) terminatee;
+        boolean terminated = process.isTerminated();
+        assertTrue("process is not terminated", terminated);
+    }
+    
+    /**
+     * Launches the given configuration and waits for an event. Returns the
+     * source of the event. If the event is not received, the launch is
+     * terminated and an exception is thrown.
+     * 
+     * @param configuration the configuration to launch
+     * @param waiter the event waiter to use
+     * @return Object the source of the event
+     * @exception Exception if the event is never received.
+     */
+    protected Object launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter) throws CoreException {
+        ILaunch launch = configuration.launch(ILaunchManager.RUN_MODE, null);
+        Object suspendee= waiter.waitForEvent();
+        if (suspendee == null) {
+            try {
+                launch.terminate();
+            } catch (CoreException e) {
+                e.printStackTrace();
+                fail("Program did not suspend, and unable to terminate launch.");
+            }
+        }
+        assertNotNull("Program did not suspend, launch terminated.", suspendee);
+        boolean terminated = launch.isTerminated();
+        assertTrue("launch did not terminate", terminated);
+        if (terminated && !ConsoleLineTracker.isClosed()) {
+            ConsoleLineTracker.waitForConsole();
+        }
+        assertTrue("Console is not closed", ConsoleLineTracker.isClosed()); 
+        return suspendee;       
+    }
+    
+    /**
+     * Returns the {@link IHyperlink} at the given offset on the given document,
+     * or <code>null</code> if there is no {@link IHyperlink} at that offset on the document.
+     * @param offset
+     * @param doc
+     * @return the {@link IHyperlink} at the given offset on the given document or <code>null</code>
+     */
+    protected IHyperlink getHyperlink(int offset, IDocument doc) {
+        if (offset >= 0 && doc != null) {
+            Position[] positions = null;
+            try {
+                positions = doc.getPositions(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY);
+            } catch (BadPositionCategoryException ex) {
+                // no links have been added
+                return null;
+            }
+            for (int i = 0; i < positions.length; i++) {
+                Position position = positions[i];
+                if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) {
+                    return ((ConsoleHyperlinkPosition)position).getHyperLink();
+                }
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Returns the {@link Color} at the given offset on the given document,
+     * or <code>null</code> if there is no {@link Color} at that offset on the document.
+     * @param offset
+     * @param doc
+     * @return the {@link Color} at the given offset on the given document or <code>null</code>
+     */
+    protected Color getColorAtOffset(int offset, IDocument document) throws BadLocationException {
+        if (document != null) {
+            IDocumentPartitioner partitioner = document.getDocumentPartitioner();
+            if (partitioner != null) {
+                ITypedRegion[] regions= partitioner.computePartitioning(offset, document.getLineInformationOfOffset(offset).getLength());
+                if (regions.length > 0) {
+                    IOConsolePartition partition = (IOConsolePartition)regions[0];
+                    return partition.getColor();
+                }   
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/AntUIPerformanceTests.java b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/AntUIPerformanceTests.java
new file mode 100644
index 0000000..3a9da64
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/AntUIPerformanceTests.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ *  Copyright (c) 2004, 2008 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.testplugin;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.ant.tests.ui.editor.performance.OpenAntEditorTest;
+import org.eclipse.ant.tests.ui.performance.SeparateVMTests;
+
+/**
+ * Performance Test suite for the Ant UI.
+ * All of the tests in this suite rely on the setup that occurs in the 
+ * ProjectCreationDecorator suite. It must always run before any of the other
+ * test suites.
+ */
+public class AntUIPerformanceTests extends TestSuite {
+
+    public static Test suite() {
+
+        TestSuite suite = new AntUIPerformanceTests();
+        suite.setName("Ant UI Performance Unit Tests");
+		suite.addTest(new TestSuite(OpenAntEditorTest.class));
+		suite.addTest(new TestSuite(SeparateVMTests.class));
+		//suite.addTest(new TestSuite(NonInitialTypingTest.class));
+		//suite.addTest(new TestSuite(OpenLaunchConfigurationDialogTests.class));
+        return suite;
+    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/AntUITestPlugin.java b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/AntUITestPlugin.java
new file mode 100644
index 0000000..7f42975
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/AntUITestPlugin.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.testplugin;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceDescription;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.Bundle;
+
+
+public class AntUITestPlugin extends AbstractUIPlugin {
+	
+	private static AntUITestPlugin deflt;
+	
+	public AntUITestPlugin() {
+		super();
+		deflt= this;
+	}
+	
+	public static AntUITestPlugin getDefault() {
+		return deflt;
+	}
+	
+	public static IWorkspace getWorkspace() {
+		return ResourcesPlugin.getWorkspace();
+	}
+	
+	public static void enableAutobuild(boolean enable) throws CoreException {
+		// disable auto build
+		IWorkspace workspace= AntUITestPlugin.getWorkspace();
+		IWorkspaceDescription desc= workspace.getDescription();
+		desc.setAutoBuilding(enable);
+		workspace.setDescription(desc);
+	}
+	
+	public File getFileInPlugin(IPath path) {
+		try {
+			Bundle bundle = getDefault().getBundle();
+			URL installURL= new URL(bundle.getEntry("/"), path.toString());
+			URL localURL= FileLocator.toFileURL(installURL);
+			return new File(localURL.getFile());
+		} catch (IOException e) {
+			return null;
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/ConsoleLineTracker.java b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/ConsoleLineTracker.java
new file mode 100644
index 0000000..231cfc4
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/ConsoleLineTracker.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.testplugin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.ui.console.IConsole;
+import org.eclipse.debug.ui.console.IConsoleLineTrackerExtension;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * Simple console line tracker extension point that collects the lines
+ * appended to the console. 
+ */
+public class ConsoleLineTracker implements IConsoleLineTrackerExtension {
+	
+	private static IConsole console;
+	private static List lines= new ArrayList(); 
+	
+	private static boolean consoleClosed= true;
+
+	/**
+	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#dispose()
+	 */
+	public void dispose() {
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#init(org.eclipse.debug.ui.console.IConsole)
+	 */
+	public void init(IConsole c) {
+	    synchronized(lines) {
+	        ConsoleLineTracker.console= c;
+	        lines= new ArrayList();
+	        consoleClosed= false;
+	    }
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#lineAppended(org.eclipse.jface.text.IRegion)
+	 */
+	public void lineAppended(IRegion line) {
+		lines.add(line);
+	}
+	
+	public static int getNumberOfMessages() {
+		return lines.size();
+	}
+	
+	public static String getMessage(int index) {
+		if (index < lines.size()){
+			IRegion lineRegion= (IRegion)lines.get(index);
+			try {
+				return console.getDocument().get(lineRegion.getOffset(), lineRegion.getLength());
+			} catch (BadLocationException e) {
+				return null;
+			}
+		}
+		return null;
+	}
+	
+	public static List getAllMessages() {
+		List all= new ArrayList(lines.size());
+		for (int i = 0; i < lines.size(); i++) {
+			IRegion lineRegion= (IRegion)lines.get(i);
+			try {
+				all.add(console.getDocument().get(lineRegion.getOffset(), lineRegion.getLength()));
+			} catch (BadLocationException e) {
+				continue;
+			}
+		}
+		return all;
+	}
+	
+	public static IDocument getDocument() {
+		return console.getDocument();
+	}
+	
+	public static void waitForConsole() {
+		synchronized (lines) {
+			if (consoleClosed) {
+				return;
+			}
+			try {
+				lines.wait(20000);
+			} catch (InterruptedException ie) {
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.console.IConsoleLineTrackerExtension#consoleClosed()
+	 */
+	public void consoleClosed() {
+		synchronized (lines) {
+			consoleClosed= true;
+			lines.notifyAll();
+		}
+	}
+    
+    public static boolean isClosed() {
+        synchronized (lines) {
+            return consoleClosed;
+        }
+    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/DebugElementKindEventWaiter.java b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/DebugElementKindEventWaiter.java
new file mode 100644
index 0000000..094a32f
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/DebugElementKindEventWaiter.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.testplugin;
+
+import org.eclipse.debug.core.DebugEvent;
+
+/**
+ * Waits for a type of event on a kind of element.  Compare this to SpecificDebugElementEventWaiter which is
+ * used to wait for a type of event on a specific debug element object.
+ */
+
+public class DebugElementKindEventWaiter extends DebugEventWaiter {
+	
+	protected Class fElementClass;
+	
+	public DebugElementKindEventWaiter(int eventKind, Class elementClass) {
+		super(eventKind);
+		fElementClass = elementClass;
+	}
+	
+	public boolean accept(DebugEvent event) {
+		Object o = event.getSource();
+		return super.accept(event) && fElementClass.isInstance(o);
+	}
+
+}
+
+
diff --git a/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/DebugEventWaiter.java b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/DebugEventWaiter.java
new file mode 100644
index 0000000..0cd2a68
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/DebugEventWaiter.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.testplugin;
+
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IDebugEventSetListener;
+
+/**
+ * The <code>DebugEventWaiter</code> is
+ * to wait for a specific kind of debug event.
+ * <p>
+ * When a <code>DebugEventWaiter</code> is created, it
+ * registers itself with the <code>DebugPlugin</code> as
+ * an <code>IDebugEventSetListener</code>.
+ * <p>
+ * NOTE: <code>DebugEventWaiter</code> objects are intended for
+ * one time use only!
+ */
+public class DebugEventWaiter implements IDebugEventSetListener {
+	/**
+	 * The kind of event the waiter is waiting for
+	 */
+	protected int fEventType;
+
+	/**
+	 * The number of milliseconds the waiter will wait before timing out.
+	 */
+	protected long fTimeout;
+
+	/**
+	 * The <code>IDebugModelManager</code> this waiter is listening to.
+	 */
+	protected DebugPlugin fDebugPlugin;
+
+	/**
+	 * The <code>DebugEvent</code> received.
+	 */
+	protected DebugEvent fEvent;
+	
+	/**
+	 * The event set that was accepted
+	 */
+	protected DebugEvent[] fEventSet;
+
+	/**
+	 * The default timeout value if none is given (5000).
+	 */
+	public static final long DEFAULT_TIMEOUT= 5000;
+
+	/**
+	 * Creates a new <code>DebugEventWaiter</code> which
+	 * waits for events of a kind <code>eventType</code>.
+	 * The wait method will wait the default timeout value.
+	 */
+	public DebugEventWaiter(int eventType) {
+		fDebugPlugin= DebugPlugin.getDefault();
+		fEventType= eventType;
+		fTimeout= DEFAULT_TIMEOUT;
+
+		fDebugPlugin.addDebugEventListener(this);
+	}
+
+	/**
+	 * Answers true if the <code>DebugEvent</code> is acceptable.
+	 */
+	public boolean accept(DebugEvent event) {
+		return event.getKind() == fEventType && event.getDetail() != DebugEvent.EVALUATION_IMPLICIT;
+	}
+	/**
+	 * Answers the event name associated with the given flag.
+	 */
+	public String getEventName(int flag) {
+		switch (flag) {
+			case DebugEvent.CREATE :
+				return "Create";
+			case DebugEvent.TERMINATE :
+				return "Terminate";
+			case DebugEvent.RESUME :
+				return "Resume";
+			case DebugEvent.SUSPEND :
+				return "Suspend";
+			default :
+				return "UNKNOWN";
+		}
+	}
+
+	/**
+	 * Handles debug events.
+	 *
+	 * @see IDebugEventListener
+	 * @see #accept(DebugEvent)
+	 */
+	public synchronized void handleDebugEvents(DebugEvent[] events) {
+		//printReceived(events);
+		for (int i = 0; i < events.length; i++) {
+			if (accept(events[i])) {
+				fEvent= events[i];
+				fEventSet = events;
+				unregister();
+				notifyAll();
+				return;
+			}
+		}
+	}
+
+	/**
+	 * Prints a message indicating which event was received.
+	 */
+	protected void printReceived(DebugEvent[] events) {
+		for (int i = 0; i < events.length; i++) {
+			System.out.println(this +" got " + events[i]);
+		}
+	}
+
+	/**
+	 * Sets the number of milliseconds to wait for this callback
+	 */
+	public void setTimeout(long milliseconds) {
+		fTimeout= milliseconds;
+	}
+
+	/**
+	 * Unregisters this waiter as a listener
+	 */
+	public void unregister() {
+		fDebugPlugin.removeDebugEventListener(this);
+	}
+
+	/**
+	 * Returns the source of the accepted event, or <code>null</code>
+	 * if no event was accepted.
+	 */
+	public synchronized Object waitForEvent() {
+		if (fEvent == null) {
+			try {
+				wait(fTimeout);
+			} catch (InterruptedException ie) {
+				System.err.println("Interrupted waiting for event");
+			}
+		}
+		unregister();
+		if (fEvent == null)
+			return null;
+		return fEvent.getSource();
+	}
+
+	/**
+	 * Returns the accepted event, if any.
+	 */
+	public DebugEvent getEvent() {
+		return fEvent;
+	}
+	
+	/**
+	 * Returns the accepted event set, if any.
+	 */
+	public DebugEvent[] getEventSet() {
+		return fEventSet;
+	}	
+}
+
diff --git a/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/ProjectCreationDecorator.java b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/ProjectCreationDecorator.java
new file mode 100644
index 0000000..cc4a291
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/ProjectCreationDecorator.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.testplugin;
+
+
+
+/**
+ * Utility class
+ */
+public class ProjectCreationDecorator {
+	
+	private static boolean fgIsJ2SE15Compatible = false ;
+	
+	static {
+		String version = System.getProperty("java.specification.version");
+		if (version != null) {
+			String[] nums = version.split("\\.");
+			if (nums.length == 2) {
+				try {
+					int major = Integer.parseInt(nums[0]);
+					int minor = Integer.parseInt(nums[1]);
+					if (major >= 1) {
+						if (minor >= 5) {
+							fgIsJ2SE15Compatible = true;
+						}
+					}
+				} catch (NumberFormatException e) {
+				}
+			}
+		}
+	};
+	
+	/**
+	 * @return if the system property "java.specification.version" is 1.5 or greater
+	 */
+	public static boolean isJ2SE15Compatible() {
+		return fgIsJ2SE15Compatible;
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/ProjectHelper.java b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/ProjectHelper.java
new file mode 100644
index 0000000..2f0c7ba
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test plugin/org/eclipse/ant/tests/ui/testplugin/ProjectHelper.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.testplugin;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.launching.IAntLaunchConstants;
+import org.eclipse.core.externaltools.internal.IExternalToolConstants;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
+import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
+import org.eclipse.ui.wizards.datatransfer.ImportOperation;
+
+/**
+ * Helper methods to set up an IProject.
+ */
+public class ProjectHelper {
+	
+	public static final IPath TEST_BUILDFILES_DIR= new Path("testbuildfiles");
+	public static final IPath TEST_RESOURCES_DIR= new Path("testresources");	
+	public static final IPath TEST_LIB_DIR= new Path("testlib");
+	
+	public static final String PROJECT_NAME= "Ant UI Tests";
+	
+	/**
+	 * Creates a IProject.
+	 */	
+	public static IProject createProject(String projectName) throws CoreException {
+		IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
+		IProject project= root.getProject(projectName);
+		if (!project.exists()) {
+			project.create(null);
+		} else {
+			project.refreshLocal(IResource.DEPTH_INFINITE, null);
+		}
+		
+		if (!project.isOpen()) {
+			project.open(null);
+		}
+		
+		if (!project.hasNature(JavaCore.NATURE_ID)) {
+			addNatureToProject(project, JavaCore.NATURE_ID, null);
+		}
+		
+		return project;
+	}
+	
+	private static void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException {
+		IProjectDescription description = proj.getDescription();
+		String[] prevNatures= description.getNatureIds();
+		String[] newNatures= new String[prevNatures.length + 1];
+		System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
+		newNatures[prevNatures.length]= natureId;
+		description.setNatureIds(newNatures);
+		proj.setDescription(description, monitor);
+	}
+	
+	/**
+	 * Removes an IProject.
+	 */		
+	public static void delete(IProject project) throws CoreException {
+		project.delete(true, true, null);
+	}
+
+
+	/**
+	 * Adds a folder to an IProject.
+	 */		
+	public static IFolder addFolder(IProject project, String containerName) throws CoreException {
+		
+			IFolder folder= project.getFolder(containerName);
+			if (!folder.exists()) {
+				folder.create(false, true, null);
+			}
+		
+		return folder;
+		
+	}
+	
+	public static void importFilesFromDirectory(File rootDir, IPath destPath, IProgressMonitor monitor) throws InvocationTargetException, IOException {		
+		IImportStructureProvider structureProvider = FileSystemStructureProvider.INSTANCE;
+		List files = new ArrayList(100);
+		addFiles(rootDir, files);
+		try {
+			ImportOperation op= new ImportOperation(destPath, rootDir, structureProvider, new ImportOverwriteQuery(), files);
+			op.setCreateContainerStructure(false);
+			op.run(monitor);
+		} catch (InterruptedException e) {
+			// should not happen
+		}
+	}	
+	
+	private static void addFiles(File dir, List collection) throws IOException {
+		File[] files = dir.listFiles();
+		List subDirs = new ArrayList(2);
+		for (int i = 0; i < files.length; i++) {
+			if (files[i].isFile()) {
+				collection.add(files[i]);
+			} else if (files[i].isDirectory()) {
+				subDirs.add(files[i]);
+			}
+		}
+		Iterator iter = subDirs.iterator();
+		while (iter.hasNext()) {
+			File subDir = (File)iter.next();
+			addFiles(subDir, collection);
+		}
+	}
+	
+	private static class ImportOverwriteQuery implements IOverwriteQuery {
+		public String queryOverwrite(String file) {
+			return ALL;
+		}	
+	}
+
+	/**
+	 * Creates two launch configurations one standard one and one for a separate VM
+	 * @param launchConfigName
+	 * @throws Exception
+	 * 
+	 * @since 3.5
+	 */
+	public static void createLaunchConfigurationForBoth(String launchConfigName) throws Exception {
+		ProjectHelper.createLaunchConfiguration(launchConfigName);
+		ProjectHelper.createLaunchConfigurationForSeparateVM(launchConfigName + "SepVM", launchConfigName);
+	}
+
+	/**
+	 * Creates a shared launch configuration for launching Ant in a separate VM with the given
+	 * name.
+	 * 
+	 * @since 3.5
+	 */
+	public static void createLaunchConfigurationForSeparateVM(String launchConfigName, String buildFileName) throws Exception {
+		String bf = buildFileName;
+		ILaunchConfigurationType type = AbstractAntUITest.getLaunchManager().getLaunchConfigurationType(IAntLaunchConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE);
+		ILaunchConfigurationWorkingCopy config = type.newInstance(AbstractAntUITest.getJavaProject().getProject().getFolder("launchConfigurations"), launchConfigName);
+		
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, "org.eclipse.ant.internal.launching.remote.InternalAntRunner"); //$NON-NLS-1$
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, "org.eclipse.ant.ui.AntClasspathProvider"); //$NON-NLS-1$
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, AbstractAntUITest.getJavaProject().getElementName());
+		if (bf == null) {
+			bf= launchConfigName;
+		} 
+		config.setAttribute(IExternalToolConstants.ATTR_LOCATION, "${workspace_loc:/" + PROJECT_NAME + "/buildfiles/" + bf + ".xml}");
+		
+		config.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
+		config.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, IAntUIConstants.REMOTE_ANT_PROCESS_FACTORY_ID);
+		 
+		ProjectHelper.setVM(config);
+				
+		config.doSave();
+	}
+
+	/**
+	 * Sets the workspace default VM on the given working copy
+	 * @param config
+	 * 
+	 * @since 3.5
+	 */
+	public static void setVM(ILaunchConfigurationWorkingCopy config) {
+		IVMInstall vm = JavaRuntime.getDefaultVMInstall();
+		String vmName= vm.getName();
+		String vmTypeID= vm.getVMInstallType().getId();			
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME, vmName);
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE, vmTypeID);
+	}
+
+	/**
+	 * Creates a shared launch configuration for launching Ant in a separate VM with the given
+	 * name.
+	 */
+	public static void createLaunchConfiguration(String launchConfigName) throws Exception {
+	    ProjectHelper.createLaunchConfiguration(launchConfigName, PROJECT_NAME + "/buildfiles/" + launchConfigName + ".xml");
+	}
+
+	/**
+	 * Creates a launch configuration with the given name in the given location
+	 * @param launchConfigName
+	 * @param path
+	 * @return the handle to the new launch configuration
+	 * @throws CoreException
+	 */
+	public static ILaunchConfiguration createLaunchConfiguration(String launchConfigName, String path) throws CoreException {
+	    ILaunchConfigurationType type = AbstractAntUITest.getLaunchManager().getLaunchConfigurationType(IAntLaunchConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE);
+		ILaunchConfigurationWorkingCopy config = type.newInstance(AbstractAntUITest.getJavaProject().getProject().getFolder("launchConfigurations"), launchConfigName);
+	
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, AbstractAntUITest.getJavaProject().getElementName());
+		config.setAttribute(IExternalToolConstants.ATTR_LOCATION, "${workspace_loc:/" + path + "}");
+		config.setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
+			
+		config.doSave();
+		return config;
+	}			
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/inputHandlers/TestSWTInputHandler.java b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/inputHandlers/TestSWTInputHandler.java
new file mode 100644
index 0000000..9e388c4
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/inputHandlers/TestSWTInputHandler.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.support.inputHandlers;
+
+
+public class TestSWTInputHandler {//extends SWTInputHandler {
+	
+   
+//    /* (non-Javadoc)
+//     * @see org.eclipse.ant.internal.ui.antsupport.inputhandler.SWTInputHandler#open(java.lang.String, java.lang.String, boolean[])
+//     */
+//    protected void open(String title, String prompt, boolean[] result) {
+//        fRequest.setInput("TestSWTInputHandler");
+//        result[0]= true;
+//    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/tasks/AntTestTask.java b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/tasks/AntTestTask.java
new file mode 100644
index 0000000..958b0dc
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/tasks/AntTestTask.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.support.tasks;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Echo;
+
+
+public class AntTestTask extends Task {
+	
+	public AntTestTask() {
+		super();
+	}
+	
+	/**
+	 * @see org.apache.tools.ant.Task#execute()
+	 */
+	public void execute() throws BuildException {
+		Echo echo= new Echo();
+		echo.setProject(getProject());
+		echo.setMessage("Testing Ant in Eclipse with a custom task");
+		echo.execute();
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/tasks/AntTestTask2.java b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/tasks/AntTestTask2.java
new file mode 100644
index 0000000..42861c1
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/tasks/AntTestTask2.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.support.tasks;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Echo;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Reference;
+
+
+public class AntTestTask2 extends Task {
+	
+	String fMessage= "Default";
+	Reference fRef= null;
+	
+	public AntTestTask2() {
+		super();
+	}
+	
+	/**
+	 * @see org.apache.tools.ant.Task#execute()
+	 */
+	public void execute() throws BuildException {
+		Echo echo= new Echo();
+		echo.setProject(getProject());
+		echo.setMessage("Testing Ant in Eclipse with a custom task2: " + fMessage);
+		echo.execute();
+	}
+	
+    public void setMessage(Cool attr) {
+        fMessage = attr.getValue();
+    }
+    
+    public void setReference(Reference ref) {
+        fRef= ref;
+    }
+	
+	/**
+     * Enumerated attribute with the values "cool", "chillin" and "awesome".
+     */
+    public static class Cool extends EnumeratedAttribute {
+        public String[] getValues() {
+            return new String[] {"cool", "chillin", "awesome"};
+        }
+    }
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/tasks/NestElementTask.java b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/tasks/NestElementTask.java
new file mode 100644
index 0000000..f6a7119
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/tasks/NestElementTask.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.tests.ui.support.tasks;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Echo;
+
+public class NestElementTask extends Task {  
+	
+	String message= "bar";
+	NestedElement e;
+    public static class NestedElement{
+    	Boolean works= Boolean.FALSE;
+    	public NestedElement() {	
+    	}
+    	
+        public void setWorks(Boolean booleanValue) {
+        	works= booleanValue;
+        }
+
+		public boolean works() {
+			return works.booleanValue();
+		}
+    }
+    public void addNestedElement(NestedElement nestedElement) {
+    	e= nestedElement;
+    }
+   
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.Task#execute()
+	 */
+	public void execute() throws BuildException {
+		Echo echo= new Echo();
+		echo.setProject(getProject());
+		if (e.works()) {
+			echo.setMessage(message);
+		} else {
+			echo.setMessage("ack");
+		}
+		echo.execute();
+	}
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/types/AntTestPath.java b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/types/AntTestPath.java
new file mode 100644
index 0000000..ecd428c
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test support/org/eclipse/ant/tests/ui/support/types/AntTestPath.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.tests.ui.support.types;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+
+public class AntTestPath extends Path {
+	
+	String message;
+	
+	public AntTestPath(Project project) {
+		super(project);
+	}
+	
+	public void setMessage(String message) {
+		this.message= message;
+	}
+	
+	public String getMessage() {
+		return message;
+	}
+	
+}
diff --git a/ant/org.eclipse.ant.tests.ui/test.xml b/ant/org.eclipse.ant.tests.ui/test.xml
new file mode 100644
index 0000000..c6f1563
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/test.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+
+<project name="testsuite" default="run" basedir=".">
+  <!-- sets the properties eclipse-home, and library-file -->
+  <!-- The property ${eclipse-home} should be passed into this script -->
+  <!-- Set a meaningful default value for when it is not. -->
+  <property name="eclipse-home" value="${basedir}\..\.."/>
+<property name="plugin-name" value="org.eclipse.ant.tests.ui"/>
+  <property name="library-file"
+            value="${eclipse-home}/plugins/org.eclipse.test/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">
+    <property name="jdt-folder" 
+              value="${eclipse-home}/jdt_folder"/>
+    <delete dir="${jdt-folder}" quiet="true"/>
+    <ant target="ui-test" antfile="${library-file}" dir="${eclipse-home}">
+      <property name="data-dir" value="${jdt-folder}"/>
+      <property name="plugin-name" value="${plugin-name}"/>
+      <property name="classname" 
+                value="org.eclipse.ant.tests.ui.testplugin.AntUITests"/>
+    </ant>
+  </target>
+	
+ <!-- This target defines the performance tests that need to be run. -->
+	  <target name="perfsuite">
+	    <property name="jdt-folder" 
+	              value="${eclipse-home}/jdt_folder"/>
+	    <delete dir="${jdt-folder}" quiet="true"/>
+	    <ant target="ui-test" antfile="${library-file}" dir="${eclipse-home}">
+	      <property name="data-dir" value="${jdt-folder}"/>
+	      <property name="plugin-name" value="${plugin-name}"/>
+	      <property name="classname" 
+	                value="org.eclipse.ant.tests.ui.testplugin.AntUIPerformanceTests"/>
+	    </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>
+
+  <!--This target runs the performance test suites and collects results.-->
+  <target name="performance" depends="init, perfsuite, 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>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/102282.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/102282.xml
new file mode 100644
index 0000000..b2e13ee
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/102282.xml
@@ -0,0 +1,23 @@
+<!--
+     Copyright (c) 2005, 2006 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
+ -->
+<project name="project" default="default">
+    <target name="default" >
+        <antcall target="antCalled"></antcall>
+    </target>
+	<target name="antCalled">
+		<javac srcdir="src"
+	         destdir="dst"
+	         classpath="jarfile"
+	         debug="on"
+		/>
+	</target>
+</project>
+
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/74840.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/74840.xml
new file mode 100644
index 0000000..c61443f
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/74840.xml
@@ -0,0 +1,5 @@
+<project name="project" default="default">
+	<target name="default">
+		<echo>${platform.location}</echo>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/85769.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/85769.xml
new file mode 100644
index 0000000..eb62226
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/85769.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<project name="debugAntCall"
+         default="default">
+	
+	<target name="default">
+		<antcall target="call">
+		</antcall>
+		<echo>default</echo>
+	</target>
+
+	<target name="call" depends="pre-call">
+		<echo>call1</echo>
+		<sleep milliseconds="1500" />
+	</target>
+	
+	<target name="pre-call">
+		<echo>pre-call1</echo>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/89115.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/89115.xml
new file mode 100644
index 0000000..541648c
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/89115.xml
@@ -0,0 +1,9 @@
+<project name= "default" default="default">
+    <target description="depends" name="default" depends="depends">
+        
+    </target>
+
+    <target name="depends">
+    </target>
+
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/89901.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/89901.xml
new file mode 100644
index 0000000..ac3467c
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/89901.xml
@@ -0,0 +1,12 @@
+<project name="project" default="default">
+	
+    <target name="default" depends="test" description="--> description">
+        <property name="test" value="yo"/>
+    </target>
+
+	<target name="test">
+		<echo>${test}</echo>
+    </target>
+
+</project>
+
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/96022.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/96022.xml
new file mode 100644
index 0000000..ba44aa8
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/96022.xml
@@ -0,0 +1,31 @@
+<project name="debugAntCall"
+         default="default">
+	
+	<property name="hey" value="there"/>
+ 
+	<target name="default">
+		<antcall target="1">
+		</antcall>
+		<echo>default</echo>
+	</target>
+
+	<target name="1" depends="2">
+		<echo>1</echo>
+		<sleep milliseconds="5" />
+	</target>
+	
+	<target name="2">
+		<antcall target="3">
+				</antcall>
+		<echo>2</echo>
+	</target>
+	
+	<target name="3" depends="4">
+		<echo>3</echo>
+		<sleep milliseconds="5" />
+	</target>
+	
+	<target name="4">
+		<echo>4</echo>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/98853.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/98853.xml
new file mode 100644
index 0000000..c9c8fbd
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/98853.xml
@@ -0,0 +1,27 @@
+<project name="test"
+         default="run-macro"
+         xmlns:xyz="http://xyz">
+
+	<macrodef name="echo-macro"
+	          uri="http://xyz">
+		<attribute name="str" />
+		<element name="some-tasks" />
+		<sequential>
+			<echo>@{str}</echo>
+			<some-tasks/>
+		</sequential>
+	</macrodef>
+
+	<target name="run-macro">
+		
+		<xyz:echo-macro str="s">
+			
+		</xyz:echo-macro>
+	</target>
+	
+	<presetdef name="my-javac" uri="http://xyz">
+		<javac fork="yes"></javac>
+	</presetdef>
+	
+	
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/antUITestsSupport.jar b/ant/org.eclipse.ant.tests.ui/testbuildfiles/antUITestsSupport.jar
new file mode 100644
index 0000000..054eec8
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/antUITestsSupport.jar
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/bad.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/bad.xml
new file mode 100644
index 0000000..f1c4d51
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/bad.xml
@@ -0,0 +1,14 @@
+<project name="Echoing" default="echo1" basedir="..">
+
+	<target name="echo1">
+		<echo messge="echo1"/>
+	</target>
+	
+	<target name="echo2">
+		<echo message="echo2"/>
+	</target>
+	
+	<target name="echo3" description= "An echo3!">
+		<echo message="echo3"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/badproject.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/badproject.xml
new file mode 100644
index 0000000..60a79a8
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/badproject.xml
@@ -0,0 +1,4 @@
+<project ndefault="make">
+	<target name="make">
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/breakpoints.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/breakpoints.xml
new file mode 100644
index 0000000..bd6c382
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/breakpoints.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<project name="debugEcho" default="default">
+	<target name="default">
+		<echo>1</echo>
+		<echo>2</echo>
+		<property name="ZZZ" value="ZZZ" />
+		<sleep milliseconds="5" />
+		<echo>3</echo>
+		<echo>4</echo>
+		<echo>5</echo>
+		<echo>6</echo>
+		<echo>7</echo>
+		<echo>8</echo>
+		<echo>9</echo>
+		<!--<sleep milliseconds="200" />-->
+	</target>
+
+	<target name="entry1" depends="default">
+		<echo>1</echo>
+		<echo>2</echo>
+	</target>
+
+	<target name="entry2" depends="default">
+		<echo>1</echo>
+		<echo>2</echo>
+	</target>
+	
+	<target name="properties">
+		<property name="AAA" value="aaa" />
+		<property name="BBB" value="bbb" />
+		<property name="CCC" value="ccc" />
+		<echo>all done</echo>
+	</target>
+	
+	<property name="name" value="value"/>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/build.Cp1251.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/build.Cp1251.xml
new file mode 100644
index 0000000..6ff9539
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/build.Cp1251.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<project name="test" default="init" basedir=".">
+
+     <target name="init">
+          <!-- displays Hello in Russian -->
+          <echo message="Çäðàâñòâóéòå"/>
+     </target>
+
+
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/build.UTF8.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/build.UTF8.xml
new file mode 100644
index 0000000..08e4733
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/build.UTF8.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="test" default="init" basedir=".">
+
+     <target name="init">
+          <!-- displays Hello in Russian -->
+          <echo message="ЗдÑ€авÑ?Ñ‚вуйÑ‚е"/>
+     </target>
+
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/build.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/build.xml
new file mode 100644
index 0000000..5cdd64d
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/build.xml
@@ -0,0 +1,14 @@
+<project name="Echoing" default="echo1" basedir="..">
+
+	<target name="echo1">
+		<echo message="echo1"/>
+	</target>
+	
+	<target name="echo2">
+		<echo message="echo2"/>
+	</target>
+	
+	<target name="echo3" description= "An echo3!">
+		<echo message="echo3"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest1.properties b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest1.properties
new file mode 100644
index 0000000..a7c3ef1
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest1.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2004, 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
+###############################################################################
+prop1=val1
+prop2 = val2
+importFileName= toBeImported.xml
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest1.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest1.xml
new file mode 100644
index 0000000..9e042ff
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest1.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="testproject" basedir="." default="main">
+	<property name="propD" value="valD" />
+    <property file="buildtest1.properties" />
+    <property name="propV" value="valV" />
+    <target name="main">
+        <property name="property_in_target" value="val"/>
+        <echo>${</echo>
+    </target>
+	<target name="pretest"></target>
+	<target name="test" depends="">
+		<echo>depends</echo>
+	</target>
+	<target name="test2"></target>
+	<target name="test3"></target>
+	<target name="testIf" if=""></target>
+	<target name="testUnless" unless="prop"></target>
+	<target name="testMoreDepends" depends="pretest, ">
+		<echo message="$"></echo>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest2.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest2.xml
new file mode 100644
index 0000000..01e31c2
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest2.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="testproject" basedir="." default="main">
+	<property name="propD" value="valD" />
+	<property file="buildtest1.properties" />
+	<target name="main" depends="properties">
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest3.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest3.xml
new file mode 100644
index 0000000..7579dc4
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest3.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="testproject" basedir="." default="main">
+	<target name="main" />
+	<target name="pretest" description="description">
+	</target>
+    <target name="test" depends="">
+		<echo>depends</echo>
+	</target>
+	<target name="test2" />
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest4.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest4.xml
new file mode 100644
index 0000000..153b9f1
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/buildtest4.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project default="task3">
+    <target name="task" description=""/>
+    <target name="task2">
+        <antcall target=""></antcall>
+	</target>
+    <target name="task3" depends=""/>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/customBoolean.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/customBoolean.xml
new file mode 100644
index 0000000..1dd37a0
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/customBoolean.xml
@@ -0,0 +1,5 @@
+<project default="defaultTargetName">
+	<target name="defaultTargetName">
+		<eclipse.buildScript recursivegeneration=""/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/debugAntCall.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/debugAntCall.xml
new file mode 100644
index 0000000..868a486
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/debugAntCall.xml
@@ -0,0 +1,18 @@
+<project name="debugAntCall"
+         default="default">
+	
+	<target name="default">
+		<antcall target="call">
+		</antcall>
+		<echo>default</echo>
+	</target>
+
+	<target name="call" depends="pre-call">
+		<echo>call1</echo>
+		<sleep milliseconds="30" />
+	</target>
+	
+	<target name="pre-call">
+		<echo>pre-call1</echo>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/dependencytest.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/dependencytest.xml
new file mode 100644
index 0000000..d26ba57
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/dependencytest.xml
@@ -0,0 +1,38 @@
+<!-- Ein test case sollte die property proposals in main       -->
+<!-- Ueberpruefen, und ob die diversen properties entsprechend -->
+<!-- der dependencies gesetzt sind                             -->
+
+<project default="main">
+
+	<property name="do_init" value="val"></property>
+	
+	<target name="properties">
+		<property name="prop_prop" value="val"></property>
+		<property name="do_not_compile" value="val"></property>
+		<echo message="executing properties"></echo>
+	</target>
+
+	<!-- should never be executed since property is not set      --> 
+	<target name="additional_properties" if="do_addit_props">
+		<property name="adit_prop" value="val" />
+		<echo message="executing additional_properties"></echo>
+	</target>
+	
+	<target name="init" if="doinit" depends="properties,additional_properties">
+		<property name="init_prop" value="val"></property>
+		<echo message="executing init"></echo>
+	</target>
+	
+	<!-- should never be executed since property should be set   -->
+	<!-- by properties because of dependencies before            --> 
+	<target name="compile" unless="do_not_compile">
+		<property name="compile_prop" value="val"></property>
+		<echo message="executing compile"></echo>
+	</target>
+
+	<target name="main" depends="init, compile">
+		<property name="main_prop" value="val"></property>
+		<echo message="executing main ${well}"></echo>
+	</target>
+	
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/echoProperties.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/echoProperties.xml
new file mode 100644
index 0000000..6473c65
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/echoProperties.xml
@@ -0,0 +1,6 @@
+<project name="Echoing properties" default="echo1" basedir="..">
+	<target name="echo1">
+		<echo message="about to echo properties"/>
+		<echoproperties/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/echoing.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/echoing.xml
new file mode 100644
index 0000000..97b4984
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/echoing.xml
@@ -0,0 +1,19 @@
+<project name="Echoing" default="echo1" basedir="..">
+
+	<target name="echo1">
+		<echo message="echo1"/>
+	</target>
+	
+	<target name="echo2">
+		<echo message="echo2"/>
+	</target>
+	
+	<target name="echo3" description= "An echo3!">
+		<echo message="echo3"/>
+	</target>
+	
+	<target name="Bug42984">
+		<echo message="user.dir: ${user.dir}"/>
+	</target>
+	
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/empty.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/empty.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/empty.xml
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/environmentVar.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/environmentVar.xml
new file mode 100644
index 0000000..a884432
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/environmentVar.xml
@@ -0,0 +1,5 @@
+<project>
+	<property environment="env"/>
+	<echo>${env.ANT_HOME}</echo>
+	<echo>${ant.home}</echo>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/extensionPointSepVM.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/extensionPointSepVM.xml
new file mode 100644
index 0000000..2735ed0
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/extensionPointSepVM.xml
@@ -0,0 +1,14 @@
+<project name="Extension point testing in separate VM"
+         default="Extension Points"
+         basedir="."
+ >
+    <taskdef name="separateVMTask" classname="org.eclipse.ant.tests.ui.support.tasks.AntTestTask">
+    </taskdef>
+    <target name="Extension Points"
+            description= "Ensure that an extra classpath entry designated as not requiring the Eclipse runtime shows up in a separate VM build"
+     >
+        <separateVMTask/>
+         <echo>${property.ui.testing}</echo>
+        <echo>${property.ui.testing2}</echo>
+    </target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/extensionPointTaskSepVM.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/extensionPointTaskSepVM.xml
new file mode 100644
index 0000000..ec6c6aa
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/extensionPointTaskSepVM.xml
@@ -0,0 +1,6 @@
+<project name="Extension Point Task" default="Extension Point Task" basedir=".">
+	<target name="Extension Point Task" description= "Ensure that an extension point defined task is present">
+		<coolUITask message="cool" reference=""/>
+		<my:coolUITask xmlns:my="testing"/>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/extensionPointTypeSepVM.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/extensionPointTypeSepVM.xml
new file mode 100644
index 0000000..bba955e
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/extensionPointTypeSepVM.xml
@@ -0,0 +1,12 @@
+<project name="Extension Point Type" default="Extension Point Type" basedir=".">
+
+	<coolUIType id="compile.classpath">
+      <fileset dir="lib">
+        <include name="**/*.jar"/>
+      </fileset>
+    </coolUIType>
+    
+	<target name="Extension Point Type" description= "Ensure that an extension point defined type is present">
+		<echo message="Ensure that an extension point defined type is present"/>
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/failingTarget.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/failingTarget.xml
new file mode 100644
index 0000000..04418e0
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/failingTarget.xml
@@ -0,0 +1,9 @@
+<project default="all">
+	<target name="all" depends="fails, echos"/>
+	<target name="fails">
+		<jar jarfile="jar16.jar" basedir="doesNotExist"/>
+	</target>
+	<target name="echos">
+		<echo>Still echo on failure</echo>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_source01.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_source01.xml
new file mode 100644
index 0000000..2732a49
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_source01.xml
@@ -0,0 +1,24 @@
+<!--
+     Copyright (c) 2005, 2006 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
+ -->
+<project default="formatTest">
+
+<!-- = = = = = = --><!-- formatTest  --><!-- = = = = = = --><target name="formatTest" depends="init" description="--> test target one"><!-- hello world --><greeting /></target>
+
+<!-- - - - - - - -->
+<!-- init        -->
+<!-- - - - - - - -->
+<target name="init">
+  <property name="greeting" value="hi" />
+  <presetdef name="greeting"><echo>${greeting}</echo>
+</presetdef>
+   </target>
+
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_target01.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_target01.xml
new file mode 100644
index 0000000..e985e85
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_target01.xml
@@ -0,0 +1,31 @@
+<!--
+     Copyright (c) 2005, 2006 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
+ -->
+<project default="formatTest">
+
+   <!-- = = = = = = -->
+   <!-- formatTest  -->
+   <!-- = = = = = = -->
+   <target name="formatTest" depends="init" description="--> test target one">
+      <!-- hello world -->
+      <greeting />
+   </target>
+
+   <!-- - - - - - - -->
+   <!-- init        -->
+   <!-- - - - - - - -->
+   <target name="init">
+      <property name="greeting" value="hi" />
+      <presetdef name="greeting">
+         <echo>${greeting}</echo>
+      </presetdef>
+   </target>
+
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_target02.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_target02.xml
new file mode 100644
index 0000000..0798275
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_target02.xml
@@ -0,0 +1,31 @@
+<!--
+     Copyright (c) 2005, 2006 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
+ -->
+<project default="formatTest">
+
+       <!-- = = = = = = -->
+       <!-- formatTest  -->
+       <!-- = = = = = = -->
+       <target name="formatTest" depends="init" description="--> test target one">
+              <!-- hello world -->
+              <greeting />
+       </target>
+
+       <!-- - - - - - - -->
+       <!-- init        -->
+       <!-- - - - - - - -->
+       <target name="init">
+              <property name="greeting" value="hi" />
+              <presetdef name="greeting">
+                     <echo>${greeting}</echo>
+              </presetdef>
+       </target>
+
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_target03.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_target03.xml
new file mode 100644
index 0000000..9ad51b9
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/formatTest_target03.xml
@@ -0,0 +1,31 @@
+<!--
+     Copyright (c) 2005, 2006 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
+ -->
+<project default="formatTest">
+
+	<!-- = = = = = = -->
+	<!-- formatTest  -->
+	<!-- = = = = = = -->
+	<target name="formatTest" depends="init" description="--> test target one">
+		<!-- hello world -->
+		<greeting />
+	</target>
+
+	<!-- - - - - - - -->
+	<!-- init        -->
+	<!-- - - - - - - -->
+	<target name="init">
+		<property name="greeting" value="hi" />
+		<presetdef name="greeting">
+			<echo>${greeting}</echo>
+		</presetdef>
+	</target>
+
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/import.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/import.xml
new file mode 100644
index 0000000..fd75a81
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/import.xml
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/importRequiringUserProp.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/importRequiringUserProp.xml
new file mode 100644
index 0000000..18a1271
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/importRequiringUserProp.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<project name="importRequiringUserProperties" default="import-default">
+	<description>${importFileName to be defined as an argument, config property or in a config property file</description>
+	<import file="${importFileName}" />
+	<target name="one" depends="import-default">
+		<echo>one</echo>
+	</target>
+
+</project>
+
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/importWithByteOrderMark.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/importWithByteOrderMark.xml
new file mode 100644
index 0000000..f6862ae
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/importWithByteOrderMark.xml
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/input.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/input.xml
new file mode 100644
index 0000000..8d70ab5
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/input.xml
@@ -0,0 +1,7 @@
+<project name="input testing" default= "input test">
+	<target name="input test">
+		<input message="Enter for echo" addproperty= "inputTest">
+		</input>
+		<echo message="${inputTest}"/>
+	</target>	
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/internalTargets.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/internalTargets.xml
new file mode 100644
index 0000000..6411253
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/internalTargets.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="-default">
+	<target name="internal1">
+		<!-- internal because does it does not have description attribute -->
+	</target>
+	
+	<target name="-internal2" description="something">
+		<!-- internal because it has name starting with '-' -->
+	</target>
+
+	<target name="non-internal" description="something">
+		<!-- non internal because it has description attribute -->
+	</target>
+
+	<target name="-default" depends="internal1,-internal2,non-internal">
+		<!-- non-internal target because it is default target -->
+	</target>
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/javac.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/javac.xml
new file mode 100644
index 0000000..61e00c2
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/javac.xml
@@ -0,0 +1,7 @@
+<project default="javacIt">
+	<target name="javacIt">
+		<javac includejavaruntime=""
+			followsymlinks=""
+			includeantruntime=""/>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/macrodef.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/macrodef.xml
new file mode 100644
index 0000000..72e3733
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/macrodef.xml
@@ -0,0 +1,22 @@
+<project default="type">
+
+	<macrodef name="eclipseMacro">
+		<attribute name="v" default="NOT SET" />
+		<attribute name="eclipse" default="yes" description="Testing Eclipse"/>
+		<element name="some-tasks" optional="yes" />
+		<sequential>
+			<echo>Eclipse!: @{v}</echo>
+		</sequential>
+	</macrodef>
+
+	<target name="type">
+		<eclipseMacro v="This is v">
+			
+		</eclipseMacro>
+		<eclipseMacro v="This is v2"/>
+		<eclipseMacro v="This is v3"/>
+		<eclipseMacro v="This is v4"/>
+		<eclipseMacro/>
+	</target>
+
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/mixed.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/mixed.xml
new file mode 100644
index 0000000..368edbb
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/mixed.xml
@@ -0,0 +1 @@
+<project><target><sql driver="" password="" url="" userid=""></sql><concat></concat></target></project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/nestedElementAttributes.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/nestedElementAttributes.xml
new file mode 100644
index 0000000..3b0d919
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/nestedElementAttributes.xml
@@ -0,0 +1,8 @@
+<project default="go">
+	<taskdef name="nestedTest" classname="org.eclipse.ant.tests.ui.support.tasks.NestElementTask" />
+	<target name="go">
+		<nestedTest>
+			<nestedelement works="" />
+		</nestedTest>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/occurrencesTest.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/occurrencesTest.xml
new file mode 100644
index 0000000..fc8793b
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/occurrencesTest.xml
@@ -0,0 +1,49 @@
+<project name="default" default="default">
+	<description>
+            default
+    </description>
+	<property name="destBase" location="c:\temp\example" />
+	<property name="workspace" location="c:\eclipse3.1\dev" />
+	<property name="coreSource" location="${workspace}${destBase}
+\example.debug.core" />
+	<property name="uiSource" location="${workspace}\example.debug.ui" />
+
+	<target name="default" description="default">
+		
+    <macrodef name="process">
+        <attribute name="destdir"/>
+    	<attribute name="symbols"/>
+        <sequential>
+            <delete dir="@{destdir}"/>
+        	<mkdir dir="@{destdir}\example.debug.core"/>
+        	<mkdir dir="@{destdir}\example.debug.ui"/>
+        	<preprocess destdir="@{destdir}\example.debug.core" symbols="@
+{symbols}">
+        		<fileset dir="${coreSource}">
+        			<exclude name="**/*.class"/>
+        		</fileset>
+        	</preprocess>
+        	<preprocess destdir="@{destdir}\example.debug.ui" symbols="@
+{symbols}">
+        		<fileset dir="${uiSource}">
+        			<exclude name="**/*.class"/>
+        		</fileset>
+        	</preprocess>
+        </sequential>
+    </macrodef>
+
+	<process destdir="${destBase}\exercise1.1" symbols="ex1"/>
+	<process destdir="${destBase}\exercise2.1" symbols="ex2"/>		
+		
+		<property name="sameNameAsProp" value="hardToDistinguish"/>
+		
+<property name="extendsDestBase" value="${destBase}/extension"/>
+		<echo>${extendsDestBase}</echo>
+		
+		<ant target="default"></ant>
+		<antcall target="default"></antcall>
+	</target>
+	
+	<target name="sameNameAsProp" unless="extendsDestBase" if="destBase"></target>
+	<fail unless="destBase" message="Property not set."/>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/outline_select_test_build.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/outline_select_test_build.xml
new file mode 100644
index 0000000..7df0f5e
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/outline_select_test_build.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="org.eclipse.ui.externaltools.internal.ant.editor" default="zip.plugin" basedir=".">
+	<target name="init" depends="properties">
+	    <property file="build.properties" />
+		<property name="version.suffix" value="_0.4.5" />
+		<property name="plugins_dir" value="${eclipse_dir}/plugins" />
+		<property name="plugin" value="org.eclipse.ui.externaltools.internal.ant.editor" />
+		<property name="full.name" value="${plugin}${version.suffix}" />
+		<property name="temp.folder" value="${basedir}/temp.folder" />
+		<property name="plugin.destination" value="${basedir}" />
+		<property name="build.result.folder" value="${basedir}" />
+		<property name="source.antEditor.jar" value="src/" />
+		<echo message="Value is ${plugins_dir}" />
+	</target>
+
+	<target name="properties" if="eclipse.running">
+		<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+	</target>
+
+</project>
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/performance/build.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/performance/build.xml
new file mode 100644
index 0000000..8134903
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/performance/build.xml
@@ -0,0 +1,2360 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 1993-2003 SEAGULL -->
+<?xm-well_formed path = ""?>
+<!-- ===================================================================
+
+Build file for the Transidiom Java components: AIS, IDT, IFT, etc.
+
+Notes:
+
+   - This is a build file for use with the Jakarta Ant build tool.
+   - naming guidelines:
+     - For properties, the names are generally moduleName.propertyType, e.g. ais.files.
+     - For targets, the names are generally action.moduleName, e.g. compile.ais.
+
+Prerequisites:
+
+   jakarta-ant from http://jakarta.apache.org
+   A JAXP-compliant XSLT transformer.
+     - Xalan, from http://xml.apache.org.
+   A JAXP-compliant DOM parser.
+     - Xerces, from http://xml.apache.org.
+
+Main targets:
+
+ clean          Removes all the generated files and directories
+ clean.classes  Removes all .class files
+ compile        Compiles all the sources into ${build.classes}
+ dist           Creates the distribution in ${build.dist}
+ jars           Creates the jar files in ${build.lib}
+ nightly-build  Creates a nightly build (does it all)
+ test           Runs the tests.
+ test.compile   Compiles the unit tests without triggering any dependencies.
+ verify         Verifies the build by performing a load tests on jar files (does not trigger the jar dependencies.)
+ zip            Creates the final ${zip-file} (does it all)
+
+TODO:
+    Distinguish between compile and runtime classpath:
+    - component.classpath.compile
+    - component.classpath.rt
+
+Authors:
+
+  Lee Breisacher: lbreisacher@seagullsw.com
+  Gary Gregory: ggregory@seagullsw.com
+
+==================================================================== -->
+<project default="zip" basedir="." name="transidiom">
+    <!-- General properties -->
+    <property file="local-build.properties"/>
+    <property file="build.properties"/>
+    <property name="COMPANY.word" value="SEAGULL"/>
+    <property name="product.name" value="Application Interface Server"/>
+    <property name="Name" value="Application Interface Server"/>
+    <property name="src.root.dir" value=".."/>
+    <property name="binary.root.dir" value="${src.root.dir}/../../BinE"/>
+    <!-- UGLY!! This creates a dependency to the 'E' tree. Not sure how to solve it, though -->
+    <property name="src.dir" value="${src.root.dir}/Source"/>
+    <property name="java.resource.dir" value="${src.root.dir}/Resources"/>
+    <property name="xslt.resource.dir" value="../../Resources/XSLT"/>
+    <property name="fdef.dirname" value="config/functions"/>
+    <property name="root.dir" value="${src.root.dir}/Root"/>
+    <property name="root.dir.sys" value="${root.dir}/System"/>
+    <property name="root.dir.sysdef" value="${root.dir.sys}/Defaults"/>
+    <property name="root.dir.server" value="${root.dir}/server"/>
+    <property name="root.dir.server-config" value="${root.dir.server}/config"/>
+    <property name="root.dir.tools-config" value="${root.dir}/tools/config"/>
+    <property name="root.dir.mq" value="${root.dir}/mq"/>
+    <property name="root.dir.server-log" value="${root.dir.server-config}/log"/>
+    <property name="root.dir.server-transform" value="${root.dir.server-config}/transform"/>
+    <property name="root.dir.tools-log" value="${root.dir.tools-config}/log"/>
+    <property name="doc.dir" value="${src.root.dir}/Doc/Deliver"/>
+    <property name="test.dir" value="${src.root.dir}/Test"/>
+    <property name="src.test.dir" value="${test.dir}/Source"/>
+    <property name="build.dir" location="${basedir}/../buildoutput"/>
+    <property name="build.classes" value="${build.dir}/classes"/>
+    <property name="build.etc" value="${build.dir}/etc"/>
+    <property name="build.lib" value="${build.dir}/lib"/>
+    <property name="build.checksum" location="${build.lib}/checksum"/>
+    <property name="all-jars.xml" location="${build.checksum}/all-jars.xml"/>
+    <property name="build.dist" value="${build.dir}/dist"/>
+    <property name="zipFileBaseName" value="AppInterface"/>
+    <property name="thirdparty.dir" value="../../../../ThirdParty"/>
+    <property name="modifiedthirdparty.dir" value="../../ModifiedThirdParty"/>
+    <property name="sourcesafemirror.dir" value="../../SourceSafeMirror"/>
+    <property name="src.sourcesafemirror.dir" value="${sourcesafemirror.dir}/Java/Source"/>
+    <!-- 3rd party jar references -->
+    <property name="apache.dir" value="${thirdparty.dir}/apache.org"/>
+    <property name="xalan.dir" value="${apache.dir}/xalan-j/2.5.1/bin"/>
+    <property name="ant.jarname" value="ant.jar"/>
+    <property name="ant.jar" value="${apache.dir}/jakarta-ant/1.5.2/${ant.jarname}"/>
+    <property name="xerces.jarname" value="xercesImpl.jar"/>
+    <property name="xerces.jar" value="${xalan.dir}/${xerces.jarname}"/>
+    <property name="xalan.jarname" value="xalan.jar"/>
+    <property name="xalan.jar" value="${xalan.dir}/${xalan.jarname}"/>
+    <property name="xsltc.jarname" value="xsltc.jar"/>
+    <property name="xsltc.jar" value="${xalan.dir}/${xsltc.jarname}"/>
+    <property name="xml-apis.jarname" value="xml-apis.jar"/>
+    <property name="xml-apis.jar" value="${xalan.dir}/${xml-apis.jarname}"/>
+    <property name="soap.jarname" value="soap.jar"/>
+    <property name="soap.jar" value="${modifiedthirdparty.dir}/Soap/2.2/java/build/lib/${soap.jarname}"/>
+    <property name="mail.jarname" value="mailapi.jar"/>
+    <property name="mail.jar" value="${thirdparty.dir}/sun/JavaMail/1.3/lib/${mail.jarname}"/>
+    <property name="activation.jarname" value="activation.jar"/>
+    <property name="activation.jar" value="${thirdparty.dir}/sun/jaf/1.0.2/${activation.jarname}"/>
+    <property name="servlet.jarname" value="servlet.jar"/>
+    <property name="servlet.dir" value="${apache.dir}/jakarta-tomcat/3.2.1/ServletAPI/lib"/>
+    <property name="servlet.jar" value="${servlet.dir}/${servlet.jarname}"/>
+    <property name="commons-httpclient.jarname" value="commons-httpclient-2.0-rc2.jar"/>
+    <property name="commons-httpclient.dir" value="${apache.dir}/commons-httpclient/2.0-rc2"/>
+    <property name="commons-httpclient.jar" value="${commons-httpclient.dir}/${commons-httpclient.jarname}"/>
+    <property name="commons-logging.jarname" value="commons-logging.jar"/>
+    <property name="commons-logging.dir" value="${apache.dir}/commons-logging/1.0.3"/>
+    <property name="commons-logging.jar" value="${commons-logging.dir}/${commons-logging.jarname}"/>
+    <property name="ibm.mq.jarname" value="com.ibm.mq.jar"/>
+    <property name="ibm.mq.jar" value="${thirdparty.dir}/IBM/MQSeries/5.2.2/${ibm.mq.jarname}"/>
+    <property name="ibm.mqbind.jar" value="${thirdparty.dir}/IBM/MQSeries/5.2.2/com.ibm.mqbind.jar"/>
+    <property name="ibm.mqjms.jar" value="${thirdparty.dir}/IBM/MQSeries/5.2.2/com.ibm.mqjms.jar"/>
+    <property name="ibm.mq.connector.jar" value="${thirdparty.dir}/IBM/MQSeries/5.2.2/connector.jar"/>
+    <property name="ibm.mq.jta.jar" value="${thirdparty.dir}/IBM/MQSeries/5.2.2/jta.jar"/>
+    <property name="microsoftsecurityclasses.zip" value="${thirdparty.dir}/Microsoft/security/5.00.2922.0/MicrosoftSecurityClasses.zip"/>
+    <property name="commons-codec.jarname" value="commons-codec-1.1.1-dev.jar"/>
+    <property name="commons-codec.jar" value="${apache.dir}/commons-codec/20030516/${commons-codec.jarname}"/>
+    <property name="commons-collections.jarname" value="commons-collections-2_1.jar"/>
+    <property name="commons-collections.jar" value="${apache.dir}/commons-collections/2.1/${commons-collections.jarname}"/>
+    <property name="commons-cli.jarname" value="commons-cli-1_0.jar"/>
+    <property name="commons-cli.jar" value="${apache.dir}/commons-cli/1.0/${commons-cli.jarname}"/>
+    <property name="commons-lang.jarname" value="commons-lang-2.0.jar"/>
+    <property name="commons-lang.jar" value="${apache.dir}/commons-lang/2.0/${commons-lang.jarname}"/>
+    <property name="commons-pool.jarname" value="commons-pool.jar"/>
+    <property name="commons-pool.jar" value="${apache.dir}/commons-pool/20030429/${commons-pool.jarname}"/>
+    <property name="ctgclient.jarname" value="ctgclient.jar"/>
+    <property name="ctgclient.dir" value="${thirdparty.dir}/IBM/CICS Transaction Gateway/5.0"/>
+    <property name="ctgclient.jar" value="${ctgclient.dir}/${ctgclient.jarname}"/>
+    <property name="jakarta-oro.jarname" value="jakarta-oro-2.0.7.jar"/>
+    <property name="jakarta-oro.jar" value="${apache.dir}/jakarta-oro/2.0.7/${jakarta-oro.jarname}"/>
+    <property name="log4j.jarname" value="log4j-1_2_7.jar"/>
+    <property name="log4j.jar" value="${apache.dir}/jakarta-log4j/1.2.7/${log4j.jarname}"/>
+    <property name="goXMLEngine.jar" value="${thirdparty.dir}/XMLGlobal/GoXMLTransform/3_0_0/lib/engine.jar"/>
+    <property name="goXMLResource.zip" value="${thirdparty.dir}/XMLGlobal/GoXMLTransform/3_0_0/lib/resource.zip"/>
+    <property name="goXMLconfig.dir" value="${thirdparty.dir}/XMLGlobal/GoXMLTransform/3_0_0/config"/>
+    <!-- JDom beta 8 is not compatible with GoXMLTransform 3.0.0, use beta 7 from GoXMLTransform 3.0.0 -->
+    <property name="jdom.jarname" value="jdom.jar"/>
+    <property name="jdom.jar" value="${thirdparty.dir}/XMLGlobal/GoXMLTransform/3_0_0/lib/${jdom.jarname}"/>
+    <property name="jaxb1.jarname" value="jaxb-api.jar"/>
+    <property name="jaxb2.jarname" value="jaxb-impl.jar"/>
+    <property name="jaxb3.jarname" value="jaxb-libs.jar"/>
+    <property name="jaxb4.jarname" value="jax-qname.jar"/>
+    <property name="jaxb5.jarname" value="namespace.jar"/>
+    <property name="jaxb6.jarname" value="xsdlib.jar"/>
+    <property name="jaxb7.jarname" value="relaxngDatatype.jar"/>
+    <property name="jaxb.jarnames" value="${jaxb1.jarname} ${jaxb2.jarname} ${jaxb3.jarname} ${jaxb4.jarname} ${jaxb5.jarname} ${jaxb6.jarname} ${jaxb7.jarname} "/>
+    <property name="jwsdp.dir" value="${thirdparty.dir}/sun/jwsdp/1.2"/>
+    <property name="jaxb.dir" value="${jwsdp.dir}/jaxb/lib"/>
+    <property name="jaxb.shared.dir" value="${jwsdp.dir}/jwsdp-shared/lib"/>
+    <property name="jaxb1.jar" value="${jaxb.dir}/${jaxb1.jarname}"/>
+    <property name="jaxb2.jar" value="${jaxb.dir}/${jaxb2.jarname}"/>
+    <property name="jaxb3.jar" value="${jaxb.dir}/${jaxb3.jarname}"/>
+    <property name="jaxb4.jar" value="${jaxb.shared.dir}/${jaxb4.jarname}"/>
+    <property name="jaxb5.jar" value="${jaxb.shared.dir}/${jaxb5.jarname}"/>
+    <property name="jaxb6.jar" value="${jaxb.shared.dir}/${jaxb6.jarname}"/>
+    <property name="jaxb7.jar" value="${jaxb.shared.dir}/${jaxb7.jarname}"/>
+    <property name="jms.jarname" value="jms-1_0_2_b.jar"/>
+    <property name="jms.jar" value="${thirdparty.dir}/sun/jms/1.0.2b/${jms.jarname}"/>
+    <property name="jce.jarname" value="jce1_2_2.jar"/>
+    <property name="jce.jar" value="${thirdparty.dir}/sun/jce/1.2.2/lib/${jce.jarname}"/>
+    <property name="jce_provider.jarname" value="sunjce_provider.jar"/>
+    <property name="jce_provider.jar" value="${thirdparty.dir}/sun/jce/1.2.2/lib/${jce_provider.jarname}"/>
+    <property name="jcert.jarname" value="jcert.jar"/>
+    <property name="jnet.jarname" value="jnet.jar"/>
+    <property name="jsse.jarname" value="jsse.jar"/>
+    <property name="jsse.dir" value="${thirdparty.dir}/sun/jsse/1.0.3_02-gl/lib"/>
+    <property name="jcert.jar" value="${jsse.dir}/${jcert.jarname}"/>
+    <property name="jnet.jar" value="${jsse.dir}/${jnet.jarname}"/>
+    <property name="jsse.jar" value="${jsse.dir}/${jsse.jarname}"/>
+    <property name="jaas.jarname" value="jaas-1_0.jar"/>
+    <property name="jaas.jar" value="${thirdparty.dir}/sun/jaas/1.0/lib/${jaas.jarname}"/>
+    <property name="jta.jarname" value="jta-1_0_1B-classes.zip"/>
+    <property name="jta.jar" value="${thirdparty.dir}/sun/jta/jta-1_0_1b/${jta.jarname}"/>
+    <property name="concurrent.jarname" value="concurrent-1_3_2.jar"/>
+    <property name="concurrent.jar" value="${thirdparty.dir}/oswego.edu/util.concurrent/1.3.2/${concurrent.jarname}"/>
+    <property name="xmlsec.jar" value="${apache.dir}/xml-security/xml-security-1_0_4/build/xmlsec-1_0_4.jar"/>
+    <property name="imsico.jarname" value="imsico-1_2_5.jar"/>
+    <property name="imsico.jar" value="${thirdparty.dir}/IBM/IMSICO/1.2.5/${imsico.jarname}"/>
+    <property name="imsico-connector.jarname" value="imsico-connector-1_2_5.jar"/>
+    <property name="imsico-connector.jar" value="${thirdparty.dir}/IBM/IMSICO/1.2.5/${imsico-connector.jarname}"/>
+    <property name="junit.jar" value="${thirdparty.dir}/junit/3.8.1/junit.jar"/>
+    <property name="mtjunit.jar" value="${thirdparty.dir}/MTJUnit/1.0/MTJUnit-1.jar"/>
+    <property name="retroguard.jar" value="${thirdparty.dir}/Retroguard/1.1.13/retroguard.jar"/>
+    <property name="j2se.tools.jarname" value="tools.jar"/>
+    <property name="j2se.tools.jar" value="${thirdparty.dir}/sun/j2se/1.3.1_08/lib/${j2se.tools.jarname}"/>
+    <property name="obfuscate.script" value="${src.root.dir}/Build/obfuscate_hsc.rgs"/>
+    <property name="obfuscate.log" value="${build.lib}/obfuscate_hsc.log"/>
+    <property name="extension.dir.name" value="ext"/>
+    <property name="compile.debug" value="on"/>
+    <property name="compile.optimize" value="off"/>
+    <!-- These two will normally be set outside this file in the build.properties file. -->
+    <property name="version" value="2.3.X.WIP"/>
+    <property name="build.id" value="0"/>
+    <!-- Jar Manifest standard properties -->
+    <property name="manifest.key.main-class" value="Main-Class"/>
+    <property name="manifest.key.class-path" value="Class-Path"/>
+    <!-- Jar Manifest Seagull properties -->
+    <property name="manifest.key.product" value="${COMPANY.word}-Product"/>
+    <property name="manifest.key.component" value="${COMPANY.word}-Component"/>
+    <property name="manifest.key.version" value="${COMPANY.word}-Version"/>
+    <property name="manifest.key.build" value="${COMPANY.word}-Build"/>
+    <property name="manifest.key.build-ts" value="${COMPANY.word}-Build-Timestamp"/>
+    <!-- Javadoc -->
+    <property name="javadoc.j2se.link" value="http://java.sun.com/j2se/1.3/docs/api/"/>
+    <!-- Checksum -->
+    <property name="checksum.algorithm.md5" value="MD5"/>
+    <property name="checksum.algorithm.sha" value="SHA"/>
+    <!-- =================================================================== -->
+    <!-- Source files and class paths -->
+    <!-- =================================================================== -->
+    <!-- AIS -->
+    <patternset id="ais.files">
+        <include name="com/seagullsw/appinterface/server/**"/>
+        <include name="com/seagullsw/perftest/"/>
+        <exclude name="com/seagullsw/appinterface/server/backend/cics/"/>
+        <exclude name="com/seagullsw/appinterface/server/backend/cobol/"/>
+        <exclude name="com/seagullsw/appinterface/server/backend/ims/"/>
+        <exclude name="com/seagullsw/appinterface/server/backend/hostconnector/"/>
+        <exclude name="com/seagullsw/appinterface/server/backend/hostconnector2/"/>
+        <exclude name="com/seagullsw/appinterface/server/backend/hc5250/"/>
+        <exclude name="com/seagullsw/appinterface/server/backend/hc3270/"/>
+        <exclude name="com/seagullsw/appinterface/server/admin/"/>
+        <exclude name="com/seagullsw/appinterface/server/InvocationUnitTests.*"/>
+    </patternset>
+    <property name="ais-core.jarname" value="ais-core.jar"/>
+    <property name="ais-core.jar" value="${build.lib}/${ais-core.jarname}"/>
+    <path id="jaxb.classpath">
+        <pathelement location="${jaxb1.jar}"/>
+        <pathelement location="${jaxb2.jar}"/>
+        <pathelement location="${jaxb3.jar}"/>
+        <pathelement location="${jaxb4.jar}"/>
+        <pathelement location="${jaxb5.jar}"/>
+        <pathelement location="${jaxb6.jar}"/>
+        <pathelement location="${jaxb7.jar}"/>
+    </path>
+    <path id="jsse.classpath">
+        <pathelement location="${jcert.jar}"/>
+        <pathelement location="${jnet.jar}"/>
+        <pathelement location="${jsse.jar}"/>
+    </path>
+    <path id="jce.classpath.rt">
+        <pathelement location="${jce.jar}"/>
+        <pathelement location="${jce_provider.jar}"/>
+    </path>
+    <path id="ais.classpath">
+        <pathelement location="${ibm.mq.jar}"/>
+        <pathelement location="${ibm.mqbind.jar}"/>
+        <pathelement location="${ibm.mqjms.jar}"/>
+        <pathelement location="${xerces.jar}"/>
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${xalan.jar}"/>
+        <pathelement location="${soap.jar}"/>
+        <pathelement location="${mail.jar}"/>
+        <pathelement location="${commons-codec.jar}"/>
+        <pathelement location="${commons-collections.jar}"/>
+        <pathelement location="${commons-httpclient.jar}"/>
+        <pathelement location="${commons-lang.jar}"/>
+        <pathelement location="${commons-pool.jar}"/>
+        <pathelement location="${commons-cli.jar}"/>
+        <path refid="jaxb.classpath"/>
+        <pathelement location="${jms.jar}"/>
+        <pathelement location="${concurrent.jar}"/>
+        <pathelement location="${jce.jar}"/>
+    </path>
+    <path id="xml.classpath.compile">
+        <pathelement location="${xml-apis.jar}"/>
+    </path>
+    <path id="xml.classpath.rt">
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${xerces.jar}"/>
+        <pathelement location="${xalan.jar}"/>
+    </path>
+    <path id="transforms.classpath">
+        <pathelement location="${jakarta-oro.jar}"/>
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${xerces.jar}"/>
+        <pathelement location="${xalan.jar}"/>
+        <pathelement location="${goXMLEngine.jar}"/>
+        <path refid="jaxb.classpath"/>
+        <pathelement location="${commons-lang.jar}"/>
+    </path>
+    <path id="ais.client.classpath">
+        <pathelement location="${ibm.mq.jar}"/>
+        <pathelement location="${ibm.mqbind.jar}"/>
+        <pathelement location="${ibm.mqjms.jar}"/>
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${commons-collections.jar}"/>
+        <pathelement location="${commons-lang.jar}"/>
+        <pathelement location="${commons-pool.jar}"/>
+        <path refid="jaxb.classpath"/>
+        <pathelement location="${jms.jar}"/>
+    </path>
+    <!-- AppInterface Communications -->
+    <patternset id="appinterfacecomm.files">
+        <include name="com/seagullsw/appinterface/comm/"/>
+        <exclude name="com/seagullsw/appinterface/comm/servlet/*"/>
+    </patternset>
+    <!-- MTalk Communications -->
+    <patternset id="mtalkcomm.files">
+        <include name="com/seagullsw/net/client/mtalk/"/>
+    </patternset>
+    <!-- AppInterface Setting -->
+    <patternset id="appinterfacesettings.files">
+        <include name="com/seagullsw/appinterface/settings/*"/>
+    </patternset>
+    <path id="appinterfacesettings.classpath">
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${commons-lang.jar}"/>
+    </path>
+    <!-- AppInterface Server Settings -->
+    <patternset id="appinterfaceserversettings.files">
+        <include name="com/seagullsw/appinterface/server/settings/"/>
+    </patternset>
+    <!-- AppInterface Client -->
+    <patternset id="ais.client.files">
+        <include name="com/seagullsw/appinterface/client/"/>
+        <include name="com/seagullsw/toolbox/config/"/>
+        <include name="com/seagullsw/toolbox/xml/"/>
+        <include name="com/seagullsw/toolbox/log/"/>
+    </patternset>
+    <property name="ais.client.jarname" value="ais-client.jar"/>
+    <property name="ais.client.jar" value="${build.lib}/${ais.client.jarname}"/>
+    <!-- AppInterface Admin Client-->
+    <patternset id="ais.adminclient.files">
+        <include name="com/seagullsw/appinterface/server/admin/*"/>
+    </patternset>
+    <path id="ais.adminclient.classpath">
+        <pathelement location="${commons-lang.jar}"/>
+        <pathelement location="${commons-cli.jar}"/>
+    </path>
+    <property name="ais-adminclient.jarname" value="ais-admin-client.jar"/>
+    <property name="ais-adminclient.jar" value="${build.lib}/${ais-adminclient.jarname}"/>
+    <!-- AppInterface Models -->
+    <patternset id="appinterfacemodels.files">
+        <include name="com/seagullsw/appinterface/model/"/>
+        <exclude name="com/seagullsw/appinterface/model/cics/"/>
+        <exclude name="com/seagullsw/appinterface/model/cobol/"/>
+        <exclude name="com/seagullsw/appinterface/model/ims/"/>
+    </patternset>
+    <!-- Java Extensions -->
+    <patternset id="javaextensions.files">
+        <include name="com/seagullsw/debug/*"/>
+        <include name="com/seagullsw/javax/"/>
+        <exclude name="com/seagullsw/javax/swing/"/>
+    </patternset>
+    <path id="javaextensions.classpath">
+        <pathelement location="${commons-lang.jar}"/>
+    </path>
+    <!-- UIFacilities -->
+    <patternset id="uifacilities.files">
+        <include name="com/parcplace/pjava/Framer/"/>
+        <include name="com/seagullsw/javax/swing/SwingUtilitiesX.*"/>
+        <include name="com/seagullsw/javax/swing/JTextPaneX.*"/>
+        <include name="com/seagullsw/javax/swing/border/"/>
+        <include name="com/seagullsw/ui/"/>
+        <include name="com/seagullsw/debug/ui/"/>
+    </patternset>
+    <path id="uifacilities.classpath">
+        <pathelement location="${commons-lang.jar}"/>
+    </path>
+    <!-- XML Services -->
+    <patternset id="xmlservices.files">
+        <include name="com/seagullsw/io/xml/"/>
+    </patternset>
+    <path id="xmlservices.classpath">
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${xerces.jar}"/>
+    </path>
+    <!-- Transforms -->
+    <patternset id="transforms.files">
+        <include name="com/seagullsw/appinterface/transforms/"/>
+    </patternset>
+    <!-- Seagull Toolbox -->
+    <patternset id="seagulltoolbox.files">
+        <include name="com/seagullsw/toolbox/"/>
+    </patternset>
+    <path id="seagulltoolbox.classpath">
+        <path refid="xml.classpath.rt"/>
+        <path refid="jaxb.classpath"/>
+        <path refid="jsse.classpath"/>
+        <pathelement location="${commons-httpclient.jar}"/>
+        <pathelement location="${commons-lang.jar}"/>
+        <pathelement location="${commons-cli.jar}"/>
+    </path>
+    <!-- Win32 Interface -->
+    <patternset id="win32interface.files">
+        <include name="com/seagullsw/appinterface/win32/"/>
+    </patternset>
+    <!-- Proxy Servlet -->
+    <patternset id="proxyservlet.files">
+        <include name="com/seagullsw/appinterface/comm/servlet/"/>
+    </patternset>
+    <property name="proxyservlet.jarname" value="ais-servlet-proxy.jar"/>
+    <property name="proxyservlet.jar" value="${build.lib}/${proxyservlet.jarname}"/>
+    <path id="proxyservlet.classpath">
+        <pathelement location="${servlet.jar}"/>
+        <pathelement location="${xerces.jar}"/>
+    </path>
+    <!-- Admin Console -->
+    <patternset id="adminconsole.files">
+        <include name="com/seagullsw/appinterface/server/admin/client/"/>
+    </patternset>
+    <property name="adminconsole.jarname" value="ais-admin.jar"/>
+    <property name="adminconsole.jar" value="${build.lib}/${adminconsole.jarname}"/>
+    <!-- Java Connector Generator -->
+    <patternset id="javaconnectorgenerator.files">
+        <include name="com/seagullsw/appinterface/tools/javaconnectorgenerator/"/>
+    </patternset>
+    <property name="javaconnectorgenerator.jarname" value="JavaConnectorGenerator.jar"/>
+    <property name="javaconnectorgenerator.jar" value="${build.lib}/${javaconnectorgenerator.jarname}"/>
+    <!-- Security Toolkit -->
+    <patternset id="securitytoolkit.files">
+        <include name="com/seagullsw/appinterface/tools/security/"/>
+    </patternset>
+    <property name="securitytoolkit.jarname" value="SecurityToolkit.jar"/>
+    <property name="securitytoolkit.jar" value="${build.lib}/${securitytoolkit.jarname}"/>
+    <!-- Tools Framework -->
+    <patternset id="devtools.framework.files">
+        <include name="com/seagullsw/appinterface/tools/framework/"/>
+    </patternset>
+    <path id="devtools.framework.classpath">
+        <pathelement location="${commons-lang.jar}"/>
+    </path>
+    <!-- Dev Tools -->
+    <patternset id="devtools.files">
+        <include name="com/seagullsw/appinterface/tools/"/>
+        <exclude name="com/seagullsw/appinterface/tools/security/"/>
+    </patternset>
+    <path id="devtools.classpath">
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${soap.jar}"/>
+        <pathelement location="${commons-lang.jar}"/>
+        <pathelement location="${jce.jar}"/>
+    </path>
+    <property name="ais-tools.jarname" value="ais-tools.jar"/>
+    <property name="ais-tools.jar" value="${build.lib}/${ais-tools.jarname}"/>
+    <!-- JavaTools (e.g. invoking the Java compiler) -->
+    <patternset id="javatools.files">
+        <include name="com/seagullsw/javatools/"/>
+    </patternset>
+    <path id="javatools.classpath">
+        <pathelement location="${j2se.tools.jar}"/>
+        <pathelement location="${jce.jar}"/>
+        <path refid="jaxb.classpath"/>
+        <pathelement location="${commons-lang.jar}"/>
+    </path>
+    <!-- Backends -->
+    <patternset id="hcbackend.files">
+        <include name="com/seagullsw/appinterface/**/*hostconnector*/"/>
+        <include name="com/seagullsw/appinterface/server/backend/hsc/**"/>
+    </patternset>
+    <patternset id="cobol.files">
+        <include name="com/seagullsw/appinterface/server/backend/cobol/"/>
+        <include name="com/seagullsw/appinterface/model/cobol/"/>
+    </patternset>
+    <path id="cobol.classpath">
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${commons-lang.jar}"/>
+        <pathelement location="${commons-httpclient.jar}"/>
+    </path>
+    <patternset id="cics.files">
+        <include name="com/seagullsw/appinterface/server/backend/cics/"/>
+        <include name="com/seagullsw/appinterface/model/cics/"/>
+    </patternset>
+    <patternset id="ims.backend.files">
+        <include name="com/seagullsw/appinterface/server/backend/ims/"/>
+        <include name="com/seagullsw/appinterface/model/ims/"/>
+    </patternset>
+    <path id="cics.backend.classpath">
+        <pathelement location="${ctgclient.jar}"/>
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${xerces.jar}"/>
+        <path refid="jaxb.classpath"/>
+        <pathelement location="${jce.jar}"/>
+        <pathelement location="${commons-codec.jar}"/>
+        <pathelement location="${commons-lang.jar}"/>
+    </path>
+    <path id="ims.backend.classpath">
+        <pathelement location="${xml-apis.jar}"/>
+        <pathelement location="${jaas.jar}"/>
+        <pathelement location="${imsico.jar}"/>
+        <pathelement location="${imsico-connector.jar}"/>
+        <pathelement location="${jce.jar}"/>
+        <pathelement location="${jta.jar}"/>
+        <pathelement location="${commons-httpclient.jar}"/>
+        <path refid="jaxb.classpath"/>
+    </path>
+    <property name="ais-5250.jarname" value="ais-5250.jar"/>
+    <property name="ais-5250.jar" value="${build.lib}/${ais-5250.jarname}"/>
+    <property name="ais-3270.jarname" value="ais-3270.jar"/>
+    <property name="ais-3270.jar" value="${build.lib}/${ais-3270.jarname}"/>
+    <property name="ais-cobol.jarname" value="ais-cobol.jar"/>
+    <property name="ais-cobol.jar" value="${build.lib}/${ais-cobol.jarname}"/>
+    <property name="ais-cics.jarname" value="ais-cics.jar"/>
+    <property name="ais-cics.jar" value="${build.lib}/${ais-cics.jarname}"/>
+    <property name="ais-ims.jarname" value="ais-ims.jar"/>
+    <property name="ais-ims.jar" value="${build.lib}/${ais-ims.jarname}"/>
+    <property name="hsc.jarname" value="gwhsc.jar"/>
+    <property name="hsc.jar" value="${build.lib}/${hsc.jarname}"/>
+    <property name="hscu.jarname" value="gwhscu.jar"/>
+    <property name="hscu.jar" value="${build.lib}/${hscu.jarname}"/>
+    <!-- HSC -->
+    <patternset id="hsc.files">
+        <include name="com/seagullsw/gateway/"/>
+        <include name="com/seagullsw/net/"/>
+        <include name="com/seagullsw/security/"/>
+        <include name="com/seagullsw/system/"/>
+        <exclude name="com/seagullsw/net/client/mtalk/"/>
+    </patternset>
+    <!-- All the XSLT files -->
+    <fileset id="xslt.files" dir="${xslt.resource.dir}">
+        <include name="*.xsl"/>
+    </fileset>
+    <!-- All the AppInterface "base" classes -->
+    <fileset id="appinterface.base.files" dir="${build.classes}">
+        <patternset refid="appinterfacecomm.files"/>
+        <patternset refid="appinterfacemodels.files"/>
+        <patternset refid="javaextensions.files"/>
+        <patternset refid="xmlservices.files"/>
+        <patternset refid="mtalkcomm.files"/>
+    </fileset>
+    <!-- All the AppInterface "base" classes -->
+    <fileset id="appinterface.baseplus.files" dir="${build.classes}">
+        <!-- What I really want to do here is refer to the .base.files
+                        fileset, but ant doesn't allow nested filesets. Sigh.
+                        <fileset refid="appinterface.base.files"/> -->
+        <patternset refid="appinterfacecomm.files"/>
+        <patternset refid="appinterfacemodels.files"/>
+        <patternset refid="javaextensions.files"/>
+        <patternset refid="xmlservices.files"/>
+        <patternset refid="appinterfacesettings.files"/>
+        <patternset refid="uifacilities.files"/>
+        <patternset refid="seagulltoolbox.files"/>
+        <patternset refid="mtalkcomm.files"/>
+        <patternset refid="transforms.files"/>
+    </fileset>
+    <!-- =================================================================== -->
+    <!-- Set file copy filters -->
+    <!-- =================================================================== -->
+    <property name="text.copyright.1" value="(c) 1993 - 2003 Seagull Business Software Ireland Ltd."/>
+    <property name="text.copyright.2" value="All Rights Reserved."/>
+    <target name="init.filters">
+        <filter token="PRODUCT" value="${product.name}"/>
+        <filter token="VERSION" value="${version}"/>
+        <filter token="BUILDID" value="${build.id}"/>
+        <filter token="BUILDTIMESTAMP" value="${BuildTimeStamp}"/>
+        <filter token="COPYRIGHT-1" value="${text.copyright.1}"/>
+        <filter token="COPYRIGHT-2" value="${text.copyright.2}"/>
+    </target>
+    <!-- =================================================================== -->
+    <!-- Compiles -->
+    <!-- =================================================================== -->
+    <target name="compile" depends="compile.ais, compile.ais.client, compile.ais.adminclient, compile.devtools, compile.proxyservlet, compile.adminconsole, compile.javaconnectorgenerator, compile.securitytoolkit, compile.hcbackend, compile.cobol, compile.cics, compile.IMSbackend" description="Compiles all the sources into ${build.classes}"/>
+    <!-- doACompile - a compile "subroutine" -->
+    <target name="doACompile">
+        <javac srcdir="${src.dir}" destdir="${build.classes}" debug="${compile.debug}" optimize="${compile.optimize}" failonerror="true" includeAntRuntime="false">
+            <patternset refid="${doACompile.files}"/>
+        </javac>
+    </target>
+    <!-- doACompileWithClasspath - a compile "subroutine" -->
+    <target name="doACompileWithClasspath">
+        <javac srcdir="${src.dir}" destdir="${build.classes}" debug="${compile.debug}" optimize="${compile.optimize}" failonerror="true" includeAntRuntime="false">
+            <patternset refid="${doACompile.files}"/>
+            <classpath refid="${doACompile.classpath}"/>
+        </javac>
+    </target>
+    <!-- AIS -->
+    <target name="compile.ais" depends="compile.toolbox, compile.xmlservices, compile.transforms, compile.uifacilities, compile.appinterfacesettings, compile.appinterfacemodels, compile.appinterfacecomm, compile.hsc, compile.mtalkcomm">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="ais.files"/>
+            <param name="doACompile.classpath" value="ais.classpath"/>
+        </antcall>
+    </target>
+    <!-- AppInterface Models -->
+    <target name="compile.appinterfacemodels" depends="prepare, compile.xmlservices">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="appinterfacemodels.files"/>
+            <param name="doACompile.classpath" value="ais.classpath"/>
+        </antcall>
+    </target>
+    <!-- AppInterface Communications -->
+    <target name="compile.appinterfacecomm" depends="prepare">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="appinterfacecomm.files"/>
+            <param name="doACompile.classpath" value="ais.classpath"/>
+        </antcall>
+    </target>
+    <!-- MTalk Communication -->
+    <target name="compile.mtalkcomm" depends="prepare">
+        <antcall target="doACompile">
+            <param name="doACompile.files" value="mtalkcomm.files"/>
+        </antcall>
+    </target>
+    <!-- AppInterface Setting -->
+    <target name="compile.appinterfacesettings" depends="prepare">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="appinterfacesettings.files"/>
+            <param name="doACompile.classpath" value="appinterfacesettings.classpath"/>
+        </antcall>
+    </target>
+    <!-- UI Facilities -->
+    <target name="compile.uifacilities" depends="prepare">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="uifacilities.files"/>
+            <param name="doACompile.classpath" value="uifacilities.classpath"/>
+        </antcall>
+    </target>
+    <!-- Java Extensions -->
+    <target name="compile.javaextensions" depends="prepare">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="javaextensions.files"/>
+            <param name="doACompile.classpath" value="javaextensions.classpath"/>
+        </antcall>
+    </target>
+    <!-- XML Services -->
+    <target name="compile.xmlservices" depends="compile.javaextensions">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="xmlservices.files"/>
+            <param name="doACompile.classpath" value="xmlservices.classpath"/>
+        </antcall>
+    </target>
+    <!-- Transforms -->
+    <target name="compile.transforms" depends="compile.javaextensions">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="transforms.files"/>
+            <param name="doACompile.classpath" value="transforms.classpath"/>
+        </antcall>
+    </target>
+    <!-- Seagull Toolbox -->
+    <target name="compile.toolbox" depends="compile.javaextensions">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="seagulltoolbox.files"/>
+            <param name="doACompile.classpath" value="seagulltoolbox.classpath"/>
+        </antcall>
+    </target>
+    <!-- Win32 Interface -->
+    <target name="compile.win32interface" depends="prepare">
+        <antcall target="doACompile">
+            <param name="doACompile.files" value="win32interface.files"/>
+        </antcall>
+    </target>
+    <!-- AppInterface Client -->
+    <target name="compile.ais.client" depends="prepare, compile.xmlservices, compile.appinterfacecomm, compile.appinterfacemodels">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="ais.client.files"/>
+            <param name="doACompile.classpath" value="ais.client.classpath"/>
+        </antcall>
+    </target>
+    <!-- AppInterface Admin Client -->
+    <target name="compile.ais.adminclient" depends="prepare, compile.xmlservices, compile.appinterfacecomm, compile.appinterfacemodels, compile.ais.client">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="ais.adminclient.files"/>
+            <param name="doACompile.classpath" value="ais.classpath"/>
+        </antcall>
+    </target>
+    <!-- Proxy Servlet -->
+    <target name="compile.proxyservlet" depends="prepare">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="proxyservlet.files"/>
+            <param name="doACompile.classpath" value="proxyservlet.classpath"/>
+        </antcall>
+    </target>
+    <!-- Admin Console -->
+    <target name="compile.adminconsole" depends="prepare, compile.devtools.framework">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="adminconsole.files"/>
+            <param name="doACompile.classpath" value="ais.adminclient.classpath"/>
+        </antcall>
+    </target>
+    <!-- Java Connector Generator -->
+    <target name="compile.javaconnectorgenerator" depends="prepare, compile.devtools.framework, compile.appinterfacemodels, compile.javatools">
+        <antcall target="doACompile">
+            <param name="doACompile.files" value="javaconnectorgenerator.files"/>
+        </antcall>
+    </target>
+    <!-- Security Toolkit -->
+    <target name="compile.securitytoolkit" depends="prepare, compile.devtools.framework, compile.appinterfacemodels, compile.javatools">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="securitytoolkit.files"/>
+            <param name="doACompile.classpath" value="devtools.classpath"/>
+        </antcall>
+    </target>
+    <!-- Tools Framework -->
+    <target name="compile.devtools.framework" depends="prepare, compile.toolbox, compile.xmlservices, compile.uifacilities, compile.appinterfacesettings">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="devtools.framework.files"/>
+            <param name="doACompile.classpath" value="devtools.framework.classpath"/>
+        </antcall>
+    </target>
+    <!-- DevTools -->
+    <target name="compile.devtools" depends="prepare, compile.devtools.framework, compile.ais.client, compile.appinterfacemodels, compile.javatools">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="devtools.files"/>
+            <param name="doACompile.classpath" value="devtools.classpath"/>
+        </antcall>
+    </target>
+    <!-- JavaTools (e.g. invoking the Java compiler) -->
+    <target name="compile.javatools" depends="prepare">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="javatools.files"/>
+            <param name="doACompile.classpath" value="javatools.classpath"/>
+        </antcall>
+    </target>
+    <!-- Backends -->
+    <target name="compile.hcbackend" depends="prepare, compile.ais">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="hcbackend.files"/>
+            <param name="doACompile.classpath" value="ais.classpath"/>
+        </antcall>
+    </target>
+    <target name="compile.cobol" depends="prepare, compile.ais">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="cobol.files"/>
+            <param name="doACompile.classpath" value="cobol.classpath"/>
+        </antcall>
+    </target>
+    <target name="compile.cics" depends="prepare, compile.ais">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="cics.files"/>
+            <param name="doACompile.classpath" value="cics.backend.classpath"/>
+        </antcall>
+    </target>
+    <target name="compile.IMSbackend" depends="prepare, compile.ais">
+        <antcall target="doACompileWithClasspath">
+            <param name="doACompile.files" value="ims.backend.files"/>
+            <param name="doACompile.classpath" value="ims.backend.classpath"/>
+        </antcall>
+    </target>
+    <!-- HSC -->
+    <target name="compile.hsc" depends="prepare">
+        <javac srcdir="${src.sourcesafemirror.dir}" classpath="${microsoftsecurityclasses.zip}" destdir="${build.classes}" debug="${compile.debug}" includeAntRuntime="false">
+            <include name="com/seagullsw/"/>
+        </javac>
+    </target>
+    <!-- JavaDoc doclet -->
+    <target name="compile.doclet">
+        <javac srcdir="${src.dir}" destdir="${build.classes}" debug="${compile.debug}" includeAntRuntime="true">
+            <include name="com/seagullsw/internaldev/tools/apidoclet//"/>
+        </javac>
+    </target>
+    <!-- =================================================================== -->
+    <!-- Create jar files -->
+    <!-- =================================================================== -->
+    <target name="compute-checksum">
+        <checksum file="${file}" algorithm="${checksum.algorithm.md5}" property="cs_value"/>
+        <echo level="info" message="${checksum.algorithm.md5} -> ${cs_value}"/>
+        <mkdir dir="${build.checksum}"/>
+        <!-- Create a text file with the checksum value. -->
+        <concat destfile="${build.checksum}/${filename}.${checksum.algorithm.md5}.txt">${cs_value}</concat>
+        <!-- Create an XML file with the checksum value. -->
+        <concat destfile="${build.checksum}/${filename}.${checksum.algorithm.md5}.xml">&lt;?xml version="1.0"?>
+&lt;!-- Build auto-generated -->
+&lt;checksum file="${filename}" algorithm="${checksum.algorithm.md5}">${cs_value}&lt;/checksum></concat>
+        <xmlvalidate file="${build.checksum}/${filename}.${checksum.algorithm.md5}.xml" lenient="true"/>
+    </target>
+    <!-- Create all-jars.xml -->
+    <target name="create-all-jars.xml">
+        <!-- Create an XML file with the jar file names created. -->
+        <concat destfile="${all-jars.xml}">&lt;?xml version="1.0"?>
+&lt;!-- Build auto-generated -->
+&lt;jars>
+    &lt;jar>${ais-core.jarname}&lt;/jar>
+    &lt;jar>${ais.client.jarname}&lt;/jar>
+    &lt;jar>${ais-adminclient.jarname}&lt;/jar>
+    &lt;jar>${proxyservlet.jarname}&lt;/jar>
+    &lt;jar>${adminconsole.jarname}&lt;/jar>
+    &lt;jar>${javaconnectorgenerator.jarname}&lt;/jar>
+    &lt;jar>${securitytoolkit.jarname}&lt;/jar>
+    &lt;jar>${ais-tools.jarname}&lt;/jar>
+    &lt;jar>${ais-5250.jarname}&lt;/jar>
+    &lt;jar>${ais-3270.jarname}&lt;/jar>
+    &lt;jar>${ais-cobol.jarname}&lt;/jar>
+    &lt;jar>${ais-cics.jarname}&lt;/jar>
+    &lt;jar>${ais-ims.jarname}&lt;/jar>
+    &lt;jar>${hsc.jarname}&lt;/jar>
+    &lt;jar>${hscu.jarname}&lt;/jar>
+&lt;/jars>
+        </concat>
+        <echo level="info" message="Created ${all-jars.xml}"/>
+        <xmlvalidate file="${all-jars.xml}" lenient="true"/>
+    </target>
+    <!-- Copy checksum files to report dir -->
+    <target name="copy-checksums">
+        <antcall target="create-all-jars.xml"/>
+        <copy todir="${reports.checksum}">
+            <fileset dir="${build.checksum}"/>
+        </copy>
+    </target>
+    <target name="jars" depends="jar.ais-core, jar.ais.client, jar.ais.adminclient, jar.proxyservlet, jar.adminconsole, jar.javaconnectorgenerator, jar.securitytoolkit, jar.ais-tools, jar.ais-5250, jar.ais-3270, jar.ais-cobol, jar.ais-cics, jar.ais-ims, jar.hsc" description="Creates the jar files in ${build.lib}">
+        <antcall target="copy-checksums"/>
+    </target>
+    <target name="jar.ais-core" depends="init, compile.ais, createSplash.ais.splashscreens">
+        <mkdir dir="${build.lib}"/>
+        <jar jarfile="${ais-core.jar}" basedir="${build.classes}">
+            <patternset refid="ais.files"/>
+            <fileset refid="appinterface.baseplus.files"/>
+            <patternset>
+                <include name="com/seagullsw/javax/swing/"/>
+                <!-- Not sure why this isn't getting included as part of uifacilities.files via appinterface.baseplus.files. -->
+            </patternset>
+            <fileset refid="xslt.files"/>
+            <fileset dir="${java.resource.dir}">
+                <include name="com/seagullsw/appinterface/server/**"/>
+                <include name="com/seagullsw/appinterface/comm/**"/>
+                <exclude name="com/seagullsw/appinterface/server/admin/**"/>
+            </fileset>
+            <fileset dir="${src.dir}">
+                <include name="com/seagullsw/**/jaxb.properties"/>
+                <include name="com/seagullsw/**/bgm.ser"/>
+            </fileset>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.main-class}" value="com.seagullsw.appinterface.server.AppInterfaceServer"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-5250.jarname} ${ais-3270.jarname} ${ais-cobol.jarname} ${ais-cics.jarname} ${ais-ims.jarname} ${xalan.jarname} ${soap.jarname} ${activation.jarname} ${mail.jarname} ${commons-collections.jarname} ${commons-pool.jarname} ${xerces.jarname} ${xml-apis.jarname} ${commons-lang.jarname} ${commons-cli.jarname} ${jaxb.jarnames} ${jakarta-oro.jarname} ${concurrent.jarname} ${commons-httpclient.jarname} ${jms.jarname} ${extension.dir.name}/engine.jar ${extension.dir.name}/resource.zip ${extension.dir.name}/jdom.jar  ../${fdef.dirname}/ ../JavaConnectors/Classes/"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="AIS Core"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${ais-core.jar}"/>
+            <param name="filename" value="${ais-core.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.ais.client" depends="init, compile.ais.client">
+        <mkdir dir="${build.lib}"/>
+        <jar jarfile="${ais.client.jar}" basedir="${build.classes}">
+            <patternset refid="ais.client.files"/>
+            <fileset refid="appinterface.base.files"/>
+            <fileset dir="${src.dir}">
+                <include name="com/seagullsw/toolbox/config/**/jaxb.properties"/>
+                <include name="com/seagullsw/toolbox/config/**/bgm.ser"/>
+            </fileset>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.class-path}" value="${xerces.jarname} ${xml-apis.jarname} ${commons-lang.jarname} ${jaxb.jarnames} ${ibm.mq.jarname} ${jms.jarname} ${mail.jarname} ${soap.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="Java Client"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${ais.client.jar}"/>
+            <param name="filename" value="${ais.client.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.ais.adminclient" depends="init, compile.ais.adminclient">
+        <mkdir dir="${build.lib}"/>
+        <jar jarfile="${ais-adminclient.jar}" basedir="${build.classes}">
+            <patternset refid="ais.adminclient.files"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.class-path}" value="${ais.client.jarname} ${xerces.jarname} ${xml-apis.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="Java Admin Client"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${ais-adminclient.jar}"/>
+            <param name="filename" value="${ais-adminclient.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.proxyservlet" depends="init, compile.proxyservlet">
+        <mkdir dir="${build.lib}"/>
+        <jar jarfile="${proxyservlet.jar}" basedir="${build.classes}">
+            <patternset refid="proxyservlet.files"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.class-path}" value="${ais.client.jarname} ${servlet.jarname} ${xerces.jarname} ${xml-apis.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="Servlet Proxy"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${proxyservlet.jar}"/>
+            <param name="filename" value="${proxyservlet.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.adminconsole" depends="init, compile.adminconsole, createSplash.ais.splashscreens">
+        <mkdir dir="${build.lib}"/>
+        <!-- Copy "resource" files that go in the jar file. -->
+        <copy toDir="${build.classes}" preservelastmodified="true">
+            <fileset dir="${java.resource.dir}">
+                <include name="com/seagullsw/appinterface/server/admin/client/"/>
+                <include name="com/seagullsw/appinterface/server/*.jpg"/>
+            </fileset>
+        </copy>
+        <jar jarfile="${adminconsole.jar}" basedir="${build.classes}">
+            <patternset refid="adminconsole.files"/>
+            <patternset refid="devtools.framework.files"/>
+            <patternset refid="ais.client.files"/>
+            <patternset refid="appinterfaceserversettings.files"/>
+            <fileset refid="appinterface.baseplus.files"/>
+            <include name="com/seagullsw/appinterface/server/*.jpg"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.main-class}" value="com.seagullsw.appinterface.server.admin.client.AppInterfaceServerAdminUIClient"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-core.jarname} ${xerces.jarname} ${xml-apis.jarname} ${xalan.jarname} ${soap.jarname} ${activation.jarname} ${mail.jarname} ${commons-cli.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="Administrative Console"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${adminconsole.jar}"/>
+            <param name="filename" value="${adminconsole.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.javaconnectorgenerator" depends="init, compile.javaconnectorgenerator">
+        <mkdir dir="${build.lib}"/>
+        <!-- Copy "resource" files that go in the jar file. -->
+        <copy toDir="${build.classes}" preservelastmodified="true" filtering="true">
+            <fileset dir="${java.resource.dir}">
+                <include name="com/seagullsw/appinterface/tools/javaconnectorgenerator/"/>
+            </fileset>
+        </copy>
+        <jar jarfile="${javaconnectorgenerator.jar}" basedir="${build.classes}">
+            <patternset refid="javaconnectorgenerator.files"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.main-class}" value="com.seagullsw.appinterface.tools.javaconnectorgenerator.JavaConnectorGenerator"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-tools.jarname} ${xml-apis.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="Java Connector Generator"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${javaconnectorgenerator.jar}"/>
+            <param name="filename" value="${javaconnectorgenerator.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.securitytoolkit" depends="init, compile.securitytoolkit">
+        <mkdir dir="${build.lib}"/>
+        <!-- Copy "resource" files that go in the jar file. -->
+        <copy toDir="${build.classes}" preservelastmodified="true" filtering="true">
+            <fileset dir="${java.resource.dir}">
+                <include name="com/seagullsw/appinterface/tools/security/"/>
+            </fileset>
+        </copy>
+        <jar jarfile="${securitytoolkit.jar}" basedir="${build.classes}">
+            <patternset refid="securitytoolkit.files"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.main-class}" value="com.seagullsw.appinterface.tools.security.SecurityToolkit"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-core.jarname} ${ais-tools.jarname} ${xml-apis.jarname} ${commons-lang.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="Security Toolkit"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${securitytoolkit.jar}"/>
+            <param name="filename" value="${securitytoolkit.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.ais-tools" depends="init, compile.devtools, createSplash.tools.splashscreens, compile.win32interface, compile.javatools">
+        <mkdir dir="${build.lib}"/>
+        <!-- Copy "resource" files that go in the jar file. -->
+        <copy toDir="${build.classes}" preservelastmodified="true">
+            <fileset dir="${java.resource.dir}">
+                <include name="com/seagullsw/appinterface/**/*.gif"/>
+            </fileset>
+        </copy>
+        <jar jarfile="${ais-tools.jar}" basedir="${build.classes}">
+            <patternset refid="devtools.files"/>
+            <patternset refid="adminconsole.files"/>
+            <fileset refid="appinterface.baseplus.files"/>
+            <patternset>
+                <include name="com/seagullsw/appinterface/**/*settings*/"/>
+                <include name="com/seagullsw/javax/swing/"/>
+                <!-- Not sure why this isn't getting included as part of uifacilities.files via appinterface.baseplus.files. -->
+            </patternset>
+            <include name="com/seagullsw/appinterface/tools/images/*.jpg"/>
+            <include name="com/seagullsw/appinterface/**/*.gif"/>
+            <patternset refid="javatools.files"/>
+            <patternset refid="win32interface.files"/>
+            <patternset refid="ais.client.files"/>
+            <fileset refid="xslt.files"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.main-class}" value="com.seagullsw.appinterface.tools.serverdef.DefinitionTool"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-cobol.jarname} ${ais-cics.jarname} ${ais-ims.jarname} ${xerces.jarname} ${xml-apis.jarname} ${xalan.jarname} ${soap.jarname} ${activation.jarname} ${mail.jarname} ${jaxb.jarnames} ${commons-lang.jarname} ${extension.dir.name}/${j2se.tools.jarname} ${ais-tools.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="Tools"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${ais-tools.jar}"/>
+            <param name="filename" value="${ais-tools.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.ais-5250" depends="init, compile.hcbackend">
+        <mkdir dir="${build.lib}"/>
+        <jar jarfile="${ais-5250.jar}" basedir="${build.classes}">
+            <patternset refid="hcbackend.files"/>
+            <exclude name="com/seagullsw/appinterface/tools/"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-core.jarname} ${hsc.jarname} ${hscu.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="5250 Connector"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${ais-5250.jar}"/>
+            <param name="filename" value="${ais-5250.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.ais-3270" depends="init, compile.hcbackend">
+        <mkdir dir="${build.lib}"/>
+        <jar jarfile="${ais-3270.jar}" basedir="${build.classes}">
+            <patternset refid="hcbackend.files"/>
+            <exclude name="com/seagullsw/appinterface/tools/"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-core.jarname} ${hsc.jarname} ${hscu.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="3270 Connector"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${ais-3270.jar}"/>
+            <param name="filename" value="${ais-3270.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.ais-cobol" depends="init, compile.cobol">
+        <mkdir dir="${build.lib}"/>
+        <jar jarfile="${ais-cobol.jar}" basedir="${build.classes}">
+            <patternset refid="cobol.files"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-core.jarname} ${ais-cics.jarname} ${ais-ims.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="Cobol Connector"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${ais-cobol.jar}"/>
+            <param name="filename" value="${ais-cobol.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.ais-cics" depends="init, compile.cics">
+        <mkdir dir="${build.lib}"/>
+        <copy toDir="${build.classes}" preservelastmodified="true">
+            <fileset dir="${src.dir}">
+                <include name="com/seagullsw/**/jaxb.properties"/>
+                <include name="com/seagullsw/**/bgm.ser"/>
+            </fileset>
+        </copy>
+        <jar jarfile="${ais-cics.jar}" basedir="${build.classes}">
+            <patternset refid="cics.files"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-core.jarname} ${ais-cobol.jarname} ${extension.dir.name}/${ctgclient.jarname} ${commons-codec.jarname} ${commons-logging.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="CICS Connector"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${ais-cics.jar}"/>
+            <param name="filename" value="${ais-cics.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.ais-ims" depends="init, compile.IMSbackend">
+        <mkdir dir="${build.lib}"/>
+        <jar jarfile="${ais-ims.jar}" basedir="${build.classes}">
+            <patternset refid="ims.backend.files"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.class-path}" value="${ais-core.jarname} ${ais-cobol.jarname} ${imsico.jarname} ${imsico-connector.jarname} ${jaas.jarname} ${jta.jarname}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="IMS Connector"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${ais-ims.jar}"/>
+            <param name="filename" value="${ais-ims.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.hsc" depends="init, compile.hsc">
+        <mkdir dir="${build.lib}"/>
+        <jar jarfile="${hscu.jar}" basedir="${build.classes}">
+            <patternset refid="hsc.files"/>
+            <manifest>
+                <attribute name="Built-By" value="${user.name}"/>
+                <attribute name="${manifest.key.product}" value="${product.name}"/>
+                <attribute name="${manifest.key.component}" value="Host Session Connector"/>
+                <attribute name="${manifest.key.version}" value="${version}"/>
+                <attribute name="${manifest.key.build}" value="${build.id}"/>
+                <attribute name="${manifest.key.build-ts}" value="${BuildTimeStamp}"/>
+            </manifest>
+        </jar>
+        <antcall target="compute-checksum">
+            <param name="file" value="${hscu.jar}"/>
+            <param name="filename" value="${hscu.jarname}"/>
+        </antcall>
+        <echo level="info" message="Running RetroGuard..."/>
+        <java classname="RetroGuard" fork="yes">
+            <arg value="${hscu.jar}"/>
+            <arg value="${hsc.jar}"/>
+            <arg value="${obfuscate.script}"/>
+            <arg value="${obfuscate.log}"/>
+            <classpath>
+                <pathelement path="${retroguard.jar}"/>
+            </classpath>
+        </java>
+        <antcall target="compute-checksum">
+            <param name="file" value="${hsc.jar}"/>
+            <param name="filename" value="${hsc.jarname}"/>
+        </antcall>
+    </target>
+    <target name="jar.testbackend" depends="test.compile">
+        <jar jarfile="${build.lib}/ais-testbackend.jar" basedir="${test.bin}">
+            <include name="com/seagullsw/appinterface/server/backend/aistest/**"/>
+            <fileset dir="${src.test.dir}">
+                <include name="com/seagullsw/appinterface/server/backend/aistest/**/jaxb.properties"/>
+                <include name="com/seagullsw/appinterface/server/backend/aistest/**/bgm.ser"/>
+            </fileset>
+        </jar>
+    </target>
+    <!-- =================================================================== -->
+    <!-- Prepares the build directory -->
+    <!-- =================================================================== -->
+    <target name="prepare" depends="init">
+        <mkdir dir="${build.dir}"/>
+        <mkdir dir="${build.classes}"/>
+    </target>
+    <!-- =================================================================== -->
+    <!-- Cleans -->
+    <!-- =================================================================== -->
+    <target name="clean" description="Removes all the generated files and directories">
+        <delete dir="${build.dir}"/>
+    </target>
+    <target name="clean.jars">
+        <delete dir="${build.lib}"/>
+    </target>
+    <target name="clean.classes" description="Removes all .class files">
+        <delete dir="${build.classes}"/>
+    </target>
+    <!-- =================================================================== -->
+    <!-- Init -->
+    <!-- =================================================================== -->
+    <target name="init" depends="banner">
+        <tstamp>
+            <!-- The date/time patterns are as defined in the Java SimpleDateFormat class. -->
+            <format property="BuildTimeStamp" pattern="yyyy-MMMMM-dd HH:mm z"/>
+        </tstamp>
+        <filter token="PRODUCT" value="${product.name}"/>
+        <filter token="VERSION" value="${version}"/>
+        <filter token="BUILDID" value="${build.id}"/>
+        <filter token="BUILDTIMESTAMP" value="${BuildTimeStamp}"/>
+        <filter token="COPYRIGHT-1" value="${text.copyright.1}"/>
+        <filter token="COPYRIGHT-2" value="${text.copyright.2}"/>
+    </target>
+    <target name="banner" unless="banner-set">
+        <property name="logxsl-prop-sep" value="->"/>
+        <echo level="info" message="ant.file ${logxsl-prop-sep} ${ant.file}"/>
+        <echo level="info" message="ant.version ${logxsl-prop-sep} ${ant.version}"/>
+        <echo level="info" message="java.vm.version ${logxsl-prop-sep} ${ant.java.version}"/>
+        <echo level="info" message="java.version ${logxsl-prop-sep} ${java.version}"/>
+        <echo level="info" message="os.name ${logxsl-prop-sep} ${os.name}"/>
+        <echo level="info" message="Build ID: ${build.id}"/>
+        <property name="banner-set" value="true"/>
+    </target>
+    <!-- =================================================================== -->
+    <!-- Splash Screens -->
+    <!-- =================================================================== -->
+    <property name="internaldev.classes" value="${build.dir}/internaldev"/>
+    <property name="splash.src" value="${src.root.dir}/Build/splashscreen"/>
+    <property name="splash.dest" value="${build.dir}/splashscreens"/>
+    <property name="server.splashscreen.line-1" value="Application Interface Server"/>
+    <property name="tools.splashscreen.line-1" value="Transidiom Developer"/>
+    <!-- Task compile.splashScreenCreator -->
+    <target name="compile.splashScreenCreator">
+        <mkdir dir="${internaldev.classes}"/>
+        <javac srcdir="${src.test.dir}" destdir="${internaldev.classes}" debug="${compile.debug}">
+            <include name="com/seagullsw/internaldev/build/SplashscreenCreator.java"/>
+        </javac>
+    </target>
+    <!--
+             Run SplashscreenCreator program which takes a "vanilla" jpg plus
+             some text and creates a new "merged" jpg.
+             This is used by the createSplash.xxx.splashscreen targets.
+        -->
+    <target name="createSplash" depends="compile.splashScreenCreator">
+        <!--  java task: failonerror works only if fork is true -->
+        <java classname="com.seagullsw.internaldev.build.SplashscreenCreator" failonerror="true" fork="true">
+            <!-- <sysproperty key="com.seagullsw.debug" value="true"/>  -->
+            <sysproperty key="com.seagullsw.quiet" value="false"/>
+            <sysproperty key="com.seagullsw.x" value="8"/>
+            <sysproperty key="com.seagullsw.y" value="196"/>
+            <sysproperty key="com.seagullsw.fontsize" value="11"/>
+            <sysproperty key="com.seagullsw.sourceScreenFile" value="${createSplash.sourceScreenFile}"/>
+            <sysproperty key="com.seagullsw.targetScreenFile" value="${createSplash.targetScreenFile}"/>
+            <sysproperty key="com.seagullsw.screenTextFile" value="${createSplash.screenTextFile}"/>
+            <classpath>
+                <pathelement location="${internaldev.classes}"/>
+            </classpath>
+        </java>
+    </target>
+    <!-- Create AIS splashscreens -->
+    <target name="createSplash.ais.splashscreens" depends="init">
+        <filter token="SERVER.SPLASHSCREEN.LINE-1" value="${server.splashscreen.line-1}"/>
+        <!-- Line 2 is in the template and uses the Version, Build and Build date tokens. -->
+        <filter token="SERVER.SPLASHSCREEN.LINE-3" value="${text.copyright.1}"/>
+        <filter token="SERVER.SPLASHSCREEN.LINE-4" value="${text.copyright.2}"/>
+        <mkdir dir="${splash.dest}"/>
+        <copy file="${splash.src}/splashscreen-template-server.txt" tofile="${splash.dest}/splashscreen-server.txt" overwrite="true" filtering="true"/>
+        <antcall target="createSplash">
+            <param name="createSplash.sourceScreenFile" value="${splash.src}/BasicSplashScreen.jpg"/>
+            <param name="createSplash.screenTextFile" value="${splash.dest}/splashscreen-server.txt"/>
+            <param name="createSplash.targetScreenFile" value="${splash.dest}/ServerSplashScreen.jpg"/>
+        </antcall>
+        <!-- Copy the splash to the AIS and SAC class path -->
+        <copy file="${splash.dest}/ServerSplashScreen.jpg" tofile="${build.classes}/com/seagullsw/appinterface/server/ServerSessionSplashScreen.jpg" overwrite="yes"/>
+    </target>
+    <!-- Create Tools splashscreens -->
+    <target name="createSplash.tools.splashscreens" depends="init">
+        <filter token="TOOLS.SPLASHSCREEN.LINE-1" value="${tools.splashscreen.line-1}"/>
+        <!-- Line 2 is in the template and uses the Version, Build and Build date tokens. -->
+        <filter token="TOOLS.SPLASHSCREEN.LINE-3" value="${text.copyright.1}"/>
+        <filter token="TOOLS.SPLASHSCREEN.LINE-4" value="${text.copyright.2}"/>
+        <mkdir dir="${splash.dest}"/>
+        <copy file="${splash.src}/splashscreen-template-developer.txt" tofile="${splash.dest}/splashscreen-developer.txt" overwrite="true" filtering="true"/>
+        <antcall target="createSplash">
+            <param name="createSplash.sourceScreenFile" value="${splash.src}/BasicSplashScreen.jpg"/>
+            <param name="createSplash.screenTextFile" value="${splash.dest}/splashscreen-developer.txt"/>
+            <param name="createSplash.targetScreenFile" value="${splash.dest}/ToolSessionSplashScreen.jpg"/>
+        </antcall>
+        <!-- Copy the splash to the Tools class path -->
+        <copy file="${splash.dest}/ToolSessionSplashScreen.jpg" tofile="${build.classes}/com/seagullsw/appinterface/tools/images/ToolSessionSplashScreen.jpg" overwrite="yes"/>
+    </target>
+    <!-- =================================================================== -->
+    <!-- Javadoc for client API -->
+    <!-- =================================================================== -->
+    <target name="javadoc_check.ais.client">
+        <uptodate property="ais.client.javadoc.notrequired" targetfile="${ais.client.dist.javadoc}/packages.html">
+            <srcfiles dir="${src.dir}">
+                <patternset refid="ais.client.files"/>
+            </srcfiles>
+        </uptodate>
+    </target>
+    <target name="javadoc.ais.client" depends="prepare, javadoc_check.ais.client" unless="ais.client.javadoc.notrequired">
+        <delete dir="${ais.client.dist.javadoc}" includeEmptyDirs="true" quiet="true"/>
+        <mkdir dir="${ais.client.dist.javadoc}"/>
+        <property name="basic-header" value="${Name}&#x2122;, AIS Client"/>
+        <property name="header+version" value="${basic-header}, v${version}"/>
+        <property name="win-title" value="${header+version} API Specification"/>
+        <property name="doc-title" value="${header+version}&lt;br/&gt;API Specification"/>
+        <javadoc packagenames="com.seagullsw.appinterface.client, com.seagullsw.appinterface.client.java, com.seagullsw.appinterface.client.ibmmq, com.seagullsw.appinterface.comm.ibmmq" sourcepath="${src.dir}" destdir="${ais.client.dist.javadoc}" windowtitle="${win-title}" doctitle="${doc-title}" header="${basic-header}" bottom="&lt;font size=&quot;-1&quot;&gt;${Name} is a trademark or registered trademarks of Seagull Holding NV in the US and other countries.&lt;br/&gt;Copyright &#169; 1993 - 2003 Seagull Business Software Ireland Ltd. All Rights Reserved.&lt;/font&gt;" author="false" version="true" use="true">
+            <classpath>
+                <path refid="ais.classpath"/>
+            </classpath>
+            <!-- The following group elements do not seem to work. -->
+            <group title="Client" packages="com.seagullsw.appinterface.client, com.seagullsw.appinterface.client.java"/>
+            <group title="IBM MQ Series Client" packages="com.seagullsw.appinterface.client.ibmmq, com.seagullsw.appinterface.comm.ibmmq"/>
+            <link href="${javadoc.j2se.link}"/>
+        </javadoc>
+    </target>
+    <target name="javadoc_check.ais.adminclient">
+        <uptodate property="ais.adminclient.javadoc.notrequired" targetfile="${ais.adminclient.dist.javadoc}/packages.html">
+            <srcfiles dir="${src.dir}">
+                <patternset refid="ais.adminclient.files"/>
+            </srcfiles>
+        </uptodate>
+    </target>
+    <target name="javadoc.ais.adminclient" depends="prepare, javadoc_check.ais.adminclient" unless="ais.adminclient.javadoc.notrequired">
+        <delete dir="${ais.adminclient.dist.javadoc}" includeEmptyDirs="true" quiet="true"/>
+        <mkdir dir="${ais.adminclient.dist.javadoc}"/>
+        <property name="basic-header" value="${Name}&#x2122;, AIS Admin Client"/>
+        <property name="header+version" value="${basic-header}, v${version}"/>
+        <property name="win-title" value="${header+version} API Specification"/>
+        <property name="doc-title" value="${header+version}&lt;br/&gt;API Specification"/>
+        <javadoc packagenames="com.seagullsw.appinterface.server.admin" sourcepath="${src.dir}" destdir="${ais.adminclient.dist.javadoc}" windowtitle="${win-title}" doctitle="${doc-title}" header="${basic-header}" bottom="&lt;font size=&quot;-1&quot;&gt;${Name} is a trademark or registered trademarks of Seagull Holding NV in the US and other countries.&lt;br/&gt;Copyright &#169; 1993 - 2003 Seagull Business Software Ireland Ltd. All Rights Reserved.&lt;/font&gt;" author="false" version="true" use="true">
+            <classpath>
+                <path refid="ais.classpath"/>
+            </classpath>
+            <!-- The following group elements do not seem to work. -->
+            <group title="Client" packages="com.seagullsw.appinterface.server.admin"/>
+            <link href="${javadoc.j2se.link}"/>
+        </javadoc>
+    </target>
+    <!-- =================================================================== -->
+    <!-- Distribution targets -->
+    <!-- =================================================================== -->
+    <target name="dist" depends="dist.ais.core, dist.ais.client, dist.aisUNIX, dist.proxyservlet, dist.transidiomcentral, dist.devtools, dist.docs" description="Creates the distribution in ${build.dist}"/>
+    <property name="ais.dist" value="${build.dist}/server"/>
+    <property name="aisUNIX.dist" value="${build.dist}/server-UNIX"/>
+    <property name="ais.client.dist" value="${build.dist}/client/java"/>
+    <property name="proxyservlet.dist" value="${build.dist}/server/servlet"/>
+    <property name="devtools.dist" value="${build.dist}/tools"/>
+    <property name="transidiomcentral.dist" value="${build.dist}/TransidiomCentral"/>
+    <!-- copy 3rd party jar files - a dist "subroutine". -->
+    <!-- Common files to the AIS and Tools? GaryG 2003-04-03 -->
+    <target name="copy3rdPartyJars">
+        <copy file="${xerces.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${xml-apis.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${xalan.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${soap.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${activation.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${mail.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-collections.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-lang.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-codec.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-logging.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-httpclient.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-pool.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-cli.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jakarta-oro.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb1.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb2.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb3.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb4.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb5.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb6.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb7.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jms.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${concurrent.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaas.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${imsico.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${imsico-connector.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jta.jar}" todir="${copy3rdPartyJars.dist.lib}" preservelastmodified="true"/>
+    </target>
+    <!-- Java Client -->
+    <property name="ais.client.dist.javadoc" value="${ais.client.dist}/docs/api"/>
+    <property name="ais.client.dist.lib" value="${ais.client.dist}/lib"/>
+    <property name="ais.client.dist.mq" value="${ais.client.dist}/mq"/>
+    <property name="ais.adminclient.dist.javadoc" value="${ais.client.dist}/admin/docs/api"/>
+    <property name="ais.adminclient.dist.sfd" value="${ais.client.dist}/admin/sfd"/>
+    <!-- dist.ais.client -->
+    <target name="dist.ais.client" depends="jar.ais.client, jar.ais.adminclient, javadoc.ais.client, javadoc.ais.adminclient">
+        <mkdir dir="${ais.client.dist}"/>
+        <mkdir dir="${ais.client.dist.javadoc}"/>
+        <mkdir dir="${ais.client.dist.lib}"/>
+        <mkdir dir="${ais.client.dist.mq}"/>
+        <mkdir dir="${ais.adminclient.dist.javadoc}"/>
+        <mkdir dir="${ais.adminclient.dist.sfd}"/>
+        <copy file="${ais.client.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-adminclient.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${xerces.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${xml-apis.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-lang.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb1.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb2.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb3.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb4.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb5.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb6.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb7.jar}" todir="${ais.client.dist.lib}" preservelastmodified="true"/>
+        <copy file="${root.dir}/mq/MQClientConnection.properties" todir="${ais.client.dist.mq}" preservelastmodified="true"/>
+        <copy todir="${ais.adminclient.dist.sfd}" preservelastmodified="true">
+            <fileset dir="${src.root.dir}/ServerAdminFunctions/InterfaceSchemas"/>
+        </copy>
+    </target>
+    <!-- AIS -->
+    <property name="ais.dist.config" value="${ais.dist}/config"/>
+    <property name="ais.dist.config.copy" value="${ais.dist}/config-default"/>
+    <property name="ais.dist.log" value="${ais.dist.config}/log"/>
+    <property name="ais.dist.transform" value="${ais.dist.config}/transform"/>
+    <property name="ais.dist.lib" value="${ais.dist}/lib"/>
+    <property name="ais.dist.lib.ext" value="${ais.dist.lib}/${extension.dir.name}"/>
+    <property name="ais.dist.mq" value="${ais.dist}/mq"/>
+    <property name="ais.dist.sys" value="${ais.dist}/system"/>
+    <property name="ais.dist.sysdef" value="${ais.dist.sys}/defaults"/>
+    <property name="root.serverSettings" value="${root.dir}/AlternativeServerSettings"/>
+    <property name="root.toolSettings" value="${root.dir}/AlternativeToolSettings"/>
+    <!-- dist.ais.core -->
+    <target name="dist.ais.core" depends="init, jar.ais-core, jar.ais-tools, jar.ais-5250, jar.ais-3270, jar.ais-cobol, jar.ais-cics, jar.ais-ims, jar.hsc, jar.adminconsole, javadoc.openbackend">
+        <mkdir dir="${ais.dist}"/>
+        <mkdir dir="${ais.dist.lib}"/>
+        <mkdir dir="${ais.dist.lib.ext}"/>
+        <mkdir dir="${ais.dist.sys}"/>
+        <mkdir dir="${ais.dist.mq}"/>
+        <copy file="${ais-core.jar}" todir="${ais.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-5250.jar}" todir="${ais.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-3270.jar}" todir="${ais.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-cobol.jar}" todir="${ais.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-cics.jar}" todir="${ais.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-ims.jar}" todir="${ais.dist.lib}" preservelastmodified="true"/>
+        <copy file="${hsc.jar}" todir="${ais.dist.lib}" preservelastmodified="true"/>
+        <copy file="${adminconsole.jar}" todir="${ais.dist.lib}" preservelastmodified="true"/>
+        <antcall target="copy3rdPartyJars">
+            <param name="copy3rdPartyJars.dist.lib" value="${ais.dist.lib}"/>
+        </antcall>
+        <!-- For SCT -->
+        <copy file="${ais-tools.jar}" todir="${ais.dist.lib}" preservelastmodified="true"/>
+        <copy file="${root.dir}/ToolUserSettings.cfg" todir="${ais.dist}" filtering="true"/>
+        <copy file="${root.dir}/start-ais.bat" todir="${ais.dist}" preservelastmodified="true"/>
+        <copy file="${root.dir}/start-ais-mq.bat" todir="${ais.dist}" preservelastmodified="true"/>
+        <copy file="${root.dir}/stop-ais.bat" todir="${ais.dist}" preservelastmodified="true"/>
+        <copy file="${root.dir.server}/ServerSettings.cfg" todir="${ais.dist}" preservelastmodified="true"/>
+        <copy file="${root.dir}/ServerBackEndSettings.cfg" todir="${ais.dist}" preservelastmodified="true"/>
+        <copy file="${root.serverSettings}/ServerDebugSettings.cfg" todir="${ais.dist.sys}" filtering="true"/>
+        <copy file="${root.serverSettings}/ServerDeveloperSettings.cfg" todir="${ais.dist.sys}" filtering="true"/>
+        <copy file="${root.serverSettings}/ServerInstallationSettings.cfg" todir="${ais.dist.sys}" filtering="true"/>
+        <copy file="${root.dir.sys}/ToolDebugSettings.cfg" todir="${ais.dist.sys}" filtering="true"/>
+        <copy todir="${ais.dist.sys}/AdminFunctionDefinitions" preservelastmodified="true">
+            <fileset dir="${src.root.dir}/ServerAdminFunctions/MappingSchemas"/>
+        </copy>
+        <copy todir="${ais.dist.transform}" preservelastmodified="true">
+            <fileset dir="${root.dir.server-transform}"/>
+        </copy>
+        <copy todir="${ais.dist.config}/comm" preservelastmodified="true">
+            <fileset dir="${root.dir.server-config}/comm"/>
+        </copy>
+        <copy todir="${ais.dist.config.copy}" preservelastmodified="true">
+            <fileset dir="${ais.dist.config}"/>
+        </copy>
+        <copy file="${root.dir.server-log}/log-category.properties" todir="${ais.dist.log}" preservelastmodified="true"/>
+        <copy file="${root.dir.server-log}/log-style.properties" todir="${ais.dist.log}" preservelastmodified="true"/>
+        <!-- Tools files -->
+        <copy file="${root.toolSettings}/ToolInstallationSettings-All.cfg" tofile="${ais.dist.sys}/ToolInstallationSettings.cfg" filtering="true"/>
+        <copy file="${root.toolSettings}/SCTToolInstallationSettings-HC.cfg" todir="${ais.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/SCTToolInstallationSettings-HC3270Only.cfg" todir="${ais.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/SCTToolInstallationSettings-HC5250Only.cfg" todir="${ais.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/SCTToolInstallationSettings-CICSOnly.cfg" todir="${ais.dist.sys}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/AppInterfaceTester-DefaultSettings.cfg" todir="${ais.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ClientControlled3270ServerSettings-DefaultSettings.cfg" todir="${ais.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ClientControlled5250ServerSettings-DefaultSettings.cfg" todir="${ais.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/DefinitionTool-DefaultSettings.cfg" todir="${ais.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/SEAGULLProject.dir" todir="${ais.dist.sysdef}"/>
+        <copy file="${root.dir.sysdef}/ServerControlled3270ServerSettings-DefaultSettings.cfg" todir="${ais.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ServerControlled5250ServerSettings-DefaultSettings.cfg" todir="${ais.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ServerOptions-DefaultSettings.cfg" todir="${ais.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ServerSettings-Skeleton.cfg" todir="${ais.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/WorkingSetSettings.cfg" todir="${ais.dist.sysdef}" filtering="true"/>
+        <!-- Java Connectors -->
+        <mkdir dir="${ais.dist}/JavaConnectors/Classes"/>
+    </target>
+    <!-- AIS UNIX-specific -->
+    <property name="aisUNIX.dist.config" value="${aisUNIX.dist}/config"/>
+    <property name="aisUNIX.dist.log" value="${aisUNIX.dist.config}/log"/>
+    <property name="aisUNIX.dist.lib" value="${aisUNIX.dist}/lib"/>
+    <property name="aisUNIX.dist.mq" value="${aisUNIX.dist}/mq"/>
+    <property name="aisUNIX.dist.sys" value="${aisUNIX.dist}/system"/>
+    <target name="dist.aisUNIX" depends="init, dist.ais.core, jar.adminconsole">
+        <mkdir dir="${aisUNIX.dist}"/>
+        <mkdir dir="${aisUNIX.dist.lib}"/>
+        <mkdir dir="${aisUNIX.dist.sys}"/>
+        <mkdir dir="${aisUNIX.dist.mq}"/>
+        <copy file="${ais-core.jar}" todir="${aisUNIX.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-5250.jar}" todir="${aisUNIX.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-3270.jar}" todir="${aisUNIX.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-cobol.jar}" todir="${aisUNIX.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-cics.jar}" todir="${aisUNIX.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-ims.jar}" todir="${aisUNIX.dist.lib}" preservelastmodified="true"/>
+        <copy file="${adminconsole.jar}" todir="${aisUNIX.dist.lib}" preservelastmodified="true"/>
+        <copy file="${hsc.jar}" todir="${aisUNIX.dist.lib}" preservelastmodified="true"/>
+        <antcall target="copy3rdPartyJars">
+            <param name="copy3rdPartyJars.dist.lib" value="${aisUNIX.dist.lib}"/>
+        </antcall>
+        <copy file="${root.dir}/UNIXServerFiles/start-ais.sh" todir="${aisUNIX.dist}" preservelastmodified="true"/>
+        <copy file="${root.dir}/UNIXServerFiles/start-ais-mq.sh" todir="${aisUNIX.dist}" preservelastmodified="true"/>
+        <copy file="${root.dir}/UNIXServerFiles/stop-ais.sh" todir="${aisUNIX.dist}" preservelastmodified="true"/>
+        <copy file="${root.dir.server}/ServerSettings.cfg" todir="${aisUNIX.dist}" preservelastmodified="true"/>
+        <copy file="${root.dir}/ServerBackEndSettings.cfg" todir="${aisUNIX.dist}" preservelastmodified="true"/>
+        <copy file="${root.serverSettings}/ServerDebugSettings.cfg" todir="${aisUNIX.dist.sys}" filtering="true"/>
+        <copy file="${root.dir}/UNIXServerFiles/ServerInstallationSettings.cfg" todir="${aisUNIX.dist.sys}" filtering="true"/>
+        <copy todir="${aisUNIX.dist.sys}/AdminFunctionDefinitions" preservelastmodified="true">
+            <fileset dir="${src.root.dir}/ServerAdminFunctions/MappingSchemas"/>
+        </copy>
+        <copy todir="${aisUNIX.dist}/config/transform" preservelastmodified="true">
+            <fileset dir="${root.dir}/server/config/transform"/>
+        </copy>
+        <copy file="${root.dir.server-log}/log-category.properties" todir="${aisUNIX.dist.log}"/>
+        <copy file="${root.dir.server-log}/log-style.properties" todir="${aisUNIX.dist.log}"/>
+    </target>
+    <!-- Proxy Servlet -->
+    <property name="proxyservlet.dist.lib" value="${proxyservlet.dist}/lib"/>
+    <target name="dist.proxyservlet" depends="jar.proxyservlet, jar.ais.client">
+        <copy file="${proxyservlet.jar}" todir="${proxyservlet.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais.client.jar}" todir="${proxyservlet.dist.lib}" preservelastmodified="true"/>
+        <copy file="${xerces.jar}" todir="${proxyservlet.dist.lib}" preservelastmodified="true"/>
+        <copy file="${xml-apis.jar}" todir="${proxyservlet.dist.lib}" preservelastmodified="true"/>
+        <copy file="${root.dir}/ServletConfigFiles/AISProxyServletReadme.txt" todir="${proxyservlet.dist}" preservelastmodified="true"/>
+        <copy file="${root.dir}/ServletConfigFiles/web.xml" todir="${proxyservlet.dist}" preservelastmodified="true"/>
+        <copy file="${doc.dir}/Transidiom HTTPS Support.doc" todir="${proxyservlet.dist}" preservelastmodified="true"/>
+        <copy file="${doc.dir}/Transidiom HTTP Requests Redirection on IIS.doc" todir="${proxyservlet.dist}" preservelastmodified="true"/>
+    </target>
+    <!-- DevTools -->
+    <property name="devtools.dist.config" value="${devtools.dist}/config"/>
+    <property name="devtools.dist.log" value="${devtools.dist.config}/log"/>
+    <property name="devtools.dist.lib" value="${devtools.dist}/lib"/>
+    <property name="devtools.dist.sys" value="${devtools.dist}/system"/>
+    <property name="devtools.dist.sysdef" value="${devtools.dist.sys}/defaults"/>
+    <target name="dist.devtools" depends="init, jar.ais-core, jar.ais-tools">
+        <mkdir dir="${devtools.dist}"/>
+        <mkdir dir="${devtools.dist.lib}"/>
+        <mkdir dir="${devtools.dist.sys}"/>
+        <mkdir dir="${devtools.dist.sysdef}"/>
+        <mkdir dir="${devtools.dist.log}"/>
+        <copy file="${ais-tools.jar}" todir="${devtools.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-core.jar}" todir="${devtools.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-5250.jar}" todir="${devtools.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-3270.jar}" todir="${devtools.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-cobol.jar}" todir="${devtools.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-cics.jar}" todir="${devtools.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-ims.jar}" todir="${devtools.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais.client.jar}" todir="${devtools.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-adminclient.jar}" todir="${devtools.dist.lib}" preservelastmodified="true"/>
+        <antcall target="copy3rdPartyJars">
+            <param name="copy3rdPartyJars.dist.lib" value="${devtools.dist.lib}"/>
+        </antcall>
+        <!-- Root -->
+        <copy file="${root.dir}/Direct Publish.bat" todir="${devtools.dist}"/>
+        <copy file="${root.dir}/DirectPublish.args" todir="${devtools.dist}"/>
+        <copy file="${root.dir}/Interface Definition Tool.bat" todir="${devtools.dist}"/>
+        <copy file="${root.dir}/CICS Connector Builder.bat" todir="${devtools.dist}"/>
+        <copy file="${root.dir}/IMS Connector Builder.bat" todir="${devtools.dist}"/>
+        <copy file="${root.dir}/Interface Function Tester.bat" todir="${devtools.dist}"/>
+        <copy file="${root.dir}/ToolUserSettings.cfg" todir="${devtools.dist}" filtering="true"/>
+        <copy file="${binary.root.dir}/Java/Win32/Bin/Win32RegistryInterface.dll" todir="${devtools.dist}" preservelastmodified="true"/>
+        <!-- system (files are in alpha order here) -->
+        <copy file="${root.toolSettings}/DFPToolInstallationSettings-HC.cfg" tofile="${devtools.dist.sys}/DFPToolInstallationSettings.cfg" filtering="true"/>
+        <copy file="${root.toolSettings}/SCTToolInstallationSettings-HC.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/SCTToolInstallationSettings-HC3270Only.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/SCTToolInstallationSettings-HC5250Only.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/SCTToolInstallationSettings-CICSOnly.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <copy file="${root.dir.sys}/ToolDebugSettings.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/ToolInstallationSettings-All.cfg" tofile="${devtools.dist.sys}/ToolInstallationSettings.cfg" filtering="true"/>
+        <copy file="${root.toolSettings}/ToolInstallationSettings-DefToolHC.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/ToolInstallationSettings-DefToolHC3270Only.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/ToolInstallationSettings-DefToolHC5250Only.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/ToolInstallationSettings-DefToolCICSOnly.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <copy file="${root.toolSettings}/ToolInstallationSettings-DefToolIMSOnly.cfg" todir="${devtools.dist.sys}" filtering="true"/>
+        <!-- system defaults -->
+        <copy file="${root.dir.sysdef}/AppInterfaceTester-DefaultSettings.cfg" todir="${devtools.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ClientControlled3270ServerSettings-DefaultSettings.cfg" todir="${devtools.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ClientControlled5250ServerSettings-DefaultSettings.cfg" todir="${devtools.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/DefinitionTool-DefaultSettings.cfg" todir="${devtools.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/SEAGULLProject.dir" todir="${devtools.dist.sysdef}"/>
+        <copy file="${root.dir.sysdef}/ServerControlled3270ServerSettings-DefaultSettings.cfg" todir="${devtools.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ServerControlled5250ServerSettings-DefaultSettings.cfg" todir="${devtools.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ServerOptions-DefaultSettings.cfg" todir="${devtools.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/ServerSettings-Skeleton.cfg" todir="${devtools.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.sysdef}/WorkingSetSettings.cfg" todir="${devtools.dist.sysdef}" filtering="true"/>
+        <copy file="${root.dir.tools-log}/log-category.properties" todir="${devtools.dist.log}" preservelastmodified="true"/>
+        <copy file="${root.dir.tools-log}/log-style.properties" todir="${devtools.dist.log}" preservelastmodified="true"/>
+    </target>
+    <!-- AIS Central -->
+    <property name="transidiomcentral.dist.lib" value="${transidiomcentral.dist}/lib"/>
+    <target name="dist.transidiomcentral" depends="init, jar.ais-core, jar.ais-tools, jar.javaconnectorgenerator, jar.securitytoolkit">
+        <mkdir dir="${transidiomcentral.dist}"/>
+        <mkdir dir="${transidiomcentral.dist.lib}"/>
+        <copy file="${ais-core.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-5250.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-3270.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-cobol.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-cics.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-ims.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais-tools.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${ais.client.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${securitytoolkit.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${javaconnectorgenerator.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-codec.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${commons-lang.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${xerces.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${xalan.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${xml-apis.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb1.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb2.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb3.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb4.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb5.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb6.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+        <copy file="${jaxb7.jar}" todir="${transidiomcentral.dist.lib}" preservelastmodified="true"/>
+    </target>
+    <!-- User Docs -->
+    <target name="dist.docs">
+        <mkdir dir="${build.dist}/docs"/>
+        <copy todir="${build.dist}/docs">
+            <fileset dir="${doc.dir}">
+                <exclude name="Transidiom HTTP*.doc"/>
+            </fileset>
+        </copy>
+    </target>
+    <!-- =================================================================== -->
+    <!-- Javadoc for open back-end API -->
+    <!-- =================================================================== -->
+    <property name="ais.dist.javadoc" value="${ais.dist}/JavaConnectors/Documentation/JavaDoc"/>
+    <target name="javadoc.openbackend" depends="compile.doclet">
+        <delete dir="${ais.dist.javadoc}" includeEmptyDirs="true" quiet="true"/>
+        <mkdir dir="${ais.dist.javadoc}"/>
+        <property name="basic-header" value="${Name}&#x2122;, AIS Java Connector"/>
+        <property name="header+version" value="${basic-header}, v${version}"/>
+        <property name="win-title" value="${header+version} API Specification"/>
+        <property name="doc-title" value="${header+version}&lt;br/&gt;API Specification"/>
+        <javadoc sourcepath="${src.dir}" destdir="${ais.dist.javadoc}" windowtitle="${win-title}" doctitle="${doc-title}" header="${basic-header}" bottom="&lt;font size=&quot;-1&quot;&gt;${Name} is a trademark or registered trademarks of Seagull Holding NV in the US and other countries.&lt;br/&gt;Copyright &#169; 1993 - 2003 Seagull Business Software Ireland Ltd. All Rights Reserved.&lt;/font&gt;" author="false" version="true" use="true" doclet="com.seagullsw.internaldev.tools.apidoclet.standard.Standard" docletpath="${build.classes};${java.resource.dir}">
+            <!-- I don't understand it, but if I leave off the ${src.dir} below, it doesn't work. -->
+            <source file="${src.dir}/com/seagullsw/appinterface/server/backend/BackEnd.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/server/backend/BackEndInfo.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/server/backend/BackEndHandler.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/server/backend/BackEndSettings.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/server/backend/Callback.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/server/backend/ClientSession.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/server/backend/InvocationContext.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/AggregateModel.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/AppInterfaceRuntimeException.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/DataElementModel.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/FieldModel.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/IllegalElementException.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/IllegalPathException.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/ModelElement.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/SequenceModel.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/StructureModel.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/data/Aggregate.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/data/DataElement.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/data/DataElementList.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/data/Field.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/data/Sequence.java"/>
+            <source file="${src.dir}/com/seagullsw/appinterface/model/data/Structure.java"/>
+            <classpath>
+                <path refid="ais.classpath"/>
+            </classpath>
+            <link href="http://java.sun.com/products/jdk/1.3.1/docs/api/"/>
+        </javadoc>
+    </target>
+    <!-- VERIFY -->
+    <path id="path.AntTasks">
+        <pathelement location="${junit.jar}"/>
+        <pathelement location="${commons-cli.jar}"/>
+        <pathelement location="${commons-httpclient.jar}"/>
+        <pathelement location="${build.classes}"/>
+        <pathelement location="${internaldev.classes}"/>
+    </path>
+    <target name="build.AntTasks">
+        <mkdir dir="${internaldev.classes}"/>
+        <javac srcdir="${src.test.dir}" destdir="${internaldev.classes}" debug="${compile.debug}" classpathref="path.AntTasks">
+            <include name="com/seagullsw/internaldev/build/JarFileVerifier.java"/>
+            <include name="com/seagullsw/internaldev/build/JarFileVerifierTask.java"/>
+            <include name="com/seagullsw/internaldev/build/IsUrlOpen.java"/>
+            <include name="com/seagullsw/internaldev/build/IsUrlOpenTask.java"/>
+        </javac>
+    </target>
+    <target name="declare.AntTasks" depends="build.AntTasks">
+        <taskdef name="verifyjar" classname="com.seagullsw.internaldev.build.JarFileVerifierTask" classpathref="path.AntTasks"/>
+        <taskdef name="isUrlOpen" classname="com.seagullsw.internaldev.build.IsUrlOpenTask" classpathref="path.AntTasks"/>
+    </target>
+    <target name="prepare.test.ext">
+        <mkdir dir="${test.lib}"/>
+        <delete dir="${test.lib.ext}"/>
+        <mkdir dir="${test.lib.ext}"/>
+    </target>
+    <target name="verify.ais.jar" depends="declare.AntTasks, prepare.test.ext">
+        <mkdir dir="${test.fdef}"/>
+        <copy file="${goXMLEngine.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <copy file="${goXMLResource.zip}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <copy file="${jdom.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <copy file="${ibm.mq.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <copy file="${ibm.mq.connector.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <copy file="${ibm.mq.jta.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <verifyjar file="${ais-core.jar}" verbose="false" debug="false">
+            <classpath>
+                <pathelement location="${ais.dist.lib}"/>
+                <pathelement location="${ais.dist.lib.ext}"/>
+                <pathelement location="${test.lib}"/>
+            </classpath>
+        </verifyjar>
+        <delete dir="${test.lib.ext}"/>
+        <delete dir="${test.fdef}"/>
+    </target>
+    <target name="verify.client.jar" depends="declare.AntTasks, prepare.test.ext">
+        <copy file="${ibm.mq.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <copy file="${jms.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <copy file="${mail.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <copy file="${soap.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <verifyjar file="${ais.client.jar}" verbose="false" debug="false">
+            <classpath>
+                <pathelement location="${ais.client.dist.lib}"/>
+                <pathelement location="${test.lib.ext}"/>
+            </classpath>
+        </verifyjar>
+        <delete dir="${test.lib.ext}"/>
+    </target>
+    <target name="verify.5250.jar" depends="declare.AntTasks">
+        <verifyjar file="${ais-5250.jar}" ignoreUnresolved="true" verbose="false" debug="false">
+            <classpath location="${ais.dist.lib}"/>
+        </verifyjar>
+    </target>
+    <target name="verify.3270.jar" depends="declare.AntTasks">
+        <verifyjar file="${ais-3270.jar}" ignoreUnresolved="true" verbose="false" debug="false">
+            <classpath location="${ais.dist.lib}"/>
+        </verifyjar>
+    </target>
+    <target name="verify.cobol.jar" depends="declare.AntTasks">
+        <verifyjar file="${ais-cobol.jar}" verbose="false" debug="false">
+            <classpath location="${ais.dist.lib}"/>
+        </verifyjar>
+    </target>
+    <target name="verify.cics.jar" depends="declare.AntTasks, prepare.test.ext">
+        <copy file="${ctgclient.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <verifyjar file="${ais-cics.jar}" verbose="false" debug="false">
+            <classpath location="${ais.dist.lib}"/>
+            <classpath location="${test.lib}"/>
+        </verifyjar>
+        <delete dir="${test.lib.ext}"/>
+    </target>
+    <target name="verify.ims.jar" depends="declare.AntTasks">
+        <verifyjar file="${ais-ims.jar}" verbose="false" debug="false">
+            <classpath location="${ais.dist.lib}"/>
+        </verifyjar>
+    </target>
+    <target name="verify.adminclient.jar" depends="declare.AntTasks">
+        <verifyjar file="${ais-adminclient.jar}" verbose="false" debug="false">
+            <classpath location="${devtools.dist.lib}"/>
+        </verifyjar>
+    </target>
+    <target name="verify.proxyservlet.jar" depends="declare.AntTasks">
+        <verifyjar file="${proxyservlet.jar}" verbose="false" debug="false">
+            <classpath>
+                <pathelement location="${proxyservlet.dist.lib}"/>
+                <pathelement location="${servlet.dir}"/>
+            </classpath>
+        </verifyjar>
+    </target>
+    <target name="verify.adminconsole.jar" depends="declare.AntTasks">
+        <verifyjar file="${adminconsole.jar}" verbose="false" debug="false">
+            <classpath location="${ais.dist.lib}"/>
+        </verifyjar>
+    </target>
+    <target name="verify.javaconnectorgenerator.jar" depends="declare.AntTasks">
+        <verifyjar file="${javaconnectorgenerator.jar}" verbose="false" debug="false">
+            <classpath location="${devtools.dist.lib}"/>
+        </verifyjar>
+    </target>
+    <target name="verify.securitytoolkit.jar" depends="declare.AntTasks">
+        <verifyjar file="${securitytoolkit.jar}" verbose="false" debug="false">
+            <classpath location="${devtools.dist.lib}"/>
+        </verifyjar>
+    </target>
+    <target name="verify.tools.jar" depends="declare.AntTasks, prepare.test.ext">
+        <copy file="${j2se.tools.jar}" todir="${test.lib.ext}" preservelastmodified="true"/>
+        <verifyjar file="${ais-tools.jar}" verbose="false" debug="false">
+            <classpath location="${devtools.dist.lib}"/>
+            <classpath location="${test.lib}"/>
+        </verifyjar>
+        <delete dir="${test.lib.ext}"/>
+    </target>
+    <target name="verify.gwhsc.jar" depends="declare.AntTasks">
+        <verifyjar file="${hsc.jar}" verbose="false" debug="false"/>
+    </target>
+    <target name="verify.gwhscu.jar" depends="declare.AntTasks">
+        <verifyjar file="${hscu.jar}" verbose="false" debug="false"/>
+    </target>
+    <target name="verify.xml" depends="banner">
+        <!-- Only check for well-formed XML here. -->
+        <xmlvalidate lenient="yes" warn="yes">
+            <fileset dir="${build.dist}" includes="**/*.xml"/>
+            <fileset dir="${build.dist}" includes="**/*.cfg"/>
+            <fileset dir="${build.dist}" includes="**/*.sfd"/>
+            <fileset dir="${build.dist}" includes="**/*.sjcd"/>
+            <fileset dir="${build.dist}" includes="**/*.sfmd"/>
+            <fileset dir="${build.dist}" includes="**/*.xsd"/>
+            <fileset dir="${build.dist}" includes="**/*.xsl"/>
+        </xmlvalidate>
+    </target>
+    <target name="verify" description="Verifies the build by performing a load tests on jar files (does not trigger the jar dependencies.)" depends="banner, verify.ais.jar, verify.client.jar, verify.5250.jar, verify.3270.jar, verify.cobol.jar, verify.cics.jar, verify.ims.jar, verify.adminclient.jar, verify.proxyservlet.jar, verify.adminconsole.jar, verify.javaconnectorgenerator.jar, verify.securitytoolkit.jar, verify.tools.jar, verify.gwhsc.jar, verify.gwhscu.jar, verify.xml"/>
+    <!-- End VERIFY targets -->
+    <!-- TEST TARGETS -->
+    <target name="junit_check">
+        <available classname="junit.framework.Test" property="junit.present"/>
+        <fail message="JUnit cannot be found." unless="junit.present"/>
+    </target>
+    <property name="test" value="${build.dir}/test"/>
+    <property name="test.bin" value="${test}/bin"/>
+    <property name="test.resources" value="${test.dir}/resources"/>
+    <property name="test.fdef" value="${test}/${fdef.dirname}"/>
+    <property name="test.lib" value="${test}/lib"/>
+    <property name="test.lib.ext" value="${test.lib}/ext"/>
+    <property name="reports.dir" value="${build.dir}/reports"/>
+    <property name="reports.checksum" value="${reports.dir}/checksum"/>
+    <property name="junit.reports.srcdir" location="reports"/>
+    <property name="junit.reports" location="${reports.dir}/junit"/>
+    <property name="junit.formatter" value="xml"/>
+    <property name="junit.fork" value="true"/>
+    <property name="junit.printsummary" value="true"/>
+    <property name="junit.includeantruntime" value="false"/>
+    <property name="junit.dir" value="../.."/>
+    <property name="junit.reports.xml" location="${junit.reports}/${junit.formatter}"/>
+    <property name="junit.report.ext" value="-junit.xml"/>
+    <target name="test.compile" description="Compiles the unit tests without triggering any dependencies.">
+        <mkdir dir="${test.bin}"/>
+        <javac destdir="${test.bin}" debug="${compile.debug}" includeAntRuntime="false">
+            <src path="${src.test.dir}"/>
+            <src path="${src.dir}/com/seagullsw/internaldev/appinterface/model"/>
+            <!-- Testing framework -->
+            <classpath location="${junit.jar}"/>
+            <classpath location="${mtjunit.jar}"/>
+            <classpath location="${xmlsec.jar}"/>
+            <!-- Jars to test, which the test cases refer to. -->
+            <classpath location="${ais-core.jar}"/>
+            <classpath location="${proxyservlet.jar}"/>
+            <classpath location="${ais.client.jar}"/>
+            <classpath location="${javaconnectorgenerator.jar}"/>
+            <classpath location="${securitytoolkit.jar}"/>
+            <classpath location="${ais-tools.jar}"/>
+            <classpath location="${ais-5250.jar}"/>
+            <classpath location="${ais-3270.jar}"/>
+            <classpath location="${ais-cobol.jar}"/>
+            <classpath location="${ais-cics.jar}"/>
+            <classpath location="${ais-ims.jar}"/>
+            <classpath location="${ais-adminclient.jar}"/>
+            <classpath location="${hsc.jar}"/>
+            <!-- dependencies -->
+            <classpath location="${ant.jar}"/>
+            <classpath location="${commons-cli.jar}"/>
+            <classpath location="${commons-httpclient.jar}"/>
+            <classpath refid="ais.classpath"/>
+            <classpath refid="proxyservlet.classpath"/>
+            <classpath refid="cobol.classpath"/>
+            <classpath refid="cics.backend.classpath"/>
+            <classpath refid="ims.backend.classpath"/>
+            <classpath refid="transforms.classpath"/>
+            <classpath refid="jsse.classpath"/>
+        </javac>
+    </target>
+    <target name="test.mkdir" depends="init">
+        <mkdir dir="${build.dir}"/>
+        <mkdir dir="${test}"/>
+        <mkdir dir="${test.bin}"/>
+    </target>
+    <target name="echo.xalan.version">
+        <echo level="info" message="Testing with ${TransformerFactory}"/>
+        <java classname="org.apache.xalan.Version"/>
+    </target>
+    <target name="report.init" depends="init, test.compile">
+        <mkdir dir="${junit.reports.xml}"/>
+        <echo level="info" message="Reporting to ${junit.reports.xml}"/>
+    </target>
+    <path id="junit.classpath">
+        <pathelement location="${ant.home}/lib/ant.jar"/>
+        <pathelement location="${ant.home}/lib/optional.jar"/>
+        <pathelement location="${ant.home}/lib/junit.jar"/>
+    </path>
+    <!-- Unit Tests: from low-level to high-level -->
+    <!-- Unit Tests: javax.lang -->
+    <target name="junit.javax.lang" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <pathelement location="${ais-tools.jar}"/>
+                <pathelement location="${j2se.tools.jar}"/>
+                <pathelement location="${commons-lang.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.unittest.javax.lang.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: javax.io -->
+    <target name="junit.javax.io" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <pathelement location="${commons-lang.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.javax.io.AllTests" todir="${junit.reports.xml}"/>
+            <test name="com.seagullsw.unittest.javax.io.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: javax.util -->
+    <target name="junit.javax.util" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.unittest.javax.util.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: Toolbox XML  -->
+    <target name="junit.toolbox.xml" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement path="${sun.boot.class.path}"/>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="xml.classpath.rt"/>
+                <pathelement location="${commons-lang.jar}"/>
+                <pathelement location="${xmlsec.jar}"/>
+                <pathelement location="${jce.jar}"/>
+                <pathelement location="${log4j.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.unittest.toolbox.xml.StringProxyTestSuite" todir="${junit.reports.xml}"/>
+            <test name="com.seagullsw.unittest.toolbox.xml.DocumentProxyTestSuite" todir="${junit.reports.xml}"/>
+            <test name="com.seagullsw.unittest.toolbox.xml.ReadDocumentWithEncodingTestSuite" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: Toolbox config  -->
+    <target name="junit.toolbox.config" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <pathelement path="${sun.boot.class.path}"/>
+                <pathelement location="${ais-core.jar}"/>
+                <pathelement location="${commons-lang.jar}"/>
+                <pathelement location="${commons-cli.jar}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.toolbox.config.ConfigurationDirectoryTestCase" todir="${junit.reports.xml}"/>
+            <test name="com.seagullsw.toolbox.config.ConfigValidatorTest" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: Toolbox logging  -->
+    <target name="junit.toolbox.log" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${ais-core.jar}"/>
+                <pathelement location="${commons-lang.jar}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.toolbox.log.LogUnitTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: config/log -->
+    <target name="junit.server.config.log" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.config.bind.log.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: config/bind/threadpool -->
+    <target name="junit.server.config.threadpool" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.config.bind.threadpool.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: config/bind/transform -->
+    <target name="junit.server.config.transform" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <path refid="transforms.classpath"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.config.bind.transform.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: config/bind/core -->
+    <target name="junit.server.config.core" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.config.bind.core.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: config/bind/management -->
+    <target name="junit.server.config.management" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.config.bind.management.JaxbUnmarshalTestCase" todir="${junit.reports.xml}"/>
+            <test name="com.seagullsw.appinterface.server.config.bind.management.ConfigurationDirectoryUnmarshalTestCase" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: Chameleon -->
+    <target name="junit.ais-core.transforms" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement path="${sun.boot.class.path}"/>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="transforms.classpath"/>
+                <pathelement location="${xmlsec.jar}"/>
+                <pathelement location="${jce.jar}"/>
+                <pathelement location="${log4j.jar}"/>
+                <pathelement location="${goXMLResource.zip}"/>
+                <pathelement location="${goXMLconfig.dir}"/>
+                <pathelement location="${jdom.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.unittest.appinterface.transforms.ApacheXPathNamespaceTestSuite" todir="${junit.reports.xml}"/>
+            <test name="com.seagullsw.unittest.appinterface.transforms.SimpleAwkTestSuite" todir="${junit.reports.xml}"/>
+            <test name="com.seagullsw.unittest.appinterface.transforms.TransformationManagerBindingTestSuite" todir="${junit.reports.xml}"/>
+            <test name="com.seagullsw.unittest.appinterface.transforms.TransformationManagerTestSuite" todir="${junit.reports.xml}"/>
+            <test name="com.seagullsw.unittest.appinterface.transforms.GoXMLTransformationManagerTestSuite" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: com.seagullsw.appinterface.server.security.auth  -->
+    <target name="junit.security.auth" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <path refid="jce.classpath.rt"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.security.auth.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: com.seagullsw.appinterface.server.crypto  -->
+    <target name="junit.crypto" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <path refid="jce.classpath.rt"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.crypto.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: com.seagullsw.toolbox.net  -->
+    <target name="junit.toolbox.net" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <pathelement location="${commons-codec.jar}"/>
+                <pathelement location="${commons-httpclient.jar}"/>
+                <pathelement location="${commons-logging.jar}"/>
+                <path refid="jce.classpath.rt"/>
+                <path refid="jsse.classpath"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.toolbox.net.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: com.seagullsw.unittest.appinterface.model  -->
+    <target name="junit.model" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <path refid="transforms.classpath"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.unittest.appinterface.model.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <target name="junit.server" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <path refid="ims.backend.classpath"/>
+                <path refid="cics.backend.classpath"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.LoadFunctionsTest" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: com.seagullsw.unittest.appinterface.server.backend.hostconnector2  -->
+    <target name="junit.hostconnector2" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${ais-5250.jar}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.unittest.appinterface.server.backend.hostconnector2.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <target name="junit.backend.hsc" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <!-- The timeout is expressed in milliseconds. -->
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <path refid="jce.classpath.rt"/>
+                <pathelement location="${ais-5250.jar}"/>
+                <pathelement location="${ais-3270.jar}"/>
+                <pathelement location="${commons-httpclient.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.config.bind.connectors.hsc.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: IMS back-end -->
+    <target name="junit.backend.ims" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <!-- The timeout is expressed in milliseconds. -->
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <path refid="ims.backend.classpath"/>
+                <path refid="jce.classpath.rt"/>
+                <pathelement location="${ais-ims.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.config.bind.connectors.ims.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <target name="junit.backend.ims.live" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <!-- The timeout is expressed in milliseconds. -->
+        <junit printsummary="${junit.printsummary}" fork="true" timeout="45000" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <path refid="ims.backend.classpath"/>
+                <path refid="jce.classpath.rt"/>
+                <pathelement location="${ais-ims.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.backend.ims.AllLiveImsIcoTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Unit Tests: CICS back-end -->
+    <target name="junit.backend.cics" depends="junit.backend.cics.common, junit.backend.cics.ctg.live, junit.backend.cics.hb, junit.backend.cics.hb.live"/>
+    <target name="junit.backend.cics.common" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <path refid="jce.classpath.rt"/>
+                <pathelement location="${ais-cics.jar}"/>
+                <pathelement location="${ctgclient.jar}"/>
+                <pathelement location="${commons-httpclient.jar}"/>
+                <pathelement location="${commons-logging.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.config.bind.connectors.cics.AllTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <target name="junit.backend.cics.ctg.live" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <!-- The timeout is expressed in milliseconds. -->
+        <junit printsummary="${junit.printsummary}" fork="true" timeout="600000" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <pathelement location="${ais-cics.jar}"/>
+                <pathelement location="${ctgclient.jar}"/>
+                <pathelement location="${commons-httpclient.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.backend.cics.AllLiveIbmCtgTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <target name="junit.backend.cics.hb" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="${junit.fork}" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <pathelement location="${ais-cics.jar}"/>
+                <pathelement location="${commons-httpclient.jar}"/>
+                <pathelement location="${commons-logging.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.backend.cics.HostBridgeByteBufferStrategyTest" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <target name="junit.backend.cics.hb.live" depends="report.init">
+        <mkdir dir="${junit.reports.xml}"/>
+        <junit printsummary="${junit.printsummary}" fork="true" timeout="600000" dir="${junit.dir}" includeantruntime="${junit.includeantruntime}">
+            <formatter type="${junit.formatter}" extension="${junit.report.ext}"/>
+            <classpath>
+                <pathelement location="${ais-core.jar}"/>
+                <path refid="ais.classpath"/>
+                <pathelement location="${ais-cics.jar}"/>
+                <pathelement location="${commons-httpclient.jar}"/>
+                <pathelement location="${commons-logging.jar}"/>
+                <pathelement location="${test.bin}"/>
+                <pathelement location="${test.resources}"/>
+                <path refid="junit.classpath"/>
+            </classpath>
+            <test name="com.seagullsw.appinterface.server.backend.cics.AllLiveHostBridgeTests" todir="${junit.reports.xml}"/>
+        </junit>
+    </target>
+    <!-- Clean reports -->
+    <target name="junit.report.clean">
+        <delete dir="${junit.reports}"/>
+    </target>
+    <!-- Create the unit tests report -->
+    <target name="junit.report" depends="init">
+        <mkdir dir="${junit.reports}"/>
+        <property name="junit.reports.frames" location="${junit.reports}/frames"/>
+        <property name="junit.reports.noframes" location="${junit.reports}/noframes"/>
+        <mkdir dir="${junit.reports.xml}"/>
+        <mkdir dir="${junit.reports.frames}"/>
+        <mkdir dir="${junit.reports.noframes}"/>
+        <echo level="info" message="Compiling all reports to ${junit.reports}..."/>
+        <junitreport todir="${junit.reports.xml}">
+            <fileset dir="${junit.reports.xml}">
+                <include name="**/*${junit.report.ext}"/>
+            </fileset>
+            <report format="noframes" todir="${junit.reports.noframes}"/>
+            <report format="frames" todir="${junit.reports.frames}"/>
+        </junitreport>
+        <echo level="info" message="The XML report is in: ${junit.reports.xml}"/>
+        <echo level="info" message="The HTML report (with frames) is in: ${junit.reports.frames}"/>
+        <echo level="info" message="The HTML report (no frames) is in: ${junit.reports.noframes}"/>
+        <!-- Rename file to index.html -->
+        <move file="${junit.reports.noframes}/junit-noframes.html" tofile="${junit.reports.noframes}/index.html"/>
+        <!-- Copy test reports home page -->
+        <copy file="${junit.reports.srcdir}/index.html" todir="${reports.dir}" overwrite="true" filtering="true"/>
+        <copy todir="${reports.dir}/images" overwrite="true">
+            <fileset dir="${junit.reports.srcdir}/images"/>
+        </copy>
+        <antcall target="report.checksums"/>
+    </target>
+    <target name="report.checksums">
+        <antcall target="copy-checksums"/>
+        <property name="temp.index" value="${reports.dir}/index-temp.html"/>
+        <xslt in="${reports.dir}/index.html" out="${temp.index}" force="true" style="${junit.reports.srcdir}/apply-data.xslt">
+            <param name="reportDir" expression="${reports.dir}"/>
+        </xslt>
+        <delete file="${reports.dir}/index.html"/>
+        <move file="${temp.index}" tofile="${reports.dir}/index.html"/>
+    </target>
+    <target name="junit.javax" depends="junit.javax.io, junit.javax.util, junit.javax.lang"/>
+    <target name="junit.server.config" depends="junit.server.config.log, junit.server.config.threadpool, junit.server.config.transform, junit.server.config.core, junit.server.config.management"/>
+    <target name="junit.toolbox" depends="junit.toolbox.config, junit.toolbox.xml, junit.toolbox.net, junit.toolbox.log"/>
+    <target name="junit.ais-core" depends="junit.javax, junit.toolbox, junit.server.config, junit.ais-core.transforms, junit.security.auth, junit.crypto, junit.model, junit.server"/>
+    <target name="junit.backend" depends="junit.backend.hsc, junit.backend.ims, junit.backend.ims.live, junit.backend.cics, junit.hostconnector2"/>
+    <target name="test" description="Runs the tests." depends="init, test.compile, junit.report.clean, junit.ais-core, junit.backend, junit.report"/>
+    <!-- Build and Zip -->
+    <target name="zip" depends="dist" description="Creates the final ${zip-file} (does it all)">
+        <property name="zip-file" location="${build.dir}/${zipFileBaseName}-build${build.id}.zip"/>
+        <delete file="${zip-file}" quiet="true"/>
+        <zip zipfile="${zip-file}" basedir="${build.dist}"/>
+    </target>
+    <target name="nightly-build" depends="init, clean, dist, verify, test" description="Creates a nightly build (does it all)">
+    </target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/projectOnly.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/projectOnly.xml
new file mode 100644
index 0000000..35ece5b
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/projectOnly.xml
@@ -0,0 +1,4 @@
+
+
+
+<project ></project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/refid.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/refid.xml
new file mode 100644
index 0000000..a9f4ae1
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/refid.xml
@@ -0,0 +1,49 @@
+<project default="1">
+	<path id="project.class.path">
+		<pathelement location="lib/" />
+		<pathelement path="${java.class.path}/" />
+		<pathelement path="${additional.path}" />
+	</path>
+
+	<target name="1">
+		<path id="project.class.path2">
+			<path refid="project.class.path" />
+		</path>
+	</target>
+	
+	<target name="compile">
+			<javac srcdir="src"
+			       destdir="dst"
+			       classpathref=""
+			       sourcepathref=""
+			       bootclasspathref=""
+			       debug="on" />
+		</target>
+	
+	<target name= "depends" depends=" compile  , 1 ">
+	</target>
+	
+	<property name="name with spaces" value="value with spaces"/>
+
+	
+	<fileset dir="dir" id="filesetTest">
+	    <include name="include"/>
+	    <exclude name="exclude"/>
+	</fileset>
+	
+	<patternset id="patternSetTest">
+			<include name="*.xml"/>
+			<exclude name="**/*Test*"/>
+	</patternset>
+	
+	<patternset id="patternSetTestBad">
+		<includesfile name="nothere"/>
+	</patternset>
+
+	<echo>${name with spaces}</echo>
+	
+	<fileset refid="filesetTest">
+		<patternset refid="patternSetTest"></patternset>
+		<patternset refid="patternSetTestBad"></patternset>
+	</fileset>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/russianbuild.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/russianbuild.xml
new file mode 100644
index 0000000..d853566
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/russianbuild.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<project name="test" default="init" basedir=".">
+
+	<target name="init">
+		<!-- displays Hello in Russian -->
+		<echo message="Çäðàâñòâóéòå"/>
+	</target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/taskdef.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/taskdef.xml
new file mode 100644
index 0000000..c912b71
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/taskdef.xml
@@ -0,0 +1,11 @@
+<project default="type">
+
+	<taskdef name="mine" classname="org.eclipse.ant.tests.ui.support.tasks.AntTestTask" classpath="antUITestsSupport.jar">
+	</taskdef>
+
+	<target name="type">
+
+	</target>
+
+	<mine></mine>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/test1.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test1.xml
new file mode 100644
index 0000000..6f60a32
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test1.xml
@@ -0,0 +1,10 @@
+
+<bla>
+  <blub></blub>
+  <klick>
+    <gurgel></gurgel>
+    <hal
+    <klack/>
+    <humpf/>
+  </klick>
+</bla>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/test2.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test2.xml
new file mode 100644
index 0000000..1ca8765
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test2.xml
@@ -0,0 +1,9 @@
+<bla>
+  <blub></blub>
+  <klick>
+    <gurgel></gurgel>
+    <hal></hal>
+    <klack/>
+    <humpf/>
+  </klick>
+</bla>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/test3.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test3.xml
new file mode 100644
index 0000000..674088e
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test3.xml
@@ -0,0 +1,4 @@
+<bla>
+  <blub>
+  </blub>
+</
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/test4.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test4.xml
new file mode 100644
index 0000000..fd60f79
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test4.xml
@@ -0,0 +1 @@
+<target name="main"><mk
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/test5.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test5.xml
new file mode 100644
index 0000000..c297d95
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/test5.xml
@@ -0,0 +1,6 @@
+<project name="main">
+	<target name="bla" />
+	<property name="prop1" value="val1"/>
+	<property name="prop2" value="val2"/>
+	<property name="prop3" value="val3"/>
+<g
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/toBeImported.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/toBeImported.xml
new file mode 100644
index 0000000..5b03f80
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/toBeImported.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<project name="toBeImported" default="import-default">
+
+	<target name="import-default" depends="depends">
+		<echo>import-default</echo>
+	</target>
+
+	<target name="depends">
+		<echo>depends</echo>
+	</target>
+</project>
+
diff --git a/ant/org.eclipse.ant.tests.ui/testbuildfiles/toBeImportedWithByteOrderMark.xml b/ant/org.eclipse.ant.tests.ui/testbuildfiles/toBeImportedWithByteOrderMark.xml
new file mode 100644
index 0000000..7a0a8ba
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testbuildfiles/toBeImportedWithByteOrderMark.xml
Binary files differ
diff --git a/ant/org.eclipse.ant.tests.ui/testresources/Test2.java b/ant/org.eclipse.ant.tests.ui/testresources/Test2.java
new file mode 100644
index 0000000..447c468
--- /dev/null
+++ b/ant/org.eclipse.ant.tests.ui/testresources/Test2.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+/*
+ * Created on Sep 21, 2004
+ *
+ * TODO To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+
+/**
+ * @author Administrator
+ *
+ * TODO To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class Test2 {
+
+	public static void main(String[] args) {
+		
+		System.out.println("preRuntest");
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/.classpath b/ant/org.eclipse.ant.ui/.classpath
new file mode 100644
index 0000000..bb1af3b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="Ant Tools Support"/>
+	<classpathentry kind="src" output="ant_runner_support_bin" path="Ant Runner Support"/>
+	<classpathentry kind="src" path="Ant Editor"/>
+	<classpathentry kind="src" output="remote_support_bin" path="Remote Ant Support"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/ant/org.eclipse.ant.ui/.externalToolBuilders/Build Ant Runner Support JAR.launch b/ant/org.eclipse.ant.ui/.externalToolBuilders/Build Ant Runner Support JAR.launch
new file mode 100644
index 0000000..076779d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/.externalToolBuilders/Build Ant Runner Support JAR.launch
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
+<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,clean"/>
+<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.debug.ui.target_run_perspective" value="perspective_none"/>
+<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot; editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.ui/Common Ant Support&quot; type=&quot;2&quot;/&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.ui/Ant Runner Support&quot; type=&quot;2&quot;/&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.ui/buildfiles/buildExtraJAR.xml&quot; type=&quot;1&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;&#10;}"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.ant.ui/buildfiles/buildExtraJAR.xml}"/>
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_RUN_IN_BACKGROUND" value="false"/>
+</launchConfiguration>
diff --git a/ant/org.eclipse.ant.ui/.externalToolBuilders/Build Remote Ant JAR.launch b/ant/org.eclipse.ant.ui/.externalToolBuilders/Build Remote Ant JAR.launch
new file mode 100644
index 0000000..82c5814
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/.externalToolBuilders/Build Remote Ant JAR.launch
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
+<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,clean"/>
+<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;launchConfigurationWorkingSet factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; name=&quot;workingSet&quot; editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot;&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.ui/buildfiles/buildRemoteExtraJAR.xml&quot; type=&quot;1&quot;/&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.ui/Common Ant Support&quot; type=&quot;2&quot;/&gt;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/org.eclipse.ant.ui/Remote Ant Support&quot; type=&quot;2&quot;/&gt;&#10;&lt;/launchConfigurationWorkingSet&gt;&#10;}"/>
+<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/>
+<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.ant.ui/buildfiles/buildRemoteExtraJAR.xml}"/>
+<booleanAttribute key="org.eclipse.debug.ui.ATTR_RUN_IN_BACKGROUND" value="false"/>
+</launchConfiguration>
diff --git a/ant/org.eclipse.ant.ui/.project b/ant/org.eclipse.ant.ui/.project
new file mode 100644
index 0000000..b8a58f6
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/.project
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.ant.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/Build Ant Runner Support JAR.launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
+			<arguments>
+				<dictionary>
+					<key>LaunchConfigHandle</key>
+					<value>&lt;project&gt;/.externalToolBuilders/Build Remote Ant JAR.launch</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.team.cvs.core.cvsnature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/ant/org.eclipse.ant.ui/.settings/org.eclipse.pde.core.prefs b/ant/org.eclipse.ant.ui/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..ee4416f
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,3 @@
+#Fri Jan 21 19:40:52 GMT-08:00 2005

+eclipse.preferences.version=1

+selfhosting.binExcludes=/org.eclipse.ant.ui/ant_runner_support_bin,/org.eclipse.ant.ui/common_ant_support_bin,/org.eclipse.ant.ui/remote_support_bin

diff --git a/ant/org.eclipse.ant.ui/Ant Editor Content Assist Dev/XDOCtasks.xml b/ant/org.eclipse.ant.ui/Ant Editor Content Assist Dev/XDOCtasks.xml
new file mode 100644
index 0000000..b82075e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor Content Assist Dev/XDOCtasks.xml
@@ -0,0 +1,18688 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tasks>
+<task name="ant" category="control"
+      classname="org.apache.tools.ant.taskdefs.Ant"
+      >
+
+  <short-description><![CDATA[Build a sub-project.]]></short-description>
+  <description>
+    <![CDATA[Build a sub-project.
+
+  <pre>
+  &lt;target name=&quot;foo&quot; depends=&quot;init&quot;&gt;
+    &lt;ant antfile=&quot;build.xml&quot; target=&quot;bar&quot; &gt;
+      &lt;property name=&quot;property1&quot; value=&quot;aaaaa&quot; /&gt;
+      &lt;property name=&quot;foo&quot; value=&quot;baz&quot; /&gt;
+    &lt;/ant&gt;</SPAN>
+  &lt;/target&gt;</SPAN>
+
+  &lt;target name=&quot;bar&quot; depends=&quot;init&quot;&gt;
+    &lt;echo message=&quot;prop is ${property1} ${foo}&quot; /&gt;
+  &lt;/target&gt;
+ </pre>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="antfile" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The buildfile to use.]]></short-description>
+        <description><![CDATA[
+          The buildfile to use.
+ Defaults to "build.xml". This file is expected to be a filename relative
+ to the dir attribute given.
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory to use as a base directory for the new Ant project.]]></short-description>
+        <description><![CDATA[
+          The directory to use as a base directory for the new Ant project.
+ Defaults to the current project's basedir, unless inheritall
+ has been set to false, in which case it doesn't have a default
+ value. This will override the basedir setting of the called project.
+        ]]></description>
+      </attribute>
+      <attribute name="inheritall" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, pass all properties to the new Ant project.]]></short-description>
+        <description><![CDATA[
+          If true, pass all properties to the new Ant project.
+ Defaults to true.
+        ]]></description>
+      </attribute>
+      <attribute name="inheritrefs" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, pass all references to the new Ant project.]]></short-description>
+        <description><![CDATA[
+          If true, pass all references to the new Ant project.
+ Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Filename to write the output to.]]></short-description>
+        <description><![CDATA[
+          Filename to write the output to.
+ This is relative to the value of the dir attribute
+ if it has been set or to the base directory of the
+ current project otherwise.
+        ]]></description>
+      </attribute>
+      <attribute name="target" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The target of the new Ant project to execute.]]></short-description>
+        <description><![CDATA[
+          The target of the new Ant project to execute.
+ Defaults to the new project's default target.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="reference" type="org.apache.tools.ant.taskdefs.Ant.Reference"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Reference element identifying a data type to carry
+ over to the new project.]]></short-description>
+        <description>
+          <![CDATA[Reference element identifying a data type to carry
+ over to the new project.]]>
+        </description>
+      </element>
+
+      <element name="property" type="org.apache.tools.ant.taskdefs.Property"
+               briefType="see &lt;property&gt;"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Property to pass to the new project.]]></short-description>
+        <description>
+          <![CDATA[Property to pass to the new project.
+ The property is passed as a 'user property']]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="antcall" category="control"
+      classname="org.apache.tools.ant.taskdefs.CallTarget"
+      >
+
+  <short-description><![CDATA[Call another target in the same project.]]></short-description>
+  <description>
+    <![CDATA[Call another target in the same project.
+
+  <pre>
+    &lt;target name="foo"&gt;
+      &lt;antcall target="bar"&gt;
+        &lt;param name="property1" value="aaaaa" /&gt;
+        &lt;param name="foo" value="baz" /&gt;
+       &lt;/antcall&gt;
+    &lt;/target&gt;
+
+    &lt;target name="bar" depends="init"&gt;
+      &lt;echo message="prop is ${property1} ${foo}" /&gt;
+    &lt;/target&gt;
+ </pre>
+
+ <p>This only works as expected if neither property1 nor foo are
+ defined in the project itself.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="inheritall" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, pass all properties to the new Ant project.]]></short-description>
+        <description><![CDATA[
+          If true, pass all properties to the new Ant project.
+ Defaults to true.
+        ]]></description>
+      </attribute>
+      <attribute name="inheritrefs" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, pass all references to the new Ant project.]]></short-description>
+        <description><![CDATA[
+          If true, pass all references to the new Ant project.
+ Defaults to false
+        ]]></description>
+      </attribute>
+      <attribute name="target" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Target to execute, required.]]></short-description>
+        <description><![CDATA[
+          Target to execute, required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="reference" type="org.apache.tools.ant.taskdefs.Ant.Reference"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Reference element identifying a data type to carry
+ over to the invoked target.]]></short-description>
+        <description>
+          <![CDATA[Reference element identifying a data type to carry
+ over to the invoked target.]]>
+        </description>
+      </element>
+
+      <element name="param" type="org.apache.tools.ant.taskdefs.Property"
+               briefType="see &lt;property&gt;"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Property to pass to the invoked target.]]></short-description>
+        <description>
+          <![CDATA[Property to pass to the invoked target.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="antlr" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ANTLR"
+      >
+
+  <short-description><![CDATA[Invokes the ANTLR Translator generator on a grammar file.]]></short-description>
+  <description>
+    <![CDATA[Invokes the ANTLR Translator generator on a grammar file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="debug" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to enable ParseView debugging.]]></short-description>
+        <description><![CDATA[
+          Sets a flag to enable ParseView debugging
+        ]]></description>
+      </attribute>
+      <attribute name="diagnostic" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to emit diagnostic text.]]></short-description>
+        <description><![CDATA[
+          Sets a flag to emit diagnostic text
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The working directory of the process.]]></short-description>
+        <description><![CDATA[
+          The working directory of the process
+        ]]></description>
+      </attribute>
+      <attribute name="glib" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets an optional super grammar file.]]></short-description>
+        <description><![CDATA[
+          Sets an optional super grammar file.
+        ]]></description>
+      </attribute>
+      <attribute name="html" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, emit html.]]></short-description>
+        <description><![CDATA[
+          If true, emit html
+        ]]></description>
+      </attribute>
+      <attribute name="outputdirectory" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory to write the generated files to.]]></short-description>
+        <description><![CDATA[
+          The directory to write the generated files to.
+        ]]></description>
+      </attribute>
+      <attribute name="target" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The grammar file to process.]]></short-description>
+        <description><![CDATA[
+          The grammar file to process.
+        ]]></description>
+      </attribute>
+      <attribute name="trace" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enables all tracing.]]></short-description>
+        <description><![CDATA[
+          If true, enables all tracing.
+        ]]></description>
+      </attribute>
+      <attribute name="tracelexer" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enables lexer tracing.]]></short-description>
+        <description><![CDATA[
+          If true, enables lexer tracing.
+        ]]></description>
+      </attribute>
+      <attribute name="traceparser" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enables parser tracing.]]></short-description>
+        <description><![CDATA[
+          If true, enables parser tracing.
+        ]]></description>
+      </attribute>
+      <attribute name="tracetreewalker" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to allow the user to enable tree walker tracing.]]></short-description>
+        <description><![CDATA[
+          Sets a flag to allow the user to enable tree walker tracing
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a classpath to be set
+ because a directory might be given for Antlr debug.]]></short-description>
+        <description>
+          <![CDATA[Adds a classpath to be set
+ because a directory might be given for Antlr debug.]]>
+        </description>
+      </element>
+
+      <element name="jvmarg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a new JVM argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a new JVM argument.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="antstructure" category="xml"
+      classname="org.apache.tools.ant.taskdefs.AntStructure"
+      >
+
+  <short-description><![CDATA[Creates a partial DTD for Ant from the currently known tasks.]]></short-description>
+  <description>
+    <![CDATA[Creates a partial DTD for Ant from the currently known tasks.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The output file.]]></short-description>
+        <description><![CDATA[
+          The output file.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="apply" category="control"
+      classname="org.apache.tools.ant.taskdefs.ExecuteOn"
+      >
+
+  <short-description><![CDATA[Executes a given command, supplying a set of files as arguments.]]></short-description>
+  <description>
+    <![CDATA[Executes a given command, supplying a set of files as arguments.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether output should be appended to or overwrite an existing file.]]></short-description>
+        <description><![CDATA[
+          Whether output should be appended to or overwrite an existing file.
+ Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory where target files are to be placed.]]></short-description>
+        <description><![CDATA[
+          The directory where target files are to be placed.
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The working directory of the process.]]></short-description>
+        <description><![CDATA[
+          The working directory of the process.
+        ]]></description>
+      </attribute>
+      <attribute name="executable" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The command to execute.]]></short-description>
+        <description><![CDATA[
+          The command to execute.
+        ]]></description>
+      </attribute>
+      <attribute name="failifexecutionfails" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Stop the build if program cannot be started.]]></short-description>
+        <description><![CDATA[
+          Stop the build if program cannot be started. Defaults to true.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Fail if the command exits with a non-zero return code.]]></short-description>
+        <description><![CDATA[
+          Fail if the command exits with a non-zero return code.
+        ]]></description>
+      </attribute>
+      <attribute name="newenvironment" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Do not propagate old environment when new environment variables are specified.]]></short-description>
+        <description><![CDATA[
+          Do not propagate old environment when new environment variables are specified.
+        ]]></description>
+      </attribute>
+      <attribute name="os" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[List of operating systems on which the command may be executed.]]></short-description>
+        <description><![CDATA[
+          List of operating systems on which the command may be executed.
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File the output of the process is redirected to.]]></short-description>
+        <description><![CDATA[
+          File the output of the process is redirected to.
+        ]]></description>
+      </attribute>
+      <attribute name="outputproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Property name whose value should be set to the output of
+ the process.]]></short-description>
+        <description><![CDATA[
+          Property name whose value should be set to the output of
+ the process.
+        ]]></description>
+      </attribute>
+      <attribute name="parallel" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, run the command only once, appending all files as arguments.]]></short-description>
+        <description><![CDATA[
+          If true, run the command only once, appending all files as arguments.
+ If false, command will be executed once for every file. Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="relative" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the filenames should be passed on the command line as
+ absolute or relative pathnames.]]></short-description>
+        <description><![CDATA[
+          Whether the filenames should be passed on the command line as
+ absolute or relative pathnames. Paths are relative to the base
+ directory of the corresponding fileset for source files or the
+ dest attribute for target files.
+        ]]></description>
+      </attribute>
+      <attribute name="resultproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of a property in which the return code of the
+ command should be stored.]]></short-description>
+        <description><![CDATA[
+          The name of a property in which the return code of the
+ command should be stored. Only of interest if failonerror=false.
+        ]]></description>
+      </attribute>
+      <attribute name="skipemptyfilesets" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If no source files have been found or are newer than their
+ corresponding target files, do not run the command.]]></short-description>
+        <description><![CDATA[
+          If no source files have been found or are newer than their
+ corresponding target files, do not run the command.
+        ]]></description>
+      </attribute>
+      <attribute name="type" type="org.apache.tools.ant.taskdefs.ExecuteOn.FileDirBoth"
+                 briefType="&quot;file&quot;, &quot;dir&quot;, &quot;both&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the command works only on files, directories or both?.]]></short-description>
+        <description><![CDATA[
+          Whether the command works only on files, directories or both?
+        ]]></description>
+      </attribute>
+      <attribute name="vmlauncher" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, launch new process with VM, otherwise use the OS's shell.]]></short-description>
+        <description><![CDATA[
+          If true, launch new process with VM, otherwise use the OS's shell.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="env" type="org.apache.tools.ant.types.Environment.Variable"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an environment variable to the launched process.]]></short-description>
+        <description>
+          <![CDATA[Add an environment variable to the launched process.]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Source files to operate upon.]]></short-description>
+        <description>
+          <![CDATA[Source files to operate upon.]]>
+        </description>
+      </element>
+
+      <element name="arg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a command-line argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a command-line argument.]]>
+        </description>
+      </element>
+
+      <element name="mapper" type="org.apache.tools.ant.types.Mapper"
+               briefType="Mapper"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Mapper to use for mapping source files to target files.]]></short-description>
+        <description>
+          <![CDATA[Mapper to use for mapping source files to target files.]]>
+        </description>
+      </element>
+
+      <element name="srcfile" type="org.apache.tools.ant.types.Commandline.Marker"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Marker that indicates where the name of the source file should
+ be put on the command line.]]></short-description>
+        <description>
+          <![CDATA[Marker that indicates where the name of the source file should
+ be put on the command line.]]>
+        </description>
+      </element>
+
+      <element name="targetfile" type="org.apache.tools.ant.types.Commandline.Marker"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Marker that indicates where the name of the target file should
+ be put on the command line.]]></short-description>
+        <description>
+          <![CDATA[Marker that indicates where the name of the target file should
+ be put on the command line.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="available" category="control"
+      classname="org.apache.tools.ant.taskdefs.Available"
+      >
+
+  <short-description><![CDATA[Will set the given property if the requested resource is available at runtime.]]></short-description>
+  <description>
+    <![CDATA[Will set the given property if the requested resource is available at 
+ runtime. This task may also be used as a condition by the condition task.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Classname of a class which must be available to set the given 
+ property.]]></short-description>
+        <description><![CDATA[
+          Set a classname of a class which must be available to set the given 
+ property.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used when searching for classes and resources.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used when searching for classes and resources.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath by reference.]]></short-description>
+        <description><![CDATA[
+          Set the classpath by reference.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File which must be present in the file system to set the given
+ property.]]></short-description>
+        <description><![CDATA[
+          Set the file which must be present in the file system to set the given
+ property.
+        ]]></description>
+      </attribute>
+      <attribute name="filepath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Path to use when looking for a file.]]></short-description>
+        <description><![CDATA[
+          Set the path to use when looking for a file.
+        ]]></description>
+      </attribute>
+      <attribute name="ignoresystemclasses" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether the search for classes should ignore the runtime classes and
+ just use the given classpath.]]></short-description>
+        <description><![CDATA[
+          Set whether the search for classes should ignore the runtime classes and
+ just use the given classpath.
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the property which will be set if the particular resource
+ is available.]]></short-description>
+        <description><![CDATA[
+          Set the name of the property which will be set if the particular resource
+ is available.
+        ]]></description>
+      </attribute>
+      <attribute name="resource" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of a Java resource which is required to set the property.]]></short-description>
+        <description><![CDATA[
+          Set the name of a Java resource which is required to set the property.
+        ]]></description>
+      </attribute>
+      <attribute name="type" type="org.apache.tools.ant.taskdefs.Available.FileDir"
+                 briefType="&quot;file&quot;, &quot;dir&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Set what type of file is required - either directory or file.]]></short-description>
+        <description><![CDATA[
+          Set what type of file is required - either directory or file.
+        ]]></description>
+      </attribute>
+      <attribute name="value" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Value to be given to the property if the desired resource is
+ available.]]></short-description>
+        <description><![CDATA[
+          Set the value to be given to the property if the desired resource is
+ available.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used when searching for classes and resources.]]></short-description>
+        <description>
+          <![CDATA[Classpath to be used when searching for classes and resources.]]>
+        </description>
+      </element>
+
+      <element name="filepath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Path to search for file resources.]]></short-description>
+        <description>
+          <![CDATA[Path to search for file resources.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="basename" category="property"
+      classname="org.apache.tools.ant.taskdefs.Basename"
+      >
+
+  <short-description><![CDATA[Sets a property to the base name of a specified file, optionally minus a suffix.]]></short-description>
+  <description>
+    <![CDATA[Sets a property to the base name of a specified file, optionally minus a
+ suffix.
+
+ This task can accept the following attributes:
+ <ul>
+ <li>file
+ <li>property
+ <li>suffix
+ </ul>
+ The <b>file</b> and <b>property</b> attributes are required. The
+ <b>suffix</b> attribute can be specified either with or without
+ the &quot;.&quot;, and the result will be the same (ie., the
+ returned file name will be minus the .suffix).
+ <p>
+ When this task executes, it will set the specified property to the
+ value of the last element in the specified file. If file is a
+ directory, the basename will be the last directory element. If file
+ is a full-path filename, the basename will be the simple file name.
+ If a suffix is specified, and the specified file ends in that suffix,
+ the basename will be the simple file name without the suffix.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File or directory to get base name from.]]></short-description>
+        <description><![CDATA[
+          File or directory to get base name from.
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Property to set base name to.]]></short-description>
+        <description><![CDATA[
+          Property to set base name to.
+        ]]></description>
+      </attribute>
+      <attribute name="suffix" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Optional suffix to remove from base name.]]></short-description>
+        <description><![CDATA[
+          Optional suffix to remove from base name.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="blgenclient" category="ejb"
+      classname="org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient"
+      >
+
+  <short-description><![CDATA[Generates a Borland Application Server 4.5 client JAR using as input the EJB JAR file.]]></short-description>
+  <description>
+    <![CDATA[Generates a Borland Application Server 4.5 client JAR using as
+ input the EJB JAR file.
+
+ Two mode are available: java mode (default) and fork mode. With the fork mode,
+ it is impossible to add classpath to the commmand line.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Path to use for classpath.]]></short-description>
+        <description><![CDATA[
+          Path to use for classpath.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Reference to existing path, to use as a classpath.]]></short-description>
+        <description><![CDATA[
+          Reference to existing path, to use as a classpath.
+        ]]></description>
+      </attribute>
+      <attribute name="clientjar" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Client JAR file name.]]></short-description>
+        <description><![CDATA[
+          Client JAR file name.
+        ]]></description>
+      </attribute>
+      <attribute name="debug" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, turn on the debug mode for each of the Borland tools launched.]]></short-description>
+        <description><![CDATA[
+          If true, turn on the debug mode for each of the Borland tools launched.
+        ]]></description>
+      </attribute>
+      <attribute name="ejbjar" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[EJB JAR file.]]></short-description>
+        <description><![CDATA[
+          EJB JAR file.
+        ]]></description>
+      </attribute>
+      <attribute name="mode" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Command launching mode: java or fork.]]></short-description>
+        <description><![CDATA[
+          Command launching mode: java or fork.
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds path to the classpath.]]></short-description>
+        <description>
+          <![CDATA[Adds path to the classpath.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="buildnumber" category="other"
+      classname="org.apache.tools.ant.taskdefs.BuildNumber"
+      >
+
+  <short-description><![CDATA[Read, increment, and write a build number in a file It will first attempt to read a build number from a file, then set the property "build.number" to the value that was read in (or 0 if no such value).]]></short-description>
+  <description>
+    <![CDATA[Read, increment, and write a build number in a file
+ It will first
+ attempt to read a build number from a file, then set the property
+ "build.number" to the value that was read in (or 0 if no such value). Then
+ it will increment the build number by one and write it back out into the
+ file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file in which the build number is stored.]]></short-description>
+        <description><![CDATA[
+          The file in which the build number is stored. Defaults to
+ "build.number" if not specified.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="bunzip2" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.BUnzip2"
+      >
+
+  <short-description><![CDATA[Expands a file that has been compressed with the BZIP2 algorithm.]]></short-description>
+  <description>
+    <![CDATA[Expands a file that has been compressed with the BZIP2
+ algorithm. Normally used to compress non-compressed archives such
+ as TAR files.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The destination file or directory; optional.]]></short-description>
+        <description><![CDATA[
+          The destination file or directory; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to expand; required.]]></short-description>
+        <description><![CDATA[
+          The file to expand; required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="bzip2" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.BZip2"
+      >
+
+  <short-description><![CDATA[Compresses a file with the BZIP2 algorithm.]]></short-description>
+  <description>
+    <![CDATA[Compresses a file with the BZIP2 algorithm. Normally used to compress
+ non-compressed archives such as TAR files.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to compress; required.]]></short-description>
+        <description><![CDATA[
+          the file to compress; required.
+        ]]></description>
+      </attribute>
+      <attribute name="zipfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The required destination file.]]></short-description>
+        <description><![CDATA[
+          the required destination file.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="cab" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.Cab"
+      matchingTask="true">
+
+  <short-description><![CDATA[Create a CAB archive.]]></short-description>
+  <description>
+    <![CDATA[Create a CAB archive.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="basedir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Base directory to look in for files to CAB.]]></short-description>
+        <description><![CDATA[
+          Base directory to look in for files to CAB.
+        ]]></description>
+      </attribute>
+      <attribute name="cabfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The name/location of where to create the .cab file.]]></short-description>
+        <description><![CDATA[
+          The name/location of where to create the .cab file.
+        ]]></description>
+      </attribute>
+      <attribute name="compress" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, compress the files otherwise only store them.]]></short-description>
+        <description><![CDATA[
+          If true, compress the files otherwise only store them.
+        ]]></description>
+      </attribute>
+      <attribute name="options" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets additional cabarc options that are not supported directly.]]></short-description>
+        <description><![CDATA[
+          Sets additional cabarc options that are not supported directly.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, display cabarc output.]]></short-description>
+        <description><![CDATA[
+          If true, display cabarc output.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files to archive.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files to archive.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="cccheckin" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckin"
+      >
+
+  <short-description><![CDATA[Performs ClearCase checkin.]]></short-description>
+  <description>
+    <![CDATA[Performs ClearCase checkin.
+
+ <p>
+ The following attributes are interpreted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+      <td>viewpath</td>
+      <td>Path to the ClearCase view file or directory that the command will operate on</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>comment</td>
+      <td>Specify a comment. Only one of comment or cfile may be used.</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>commentfile</td>
+      <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>nowarn</td>
+      <td>Suppress warning messages</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>preservetime</td>
+      <td>Preserve the modification time</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>keepcopy</td>
+      <td>Keeps a copy of the file with a .keep extension</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>identical</td>
+      <td>Allows the file to be checked in even if it is identical to the original</td>
+      <td>No</td>
+   <tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="cleartooldir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the cleartool executable is located.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the cleartool executable is located.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Comment string.]]></short-description>
+        <description><![CDATA[
+          Sets the comment string.
+        ]]></description>
+      </attribute>
+      <attribute name="commentfile" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies a file containing a comment.]]></short-description>
+        <description><![CDATA[
+          Specifies a file containing a comment.
+        ]]></description>
+      </attribute>
+      <attribute name="identical" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, allows the file to be checked in even
+ if it is identical to the original.]]></short-description>
+        <description><![CDATA[
+          If true, allows the file to be checked in even
+ if it is identical to the original.
+        ]]></description>
+      </attribute>
+      <attribute name="keepcopy" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, keeps a copy of the file with a .keep extension.]]></short-description>
+        <description><![CDATA[
+          If true, keeps a copy of the file with a .keep extension.
+        ]]></description>
+      </attribute>
+      <attribute name="nowarn" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, suppress warning messages.]]></short-description>
+        <description><![CDATA[
+          If true, suppress warning messages.
+        ]]></description>
+      </attribute>
+      <attribute name="preservetime" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, preserve the modification time.]]></short-description>
+        <description><![CDATA[
+          If true, preserve the modification time.
+        ]]></description>
+      </attribute>
+      <attribute name="viewpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the item in a ClearCase view to operate on.]]></short-description>
+        <description><![CDATA[
+          Set the path to the item in a ClearCase view to operate on.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="cccheckout" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckout"
+      >
+
+  <short-description><![CDATA[Performs ClearCase checkout.]]></short-description>
+  <description>
+    <![CDATA[Performs ClearCase checkout.
+
+ <p>
+ The following attributes are interpretted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+      <td>viewpath</td>
+      <td>Path to the ClearCase view file or directory that the command will operate on</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>reserved</td>
+      <td>Specifies whether to check out the file as reserved or not</td>
+      <td>Yes</td>
+   <tr>
+   <tr>
+      <td>out</td>
+      <td>Creates a writable file under a different filename</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>nodata</td>
+      <td>Checks out the file but does not create an editable file containing its data</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>branch</td>
+      <td>Specify a branch to check out the file to</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>version</td>
+      <td>Allows checkout of a version other than main latest</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>nowarn</td>
+      <td>Suppress warning messages</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>comment</td>
+      <td>Specify a comment. Only one of comment or cfile may be used.</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>commentfile</td>
+      <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+      <td>No</td>
+   <tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="branch" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specify a branch to check out the file to.]]></short-description>
+        <description><![CDATA[
+          Specify a branch to check out the file to.
+        ]]></description>
+      </attribute>
+      <attribute name="cleartooldir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the cleartool executable is located.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the cleartool executable is located.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Comment string.]]></short-description>
+        <description><![CDATA[
+          Sets the comment string.
+        ]]></description>
+      </attribute>
+      <attribute name="commentfile" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies a file containing a comment.]]></short-description>
+        <description><![CDATA[
+          Specifies a file containing a comment.
+        ]]></description>
+      </attribute>
+      <attribute name="nodata" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, checks out the file but does not create an
+ editable file containing its data.]]></short-description>
+        <description><![CDATA[
+          If true, checks out the file but does not create an
+ editable file containing its data.
+        ]]></description>
+      </attribute>
+      <attribute name="nowarn" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, warning messages are suppressed.]]></short-description>
+        <description><![CDATA[
+          If true, warning messages are suppressed.
+        ]]></description>
+      </attribute>
+      <attribute name="out" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Creates a writable file under a different filename.]]></short-description>
+        <description><![CDATA[
+          Creates a writable file under a different filename.
+        ]]></description>
+      </attribute>
+      <attribute name="reserved" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, checks out the file as reserved.]]></short-description>
+        <description><![CDATA[
+          If true, checks out the file as reserved.
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, allows checkout of a version other than main latest.]]></short-description>
+        <description><![CDATA[
+          If true, allows checkout of a version other than main latest.
+        ]]></description>
+      </attribute>
+      <attribute name="viewpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the item in a ClearCase view to operate on.]]></short-description>
+        <description><![CDATA[
+          Set the path to the item in a ClearCase view to operate on.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ccmcheckin" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckin"
+      >
+
+  <short-description><![CDATA[Performs Continuus checkin command.]]></short-description>
+  <description>
+    <![CDATA[Performs Continuus checkin command.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="ccmdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the ccm executable is located.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the ccm executable is located.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies a comment.]]></short-description>
+        <description><![CDATA[
+          Specifies a comment.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the file that the command will operate on.]]></short-description>
+        <description><![CDATA[
+          Sets the path to the file that the command will operate on.
+        ]]></description>
+      </attribute>
+      <attribute name="task" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the task number used to check
+ in the file (may use 'default').]]></short-description>
+        <description><![CDATA[
+          Specifies the task number used to check
+ in the file (may use 'default').
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ccmcheckintask" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckinDefault"
+      >
+
+  <short-description><![CDATA[Performs Continuus Checkin Default task command.]]></short-description>
+  <description>
+    <![CDATA[Performs Continuus Checkin Default task command.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="ccmdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the ccm executable is located.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the ccm executable is located.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies a comment.]]></short-description>
+        <description><![CDATA[
+          Specifies a comment.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the file that the command will operate on.]]></short-description>
+        <description><![CDATA[
+          Sets the path to the file that the command will operate on.
+        ]]></description>
+      </attribute>
+      <attribute name="task" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the task number used to check
+ in the file (may use 'default').]]></short-description>
+        <description><![CDATA[
+          Specifies the task number used to check
+ in the file (may use 'default').
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ccmcheckout" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckout"
+      >
+
+  <short-description><![CDATA[Performs Continuus checkout command.]]></short-description>
+  <description>
+    <![CDATA[Performs Continuus checkout command.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="ccmdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the ccm executable is located.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the ccm executable is located.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies a comment.]]></short-description>
+        <description><![CDATA[
+          Specifies a comment.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the file that the command will operate on.]]></short-description>
+        <description><![CDATA[
+          Sets the path to the file that the command will operate on.
+        ]]></description>
+      </attribute>
+      <attribute name="task" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the task number used to check
+ in the file (may use 'default').]]></short-description>
+        <description><![CDATA[
+          Specifies the task number used to check
+ in the file (may use 'default').
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ccmcreatetask" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCreateTask"
+      >
+
+  <short-description><![CDATA[Creates new Continuus ccm task and sets it as the default.]]></short-description>
+  <description>
+    <![CDATA[Creates new Continuus ccm task and sets it as the default.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="ccmdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the ccm executable is located.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the ccm executable is located.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies a comment.]]></short-description>
+        <description><![CDATA[
+          Specifies a comment.
+        ]]></description>
+      </attribute>
+      <attribute name="platform" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the target platform.]]></short-description>
+        <description><![CDATA[
+          Specifies the target platform.
+        ]]></description>
+      </attribute>
+      <attribute name="release" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specify the CCM release.]]></short-description>
+        <description><![CDATA[
+          Specify the CCM release.
+        ]]></description>
+      </attribute>
+      <attribute name="resolver" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the resolver.]]></short-description>
+        <description><![CDATA[
+          Specifies the resolver.
+        ]]></description>
+      </attribute>
+      <attribute name="subsystem" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the subsystem.]]></short-description>
+        <description><![CDATA[
+          Specifies the subsystem.
+        ]]></description>
+      </attribute>
+      <attribute name="task" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the task number used to checkin
+ the file (may use 'default').]]></short-description>
+        <description><![CDATA[
+          Specifies the task number used to checkin
+ the file (may use 'default').
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ccmreconfigure" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMReconfigure"
+      >
+
+  <short-description><![CDATA[Task allows to reconfigure a project, recurcively or not]]></short-description>
+  <description>
+    <![CDATA[Task allows to reconfigure a project, recurcively or not]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="ccmdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the ccm executable is located.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the ccm executable is located.
+        ]]></description>
+      </attribute>
+      <attribute name="ccmproject" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Ccm project on which the operation is applied.]]></short-description>
+        <description><![CDATA[
+          Sets the ccm project on which the operation is applied.
+        ]]></description>
+      </attribute>
+      <attribute name="recurse" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, recurse on subproject (default false).]]></short-description>
+        <description><![CDATA[
+          If true, recurse on subproject (default false).
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, do a verbose reconfigure operation (default false).]]></short-description>
+        <description><![CDATA[
+          If true, do a verbose reconfigure operation (default false).
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ccuncheckout" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCUnCheckout"
+      >
+
+  <short-description><![CDATA[Performs ClearCase UnCheckout command.]]></short-description>
+  <description>
+    <![CDATA[Performs ClearCase UnCheckout command.
+
+ <p>
+ The following attributes are interpretted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+      <td>viewpath</td>
+      <td>Path to the ClearCase view file or directory that the command will operate on</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>keepcopy</td>
+      <td>Specifies whether to keep a copy of the file with a .keep extension or not</td>
+      <td>No</td>
+   <tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="cleartooldir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the cleartool executable is located.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the cleartool executable is located.
+        ]]></description>
+      </attribute>
+      <attribute name="keepcopy" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, keep a copy of the file with a .keep extension.]]></short-description>
+        <description><![CDATA[
+          If true, keep a copy of the file with a .keep extension.
+        ]]></description>
+      </attribute>
+      <attribute name="viewpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the item in a ClearCase view to operate on.]]></short-description>
+        <description><![CDATA[
+          Set the path to the item in a ClearCase view to operate on.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ccupdate" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCUpdate"
+      >
+
+  <short-description><![CDATA[Performs a ClearCase Update command.]]></short-description>
+  <description>
+    <![CDATA[Performs a ClearCase Update command.
+
+ <p>
+ The following attributes are interpretted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+      <td>viewpath</td>
+      <td>Path to the ClearCase view file or directory that the command will operate on</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>graphical</td>
+      <td>Displays a graphical dialog during the update</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>log</td>
+      <td>Specifies a log file for ClearCase to write to</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>overwrite</td>
+      <td>Specifies whether to overwrite hijacked files or not</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>rename</td>
+      <td>Specifies that hijacked files should be renamed with a .keep extension</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>currenttime</td>
+      <td>Specifies that modification time should be written as the current time. Either currenttime or preservetime can be specified.</td>
+      <td>No</td>
+   <tr>
+   <tr>
+      <td>preservetime</td>
+      <td>Specifies that modification time should preserved from the VOB time. Either currenttime or preservetime can be specified.</td>
+      <td>No</td>
+   <tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="cleartooldir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the cleartool executable is located.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the cleartool executable is located.
+        ]]></description>
+      </attribute>
+      <attribute name="currenttime" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, modification time should be written as the current time.]]></short-description>
+        <description><![CDATA[
+          If true, modification time should be written as the current time.
+ Either currenttime or preservetime can be specified.
+        ]]></description>
+      </attribute>
+      <attribute name="graphical" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, displays a graphical dialog during the update.]]></short-description>
+        <description><![CDATA[
+          If true, displays a graphical dialog during the update.
+        ]]></description>
+      </attribute>
+      <attribute name="log" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Log file where cleartool records
+ the status of the command.]]></short-description>
+        <description><![CDATA[
+          Sets the log file where cleartool records
+ the status of the command.
+        ]]></description>
+      </attribute>
+      <attribute name="overwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, overwrite hijacked files.]]></short-description>
+        <description><![CDATA[
+          If true, overwrite hijacked files.
+        ]]></description>
+      </attribute>
+      <attribute name="preservetime" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, modification time should be preserved from the VOB time.]]></short-description>
+        <description><![CDATA[
+          If true, modification time should be preserved from the VOB time.
+ Either currenttime or preservetime can be specified.
+        ]]></description>
+      </attribute>
+      <attribute name="rename" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, hijacked files are renamed with a .keep extension.]]></short-description>
+        <description><![CDATA[
+          If true, hijacked files are renamed with a .keep extension.
+        ]]></description>
+      </attribute>
+      <attribute name="viewpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the item in a ClearCase view to operate on.]]></short-description>
+        <description><![CDATA[
+          Set the path to the item in a ClearCase view to operate on.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="checksum" category="control"
+      classname="org.apache.tools.ant.taskdefs.Checksum"
+      matchingTask="true">
+
+  <short-description><![CDATA[Used to create or verify file checksums.]]></short-description>
+  <description>
+    <![CDATA[Used to create or verify file checksums.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="algorithm" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the algorithm to be used to compute the checksum.]]></short-description>
+        <description><![CDATA[
+          Specifies the algorithm to be used to compute the checksum.
+ Defaults to "MD5". Other popular algorithms like "SHA" may be used as well.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File for which the checksum is to be calculated.]]></short-description>
+        <description><![CDATA[
+          Sets the file for which the checksum is to be calculated.
+        ]]></description>
+      </attribute>
+      <attribute name="fileext" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[File extension that is be to used to
+ create or identify destination file.]]></short-description>
+        <description><![CDATA[
+          Sets the file extension that is be to used to
+ create or identify destination file.
+        ]]></description>
+      </attribute>
+      <attribute name="forceoverwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether or not to overwrite existing file irrespective of 
+ whether it is newer than
+ the source file.]]></short-description>
+        <description><![CDATA[
+          Whether or not to overwrite existing file irrespective of 
+ whether it is newer than
+ the source file.  Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Property to hold the generated checksum.]]></short-description>
+        <description><![CDATA[
+          Sets the property to hold the generated checksum.
+        ]]></description>
+      </attribute>
+      <attribute name="provider" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[MessageDigest algorithm provider to be used
+ to calculate the checksum.]]></short-description>
+        <description><![CDATA[
+          Sets the MessageDigest algorithm provider to be used
+ to calculate the checksum.
+        ]]></description>
+      </attribute>
+      <attribute name="readbuffersize" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[The size of the read buffer to use.]]></short-description>
+        <description><![CDATA[
+          The size of the read buffer to use.
+        ]]></description>
+      </attribute>
+      <attribute name="verifyproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Verify property.]]></short-description>
+        <description><![CDATA[
+          Sets the verify property.  This project property holds
+ the result of a checksum verification - "true" or "false"
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Files to generate checksums for.]]></short-description>
+        <description>
+          <![CDATA[Files to generate checksums for.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="chmod" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.Chmod"
+      >
+
+  <short-description><![CDATA[Chmod equivalent for unix-like environments.]]></short-description>
+  <description>
+    <![CDATA[Chmod equivalent for unix-like environments.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether output should be appended to or overwrite an existing file.]]></short-description>
+        <description><![CDATA[
+          Whether output should be appended to or overwrite an existing file.
+ Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="defaultexcludes" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether default exclusions should be used or not.]]></short-description>
+        <description><![CDATA[
+          Sets whether default exclusions should be used or not.
+        ]]></description>
+      </attribute>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory where target files are to be placed.]]></short-description>
+        <description><![CDATA[
+          The directory where target files are to be placed.
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory which holds the files whose permissions must be changed.]]></short-description>
+        <description><![CDATA[
+          The directory which holds the files whose permissions must be changed.
+        ]]></description>
+      </attribute>
+      <attribute name="excludes" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set of exclude patterns.]]></short-description>
+        <description><![CDATA[
+          Sets the set of exclude patterns. Patterns may be separated by a comma
+ or a space.
+        ]]></description>
+      </attribute>
+      <attribute name="executable" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The command to execute.]]></short-description>
+        <description><![CDATA[
+          The command to execute.
+        ]]></description>
+      </attribute>
+      <attribute name="failifexecutionfails" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Stop the build if program cannot be started.]]></short-description>
+        <description><![CDATA[
+          Stop the build if program cannot be started. Defaults to true.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Fail if the command exits with a non-zero return code.]]></short-description>
+        <description><![CDATA[
+          Fail if the command exits with a non-zero return code.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file or single directory of which the permissions must be changed.]]></short-description>
+        <description><![CDATA[
+          The file or single directory of which the permissions must be changed.
+        ]]></description>
+      </attribute>
+      <attribute name="includes" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set of include patterns.]]></short-description>
+        <description><![CDATA[
+          Sets the set of include patterns. Patterns may be separated by a comma
+ or a space.
+        ]]></description>
+      </attribute>
+      <attribute name="newenvironment" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Do not propagate old environment when new environment variables are specified.]]></short-description>
+        <description><![CDATA[
+          Do not propagate old environment when new environment variables are specified.
+        ]]></description>
+      </attribute>
+      <attribute name="os" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[List of operating systems on which the command may be executed.]]></short-description>
+        <description><![CDATA[
+          List of operating systems on which the command may be executed.
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File the output of the process is redirected to.]]></short-description>
+        <description><![CDATA[
+          File the output of the process is redirected to.
+        ]]></description>
+      </attribute>
+      <attribute name="outputproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Property name whose value should be set to the output of
+ the process.]]></short-description>
+        <description><![CDATA[
+          Property name whose value should be set to the output of
+ the process.
+        ]]></description>
+      </attribute>
+      <attribute name="parallel" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, run the command only once, appending all files as arguments.]]></short-description>
+        <description><![CDATA[
+          If true, run the command only once, appending all files as arguments.
+ If false, command will be executed once for every file. Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="perm" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The new permissions.]]></short-description>
+        <description><![CDATA[
+          The new permissions.
+        ]]></description>
+      </attribute>
+      <attribute name="relative" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the filenames should be passed on the command line as
+ absolute or relative pathnames.]]></short-description>
+        <description><![CDATA[
+          Whether the filenames should be passed on the command line as
+ absolute or relative pathnames. Paths are relative to the base
+ directory of the corresponding fileset for source files or the
+ dest attribute for target files.
+        ]]></description>
+      </attribute>
+      <attribute name="resultproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of a property in which the return code of the
+ command should be stored.]]></short-description>
+        <description><![CDATA[
+          The name of a property in which the return code of the
+ command should be stored. Only of interest if failonerror=false.
+        ]]></description>
+      </attribute>
+      <attribute name="skipemptyfilesets" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If no source files have been found or are newer than their
+ corresponding target files, do not run the command.]]></short-description>
+        <description><![CDATA[
+          If no source files have been found or are newer than their
+ corresponding target files, do not run the command.
+        ]]></description>
+      </attribute>
+      <attribute name="type" type="org.apache.tools.ant.taskdefs.ExecuteOn.FileDirBoth"
+                 briefType="&quot;file&quot;, &quot;dir&quot;, &quot;both&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the command works only on files, directories or both?.]]></short-description>
+        <description><![CDATA[
+          Whether the command works only on files, directories or both?
+        ]]></description>
+      </attribute>
+      <attribute name="vmlauncher" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, launch new process with VM, otherwise use the OS's shell.]]></short-description>
+        <description><![CDATA[
+          If true, launch new process with VM, otherwise use the OS's shell.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="env" type="org.apache.tools.ant.types.Environment.Variable"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an environment variable to the launched process.]]></short-description>
+        <description>
+          <![CDATA[Add an environment variable to the launched process.]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Source files to operate upon.]]></short-description>
+        <description>
+          <![CDATA[Source files to operate upon.]]>
+        </description>
+      </element>
+
+      <element name="arg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a command-line argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a command-line argument.]]>
+        </description>
+      </element>
+
+      <element name="exclude" type="org.apache.tools.ant.types.PatternSet.NameEntry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a name entry on the exclude list.]]></short-description>
+        <description>
+          <![CDATA[Add a name entry on the exclude list.]]>
+        </description>
+      </element>
+
+      <element name="include" type="org.apache.tools.ant.types.PatternSet.NameEntry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a name entry on the include list.]]></short-description>
+        <description>
+          <![CDATA[Add a name entry on the include list.]]>
+        </description>
+      </element>
+
+      <element name="mapper" type="org.apache.tools.ant.types.Mapper"
+               briefType="Mapper"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Mapper to use for mapping source files to target files.]]></short-description>
+        <description>
+          <![CDATA[Mapper to use for mapping source files to target files.]]>
+        </description>
+      </element>
+
+      <element name="patternset" type="org.apache.tools.ant.types.PatternSet"
+               briefType="Patternset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a set of patterns.]]></short-description>
+        <description>
+          <![CDATA[Add a set of patterns.]]>
+        </description>
+      </element>
+
+      <element name="srcfile" type="org.apache.tools.ant.types.Commandline.Marker"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Marker that indicates where the name of the source file should
+ be put on the command line.]]></short-description>
+        <description>
+          <![CDATA[Marker that indicates where the name of the source file should
+ be put on the command line.]]>
+        </description>
+      </element>
+
+      <element name="targetfile" type="org.apache.tools.ant.types.Commandline.Marker"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Marker that indicates where the name of the target file should
+ be put on the command line.]]></short-description>
+        <description>
+          <![CDATA[Marker that indicates where the name of the target file should
+ be put on the command line.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="concat" category="other"
+      classname="org.apache.tools.ant.taskdefs.Concat"
+      >
+
+  <short-description><![CDATA[This class contains the 'concat' task, used to concatenate a series of files into a single stream.]]></short-description>
+  <description>
+    <![CDATA[This class contains the 'concat' task, used to concatenate a series
+ of files into a single stream. The destination of this stream may
+ be the system console, or a file. The following is a sample
+ invocation:
+
+ <pre>
+ &lt;concat destfile=&quot;${build.dir}/index.xml&quot;
+   append=&quot;false&quot;&gt;
+
+   &lt;fileset dir=&quot;${xml.root.dir}&quot;
+     includes=&quot;*.xml&quot; /&gt;
+
+ &lt;/concat&gt;
+ </pre>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Behavior when the destination file exists.]]></short-description>
+        <description><![CDATA[
+          Sets the behavior when the destination file exists. If set to
+ <code>true</code> the stream data will be appended to the
+ existing file, otherwise the existing file will be
+ overwritten. Defaults to <code>false</code>.
+        ]]></description>
+      </attribute>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination file, or uses the console if not specified.]]></short-description>
+        <description><![CDATA[
+          Sets the destination file, or uses the console if not specified.
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Encoding for the input files, used when displaying the
+ data via the console.]]></short-description>
+        <description><![CDATA[
+          Sets the encoding for the input files, used when displaying the
+ data via the console.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="filelist" type="org.apache.tools.ant.types.FileList"
+               briefType="Filelist"
+               required="NOTDEFINED">
+        <short-description><![CDATA[List of files to concatenate.]]></short-description>
+        <description>
+          <![CDATA[List of files to concatenate.]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Set of files to concatenate.]]></short-description>
+        <description>
+          <![CDATA[Set of files to concatenate.]]>
+        </description>
+      </element>
+
+    </elements>
+
+      <body >
+        <description><![CDATA[
+          This method adds text which appears in the 'concat' element.
+        ]]></description>
+      </body>
+
+  </structure>
+
+</task>
+
+
+<task name="condition" category="control"
+      classname="org.apache.tools.ant.taskdefs.ConditionTask"
+      >
+
+  <short-description><![CDATA[Task to set a property conditionally using &lt;uptodate&gt;, &lt;available&gt;, and many other supported conditions.]]></short-description>
+  <description>
+    <![CDATA[Task to set a property conditionally using &lt;uptodate&gt;, &lt;available&gt;,
+ and many other supported conditions.
+
+ <p>This task supports boolean logic as well as pluggable conditions
+ to decide, whether a property should be set.</p>
+
+ <p>This task does not extend Task to take advantage of
+ ConditionBase.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the property to set.]]></short-description>
+        <description><![CDATA[
+          The name of the property to set. Required.
+        ]]></description>
+      </attribute>
+      <attribute name="value" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The value for the property to set, if condition evaluates to true.]]></short-description>
+        <description><![CDATA[
+          The value for the property to set, if condition evaluates to true.
+ Defaults to "true".
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="and" type="org.apache.tools.ant.taskdefs.condition.And"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;and&gt; condition "container".]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;and&gt; condition "container".]]>
+        </description>
+      </element>
+
+      <element name="available" type="org.apache.tools.ant.taskdefs.Available"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;available&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;available&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="checksum" type="org.apache.tools.ant.taskdefs.Checksum"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;checksum&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;checksum&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="contains" type="org.apache.tools.ant.taskdefs.condition.Contains"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;contains&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;contains&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="equals" type="org.apache.tools.ant.taskdefs.condition.Equals"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;equals&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;equals&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="filesmatch" type="org.apache.tools.ant.taskdefs.condition.FilesMatch"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;filesmatch&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;filesmatch&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="http" type="org.apache.tools.ant.taskdefs.condition.Http"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;http&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;http&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="isfalse" type="org.apache.tools.ant.taskdefs.condition.IsFalse"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;isfalse&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;isfalse&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="isset" type="org.apache.tools.ant.taskdefs.condition.IsSet"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;isset&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;isset&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="istrue" type="org.apache.tools.ant.taskdefs.condition.IsTrue"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;istrue&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;istrue&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="not" type="org.apache.tools.ant.taskdefs.condition.Not"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;not&gt; condition "container".]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;not&gt; condition "container".]]>
+        </description>
+      </element>
+
+      <element name="or" type="org.apache.tools.ant.taskdefs.condition.Or"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;or&gt; condition "container".]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;or&gt; condition "container".]]>
+        </description>
+      </element>
+
+      <element name="os" type="org.apache.tools.ant.taskdefs.condition.Os"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;os&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;os&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="socket" type="org.apache.tools.ant.taskdefs.condition.Socket"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;socket&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;socket&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="uptodate" type="org.apache.tools.ant.taskdefs.UpToDate"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;uptodate&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;uptodate&gt; condition.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="copy" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.Copy"
+      >
+
+  <short-description><![CDATA[Copies a file or directory to a new file or directory.]]></short-description>
+  <description>
+    <![CDATA[Copies a file or directory to a new file
+ or directory.  Files are only copied if the source file is newer
+ than the destination file, or when the destination file does not
+ exist.  It is possible to explicitly overwrite existing files.</p>
+
+ <p>This implementation is based on Arnout Kuiper's initial design
+ document, the following mailing list discussions, and the
+ copyfile/copydir tasks.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Character encoding.]]></short-description>
+        <description><![CDATA[
+          Sets the character encoding
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If false, note errors to the output but keep going.]]></short-description>
+        <description><![CDATA[
+          If false, note errors to the output but keep going.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Single source file to copy.]]></short-description>
+        <description><![CDATA[
+          Sets a single source file to copy.
+        ]]></description>
+      </attribute>
+      <attribute name="filtering" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enables filtering.]]></short-description>
+        <description><![CDATA[
+          If true, enables filtering.
+        ]]></description>
+      </attribute>
+      <attribute name="flatten" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[When copying directory trees, the files can be "flattened"
+ into a single directory.]]></short-description>
+        <description><![CDATA[
+          When copying directory trees, the files can be "flattened"
+ into a single directory.  If there are multiple files with
+ the same name in the source directory tree, only the first
+ file will be copied into the "flattened" directory, unless
+ the forceoverwrite attribute is true.
+        ]]></description>
+      </attribute>
+      <attribute name="includeemptydirs" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Used to copy empty directories.]]></short-description>
+        <description><![CDATA[
+          Used to copy empty directories.
+        ]]></description>
+      </attribute>
+      <attribute name="overwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Overwrite any existing destination file(s).]]></short-description>
+        <description><![CDATA[
+          Overwrite any existing destination file(s).
+        ]]></description>
+      </attribute>
+      <attribute name="preservelastmodified" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Give the copied files the same last modified time as the original files.]]></short-description>
+        <description><![CDATA[
+          Give the copied files the same last modified time as the original files.
+        ]]></description>
+      </attribute>
+      <attribute name="todir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory.]]></short-description>
+        <description><![CDATA[
+          Sets the destination directory.
+        ]]></description>
+      </attribute>
+      <attribute name="tofile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination file.]]></short-description>
+        <description><![CDATA[
+          Sets the destination file.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Used to force listing of all names of copied files.]]></short-description>
+        <description><![CDATA[
+          Used to force listing of all names of copied files.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files to copy.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files to copy.]]>
+        </description>
+      </element>
+
+      <element name="filterchain" type="org.apache.tools.ant.types.FilterChain"
+               briefType="FilterChain"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a FilterChain.]]></short-description>
+        <description>
+          <![CDATA[Adds a FilterChain.]]>
+        </description>
+      </element>
+
+      <element name="filterset" type="org.apache.tools.ant.types.FilterSet"
+               briefType="Filterset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a filterset.]]></short-description>
+        <description>
+          <![CDATA[Adds a filterset.]]>
+        </description>
+      </element>
+
+      <element name="mapper" type="org.apache.tools.ant.types.Mapper"
+               briefType="Mapper"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Defines the mapper to map source to destination files.]]></short-description>
+        <description>
+          <![CDATA[Defines the mapper to map source to destination files.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="copydir" category="other"
+      classname="org.apache.tools.ant.taskdefs.Copydir"
+      deprecated="true"
+      matchingTask="true">
+
+  <short-description><![CDATA[Copies a directory.]]></short-description>
+  <description>
+    <![CDATA[Copies a directory.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+      <attribute name="filtering" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+      <attribute name="flatten" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+      <attribute name="forceoverwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="copyfile" category="other"
+      classname="org.apache.tools.ant.taskdefs.Copyfile"
+      deprecated="true"
+      >
+
+  <short-description><![CDATA[Copies a file.]]></short-description>
+  <description>
+    <![CDATA[Copies a file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+      <attribute name="filtering" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+      <attribute name="forceoverwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="csc" category="dotnet"
+      classname="org.apache.tools.ant.taskdefs.optional.dotnet.CSharp"
+      matchingTask="true">
+
+  <short-description><![CDATA[Compiles C# source into executables or modules.]]></short-description>
+  <description>
+    <![CDATA[Compiles C# source into executables or modules.
+
+  The task will only work on win2K until other platforms support
+  csc.exe or an equivalent. CSC.exe must be on the execute path too. <p>
+
+  All parameters are optional: &lt;csc/&gt; should suffice to produce a debug
+  build of all *.cs files. References to external files do require explicit
+  enumeration, so are one of the first attributes to consider adding. <p>
+
+  The task is a directory based task, so attributes like <b>includes="*.cs"
+  </b> and <b>excludes="broken.cs"</b> can be used to control the files pulled
+  in. By default, all *.cs files from the project folder down are included in
+  the command. When this happens the output file -if not specified- is taken
+  as the first file in the list, which may be somewhat hard to control.
+  Specifying the output file with <b>'outfile'</b> seems prudent. <p>
+
+  <p>
+
+  TODO
+  <ol>
+    <li> is incremental build still broken in beta-1?
+    <li> is Win32Icon broken?
+    <li> all the missing options
+  </ol>
+  <p>
+
+  History
+  <Table>
+
+    <tr>
+
+      <td>
+        0.3
+      </td>
+
+      <td>
+        Beta 1 edition
+      </td>
+
+      <td>
+        To avoid having to remember which assemblies to include, the task
+        automatically refers to the main dotnet libraries in Beta1.
+      </tr>
+
+      <tr>
+
+        <td>
+          0.2
+        </td>
+
+        <td>
+          Slightly different
+        </td>
+
+        <td>
+          Split command execution to a separate class;
+        </tr>
+
+        <tr>
+
+          <td>
+            0.1
+          </td>
+
+          <td>
+            "I can't believe it's so rudimentary"
+          </td>
+
+          <td>
+            First pass; minimal builds only support;
+          </tr>
+
+        </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="additionalmodules" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Semicolon separated list of modules to refer to.]]></short-description>
+        <description><![CDATA[
+          Semicolon separated list of modules to refer to.
+        ]]></description>
+      </attribute>
+      <attribute name="debug" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Debug flag on or off.]]></short-description>
+        <description><![CDATA[
+          set the debug flag on or off.
+        ]]></description>
+      </attribute>
+      <attribute name="definitions" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Semicolon separated list of defined constants.]]></short-description>
+        <description><![CDATA[
+          Semicolon separated list of defined constants.
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory of files to be compiled.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory of files to be compiled.
+        ]]></description>
+      </attribute>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of exe/library to create.]]></short-description>
+        <description><![CDATA[
+          Set the name of exe/library to create.
+        ]]></description>
+      </attribute>
+      <attribute name="docfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File for generated XML documentation.]]></short-description>
+        <description><![CDATA[
+          file for generated XML documentation
+        ]]></description>
+      </attribute>
+      <attribute name="extraoptions" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Any extra options which are not explicitly supported
+ by this task.]]></short-description>
+        <description><![CDATA[
+          Any extra options which are not explicitly supported
+ by this task.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, fail on compilation errors.]]></short-description>
+        <description><![CDATA[
+          If true, fail on compilation errors.
+        ]]></description>
+      </attribute>
+      <attribute name="filealign" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[File alignment.]]></short-description>
+        <description><![CDATA[
+          Set the file alignment.
+ Valid values are 0,512, 1024, 2048, 4096, 8192,
+ and 16384, 0 means 'leave to the compiler'
+        ]]></description>
+      </attribute>
+      <attribute name="fullpaths" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, print the full path of files on errors.]]></short-description>
+        <description><![CDATA[
+          If true, print the full path of files on errors.
+        ]]></description>
+      </attribute>
+      <attribute name="includedefaultreferences" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, automatically includes the common assemblies
+ in dotnet, and tells the compiler to link in mscore.dll.
+
+  set the automatic reference inclusion flag on or off this flag controls
+  the string of references and the /nostdlib option in CSC.]]></short-description>
+        <description><![CDATA[
+          If true, automatically includes the common assemblies
+ in dotnet, and tells the compiler to link in mscore.dll.
+
+  set the automatic reference inclusion flag on or off this flag controls
+  the string of references and the /nostdlib option in CSC
+        ]]></description>
+      </attribute>
+      <attribute name="incremental" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Incremental compilation flag on or off.]]></short-description>
+        <description><![CDATA[
+          set the incremental compilation flag on or off.
+        ]]></description>
+      </attribute>
+      <attribute name="mainclass" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of main class for executables.]]></short-description>
+        <description><![CDATA[
+          Sets the name of main class for executables.
+        ]]></description>
+      </attribute>
+      <attribute name="noconfig" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[A flag that tells the compiler not to read in the compiler 
+ settings files 'csc.rsp' in its bin directory and then the local directory.]]></short-description>
+        <description><![CDATA[
+          A flag that tells the compiler not to read in the compiler 
+ settings files 'csc.rsp' in its bin directory and then the local directory
+        ]]></description>
+      </attribute>
+      <attribute name="optimize" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enables optimization flag.]]></short-description>
+        <description><![CDATA[
+          If true, enables optimization flag.
+        ]]></description>
+      </attribute>
+      <attribute name="outputfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Output file.]]></short-description>
+        <description><![CDATA[
+          Set the output file
+        ]]></description>
+      </attribute>
+      <attribute name="referencefiles" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Path of references to include.]]></short-description>
+        <description><![CDATA[
+          Path of references to include.
+ Wildcards should work.
+        ]]></description>
+      </attribute>
+      <attribute name="references" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Semicolon separated list of DLLs to refer to.]]></short-description>
+        <description><![CDATA[
+          Semicolon separated list of DLLs to refer to.
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source directory of the files to be compiled.]]></short-description>
+        <description><![CDATA[
+          Set the source directory of the files to be compiled.
+        ]]></description>
+      </attribute>
+      <attribute name="targettype" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Type of target.]]></short-description>
+        <description><![CDATA[
+          Set the type of target.
+        ]]></description>
+      </attribute>
+      <attribute name="unsafe" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enables the unsafe keyword.]]></short-description>
+        <description><![CDATA[
+          If true, enables the unsafe keyword.
+        ]]></description>
+      </attribute>
+      <attribute name="utf8output" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, require all compiler output to be in UTF8 format.]]></short-description>
+        <description><![CDATA[
+          If true, require all compiler output to be in UTF8 format.
+        ]]></description>
+      </attribute>
+      <attribute name="warnlevel" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Level of warning currently between 1 and 4
+ with 4 being the strictest.]]></short-description>
+        <description><![CDATA[
+          Level of warning currently between 1 and 4
+ with 4 being the strictest.
+        ]]></description>
+      </attribute>
+      <attribute name="win32icon" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Filename of icon to include.]]></short-description>
+        <description><![CDATA[
+          Set the filename of icon to include.
+        ]]></description>
+      </attribute>
+      <attribute name="win32res" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Filename of a win32 resource (.RES) file to include.]]></short-description>
+        <description><![CDATA[
+          Sets the filename of a win32 resource (.RES) file to include.
+ This is not a .NET resource, but what Windows is used to.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="cvs" category="scm"
+      classname="org.apache.tools.ant.taskdefs.Cvs"
+      >
+
+  <short-description><![CDATA[Performs operations on a CVS repository. original 1.20 NOTE: This implementation has been moved to AbstractCvsTask with the addition of some accessors for extensibility.]]></short-description>
+  <description>
+    <![CDATA[Performs operations on a CVS repository.
+
+ original 1.20
+
+  NOTE: This implementation has been moved to AbstractCvsTask with
+  the addition of some accessors for extensibility.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to append output/error when redirecting to a file.]]></short-description>
+        <description><![CDATA[
+          Whether to append output/error when redirecting to a file.
+        ]]></description>
+      </attribute>
+      <attribute name="command" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The CVS command to execute.]]></short-description>
+        <description><![CDATA[
+          The CVS command to execute.
+        ]]></description>
+      </attribute>
+      <attribute name="compression" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, this is the same as compressionlevel="3".]]></short-description>
+        <description><![CDATA[
+          If true, this is the same as compressionlevel="3".
+        ]]></description>
+      </attribute>
+      <attribute name="compressionlevel" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[If set to a value 1-9 it adds -zN to the cvs command line, else
+ it disables compression.]]></short-description>
+        <description><![CDATA[
+          If set to a value 1-9 it adds -zN to the cvs command line, else
+ it disables compression.
+        ]]></description>
+      </attribute>
+      <attribute name="cvsroot" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The CVSROOT variable.]]></short-description>
+        <description><![CDATA[
+          The CVSROOT variable.
+        ]]></description>
+      </attribute>
+      <attribute name="cvsrsh" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The CVS_RSH variable.]]></short-description>
+        <description><![CDATA[
+          The CVS_RSH variable.
+        ]]></description>
+      </attribute>
+      <attribute name="date" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Use the most recent revision no later than the given date.]]></short-description>
+        <description><![CDATA[
+          Use the most recent revision no later than the given date.
+        ]]></description>
+      </attribute>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory where the checked out files should be placed.]]></short-description>
+        <description><![CDATA[
+          The directory where the checked out files should be placed.
+        ]]></description>
+      </attribute>
+      <attribute name="error" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to direct standard error from the command.]]></short-description>
+        <description><![CDATA[
+          The file to direct standard error from the command.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Stop the build process if the command exits with
+ a return code other than 0.]]></short-description>
+        <description><![CDATA[
+          Stop the build process if the command exits with
+ a return code other than 0.
+ Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="noexec" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, report only and don't change any files.]]></short-description>
+        <description><![CDATA[
+          If true, report only and don't change any files.
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to direct standard output from the command.]]></short-description>
+        <description><![CDATA[
+          The file to direct standard output from the command.
+        ]]></description>
+      </attribute>
+      <attribute name="package" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The package/module to operate upon.]]></short-description>
+        <description><![CDATA[
+          The package/module to operate upon.
+        ]]></description>
+      </attribute>
+      <attribute name="passfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Password file to read passwords from.]]></short-description>
+        <description><![CDATA[
+          Password file to read passwords from.
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Port used by CVS to communicate with the server.]]></short-description>
+        <description><![CDATA[
+          Port used by CVS to communicate with the server.
+        ]]></description>
+      </attribute>
+      <attribute name="quiet" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, suppress informational messages.]]></short-description>
+        <description><![CDATA[
+          If true, suppress informational messages.
+        ]]></description>
+      </attribute>
+      <attribute name="tag" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The tag of the package/module to operate upon.]]></short-description>
+        <description><![CDATA[
+          The tag of the package/module to operate upon.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="commandline" type="org.apache.tools.ant.types.Commandline"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds direct command-line to execute.]]></short-description>
+        <description>
+          <![CDATA[Adds direct command-line to execute.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="cvschangelog" category="other"
+      classname="org.apache.tools.ant.taskdefs.cvslib.ChangeLogTask"
+      >
+
+  <short-description><![CDATA[Examines the output of cvs log and group related changes together.]]></short-description>
+  <description>
+    <![CDATA[Examines the output of cvs log and group related changes together.
+
+ It produces an XML output representing the list of changes.
+ <PRE>
+ <FONT color=#0000ff>&lt;!-- Root element --&gt;</FONT>
+ <FONT color=#6a5acd>&lt;!ELEMENT</FONT> changelog <FONT color=#ff00ff>(entry</FONT><FONT color=#ff00ff>+</FONT><FONT color=#ff00ff>)</FONT><FONT color=#6a5acd>&gt;</FONT>
+ <FONT color=#0000ff>&lt;!-- CVS Entry --&gt;</FONT>
+ <FONT color=#6a5acd>&lt;!ELEMENT</FONT> entry <FONT color=#ff00ff>(date,author,file</FONT><FONT color=#ff00ff>+</FONT><FONT color=#ff00ff>,msg)</FONT><FONT color=#6a5acd>&gt;</FONT>
+ <FONT color=#0000ff>&lt;!-- Date of cvs entry --&gt;</FONT>
+ <FONT color=#6a5acd>&lt;!ELEMENT</FONT> date <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
+ <FONT color=#0000ff>&lt;!-- Author of change --&gt;</FONT>
+ <FONT color=#6a5acd>&lt;!ELEMENT</FONT> author <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
+ <FONT color=#0000ff>&lt;!-- List of files affected --&gt;</FONT>
+ <FONT color=#6a5acd>&lt;!ELEMENT</FONT> msg <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
+ <FONT color=#0000ff>&lt;!-- File changed --&gt;</FONT>
+ <FONT color=#6a5acd>&lt;!ELEMENT</FONT> file <FONT color=#ff00ff>(name,revision,prevrevision</FONT><FONT color=#ff00ff>?</FONT><FONT color=#ff00ff>)</FONT><FONT color=#6a5acd>&gt;</FONT>
+ <FONT color=#0000ff>&lt;!-- Name of the file --&gt;</FONT>
+ <FONT color=#6a5acd>&lt;!ELEMENT</FONT> name <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
+ <FONT color=#0000ff>&lt;!-- Revision number --&gt;</FONT>
+ <FONT color=#6a5acd>&lt;!ELEMENT</FONT> revision <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
+ <FONT color=#0000ff>&lt;!-- Previous revision number --&gt;</FONT>
+ <FONT color=#6a5acd>&lt;!ELEMENT</FONT> prevrevision <FONT color=#ff00ff>(#PCDATA)</FONT><FONT color=#6a5acd>&gt;</FONT>
+ </PRE>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="daysinpast" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Number of days worth of log entries to process.]]></short-description>
+        <description><![CDATA[
+          Set the number of days worth of log entries to process.
+        ]]></description>
+      </attribute>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Output file for the log.]]></short-description>
+        <description><![CDATA[
+          Set the output file for the log.
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Base dir for cvs.]]></short-description>
+        <description><![CDATA[
+          Set the base dir for cvs.
+        ]]></description>
+      </attribute>
+      <attribute name="end" type="java.util.Date"
+                 briefType="Date" required="NOTDEFINED">
+        <short-description><![CDATA[Date at which the changelog should stop.]]></short-description>
+        <description><![CDATA[
+          Set the date at which the changelog should stop.
+        ]]></description>
+      </attribute>
+      <attribute name="start" type="java.util.Date"
+                 briefType="Date" required="NOTDEFINED">
+        <short-description><![CDATA[Date at which the changelog should start.]]></short-description>
+        <description><![CDATA[
+          Set the date at which the changelog should start.
+        ]]></description>
+      </attribute>
+      <attribute name="usersfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Lookup list of user names & addresses.]]></short-description>
+        <description><![CDATA[
+          Set a lookup list of user names & addresses
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files about which cvs logs will be generated.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files about which cvs logs will be generated.]]>
+        </description>
+      </element>
+
+      <element name="user" type="org.apache.tools.ant.taskdefs.cvslib.CvsUser"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a user to list changelog knows about.]]></short-description>
+        <description>
+          <![CDATA[Add a user to list changelog knows about.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="cvspass" category="scm"
+      classname="org.apache.tools.ant.taskdefs.CVSPass"
+      >
+
+  <short-description><![CDATA[Adds an new entry to a CVS password file.]]></short-description>
+  <description>
+    <![CDATA[Adds an new entry to a CVS password file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="cvsroot" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The CVS repository to add an entry for.]]></short-description>
+        <description><![CDATA[
+          The CVS repository to add an entry for.
+        ]]></description>
+      </attribute>
+      <attribute name="passfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Password file to add the entry to.]]></short-description>
+        <description><![CDATA[
+          Password file to add the entry to.
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Password to be added to the password file.]]></short-description>
+        <description><![CDATA[
+          Password to be added to the password file.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="cvstagdiff" category="other"
+      classname="org.apache.tools.ant.taskdefs.cvslib.CvsTagDiff"
+      >
+
+  <short-description><![CDATA[Examines the output of cvs rdiff between two tags.]]></short-description>
+  <description>
+    <![CDATA[Examines the output of cvs rdiff between two tags.
+
+ It produces an XML output representing the list of changes.
+ <PRE>
+ &lt;!-- Root element --&gt;
+ &lt;!ELEMENT tagdiff ( entry+ ) &gt;
+ &lt;!-- Start tag of the report --&gt;
+ &lt;!ATTLIST tagdiff startTag NMTOKEN #IMPLIED &gt;
+ &lt;!-- End tag of the report --&gt;
+ &lt;!ATTLIST tagdiff endTag NMTOKEN #IMPLIED &gt;
+ &lt;!-- Start date of the report --&gt;
+ &lt;!ATTLIST tagdiff startDate NMTOKEN #IMPLIED &gt;
+ &lt;!-- End date of the report --&gt;
+ &lt;!ATTLIST tagdiff endDate NMTOKEN #IMPLIED &gt;
+
+ &lt;!-- CVS tag entry --&gt;
+ &lt;!ELEMENT entry ( file ) &gt;
+ &lt;!-- File added, changed or removed --&gt;
+ &lt;!ELEMENT file ( name, revision?, prevrevision? ) &gt;
+ &lt;!-- Name of the file --&gt;
+ &lt;!ELEMENT name ( #PCDATA ) &gt;
+ &lt;!-- Revision number --&gt;
+ &lt;!ELEMENT revision ( #PCDATA ) &gt;
+ &lt;!-- Previous revision number --&gt;
+ &lt;!ELEMENT prevrevision ( #PCDATA ) &gt;
+ </PRE>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="compression" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, this is the same as compressionlevel="3".]]></short-description>
+        <description><![CDATA[
+          If true, this is the same as compressionlevel="3".
+        ]]></description>
+      </attribute>
+      <attribute name="compressionlevel" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[If set to a value 1-9 it adds -zN to the cvs command line, else
+ it disables compression.]]></short-description>
+        <description><![CDATA[
+          If set to a value 1-9 it adds -zN to the cvs command line, else
+ it disables compression.
+        ]]></description>
+      </attribute>
+      <attribute name="cvsroot" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The CVSROOT variable.]]></short-description>
+        <description><![CDATA[
+          The CVSROOT variable.
+        ]]></description>
+      </attribute>
+      <attribute name="cvsrsh" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The CVS_RSH variable.]]></short-description>
+        <description><![CDATA[
+          The CVS_RSH variable.
+        ]]></description>
+      </attribute>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Output file for the diff.]]></short-description>
+        <description><![CDATA[
+          Set the output file for the diff.
+        ]]></description>
+      </attribute>
+      <attribute name="enddate" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[End date.]]></short-description>
+        <description><![CDATA[
+          Set the end date.
+        ]]></description>
+      </attribute>
+      <attribute name="endtag" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[End tag.]]></short-description>
+        <description><![CDATA[
+          Set the end tag.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Stop the build process if the command exits with
+ a return code other than 0.]]></short-description>
+        <description><![CDATA[
+          Stop the build process if the command exits with
+ a return code other than 0.
+ Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="package" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The package/module to analyze.]]></short-description>
+        <description><![CDATA[
+          The package/module to analyze.
+        ]]></description>
+      </attribute>
+      <attribute name="passfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Password file to read passwords from.]]></short-description>
+        <description><![CDATA[
+          Password file to read passwords from.
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Port used by CVS to communicate with the server.]]></short-description>
+        <description><![CDATA[
+          Port used by CVS to communicate with the server.
+        ]]></description>
+      </attribute>
+      <attribute name="quiet" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, suppress informational messages.]]></short-description>
+        <description><![CDATA[
+          If true, suppress informational messages.
+        ]]></description>
+      </attribute>
+      <attribute name="startdate" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Start date.]]></short-description>
+        <description><![CDATA[
+          Set the start date.
+        ]]></description>
+      </attribute>
+      <attribute name="starttag" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Start tag.]]></short-description>
+        <description><![CDATA[
+          Set the start tag.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ddcreator" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ejb.DDCreator"
+      matchingTask="true">
+
+  <short-description><![CDATA[Builds a serialized deployment descriptor given a text file description of the descriptor in the format supported by WebLogic.]]></short-description>
+  <description>
+    <![CDATA[Builds a serialized deployment descriptor given a text file description of the
+ descriptor in the format supported by WebLogic.
+
+ This ant task is a front end for the weblogic DDCreator tool.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for this compilation.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used for this compilation.
+        ]]></description>
+      </attribute>
+      <attribute name="descriptors" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory from where the text descriptions of the deployment descriptors are
+ to be read.]]></short-description>
+        <description><![CDATA[
+          Set the directory from where the text descriptions of the deployment descriptors are
+ to be read.
+        ]]></description>
+      </attribute>
+      <attribute name="dest" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory into which the serialized deployment descriptors are to
+ be written.]]></short-description>
+        <description><![CDATA[
+          Set the directory into which the serialized deployment descriptors are to
+ be written.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="delete" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.Delete"
+      matchingTask="true">
+
+  <short-description><![CDATA[Deletes a file or directory, or set of files defined by a fileset.]]></short-description>
+  <description>
+    <![CDATA[Deletes a file or directory, or set of files defined by a fileset.
+ The original delete task would delete a file, or a set of files 
+ using the include/exclude syntax.  The deltree task would delete a 
+ directory tree.  This task combines the functionality of these two
+ originally distinct tasks.
+ <p>Currently Delete extends MatchingTask.  This is intend <i>only</i>
+ to provide backwards compatibility for a release.  The future position
+ is to use nested filesets exclusively.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="defaultexcludes" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether default exclusions should be used or not.]]></short-description>
+        <description><![CDATA[
+          Sets whether default exclusions should be used or not.
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Directory from which files are to be deleted.]]></short-description>
+        <description><![CDATA[
+          Set the directory from which files are to be deleted
+        ]]></description>
+      </attribute>
+      <attribute name="excludes" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set of exclude patterns.]]></short-description>
+        <description><![CDATA[
+          Sets the set of exclude patterns. Patterns may be separated by a comma
+ or a space.
+        ]]></description>
+      </attribute>
+      <attribute name="excludesfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the file containing the includes patterns.]]></short-description>
+        <description><![CDATA[
+          Sets the name of the file containing the includes patterns.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If false, note errors but continue.]]></short-description>
+        <description><![CDATA[
+          If false, note errors but continue.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of a single file to be removed.]]></short-description>
+        <description><![CDATA[
+          Set the name of a single file to be removed.
+        ]]></description>
+      </attribute>
+      <attribute name="includeemptydirs" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, delete empty directories.]]></short-description>
+        <description><![CDATA[
+          If true, delete empty directories.
+        ]]></description>
+      </attribute>
+      <attribute name="includes" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set of include patterns.]]></short-description>
+        <description><![CDATA[
+          Sets the set of include patterns. Patterns may be separated by a comma
+ or a space.
+        ]]></description>
+      </attribute>
+      <attribute name="includesfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the file containing the includes patterns.]]></short-description>
+        <description><![CDATA[
+          Sets the name of the file containing the includes patterns.
+        ]]></description>
+      </attribute>
+      <attribute name="quiet" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true and the file does not exist, do not display a diagnostic
+ message or modify the exit status to reflect an error.]]></short-description>
+        <description><![CDATA[
+          If true and the file does not exist, do not display a diagnostic
+ message or modify the exit status to reflect an error.
+ This means that if a file or directory cannot be deleted,
+ then no error is reported. This setting emulates the
+ -f option to the Unix &quot;rm&quot; command.
+ Default is false meaning things are &quot;noisy&quot;
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, list all names of deleted files.]]></short-description>
+        <description><![CDATA[
+          If true, list all names of deleted files.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files to be deleted.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files to be deleted.]]>
+        </description>
+      </element>
+
+      <element name="exclude" type="org.apache.tools.ant.types.PatternSet.NameEntry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a name entry on the exclude list.]]></short-description>
+        <description>
+          <![CDATA[add a name entry on the exclude list]]>
+        </description>
+      </element>
+
+      <element name="excludesfile" type="org.apache.tools.ant.types.PatternSet.NameEntry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a name entry on the include files list.]]></short-description>
+        <description>
+          <![CDATA[add a name entry on the include files list]]>
+        </description>
+      </element>
+
+      <element name="include" type="org.apache.tools.ant.types.PatternSet.NameEntry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a name entry on the include list.]]></short-description>
+        <description>
+          <![CDATA[add a name entry on the include list]]>
+        </description>
+      </element>
+
+      <element name="includesfile" type="org.apache.tools.ant.types.PatternSet.NameEntry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a name entry on the include files list.]]></short-description>
+        <description>
+          <![CDATA[add a name entry on the include files list]]>
+        </description>
+      </element>
+
+      <element name="patternset" type="org.apache.tools.ant.types.PatternSet"
+               briefType="Patternset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a set of patterns.]]></short-description>
+        <description>
+          <![CDATA[add a set of patterns]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="deltree" category="other"
+      classname="org.apache.tools.ant.taskdefs.Deltree"
+      deprecated="true"
+      >
+
+  <short-description><![CDATA[No Description.]]></short-description>
+  <description>
+    <![CDATA[]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Directory to be deleted.]]></short-description>
+        <description><![CDATA[
+          Set the directory to be deleted
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="depend" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.depend.Depend"
+      matchingTask="true">
+
+  <short-description><![CDATA[Generates a dependency file for a given set of classes.]]></short-description>
+  <description>
+    <![CDATA[Generates a dependency file for a given set of classes.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="cache" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Dependency cache file.]]></short-description>
+        <description><![CDATA[
+          Sets the dependency cache file.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for this dependency check.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used for this dependency check.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a classpath defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a classpath defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="closure" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, transitive dependencies are followed until the
+ closure of the dependency set if reached.]]></short-description>
+        <description><![CDATA[
+          If true, transitive dependencies are followed until the
+ closure of the dependency set if reached.
+ When not set, the depend task will only follow
+ direct dependencies between classes.
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory where the compiled Java files exist.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory where the compiled Java files exist.
+        ]]></description>
+      </attribute>
+      <attribute name="dump" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, the dependency information will be written
+ to the debug level log.]]></short-description>
+        <description><![CDATA[
+          If true, the dependency information will be written
+ to the debug level log.
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Directories path to find the Java source files.]]></short-description>
+        <description><![CDATA[
+          Set the directories path to find the Java source files.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a classpath to be used for this dependency check.]]></short-description>
+        <description>
+          <![CDATA[Adds a classpath to be used for this dependency check.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="dependset" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.DependSet"
+      matchingTask="true">
+
+  <short-description><![CDATA[Examines and removes out of date target files.]]></short-description>
+  <description>
+    <![CDATA[Examines and removes out of date target files.  If any of the target files
+ are out of date with respect to any of the source files, all target
+ files are removed.  This is useful where dependencies cannot be
+ computed (for example, dynamically interpreted parameters or files
+ that need to stay in synch but are not directly linked) or where
+ the ant task in question could compute them but does not (for
+ example, the linked DTD for an XML file using the style task).
+
+ nested arguments:
+ <ul>
+ <li>srcfileset     (fileset describing the source files to examine)
+ <li>srcfilelist    (filelist describing the source files to examine)
+ <li>targetfileset  (fileset describing the target files to examine)
+ <li>targetfilelist (filelist describing the target files to examine)
+ </ul>
+ At least one instance of either a fileset or filelist for both source and 
+ target are required.
+ <p>
+ This task will examine each of the source files against each of the target 
+ files. If any target files are out of date with respect to any of the source 
+ files, all targets are removed. If any files named in a (src or target) 
+ filelist do not exist, all targets are removed.
+ Hint: If missing files should be ignored, specify them as include patterns 
+ in filesets, rather than using filelists.
+ </p><p>
+ This task attempts to optimize speed of dependency checking.  It will stop 
+ after the first out of date file is found and remove all targets, rather 
+ than exhaustively checking every source vs target combination unnecessarily.
+ </p><p>
+ Example uses: 
+ <ul><li>
+ Record the fact that an XML file must be up to date
+ with respect to its XSD (Schema file), even though the XML file
+ itself includes no reference to its XSD.
+ </li><li>
+ Record the fact that an XSL stylesheet includes other
+ sub-stylesheets
+ </li><li>
+ Record the fact that java files must be recompiled if the ant build
+ file changes
+ </li></ul>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+    </attributes>
+
+    <elements>
+      <element name="srcfilelist" type="org.apache.tools.ant.types.FileList"
+               briefType="Filelist"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a list of source files.]]></short-description>
+        <description>
+          <![CDATA[Add a list of source files.]]>
+        </description>
+      </element>
+
+      <element name="srcfileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a set of source files.]]></short-description>
+        <description>
+          <![CDATA[Add a set of source files.]]>
+        </description>
+      </element>
+
+      <element name="targetfilelist" type="org.apache.tools.ant.types.FileList"
+               briefType="Filelist"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a list of target files.]]></short-description>
+        <description>
+          <![CDATA[Add a list of target files.]]>
+        </description>
+      </element>
+
+      <element name="targetfileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a set of target files.]]></short-description>
+        <description>
+          <![CDATA[Add a set of target files.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="dirname" category="property"
+      classname="org.apache.tools.ant.taskdefs.Dirname"
+      >
+
+  <short-description><![CDATA[Determines the directory name of the specified file.]]></short-description>
+  <description>
+    <![CDATA[Determines the directory name of the specified file.
+
+ This task can accept the following attributes:
+ <ul>
+ <li>file
+ <li>property
+ </ul>
+ Both <b>file</b> and <b>property</b> are required.
+ <p>
+ When this task executes, it will set the specified property to the
+ value of the specified file up to, but not including, the last path
+ element. If file is a file, the directory will be the current
+ directory.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Path to take the dirname of.]]></short-description>
+        <description><![CDATA[
+          Path to take the dirname of.
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the property to set.]]></short-description>
+        <description><![CDATA[
+          The name of the property to set.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ear" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.Ear"
+      matchingTask="true">
+
+  <short-description><![CDATA[Creates a EAR archive.]]></short-description>
+  <description>
+    <![CDATA[Creates a EAR archive. Based on WAR task]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="appxml" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File to incorporate as application.xml.]]></short-description>
+        <description><![CDATA[
+          File to incorporate as application.xml.
+        ]]></description>
+      </attribute>
+      <attribute name="basedir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Directory from which to archive files; optional.]]></short-description>
+        <description><![CDATA[
+          Directory from which to archive files; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="compress" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether we want to compress the files or only store them;
+ optional, default=true;.]]></short-description>
+        <description><![CDATA[
+          Whether we want to compress the files or only store them;
+ optional, default=true;
+        ]]></description>
+      </attribute>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to create; required.]]></short-description>
+        <description><![CDATA[
+          The file to create; required.
+        ]]></description>
+      </attribute>
+      <attribute name="duplicate" type="org.apache.tools.ant.taskdefs.Zip.Duplicate"
+                 briefType="&quot;add&quot;, &quot;preserve&quot;, &quot;fail&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Sets behavior for when a duplicate file is about to be added -
+ one of <code>keep</code>, <code>skip</code> or <code>overwrite</code>.]]></short-description>
+        <description><![CDATA[
+          Sets behavior for when a duplicate file is about to be added -
+ one of <code>keep</code>, <code>skip</code> or <code>overwrite</code>.
+ Possible values are: <code>keep</code> (keep both
+ of the files); <code>skip</code> (keep the first version
+ of the file found); <code>overwrite</code> overwrite the file
+ with the new file
+ Default for zip tasks is <code>keep</code>
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Encoding to use for filenames, defaults to the platform's
+ default encoding.]]></short-description>
+        <description><![CDATA[
+          Encoding to use for filenames, defaults to the platform's
+ default encoding.
+
+ <p>For a list of possible values see <a
+ href="http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html">http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html</a>.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="filesonly" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, emulate Sun's jar utility by not adding parent directories;
+ optional, defaults to false.]]></short-description>
+        <description><![CDATA[
+          If true, emulate Sun's jar utility by not adding parent directories;
+ optional, defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="index" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether or not to create an index list for classes.]]></short-description>
+        <description><![CDATA[
+          Set whether or not to create an index list for classes.
+ This may speed up classloading in some cases.
+        ]]></description>
+      </attribute>
+      <attribute name="manifest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The manifest file to use.]]></short-description>
+        <description><![CDATA[
+          The manifest file to use. This can be either the location of a manifest,
+ or the name of a jar added through a fileset. If its the name of an added
+ jar, the task expects the manifest to be in the jar at META-INF/MANIFEST.MF.
+        ]]></description>
+      </attribute>
+      <attribute name="update" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, updates an existing file, otherwise overwrite
+ any existing one; optional defaults to false.]]></short-description>
+        <description><![CDATA[
+          If true, updates an existing file, otherwise overwrite
+ any existing one; optional defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="whenempty" type="org.apache.tools.ant.taskdefs.Zip.WhenEmpty"
+                 briefType="&quot;fail&quot;, &quot;skip&quot;, &quot;create&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Sets behavior of the task when no files match.]]></short-description>
+        <description><![CDATA[
+          Sets behavior of the task when no files match.
+ Possible values are: <code>fail</code> (throw an exception
+ and halt the build); <code>skip</code> (do not create
+ any archive, but issue a warning); <code>create</code>
+ (make an archive with no entries).
+ Default for zip tasks is <code>skip</code>;
+ for jar tasks, <code>create</code>.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="archives" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds zipfileset.]]></short-description>
+        <description>
+          <![CDATA[Adds zipfileset.]]>
+        </description>
+      </element>
+
+      <element name="manifest" type="org.apache.tools.ant.taskdefs.Manifest"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Allows the manifest for the archive file to be provided inline
+ in the buildfile rather than in an external file.]]></short-description>
+        <description>
+          <![CDATA[Allows the manifest for the archive file to be provided inline
+ in the buildfile rather than in an external file.]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files.]]>
+        </description>
+      </element>
+
+      <element name="metainf" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a zipfileset to include in the META-INF directory.]]></short-description>
+        <description>
+          <![CDATA[Adds a zipfileset to include in the META-INF directory.]]>
+        </description>
+      </element>
+
+      <element name="zipgroupfileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a group of zip files.]]></short-description>
+        <description>
+          <![CDATA[Adds a group of zip files.]]>
+        </description>
+      </element>
+
+      <element name="zipfileset" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files that can be
+ read from an archive and be given a prefix/fullpath.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files that can be
+ read from an archive and be given a prefix/fullpath.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="echo" category="utility"
+      classname="org.apache.tools.ant.taskdefs.Echo"
+      >
+
+  <short-description><![CDATA[Writes a message to the Ant logging facilities.]]></short-description>
+  <description>
+    <![CDATA[Writes a message to the Ant logging facilities.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, append to existing file.]]></short-description>
+        <description><![CDATA[
+          If true, append to existing file.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File to write to.]]></short-description>
+        <description><![CDATA[
+          File to write to.
+        ]]></description>
+      </attribute>
+      <attribute name="level" type="org.apache.tools.ant.taskdefs.Echo.EchoLevel"
+                 briefType="&quot;error&quot;, &quot;warning&quot;, &quot;info&quot;, &quot;verbose&quot;, &quot;debug&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Logging level.]]></short-description>
+        <description><![CDATA[
+          Set the logging level. Level should be one of
+ <ul>
+  <li>error</li>
+  <li>warning</li>
+  <li>info</li>
+  <li>verbose</li>
+  <li>debug</li>
+ </ul>
+ <p>The default is &quot;warning&quot; to ensure that messages are
+ displayed by default when using the -quiet command line option.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="message" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Message to write.]]></short-description>
+        <description><![CDATA[
+          Message to write.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+      <body >
+        <description><![CDATA[
+          Set a multiline message.
+        ]]></description>
+      </body>
+
+  </structure>
+
+</task>
+
+
+<task name="echoproperties" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.EchoProperties"
+      >
+
+  <short-description><![CDATA[Displays all the current properties in the build.]]></short-description>
+  <description>
+    <![CDATA[Displays all the current properties in the build. The output can be sent to
+  a file if desired. <P>
+
+  Attribute "destfile" defines a file to send the properties to. This can be
+  processed as a standard property file later. <P>
+
+  Attribute "prefix" defines a prefix which is used to filter the properties
+  only those properties starting with this prefix will be echoed. <P>
+
+  By default, the "failonerror" attribute is enabled. If an error occurs while
+  writing the properties to a file, and this attribute is enabled, then a
+  BuildException will be thrown. If disabled, then IO errors will be reported
+  as a log statement, but no error will be thrown. <P>
+
+  Examples: <pre>
+  &lt;echoproperties  /&gt;
+ </pre> Report the current properties to the log. <P>
+
+  <pre>
+  &lt;echoproperties destfile="my.properties" /&gt;
+ </pre> Report the current properties to the file "my.properties", and will
+  fail the build if the file could not be created or written to. <P>
+
+  <pre>
+  &lt;echoproperties destfile="my.properties" failonerror="false"
+      prefix="ant" /&gt;
+ </pre> Report all properties beginning with 'ant' to the file
+  "my.properties", and will log a message if the file could not be created or
+  written to, but will still allow the build to continue.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File to store the property output.]]></short-description>
+        <description><![CDATA[
+          Set a file to store the property output.  If this is never specified,
+  then the output will be sent to the Ant log.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, the task will fail if an error occurs writing the properties
+ file, otherwise errors are just logged.]]></short-description>
+        <description><![CDATA[
+          If true, the task will fail if an error occurs writing the properties
+ file, otherwise errors are just logged.
+        ]]></description>
+      </attribute>
+      <attribute name="prefix" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[If the prefix is set, then only properties which start with this
+  prefix string will be recorded.]]></short-description>
+        <description><![CDATA[
+          If the prefix is set, then only properties which start with this
+  prefix string will be recorded.  If this is never set, or it is set
+  to an empty string or <tt>null</tt>, then all properties will be
+  recorded. <P>
+
+  For example, if the property is set as:
+    <PRE>&lt;echoproperties  prefix="ant." /&gt;</PRE>
+  then the property "ant.home" will be recorded, but "ant-example"
+  will not.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ejbc" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ejb.Ejbc"
+      matchingTask="true">
+
+  <short-description><![CDATA[Builds EJB support classes using WebLogic's ejbc tool from a directory containing a set of deployment descriptors.]]></short-description>
+  <description>
+    <![CDATA[Builds EJB support classes using WebLogic's ejbc tool from a directory containing
+ a set of deployment descriptors.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for this compilation.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used for this compilation.
+        ]]></description>
+      </attribute>
+      <attribute name="descriptors" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory from where the serialized deployment descriptors are
+ to be read.]]></short-description>
+        <description><![CDATA[
+          Set the directory from where the serialized deployment descriptors are
+ to be read.
+        ]]></description>
+      </attribute>
+      <attribute name="dest" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory into which the support classes, RMI stubs, etc are to be written.]]></short-description>
+        <description><![CDATA[
+          Set the directory into which the support classes, RMI stubs, etc are to be written.
+        ]]></description>
+      </attribute>
+      <attribute name="keepgenerated" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[If true, ejbc will keep the
+ intermediate Java files used to build the class files.]]></short-description>
+        <description><![CDATA[
+          If true, ejbc will keep the
+ intermediate Java files used to build the class files.
+ This can be useful when debugging.
+        ]]></description>
+      </attribute>
+      <attribute name="manifest" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the generated manifest file.]]></short-description>
+        <description><![CDATA[
+          Set the name of the generated manifest file.
+
+ For each EJB that is processed an entry is created in this file. This can then be used
+ to create a jar file for dploying the beans.
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory containing the source code for the home interface, remote interface
+ and public key class definitions.]]></short-description>
+        <description><![CDATA[
+          Set the directory containing the source code for the home interface, remote interface
+ and public key class definitions.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ejbjar" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ejb.EjbJar"
+      matchingTask="true">
+
+  <short-description><![CDATA[Provides automated EJB JAR file creation.]]></short-description>
+  <description>
+    <![CDATA[Provides automated EJB JAR file creation.
+ <p>
+ Extends the
+ MatchingTask class provided in the default ant distribution to provide a
+ directory scanning EJB jarfile generator.
+ </p>
+
+ <p>
+ The task works by taking the deployment descriptors one at a time and
+ parsing them to locate the names of the classes which should be placed in
+ the jar. The classnames are translated to java.io.Files by replacing
+ periods with File.separatorChar and resolving the generated filename as a
+ relative path under the srcDir attribute. All necessary files are then
+ assembled into a jarfile. One jarfile is constructed for each deployment
+ descriptor found.
+ </p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="basejarname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Base name of the EJB JAR that is to be created if it is not
+ to be determined from the name of the deployment descriptor files.]]></short-description>
+        <description><![CDATA[
+          Set the base name of the EJB JAR that is to be created if it is not
+ to be determined from the name of the deployment descriptor files.
+        ]]></description>
+      </attribute>
+      <attribute name="basenameterminator" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The string which terminates the bean name.]]></short-description>
+        <description><![CDATA[
+          The string which terminates the bean name.
+ The convention used by this task is
+ that bean descriptors are named as the BeanName with some suffix. The
+ baseNameTerminator string separates the bean name and the suffix and
+ is used to determine the bean name.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to use when resolving classes for inclusion in the jar.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to use when resolving classes for inclusion in the jar.
+        ]]></description>
+      </attribute>
+      <attribute name="dependency" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Analyzer to use when adding in dependencies to the JAR.]]></short-description>
+        <description><![CDATA[
+          Set the analyzer to use when adding in dependencies to the JAR.
+        ]]></description>
+      </attribute>
+      <attribute name="descriptordir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Descriptor directory.]]></short-description>
+        <description><![CDATA[
+          Set the descriptor directory. The descriptor directory contains the
+ EJB deployment descriptors. These are XML files that declare the
+ properties of a bean in a particular deployment scenario. Such
+ properties include, for example, the transactional nature of the bean
+ and the security access control to the bean's methods.
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory. The EJB jar files will be written into
+ this directory. The jar files that exist in this directory are also
+ used when determining if the contents of the jar file have changed.
+ Note that this parameter is only used if no deployment tools are
+ specified. Typically each deployment tool will specify its own
+ destination directory.
+        ]]></description>
+      </attribute>
+      <attribute name="flatdestdir" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Controls whether the
+ destination JARs are written out in the destination directory with
+ the same hierarchical structure from which the deployment descriptors
+ have been read.]]></short-description>
+        <description><![CDATA[
+          Controls whether the
+ destination JARs are written out in the destination directory with
+ the same hierarchical structure from which the deployment descriptors
+ have been read. If this is set to true the generated EJB jars are
+ written into the root of the destination directory, otherwise they
+ are written out in the same relative position as the deployment
+ descriptors in the descriptor directory.
+        ]]></description>
+      </attribute>
+      <attribute name="genericjarsuffix" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Suffix for the generated jar file.]]></short-description>
+        <description><![CDATA[
+          Set the suffix for the generated jar file. When generic jars are
+ generated, they have a suffix which is appended to the the bean name
+ to create the name of the jar file. Note that this suffix includes
+ the extension fo te jar file and should therefore end with an
+ appropriate extension such as .jar or .ear
+        ]]></description>
+      </attribute>
+      <attribute name="manifest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Manifest file to use when jarring.]]></short-description>
+        <description><![CDATA[
+          Set the Manifest file to use when jarring. As of EJB 1.1, manifest
+ files are no longer used to configure the EJB. However, they still
+ have a vital importance if the EJB is intended to be packaged in an
+ EAR file. By adding "Class-Path" settings to a Manifest file, the EJB
+ can look for classes inside the EAR file itself, allowing for easier
+ deployment. This is outlined in the J2EE specification, and all J2EE
+ components are meant to support it.
+        ]]></description>
+      </attribute>
+      <attribute name="naming" type="org.apache.tools.ant.taskdefs.optional.ejb.EjbJar.NamingScheme"
+                 briefType="&quot;ejb-name&quot;, &quot;directory&quot;, &quot;descriptor&quot;, &quot;basejarname&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Naming scheme used to determine the name of the generated jars
+ from the deployment descriptor.]]></short-description>
+        <description><![CDATA[
+          Set the naming scheme used to determine the name of the generated jars
+ from the deployment descriptor
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source directory, which is the directory that
+ contains the classes that will be added to the EJB jar.]]></short-description>
+        <description><![CDATA[
+          Sets the source directory, which is the directory that
+ contains the classes that will be added to the EJB jar. Typically
+ this will include the home and remote interfaces and the bean class.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="borland" type="org.apache.tools.ant.taskdefs.optional.ejb.BorlandDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a deployment tool for Borland server.]]></short-description>
+        <description>
+          <![CDATA[Adds a deployment tool for Borland server.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds to the classpath used to locate the super classes and
+ interfaces of the classes that will make up the EJB JAR.]]></short-description>
+        <description>
+          <![CDATA[Adds to the classpath used to locate the super classes and
+ interfaces of the classes that will make up the EJB JAR.]]>
+        </description>
+      </element>
+
+      <element name="dtd" type="org.apache.tools.ant.taskdefs.optional.ejb.EjbJar.DTDLocation"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a DTD location record.]]></short-description>
+        <description>
+          <![CDATA[Create a DTD location record. This stores the location of a DTD. The
+ DTD is identified by its public Id. The location may either be a file
+ location or a resource location.]]>
+        </description>
+      </element>
+
+      <element name="iplanet" type="org.apache.tools.ant.taskdefs.optional.ejb.IPlanetDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a deployment tool for iPlanet Application Server.]]></short-description>
+        <description>
+          <![CDATA[Adds a deployment tool for iPlanet Application Server.]]>
+        </description>
+      </element>
+
+      <element name="jboss" type="org.apache.tools.ant.taskdefs.optional.ejb.JbossDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a deployment tool for JBoss server.]]></short-description>
+        <description>
+          <![CDATA[Adds a deployment tool for JBoss server.]]>
+        </description>
+      </element>
+
+      <element name="jonas" type="org.apache.tools.ant.taskdefs.optional.ejb.JonasDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a deployment tool for JOnAS server.]]></short-description>
+        <description>
+          <![CDATA[Adds a deployment tool for JOnAS server.]]>
+        </description>
+      </element>
+
+      <element name="support" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a fileset for support elements.]]></short-description>
+        <description>
+          <![CDATA[Adds a fileset for support elements.]]>
+        </description>
+      </element>
+
+      <element name="weblogic" type="org.apache.tools.ant.taskdefs.optional.ejb.WeblogicDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a deployment tool for Weblogic server.]]></short-description>
+        <description>
+          <![CDATA[Adds a deployment tool for Weblogic server.]]>
+        </description>
+      </element>
+
+      <element name="weblogictoplink" type="org.apache.tools.ant.taskdefs.optional.ejb.WeblogicTOPLinkDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a deployment tool for Weblogic when using the Toplink
+ Object-Relational mapping.]]></short-description>
+        <description>
+          <![CDATA[Adds a deployment tool for Weblogic when using the Toplink
+ Object-Relational mapping.]]>
+        </description>
+      </element>
+
+      <element name="websphere" type="org.apache.tools.ant.taskdefs.optional.ejb.WebsphereDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a deployment tool for Websphere 4.0 server.]]></short-description>
+        <description>
+          <![CDATA[Adds a deployment tool for Websphere 4.0 server.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="exec" category="control"
+      classname="org.apache.tools.ant.taskdefs.ExecTask"
+      >
+
+  <short-description><![CDATA[Executes a given command if the os platform is appropriate.]]></short-description>
+  <description>
+    <![CDATA[Executes a given command if the os platform is appropriate.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether output should be appended to or overwrite an existing file.]]></short-description>
+        <description><![CDATA[
+          Whether output should be appended to or overwrite an existing file.
+ Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The working directory of the process.]]></short-description>
+        <description><![CDATA[
+          The working directory of the process.
+        ]]></description>
+      </attribute>
+      <attribute name="executable" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The command to execute.]]></short-description>
+        <description><![CDATA[
+          The command to execute.
+        ]]></description>
+      </attribute>
+      <attribute name="failifexecutionfails" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Stop the build if program cannot be started.]]></short-description>
+        <description><![CDATA[
+          Stop the build if program cannot be started. Defaults to true.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Fail if the command exits with a non-zero return code.]]></short-description>
+        <description><![CDATA[
+          Fail if the command exits with a non-zero return code.
+        ]]></description>
+      </attribute>
+      <attribute name="newenvironment" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Do not propagate old environment when new environment variables are specified.]]></short-description>
+        <description><![CDATA[
+          Do not propagate old environment when new environment variables are specified.
+        ]]></description>
+      </attribute>
+      <attribute name="os" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[List of operating systems on which the command may be executed.]]></short-description>
+        <description><![CDATA[
+          List of operating systems on which the command may be executed.
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File the output of the process is redirected to.]]></short-description>
+        <description><![CDATA[
+          File the output of the process is redirected to.
+        ]]></description>
+      </attribute>
+      <attribute name="outputproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Property name whose value should be set to the output of
+ the process.]]></short-description>
+        <description><![CDATA[
+          Property name whose value should be set to the output of
+ the process.
+        ]]></description>
+      </attribute>
+      <attribute name="resultproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of a property in which the return code of the
+ command should be stored.]]></short-description>
+        <description><![CDATA[
+          The name of a property in which the return code of the
+ command should be stored. Only of interest if failonerror=false.
+        ]]></description>
+      </attribute>
+      <attribute name="vmlauncher" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, launch new process with VM, otherwise use the OS's shell.]]></short-description>
+        <description><![CDATA[
+          If true, launch new process with VM, otherwise use the OS's shell.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="env" type="org.apache.tools.ant.types.Environment.Variable"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an environment variable to the launched process.]]></short-description>
+        <description>
+          <![CDATA[Add an environment variable to the launched process.]]>
+        </description>
+      </element>
+
+      <element name="arg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a command-line argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a command-line argument.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="fail" category="control"
+      classname="org.apache.tools.ant.taskdefs.Exit"
+      >
+
+  <short-description><![CDATA[Exits the active build, giving an additional message if available.]]></short-description>
+  <description>
+    <![CDATA[Exits the active build, giving an additional message
+ if available.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="if" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Only fail if a property of the given name exists in the current project.]]></short-description>
+        <description><![CDATA[
+          Only fail if a property of the given name exists in the current project.
+        ]]></description>
+      </attribute>
+      <attribute name="message" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[A message giving further information on why the build exited.]]></short-description>
+        <description><![CDATA[
+          A message giving further information on why the build exited.
+        ]]></description>
+      </attribute>
+      <attribute name="unless" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Only fail if a property of the given name does not
+ exist in the current project.]]></short-description>
+        <description><![CDATA[
+          Only fail if a property of the given name does not
+ exist in the current project.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+      <body >
+        <description><![CDATA[
+          Set a multiline message.
+        ]]></description>
+      </body>
+
+  </structure>
+
+</task>
+
+
+<task name="filter" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.Filter"
+      >
+
+  <short-description><![CDATA[Sets a token filter that is used by the file copy tasks to do token substitution.]]></short-description>
+  <description>
+    <![CDATA[Sets a token filter that is used by the file copy tasks
+ to do token substitution. Sets mutiple tokens by
+ reading these from a file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="filtersfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file from which the filters must be read.]]></short-description>
+        <description><![CDATA[
+          The file from which the filters must be read.
+ This file must be a formatted as a property file.
+        ]]></description>
+      </attribute>
+      <attribute name="token" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The token string without @ delimiters.]]></short-description>
+        <description><![CDATA[
+          The token string without @ delimiters.
+        ]]></description>
+      </attribute>
+      <attribute name="value" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The string that should replace the token during filtered copies.]]></short-description>
+        <description><![CDATA[
+          The string that should replace the token during filtered copies.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="fixcrlf" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.FixCRLF"
+      matchingTask="true">
+
+  <short-description><![CDATA[Converts text source files to local OS formatting conventions, as well as repair text files damaged by misconfigured or misguided editors or file transfer programs.]]></short-description>
+  <description>
+    <![CDATA[Converts text source files to local OS formatting conventions, as
+ well as repair text files damaged by misconfigured or misguided editors or
+ file transfer programs.
+ <p>
+ This task can take the following arguments:
+ <ul>
+ <li>srcdir
+ <li>destdir
+ <li>include
+ <li>exclude
+ <li>cr
+ <li>eol
+ <li>tab
+ <li>eof
+ <li>encoding
+ </ul>
+ Of these arguments, only <b>sourcedir</b> is required.
+ <p>
+ When this task executes, it will scan the srcdir based on the include
+ and exclude properties.
+ <p>
+ This version generalises the handling of EOL characters, and allows
+ for CR-only line endings (which I suspect is the standard on Macs.)
+ Tab handling has also been generalised to accommodate any tabwidth
+ from 2 to 80, inclusive.  Importantly, it will leave untouched any
+ literal TAB characters embedded within string or character constants.
+ <p>
+ <em>Warning:</em> do not run on binary files.
+ <em>Caution:</em> run with care on carefully formatted files.
+ This may sound obvious, but if you don't specify asis, presume that
+ your files are going to be modified.  If "tabs" is "add" or "remove",
+ whitespace characters may be added or removed as necessary.  Similarly,
+ for CR's - in fact "eol"="crlf" or cr="add" can result in cr
+ characters being removed in one special case accommodated, i.e.,
+ CRCRLF is regarded as a single EOL to handle cases where other
+ programs have converted CRLF into CRCRLF.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination where the fixed files should be placed.]]></short-description>
+        <description><![CDATA[
+          Set the destination where the fixed files should be placed.
+ Default is to replace the original file.
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the encoding Ant expects the files to be in -
+ defaults to the platforms default encoding.]]></short-description>
+        <description><![CDATA[
+          Specifies the encoding Ant expects the files to be in -
+ defaults to the platforms default encoding.
+        ]]></description>
+      </attribute>
+      <attribute name="eof" type="org.apache.tools.ant.taskdefs.FixCRLF.AddAsisRemove"
+                 briefType="&quot;add&quot;, &quot;asis&quot;, &quot;remove&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Specify how DOS EOF (control-z) characters are to be handled.]]></short-description>
+        <description><![CDATA[
+          Specify how DOS EOF (control-z) characters are to be handled.
+        ]]></description>
+      </attribute>
+      <attribute name="eol" type="org.apache.tools.ant.taskdefs.FixCRLF.CrLf"
+                 briefType="&quot;asis&quot;, &quot;cr&quot;, &quot;lf&quot;, &quot;crlf&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Specify how EndOfLine characters are to be handled.]]></short-description>
+        <description><![CDATA[
+          Specify how EndOfLine characters are to be handled.
+        ]]></description>
+      </attribute>
+      <attribute name="javafiles" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set to true if modifying Java source files.]]></short-description>
+        <description><![CDATA[
+          Set to true if modifying Java source files.
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source dir to find the source text files.]]></short-description>
+        <description><![CDATA[
+          Set the source dir to find the source text files.
+        ]]></description>
+      </attribute>
+      <attribute name="tab" type="org.apache.tools.ant.taskdefs.FixCRLF.AddAsisRemove"
+                 briefType="&quot;add&quot;, &quot;asis&quot;, &quot;remove&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Specify how tab characters are to be handled.]]></short-description>
+        <description><![CDATA[
+          Specify how tab characters are to be handled.
+        ]]></description>
+      </attribute>
+      <attribute name="tablength" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Specify tab length in characters.]]></short-description>
+        <description><![CDATA[
+          Specify tab length in characters.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ftp" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.net.FTP"
+      >
+
+  <short-description><![CDATA[Basic FTP client.]]></short-description>
+  <description>
+    <![CDATA[Basic FTP client. Performs the following actions:
+ <ul>
+   <li> <strong>send</strong> - send files to a remote server. This is the
+   default action.</li>
+   <li> <strong>get</strong> - retrive files from a remote server.</li>
+   <li> <strong>del</strong> - delete files from a remote server.</li>
+   <li> <strong>list</strong> - create a file listing.</li>
+   <li> <strong>chmod</strong> - change unix file permissions.</li>
+ </ul>
+ <strong>Note:</strong> Some FTP servers - notably the Solaris server - seem
+ to hold data ports open after a "retr" operation, allowing them to timeout
+ instead of shutting them down cleanly. This happens in active or passive
+ mode, and the ports will remain open even after ending the FTP session. FTP
+ "send" operations seem to close ports immediately. This behavior may cause
+ problems on some systems when downloading large sets of files.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="action" type="org.apache.tools.ant.taskdefs.optional.net.FTP.Action"
+                 briefType="&quot;send&quot;, &quot;put&quot;, &quot;recv&quot;, &quot;get&quot;, &quot;del&quot;, &quot;delete&quot;, &quot;list&quot;, &quot;mkdir&quot;, &quot;chmod&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[FTP action to be taken.]]></short-description>
+        <description><![CDATA[
+          Sets the FTP action to be taken. Currently accepts "put", "get", "del",
+ "mkdir", "chmod" and "list".
+        ]]></description>
+      </attribute>
+      <attribute name="binary" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, uses binary mode, otherwise text mode (default is binary).]]></short-description>
+        <description><![CDATA[
+          If true, uses binary mode, otherwise text mode (default is binary).
+        ]]></description>
+      </attribute>
+      <attribute name="chmod" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[File permission mode (Unix only) for files sent to the server.]]></short-description>
+        <description><![CDATA[
+          Sets the file permission mode (Unix only) for files sent to the server.
+        ]]></description>
+      </attribute>
+      <attribute name="depends" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set to true to transmit only files that are new or changed from their
+ remote counterparts.]]></short-description>
+        <description><![CDATA[
+          Set to true to transmit only files that are new or changed from their
+ remote counterparts. The default is to transmit all files.
+        ]]></description>
+      </attribute>
+      <attribute name="ignorenoncriticalerrors" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to skip errors on directory creation.
+ (and maybe later other server specific errors).]]></short-description>
+        <description><![CDATA[
+          set the flag to skip errors on directory creation.
+ (and maybe later other server specific errors)
+        ]]></description>
+      </attribute>
+      <attribute name="listing" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The output file for the "list" action.]]></short-description>
+        <description><![CDATA[
+          The output file for the "list" action. This attribute is ignored for
+ any other actions.
+        ]]></description>
+      </attribute>
+      <attribute name="newer" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[A synonym for <tt>depends</tt>.]]></short-description>
+        <description><![CDATA[
+          A synonym for <tt>depends</tt>. Set to true to transmit only new or changed
+ files.
+        ]]></description>
+      </attribute>
+      <attribute name="passive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies whether to use passive mode.]]></short-description>
+        <description><![CDATA[
+          Specifies whether to use passive mode. Set to true if you are behind a
+ firewall and cannot connect without it. Passive mode is disabled by
+ default.
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Login password for the given user id.]]></short-description>
+        <description><![CDATA[
+          Sets the login password for the given user id.
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[FTP port used by the remote server.]]></short-description>
+        <description><![CDATA[
+          Sets the FTP port used by the remote server.
+        ]]></description>
+      </attribute>
+      <attribute name="remotedir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Remote directory where files will be placed.]]></short-description>
+        <description><![CDATA[
+          Sets the remote directory where files will be placed. This may be a
+ relative or absolute path, and must be in the path syntax expected by
+ the remote server. No correction of path syntax will be performed.
+        ]]></description>
+      </attribute>
+      <attribute name="separator" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Remote file separator character.]]></short-description>
+        <description><![CDATA[
+          Sets the remote file separator character. This normally defaults to the
+ Unix standard forward slash, but can be manually overridden using this
+ call if the remote server requires some other separator. Only the first
+ character of the string is used.
+        ]]></description>
+      </attribute>
+      <attribute name="server" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[FTP server to send files to.]]></short-description>
+        <description><![CDATA[
+          Sets the FTP server to send files to.
+        ]]></description>
+      </attribute>
+      <attribute name="skipfailedtransfers" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enables unsuccessful file put, delete and get
+ operations to be skipped with a warning and the remainder
+ of the files still transferred.]]></short-description>
+        <description><![CDATA[
+          If true, enables unsuccessful file put, delete and get
+ operations to be skipped with a warning and the remainder
+ of the files still transferred.
+        ]]></description>
+      </attribute>
+      <attribute name="umask" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Default mask for file creation on a unix server.]]></short-description>
+        <description><![CDATA[
+          Sets the default mask for file creation on a unix server.
+        ]]></description>
+      </attribute>
+      <attribute name="userid" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Login user id to use on the specified server.]]></short-description>
+        <description><![CDATA[
+          Sets the login user id to use on the specified server.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set to true to receive notification about each file as it is
+ transferred.]]></short-description>
+        <description><![CDATA[
+          Set to true to receive notification about each file as it is
+ transferred.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[A set of files to upload or download.]]></short-description>
+        <description>
+          <![CDATA[A set of files to upload or download]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="genkey" category="java"
+      classname="org.apache.tools.ant.taskdefs.GenerateKey"
+      >
+
+  <short-description><![CDATA[Generates a key in a keystore.]]></short-description>
+  <description>
+    <![CDATA[Generates a key in a keystore.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="alias" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The alias to add under.]]></short-description>
+        <description><![CDATA[
+          The alias to add under.
+        ]]></description>
+      </attribute>
+      <attribute name="dname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The distinguished name for entity.]]></short-description>
+        <description><![CDATA[
+          The distinguished name for entity.
+        ]]></description>
+      </attribute>
+      <attribute name="keyalg" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The method to use when generating name-value pair.]]></short-description>
+        <description><![CDATA[
+          The method to use when generating name-value pair.
+        ]]></description>
+      </attribute>
+      <attribute name="keypass" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Password for private key (if different).]]></short-description>
+        <description><![CDATA[
+          Password for private key (if different).
+        ]]></description>
+      </attribute>
+      <attribute name="keysize" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates the size of key generated.]]></short-description>
+        <description><![CDATA[
+          Indicates the size of key generated.
+        ]]></description>
+      </attribute>
+      <attribute name="keystore" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Keystore location.]]></short-description>
+        <description><![CDATA[
+          Keystore location.
+        ]]></description>
+      </attribute>
+      <attribute name="sigalg" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The algorithm to use in signing.]]></short-description>
+        <description><![CDATA[
+          The algorithm to use in signing.
+        ]]></description>
+      </attribute>
+      <attribute name="storepass" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Password for keystore integrity.]]></short-description>
+        <description><![CDATA[
+          Password for keystore integrity.
+ Must be at least 6 characters long.
+        ]]></description>
+      </attribute>
+      <attribute name="storetype" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Keystore type.]]></short-description>
+        <description><![CDATA[
+          Keystore type.
+        ]]></description>
+      </attribute>
+      <attribute name="validity" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates how many days certificate is valid.]]></short-description>
+        <description><![CDATA[
+          Indicates how many days certificate is valid.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, verbose output when signing.]]></short-description>
+        <description><![CDATA[
+          If true, verbose output when signing.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="dname" type="org.apache.tools.ant.taskdefs.GenerateKey.DistinguishedName"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Distinguished name list.]]></short-description>
+        <description>
+          <![CDATA[Distinguished name list.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="get" category="network"
+      classname="org.apache.tools.ant.taskdefs.Get"
+      >
+
+  <short-description><![CDATA[Gets a particular file from a URL source.]]></short-description>
+  <description>
+    <![CDATA[Gets a particular file from a URL source.
+ Options include verbose reporting, timestamp based fetches and controlling
+ actions on failures. NB: access through a firewall only works if the whole
+ Java runtime is correctly configured.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Where to copy the source file.]]></short-description>
+        <description><![CDATA[
+          Where to copy the source file.
+        ]]></description>
+      </attribute>
+      <attribute name="ignoreerrors" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, log errors but do not treat as fatal.]]></short-description>
+        <description><![CDATA[
+          If true, log errors but do not treat as fatal.
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Password for the basic authentication.]]></short-description>
+        <description><![CDATA[
+          password for the basic authentication.
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.net.URL"
+                 briefType="URL" required="NOTDEFINED">
+        <short-description><![CDATA[URL to get.]]></short-description>
+        <description><![CDATA[
+          Set the URL to get.
+        ]]></description>
+      </attribute>
+      <attribute name="usetimestamp" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, conditionally download a file based on the timestamp
+ of the local copy.]]></short-description>
+        <description><![CDATA[
+          If true, conditionally download a file based on the timestamp
+ of the local copy.
+
+ <p>In this situation, the if-modified-since header is set so
+ that the file is only fetched if it is newer than the local
+ file (or there is no local file) This flag is only valid on
+ HTTP connections, it is ignored in other cases.  When the flag
+ is set, the local copy of the downloaded file will also have
+ its timestamp set to the remote file time.</p>
+
+ <p>Note that remote files of date 1/1/1970 (GMT) are treated as
+ 'no timestamp', and web servers often serve files with a
+ timestamp in the future by replacing their timestamp with that
+ of the current time. Also, inter-computer clock differences can
+ cause no end of grief.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="username" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Username for basic auth.]]></short-description>
+        <description><![CDATA[
+          Username for basic auth.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, show verbose progress information.]]></short-description>
+        <description><![CDATA[
+          If true, show verbose progress information.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="gunzip" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.GUnzip"
+      >
+
+  <short-description><![CDATA[Expands a file that has been compressed with the GZIP algorithm.]]></short-description>
+  <description>
+    <![CDATA[Expands a file that has been compressed with the GZIP
+ algorithm. Normally used to compress non-compressed archives such
+ as TAR files.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The destination file or directory; optional.]]></short-description>
+        <description><![CDATA[
+          The destination file or directory; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to expand; required.]]></short-description>
+        <description><![CDATA[
+          The file to expand; required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="gzip" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.GZip"
+      >
+
+  <short-description><![CDATA[Compresses a file with the GZIP algorithm.]]></short-description>
+  <description>
+    <![CDATA[Compresses a file with the GZIP algorithm. Normally used to compress
+ non-compressed archives such as TAR files.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to compress; required.]]></short-description>
+        <description><![CDATA[
+          the file to compress; required.
+        ]]></description>
+      </attribute>
+      <attribute name="zipfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The required destination file.]]></short-description>
+        <description><![CDATA[
+          the required destination file.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="icontract" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.IContract"
+      matchingTask="true">
+
+  <short-description><![CDATA[Instruments Java classes with iContract DBC preprocessor.]]></short-description>
+  <description>
+    <![CDATA[Instruments Java classes with iContract DBC preprocessor.
+ <br/>
+ The task can generate a properties file for <a href="http://hjem.sol.no/hellesoy/icontrol.html">iControl</a>,
+ a graphical user interface that lets you turn on/off assertions. iControl generates a control file that you can refer to
+ from this task using the controlfile attribute.
+ iContract is at <a href="http://www.reliable-systems.com/tools/">http://www.reliable-systems.com/tools/</a>
+ <p/>
+ Thanks to Rainer Schmitz for enhancements and comments.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="builddir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Build directory for instrumented classes.]]></short-description>
+        <description><![CDATA[
+          Sets the build directory for instrumented classes.
+        ]]></description>
+      </attribute>
+      <attribute name="classdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Class directory (uninstrumented classes).]]></short-description>
+        <description><![CDATA[
+          Sets the class directory (uninstrumented classes).
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for invocation of iContract.]]></short-description>
+        <description><![CDATA[
+          Sets the classpath to be used for invocation of iContract.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a classpath defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a classpath defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="controlfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Control file to pass to iContract.]]></short-description>
+        <description><![CDATA[
+          Sets the control file to pass to iContract.
+        ]]></description>
+      </attribute>
+      <attribute name="failthrowable" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Throwable (Exception) to be thrown on assertion violation.]]></short-description>
+        <description><![CDATA[
+          Sets the Throwable (Exception) to be thrown on assertion violation.
+        ]]></description>
+      </attribute>
+      <attribute name="instrumentdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Instrumentation directory.]]></short-description>
+        <description><![CDATA[
+          Sets the instrumentation directory.
+        ]]></description>
+      </attribute>
+      <attribute name="invariant" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Turns on/off invariant instrumentation.]]></short-description>
+        <description><![CDATA[
+          Turns on/off invariant instrumentation.
+        ]]></description>
+      </attribute>
+      <attribute name="post" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Turns on/off postcondition instrumentation.]]></short-description>
+        <description><![CDATA[
+          Turns on/off postcondition instrumentation.
+        ]]></description>
+      </attribute>
+      <attribute name="pre" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Turns on/off precondition instrumentation.]]></short-description>
+        <description><![CDATA[
+          Turns on/off precondition instrumentation.
+        ]]></description>
+      </attribute>
+      <attribute name="quiet" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Tells iContract to be quiet.]]></short-description>
+        <description><![CDATA[
+          Tells iContract to be quiet.
+        ]]></description>
+      </attribute>
+      <attribute name="repbuilddir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Build directory for instrumented classes.]]></short-description>
+        <description><![CDATA[
+          Sets the build directory for instrumented classes.
+        ]]></description>
+      </attribute>
+      <attribute name="repositorydir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Build directory for repository classes.]]></short-description>
+        <description><![CDATA[
+          Sets the build directory for repository classes.
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source directory.]]></short-description>
+        <description><![CDATA[
+          Sets the source directory.
+        ]]></description>
+      </attribute>
+      <attribute name="targets" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the file where targets will be written.]]></short-description>
+        <description><![CDATA[
+          Sets the name of the file where targets will be written. That is the
+ file that tells iContract what files to process.
+        ]]></description>
+      </attribute>
+      <attribute name="updateicontrol" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, updates iControl properties file.]]></short-description>
+        <description><![CDATA[
+          If true, updates iControl properties file
+        ]]></description>
+      </attribute>
+      <attribute name="verbosity" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Verbosity level of iContract.]]></short-description>
+        <description><![CDATA[
+          Sets the verbosity level of iContract. Any combination of
+ error*,warning*,note*,info*,progress*,debug* (comma separated) can be
+ used. Defaults to error*,warning*
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Classpath.]]></short-description>
+        <description>
+          <![CDATA[Sets the classpath.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="ilasm" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.dotnet.Ilasm"
+      matchingTask="true">
+
+  <short-description><![CDATA[Assembles .NET Intermediate Language files.]]></short-description>
+  <description>
+    <![CDATA[Assembles .NET Intermediate Language files. The task will only work
+  on win2K until other platforms support csc.exe or an equivalent. ilasm.exe
+  must be on the execute path too. <p>
+
+  <p>
+
+  All parameters are optional: &lt;il/&gt; should suffice to produce a debug
+  build of all *.il files. The option set is roughly compatible with the
+  CSharp class; even though the command line options are only vaguely
+  equivalent. [The low level commands take things like /OUT=file, csc wants
+  /out:file ... /verbose is used some places; /quiet here in ildasm... etc.]
+  It would be nice if someone made all the command line tools consistent (and
+  not as brittle as the java cmdline tools) <p>
+
+  The task is a directory based task, so attributes like <b>includes="*.il"
+  </b> and <b>excludes="broken.il"</b> can be used to control the files pulled
+  in. Each file is built on its own, producing an appropriately named output
+  file unless manually specified with <b>outfile</b>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="debug" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Debug flag on or off.]]></short-description>
+        <description><![CDATA[
+          set the debug flag on or off.
+        ]]></description>
+      </attribute>
+      <attribute name="extraoptions" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Any extra options which are not explicitly
+ supported by this task.]]></short-description>
+        <description><![CDATA[
+          Any extra options which are not explicitly
+ supported by this task.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, fails if ilasm tool fails.]]></short-description>
+        <description><![CDATA[
+          If true, fails if ilasm tool fails.
+        ]]></description>
+      </attribute>
+      <attribute name="keyfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The name of a file containing a private key.]]></short-description>
+        <description><![CDATA[
+          the name of a file containing a private key.
+        ]]></description>
+      </attribute>
+      <attribute name="listing" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, produce a listing (off by default).]]></short-description>
+        <description><![CDATA[
+          If true, produce a listing (off by default).
+        ]]></description>
+      </attribute>
+      <attribute name="outputfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Output file.]]></short-description>
+        <description><![CDATA[
+          Set the output file.
+        ]]></description>
+      </attribute>
+      <attribute name="resourcefile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of resource file to include.]]></short-description>
+        <description><![CDATA[
+          name of resource file to include.
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source directory containing the files to be compiled.]]></short-description>
+        <description><![CDATA[
+          Set the source directory containing the files to be compiled.
+        ]]></description>
+      </attribute>
+      <attribute name="targettype" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Type of target, either "exe" or "library".]]></short-description>
+        <description><![CDATA[
+          Sets the type of target, either "exe" or "library".
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enable verbose ILASM output.]]></short-description>
+        <description><![CDATA[
+          If true, enable verbose ILASM output.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="input" category="control"
+      classname="org.apache.tools.ant.taskdefs.Input"
+      >
+
+  <short-description><![CDATA[Reads an input line from the console.]]></short-description>
+  <description>
+    <![CDATA[Reads an input line from the console.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="addproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Defines the name of a property to be created from input.]]></short-description>
+        <description><![CDATA[
+          Defines the name of a property to be created from input. Behaviour is
+ according to property task which means that existing properties
+ cannot be overriden.
+        ]]></description>
+      </attribute>
+      <attribute name="message" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Message which gets displayed to the user during the build run.]]></short-description>
+        <description><![CDATA[
+          Sets the Message which gets displayed to the user during the build run.
+        ]]></description>
+      </attribute>
+      <attribute name="validargs" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Defines valid input parameters as comma separated strings.]]></short-description>
+        <description><![CDATA[
+          Defines valid input parameters as comma separated strings. If set, input
+ task will reject any input not defined as accepted and requires the user
+ to reenter it. Validargs are case sensitive. If you want 'a' and 'A' to
+ be accepted you need to define both values as accepted arguments.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+      <body >
+        <description><![CDATA[
+          Set a multiline message.
+        ]]></description>
+      </body>
+
+  </structure>
+
+</task>
+
+
+<task name="iplanet-ejbc" category="ejb"
+      classname="org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbcTask"
+      >
+
+  <short-description><![CDATA[Compiles EJB stubs and skeletons for the iPlanet Application Server.]]></short-description>
+  <description>
+    <![CDATA[Compiles EJB stubs and skeletons for the iPlanet Application Server.
+ The EJBs to be processed are specified by the EJB 1.1 standard XML
+ descriptor, and additional attributes are obtained from the iPlanet Application
+ Server-specific XML descriptor.  Since the XML descriptors can include
+ multiple EJBs, this is a convenient way of specifying many EJBs in a single
+ Ant task.  The following attributes are allowed:
+   <ul>
+     <li><i>ejbdescriptor</i> -- Standard EJB 1.1 XML descriptor (typically
+                                 titled "ejb-jar.xml").  This attribute is
+                                 required.
+     <li><i>iasdescriptor</i> -- EJB XML descriptor for iPlanet Application
+                                 Server (typically titled "ias-ejb-jar.xml).
+                                 This attribute is required.
+     <li><i>dest</i> -- The is the base directory where the RMI stubs and
+                        skeletons are written.  In addition, the class files
+                        for each bean (home interface, remote interface, and
+                        EJB implementation) must be found in this directory.
+                        This attribute is required.
+     <li><i>classpath</i> -- The classpath used when generating EJB stubs and
+                             skeletons.  This is an optional attribute (if
+                             omitted, the classpath specified when Ant was
+                             started will be used).  Nested "classpath"
+                             elements may also be used.
+     <li><i>keepgenerated</i> -- Indicates whether or not the Java source
+                                 files which are generated by ejbc will be
+                                 saved or automatically deleted.  If "yes",
+                                 the source files will be retained.  This is
+                                 an optional attribute (if omitted, it
+                                 defaults to "no").
+     <li><i>debug</i> -- Indicates whether or not the ejbc utility should
+                         log additional debugging statements to the standard
+                         output.  If "yes", the additional debugging statements
+                         will be generated (if omitted, it defaults to "no").
+     <li><i>iashome</i> -- May be used to specify the "home" directory for
+                           this iPlanet Application Server installation.  This
+                           is used to find the ejbc utility if it isn't
+                           included in the user's system path.  This is an
+                           optional attribute (if specified, it should refer
+                           to the <code>[install-location]/iplanet/ias6/ias
+                           </code> directory).  If omitted, the ejbc utility
+                           must be on the user's system path.
+   </ul>
+ <p>
+ For each EJB specified, this task will locate the three classes that comprise
+ the EJB.  If these class files cannot be located in the <code>dest</code>
+ directory, the task will fail.  The task will also attempt to locate the EJB
+ stubs and skeletons in this directory.  If found, the timestamps on the
+ stubs and skeletons will be checked to ensure they are up to date.  Only if
+ these files cannot be found or if they are out of date will ejbc be called
+ to generate new stubs and skeletons.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used when compiling the EJB stubs and skeletons.]]></short-description>
+        <description><![CDATA[
+          Sets the classpath to be used when compiling the EJB stubs and skeletons.
+        ]]></description>
+      </attribute>
+      <attribute name="debug" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, debugging output will be generated when ejbc is
+ executed.]]></short-description>
+        <description><![CDATA[
+          If true, debugging output will be generated when ejbc is
+ executed.
+        ]]></description>
+      </attribute>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory where the EJB source classes must exist
+ and where the stubs and skeletons will be written.]]></short-description>
+        <description><![CDATA[
+          Sets the destination directory where the EJB source classes must exist
+ and where the stubs and skeletons will be written.  The destination
+ directory must exist before this task is executed.
+        ]]></description>
+      </attribute>
+      <attribute name="ejbdescriptor" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Location of the standard XML EJB descriptor.]]></short-description>
+        <description><![CDATA[
+          Sets the location of the standard XML EJB descriptor.  Typically, this
+ file is named "ejb-jar.xml".
+        ]]></description>
+      </attribute>
+      <attribute name="iasdescriptor" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Location of the iAS-specific XML EJB descriptor.]]></short-description>
+        <description><![CDATA[
+          Sets the location of the iAS-specific XML EJB descriptor.  Typically,
+ this file is named "ias-ejb-jar.xml".
+        ]]></description>
+      </attribute>
+      <attribute name="iashome" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[May be used to specify the "home" directory for this iAS installation.]]></short-description>
+        <description><![CDATA[
+          May be used to specify the "home" directory for this iAS installation.
+ The directory specified should typically be
+ <code>[install-location]/iplanet/ias6/ias</code>.
+        ]]></description>
+      </attribute>
+      <attribute name="keepgenerated" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, the Java source files which are generated by ejbc will be saved .]]></short-description>
+        <description><![CDATA[
+          If true, the Java source files which are generated by ejbc will be saved .
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds to the classpath used when compiling the EJB stubs and skeletons.]]></short-description>
+        <description>
+          <![CDATA[Adds to the classpath used when compiling the EJB stubs and skeletons.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jar" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.Jar"
+      matchingTask="true">
+
+  <short-description><![CDATA[Creates a JAR archive.]]></short-description>
+  <description>
+    <![CDATA[Creates a JAR archive.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="basedir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Directory from which to archive files; optional.]]></short-description>
+        <description><![CDATA[
+          Directory from which to archive files; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="compress" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether we want to compress the files or only store them;
+ optional, default=true;.]]></short-description>
+        <description><![CDATA[
+          Whether we want to compress the files or only store them;
+ optional, default=true;
+        ]]></description>
+      </attribute>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to create; required.]]></short-description>
+        <description><![CDATA[
+          The file to create; required.
+        ]]></description>
+      </attribute>
+      <attribute name="duplicate" type="org.apache.tools.ant.taskdefs.Zip.Duplicate"
+                 briefType="&quot;add&quot;, &quot;preserve&quot;, &quot;fail&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Sets behavior for when a duplicate file is about to be added -
+ one of <code>keep</code>, <code>skip</code> or <code>overwrite</code>.]]></short-description>
+        <description><![CDATA[
+          Sets behavior for when a duplicate file is about to be added -
+ one of <code>keep</code>, <code>skip</code> or <code>overwrite</code>.
+ Possible values are: <code>keep</code> (keep both
+ of the files); <code>skip</code> (keep the first version
+ of the file found); <code>overwrite</code> overwrite the file
+ with the new file
+ Default for zip tasks is <code>keep</code>
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Encoding to use for filenames, defaults to the platform's
+ default encoding.]]></short-description>
+        <description><![CDATA[
+          Encoding to use for filenames, defaults to the platform's
+ default encoding.
+
+ <p>For a list of possible values see <a
+ href="http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html">http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html</a>.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="filesonly" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, emulate Sun's jar utility by not adding parent directories;
+ optional, defaults to false.]]></short-description>
+        <description><![CDATA[
+          If true, emulate Sun's jar utility by not adding parent directories;
+ optional, defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="index" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether or not to create an index list for classes.]]></short-description>
+        <description><![CDATA[
+          Set whether or not to create an index list for classes.
+ This may speed up classloading in some cases.
+        ]]></description>
+      </attribute>
+      <attribute name="manifest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The manifest file to use.]]></short-description>
+        <description><![CDATA[
+          The manifest file to use. This can be either the location of a manifest,
+ or the name of a jar added through a fileset. If its the name of an added
+ jar, the task expects the manifest to be in the jar at META-INF/MANIFEST.MF.
+        ]]></description>
+      </attribute>
+      <attribute name="update" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, updates an existing file, otherwise overwrite
+ any existing one; optional defaults to false.]]></short-description>
+        <description><![CDATA[
+          If true, updates an existing file, otherwise overwrite
+ any existing one; optional defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="whenempty" type="org.apache.tools.ant.taskdefs.Zip.WhenEmpty"
+                 briefType="&quot;fail&quot;, &quot;skip&quot;, &quot;create&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Sets behavior of the task when no files match.]]></short-description>
+        <description><![CDATA[
+          Sets behavior of the task when no files match.
+ Possible values are: <code>fail</code> (throw an exception
+ and halt the build); <code>skip</code> (do not create
+ any archive, but issue a warning); <code>create</code>
+ (make an archive with no entries).
+ Default for zip tasks is <code>skip</code>;
+ for jar tasks, <code>create</code>.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="manifest" type="org.apache.tools.ant.taskdefs.Manifest"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Allows the manifest for the archive file to be provided inline
+ in the buildfile rather than in an external file.]]></short-description>
+        <description>
+          <![CDATA[Allows the manifest for the archive file to be provided inline
+ in the buildfile rather than in an external file.]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files.]]>
+        </description>
+      </element>
+
+      <element name="metainf" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a zipfileset to include in the META-INF directory.]]></short-description>
+        <description>
+          <![CDATA[Adds a zipfileset to include in the META-INF directory.]]>
+        </description>
+      </element>
+
+      <element name="zipgroupfileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a group of zip files.]]></short-description>
+        <description>
+          <![CDATA[Adds a group of zip files.]]>
+        </description>
+      </element>
+
+      <element name="zipfileset" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files that can be
+ read from an archive and be given a prefix/fullpath.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files that can be
+ read from an archive and be given a prefix/fullpath.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jarlib-available" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.extension.JarLibAvailableTask"
+      >
+
+  <short-description><![CDATA[Checks whether an extension is present in a fileset or an extensionSet.]]></short-description>
+  <description>
+    <![CDATA[Checks whether an extension is present in a fileset or an extensionSet.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The JAR library to check.]]></short-description>
+        <description><![CDATA[
+          The JAR library to check.
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of property to set if extensions are available.]]></short-description>
+        <description><![CDATA[
+          The name of property to set if extensions are available.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="extension" type="org.apache.tools.ant.taskdefs.optional.extension.ExtensionAdapter"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Extension looking for.]]></short-description>
+        <description>
+          <![CDATA[Set the Extension looking for.]]>
+        </description>
+      </element>
+
+      <element name="extensionset" type="org.apache.tools.ant.taskdefs.optional.extension.ExtensionSet"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of extensions to search in.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of extensions to search in.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jarlib-display" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.extension.JarLibDisplayTask"
+      >
+
+  <short-description><![CDATA[Displays the "Optional Package" and "Package Specification" information contained within the specified JARs.]]></short-description>
+  <description>
+    <![CDATA[Displays the "Optional Package" and "Package Specification" information
+ contained within the specified JARs.
+
+ <p>Prior to JDK1.3, an "Optional Package" was known as an Extension.
+ The specification for this mechanism is available in the JDK1.3
+ documentation in the directory
+ $JDK_HOME/docs/guide/extensions/versioning.html. Alternatively it is
+ available online at <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html">
+ http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The JAR library to display information for.]]></short-description>
+        <description><![CDATA[
+          The JAR library to display information for.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files about which library data will be displayed.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files about which library data will be displayed.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jarlib-manifest" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.extension.JarLibManifestTask"
+      >
+
+  <short-description><![CDATA[Generates a manifest that declares all the dependencies.]]></short-description>
+  <description>
+    <![CDATA[Generates a manifest that declares all the dependencies.
+ The dependencies are determined by looking in the
+ specified path and searching for Extension / "Optional Package"
+ specifications in the manifests of the jars.
+
+ <p>Prior to JDK1.3, an "Optional Package" was known as an Extension.
+ The specification for this mechanism is available in the JDK1.3
+ documentation in the directory
+ $JDK_HOME/docs/guide/extensions/versioning.html. Alternatively it is
+ available online at <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html">
+ http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The location where generated manifest is placed.]]></short-description>
+        <description><![CDATA[
+          The location where generated manifest is placed.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="attribute" type="org.apache.tools.ant.taskdefs.optional.extension.ExtraAttribute"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds an attribute that is to be put in main section of manifest.]]></short-description>
+        <description>
+          <![CDATA[Adds an attribute that is to be put in main section of manifest.]]>
+        </description>
+      </element>
+
+      <element name="depends" type="org.apache.tools.ant.taskdefs.optional.extension.ExtensionSet"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of extensions that this library requires.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of extensions that this library requires.]]>
+        </description>
+      </element>
+
+      <element name="extension" type="org.apache.tools.ant.taskdefs.optional.extension.ExtensionAdapter"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds an extension that this library implements.]]></short-description>
+        <description>
+          <![CDATA[Adds an extension that this library implements.]]>
+        </description>
+      </element>
+
+      <element name="options" type="org.apache.tools.ant.taskdefs.optional.extension.ExtensionSet"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of extensions that this library optionally requires.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of extensions that this library optionally requires.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jarlib-resolve" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.extension.JarLibResolveTask"
+      >
+
+  <short-description><![CDATA[Tries to locate a JAR to satisfy an extension and place location of JAR into property.]]></short-description>
+  <description>
+    <![CDATA[Tries to locate a JAR to satisfy an extension and place
+ location of JAR into property.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="checkextension" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, libraries returned by nested resolvers should be
+ checked to see if they supply extension.]]></short-description>
+        <description><![CDATA[
+          If true, libraries returned by nested resolvers should be
+ checked to see if they supply extension.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, failure to locate library should fail build.]]></short-description>
+        <description><![CDATA[
+          If true, failure to locate library should fail build.
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the property in which the location of
+ library is stored.]]></short-description>
+        <description><![CDATA[
+          The name of the property in which the location of
+ library is stored.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="ant" type="org.apache.tools.ant.taskdefs.optional.extension.resolvers.AntResolver"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds Ant resolver to run an Ant buildfile to generate a library.]]></short-description>
+        <description>
+          <![CDATA[Adds Ant resolver to run an Ant buildfile to generate a library.]]>
+        </description>
+      </element>
+
+      <element name="extension" type="org.apache.tools.ant.taskdefs.optional.extension.ExtensionAdapter"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Extension looking for.]]></short-description>
+        <description>
+          <![CDATA[Set the Extension looking for.]]>
+        </description>
+      </element>
+
+      <element name="location" type="org.apache.tools.ant.taskdefs.optional.extension.resolvers.LocationResolver"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds location resolver to look for a library in a location
+ relative to project directory.]]></short-description>
+        <description>
+          <![CDATA[Adds location resolver to look for a library in a location
+ relative to project directory.]]>
+        </description>
+      </element>
+
+      <element name="url" type="org.apache.tools.ant.taskdefs.optional.extension.resolvers.URLResolver"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a URL resolver to download a library from a URL
+ to a local file.]]></short-description>
+        <description>
+          <![CDATA[Adds a URL resolver to download a library from a URL
+ to a local file.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="java" category="java"
+      classname="org.apache.tools.ant.taskdefs.Java"
+      >
+
+  <short-description><![CDATA[Launcher for Java applications.]]></short-description>
+  <description>
+    <![CDATA[Launcher for Java applications. Allows use of
+ the same JVM for the called application thus resulting in much
+ faster operation.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, append output to existing file.]]></short-description>
+        <description><![CDATA[
+          If true, append output to existing file.
+        ]]></description>
+      </attribute>
+      <attribute name="classname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Java class to execute.]]></short-description>
+        <description><![CDATA[
+          Sets the Java class to execute.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used when running the Java class.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used when running the Java class
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to use, by reference.]]></short-description>
+        <description><![CDATA[
+          Classpath to use, by reference.
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The working directory of the process.]]></short-description>
+        <description><![CDATA[
+          The working directory of the process
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, then fail if the command exits with a
+ returncode other than 0.]]></short-description>
+        <description><![CDATA[
+          If true, then fail if the command exits with a
+ returncode other than 0
+        ]]></description>
+      </attribute>
+      <attribute name="fork" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, execute in a new VM.]]></short-description>
+        <description><![CDATA[
+          If true, execute in a new VM.
+        ]]></description>
+      </attribute>
+      <attribute name="jvmversion" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[JVM version.]]></short-description>
+        <description><![CDATA[
+          Sets the JVM version.
+        ]]></description>
+      </attribute>
+      <attribute name="jar" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The location of the JAR file to execute.]]></short-description>
+        <description><![CDATA[
+          The location of the JAR file to execute.
+        ]]></description>
+      </attribute>
+      <attribute name="jvm" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Command used to start the VM (only if not forking).]]></short-description>
+        <description><![CDATA[
+          Set the command used to start the VM (only if not forking).
+        ]]></description>
+      </attribute>
+      <attribute name="jvmargs" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Command line arguments for the JVM.]]></short-description>
+        <description><![CDATA[
+          Set the command line arguments for the JVM.
+        ]]></description>
+      </attribute>
+      <attribute name="maxmemory" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Corresponds to -mx or -Xmx depending on VM version.]]></short-description>
+        <description><![CDATA[
+          Corresponds to -mx or -Xmx depending on VM version.
+        ]]></description>
+      </attribute>
+      <attribute name="newenvironment" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, use a completely new environment.]]></short-description>
+        <description><![CDATA[
+          If true, use a completely new environment.
+
+ <p>Will be ignored if we are not forking a new VM.
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File the output of the process is redirected to.]]></short-description>
+        <description><![CDATA[
+          File the output of the process is redirected to.
+        ]]></description>
+      </attribute>
+      <attribute name="timeout" type="java.lang.Long"
+                 briefType="long" required="NOTDEFINED">
+        <short-description><![CDATA[Timeout in milliseconds after which the process will be killed.]]></short-description>
+        <description><![CDATA[
+          Timeout in milliseconds after which the process will be killed.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="env" type="org.apache.tools.ant.types.Environment.Variable"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds an environment variable.]]></short-description>
+        <description>
+          <![CDATA[Adds an environment variable.
+
+ <p>Will be ignored if we are not forking a new VM.]]>
+        </description>
+      </element>
+
+      <element name="sysproperty" type="org.apache.tools.ant.types.Environment.Variable"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a system property.]]></short-description>
+        <description>
+          <![CDATA[Adds a system property.]]>
+        </description>
+      </element>
+
+      <element name="arg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a command-line argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a command-line argument.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to the classpath.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to the classpath.]]>
+        </description>
+      </element>
+
+      <element name="jvmarg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a JVM argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a JVM argument.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="javac" category="java"
+      classname="org.apache.tools.ant.taskdefs.Javac"
+      matchingTask="true">
+
+  <!-- javac task -->
+<external>
+<description>
+
+<p>Compiles a Java source tree.</p>
+
+<p>The source and destination directory will be recursively scanned for Java
+source files to compile. Only Java files that have no corresponding class file
+or where the class file is older than the java file will be compiled.</p>
+
+<p>Note: Ant uses only the names of the source and class files to find
+the classes that need a rebuild. It will not scan the source and therefor
+will have no knowledge about nested classes, classes that are named different
+from the source file and so on.</p>
+
+<p>The directory structure of the source tree should follow the package
+hierarchy.</p>
+
+<p>It is possible to refine the set of files that are being compiled/copied.
+This can be done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, <i>excludesfile</i> and <i>defaultexcludes</i>
+attributes. With the <i>includes</i> or <i>includesfile</i> attribute you specify the files you want to
+have included by using patterns. The <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the <i>defaultexcludes</i> attribute, you can specify whether you
+want to use default exclusions or not. See the section on <a
+href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
+inclusion/exclusion of files works, and how to write patterns.</p>
+
+<p>It is possible to use different compilers. This can be selected with the
+&quot;build.compiler&quot; property or the compiler attribute. Here are the choices:-</p>
+<ul>
+  <li>classic (the standard compiler of JDK 1.1/1.2) - javac1.1 and
+     javac1.2 can be used as aliases</li>
+  <li>modern (the standard compiler of JDK 1.3/1.4) - javac1.3 and
+     javac1.4 can be used as aliases</li>
+  <li>jikes (the <a
+    href="http://oss.software.ibm.com/developerworks/opensource/jikes/project" target="_top">Jikes</a>
+    compiler)</li>
+  <li>jvc (the Command-Line Compiler from Microsoft's SDK for Java /
+    Visual J++) - microsoft can be used as an alias</li>
+  <li>kjc (the <a href="http://www.dms.at/kopi/" target="_top">kopi</a>
+    compiler)</li>
+  <li>gcj (the gcj compiler from gcc)</li>
+  <li>sj (Symantec java compiler) - symantec can be used as an alias</li>
+  <li>extJavac (run either modern or classic in a JVM of its own)</li>
+</ul>
+<p>For JDK 1.1/1.2, classic is the default. For JDK 1.3/1.4, modern is the default.
+If you wish to use a different compiler interface than those
+supplied, write a class that implements the CompilerAdapter interface
+(package org.apache.tools.ant.taskdefs.compilers). Supply the full
+classname in the &quot;build.compiler&quot; property.</p>
+
+<p>The fork attribute overrides the build.compiler setting and expects
+a JDK1.1 or higher to be set in java.home.</p>
+
+<p>This task will drop all entries that point to non-existent
+files/directories from the CLASSPATH it passes to the compiler.</p>
+
+<p><strong>Windows Note:</strong>When the modern compiler is used
+in unforked mode on Windows, it locks up the files present in the
+classpath of the &lt;javac&gt; task, and does not release them.  The side
+effect of this is that you will not be able to delete or move
+those files later on in the build.  The workaround is to fork when
+invoking the compiler.</p>
+
+</description>
+
+<section anchor="examples" name="Examples">
+<pre>  &lt;javac srcdir=&quot;${src}&quot;
+         destdir=&quot;${build}&quot;
+         classpath=&quot;xyz.jar&quot;
+         debug=&quot;on&quot;
+  /&gt;</pre>
+<p>compiles all <code>.java</code> files under the <code>${src}</code>
+directory, and stores
+the <code>.class</code> files in the <code>${build}</code> directory.
+The classpath used contains <code>xyz.jar</code>, and debug information is on.</p>
+
+<pre>  &lt;javac srcdir=&quot;${src}&quot;
+         destdir=&quot;${build}&quot;
+         fork=&quot;true&quot;
+  /&gt;</pre>
+<p>compiles all <code>.java</code> files under the <code>${src}</code>
+directory, and stores the <code>.class</code> files in the
+<code>${build}</code> directory.  This will fork off the javac
+compiler using the default javac executable.</p>
+
+<pre>  &lt;javac srcdir=&quot;${src}&quot;
+         destdir=&quot;${build}&quot;
+         fork=&quot;java$$javac.exe&quot;
+  /&gt;</pre>
+<p>compiles all <code>.java</code> files under the <code>${src}</code>
+directory, and stores the <code>.class</code> files in the
+<code>${build}</code> directory.  This will fork off the javac
+compiler using the executable named <code>java$javac.exe</code>.  Note
+that the <code>$</code> sign needs to be escaped by a second one.</p>
+
+<pre>  &lt;javac srcdir=&quot;${src}&quot;
+         destdir=&quot;${build}&quot;
+         includes=&quot;mypackage/p1/**,mypackage/p2/**&quot;
+         excludes=&quot;mypackage/p1/testpackage/**&quot;
+         classpath=&quot;xyz.jar&quot;
+         debug=&quot;on&quot;
+  /&gt;</pre>
+<p>compiles <code>.java</code> files under the <code>${src}</code>
+directory, and stores the
+<code>.class</code> files in the <code>${build}</code> directory.
+The classpath used contains <code>xyz.jar</code>, and debug information is on.
+Only files under <code>mypackage/p1</code> and <code>mypackage/p2</code> are
+used. Files in the <code>mypackage/p1/testpackage</code> directory are excluded
+from compilation.</p>
+
+<pre>  &lt;javac srcdir=&quot;${src}:${src2}&quot;
+         destdir=&quot;${build}&quot;
+         includes=&quot;mypackage/p1/**,mypackage/p2/**&quot;
+         excludes=&quot;mypackage/p1/testpackage/**&quot;
+         classpath=&quot;xyz.jar&quot;
+         debug=&quot;on&quot;
+  /&gt;</pre>
+
+<p>is the same as the previous example, with the addition of a second
+source path, defined by
+the property <code>src2</code>. This can also be represented using nested
+<code>&lt;src&gt;</code> elements as follows:</p>
+
+<pre>  &lt;javac destdir=&quot;${build}&quot;
+         classpath=&quot;xyz.jar&quot;
+         debug=&quot;on&quot;&gt;
+    &lt;src path=&quot;${src}&quot;/&gt;
+    &lt;src path=&quot;${src2}&quot;/&gt;
+    &lt;include name=&quot;mypackage/p1/**&quot;/&gt;
+    &lt;include name=&quot;mypackage/p2/**&quot;/&gt;
+    &lt;exclude name=&quot;mypackage/p1/testpackage/**&quot;/&gt;
+  &lt;/javac&gt;</pre>
+
+<p><b>Note:</b> If you are using Ant on Windows and a new DOS window pops up
+for every use of an external compiler, this may be a problem of the JDK you are using.
+This problem may occur with all JDKs &lt; 1.2.</p>
+
+<p><b>Note:</b> If you wish to compile only source-files located in some packages below a
+common root you should not include these packages in the srcdir-attribute. Use include/exclude-attributes
+or elements to filter for these packages. If you include part of your package-structure inside the srcdir-attribute
+(or nested src-elements) Ant will start to recompile your sources every time you call it.</p>
+
+</section>
+
+<section anchor="jikes" name="Jikes Notes">
+
+<p>Jikes supports some extra options, which can be set be defining
+properties prior to invoking the task. The ant developers are aware that
+this is ugly and inflexible -expect a better solution in the future. All
+the options are boolean, and must be set to &quot;true&quot; or &quot;yes&quot; to be
+interpreted as anything other than false; by default
+build.compiler.warnings is &quot;true&quot; while all others are &quot;false&quot;</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top">
+	build.compiler.emacs
+	</td>
+	<td valign="top">
+	Enable emacs compatible error messages
+    </td>
+  </tr>
+  <tr>
+    <td valign="top">
+	build.compiler.warnings<br />
+        <b>This property has been deprecated, use the nowarn attribute
+          instead</b>
+	</td>
+	<td valign="top">
+	don't disable warning messages
+    </td>
+  </tr>
+  <tr>
+    <td valign="top">
+	build.compiler.pedantic
+	</td>
+	<td valign="top">
+	enable pedantic warnings
+    </td>
+  </tr>
+  <tr>
+    <td valign="top">
+	build.compiler.fulldepend
+	</td>
+	<td valign="top">
+	enable full dependency checking,<br />
+	&quot;+F&quot; in the jikes manual.
+    </td>
+  </tr>
+</table>
+
+</section>
+</external>
+
+  <short-description><![CDATA[Compiles Java source files.]]></short-description>
+  <description>
+    <![CDATA[Compiles Java source files. This task can take the following
+ arguments:
+ <ul>
+ <li>sourcedir
+ <li>destdir
+ <li>deprecation
+ <li>classpath
+ <li>bootclasspath
+ <li>extdirs
+ <li>optimize
+ <li>debug
+ <li>encoding
+ <li>target
+ <li>depend
+ <li>vebose
+ <li>failonerror
+ <li>includeantruntime
+ <li>includejavaruntime
+ <li>source
+ <li>compiler
+ </ul>
+ Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required.
+ <p>
+ When this task executes, it will recursively scan the sourcedir and
+ destdir looking for Java source files to compile. This task makes its
+ compile decision based on timestamp.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="bootclasspathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a classpath defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a classpath defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="bootclasspath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Bootclasspath that will be used to compile the classes
+ against.]]></short-description>
+        <description><![CDATA[
+          Sets the bootclasspath that will be used to compile the classes
+ against.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for this compilation.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used for this compilation.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a classpath defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a classpath defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="compiler" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Choose the implementation for this particular task.]]></short-description>
+        <description><![CDATA[
+          Choose the implementation for this particular task.
+        ]]></description>
+      </attribute>
+      <attribute name="debug" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates whether source should be compiled
+ with debug information; defaults to off.]]></short-description>
+        <description><![CDATA[
+          Indicates whether source should be compiled
+ with debug information; defaults to off.
+        ]]></description>
+      </attribute>
+      <attribute name="debuglevel" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Keyword list to be appended to the -g command-line switch.]]></short-description>
+        <description><![CDATA[
+          Keyword list to be appended to the -g command-line switch.
+
+ This will be ignored by all implementations except modern
+ and classic(ver >= 1.2). Legal values are none or a
+ comma-separated list of the following keywords: lines, vars,
+ and source. If debuglevel is not specified, by default, :none
+ will be appended to -g. If debug is not turned on, this attribute
+ will be ignored.
+        ]]></description>
+      </attribute>
+      <attribute name="depend" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Enables dependency-tracking for compilers
+ that support this (jikes and classic).]]></short-description>
+        <description><![CDATA[
+          Enables dependency-tracking for compilers
+ that support this (jikes and classic).
+        ]]></description>
+      </attribute>
+      <attribute name="deprecation" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates whether source should be
+ compiled with deprecation information; defaults to off.]]></short-description>
+        <description><![CDATA[
+          Indicates whether source should be
+ compiled with deprecation information; defaults to off.
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory into which the Java source
+ files should be compiled.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory into which the Java source
+ files should be compiled.
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Java source file encoding name.]]></short-description>
+        <description><![CDATA[
+          Set the Java source file encoding name.
+        ]]></description>
+      </attribute>
+      <attribute name="executable" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the javac executable.]]></short-description>
+        <description><![CDATA[
+          Sets the the name of the javac executable.
+
+ <p>Ignored unless fork is true or extJavac has been specified
+ as the compiler.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="extdirs" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Extension directories that will be used during the
+ compilation.]]></short-description>
+        <description><![CDATA[
+          Sets the extension directories that will be used during the
+ compilation.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates whether the build will continue
+ even if there are compilation errors; defaults to true.]]></short-description>
+        <description><![CDATA[
+          Indicates whether the build will continue
+ even if there are compilation errors; defaults to true.
+        ]]></description>
+      </attribute>
+      <attribute name="fork" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, forks the javac compiler.]]></short-description>
+        <description><![CDATA[
+          If true, forks the javac compiler.
+        ]]></description>
+      </attribute>
+      <attribute name="includeantruntime" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, includes Ant's own classpath in the classpath.]]></short-description>
+        <description><![CDATA[
+          If true, includes Ant's own classpath in the classpath.
+        ]]></description>
+      </attribute>
+      <attribute name="includejavaruntime" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, includes the Java runtime libraries in the classpath.]]></short-description>
+        <description><![CDATA[
+          If true, includes the Java runtime libraries in the classpath.
+        ]]></description>
+      </attribute>
+      <attribute name="listfiles" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, list the source files being handed off to the compiler.]]></short-description>
+        <description><![CDATA[
+          If true, list the source files being handed off to the compiler.
+        ]]></description>
+      </attribute>
+      <attribute name="memoryinitialsize" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The initial size of the memory for the underlying VM
+ if javac is run externally; ignored otherwise.]]></short-description>
+        <description><![CDATA[
+          The initial size of the memory for the underlying VM
+ if javac is run externally; ignored otherwise.
+ Defaults to the standard VM memory setting.
+ (Examples: 83886080, 81920k, or 80m)
+        ]]></description>
+      </attribute>
+      <attribute name="memorymaximumsize" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The maximum size of the memory for the underlying VM
+ if javac is run externally; ignored otherwise.]]></short-description>
+        <description><![CDATA[
+          The maximum size of the memory for the underlying VM
+ if javac is run externally; ignored otherwise.
+ Defaults to the standard VM memory setting.
+ (Examples: 83886080, 81920k, or 80m)
+        ]]></description>
+      </attribute>
+      <attribute name="nowarn" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enables the -nowarn option.]]></short-description>
+        <description><![CDATA[
+          If true, enables the -nowarn option.
+        ]]></description>
+      </attribute>
+      <attribute name="optimize" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, compiles with optimization enabled.]]></short-description>
+        <description><![CDATA[
+          If true, compiles with optimization enabled.
+        ]]></description>
+      </attribute>
+      <attribute name="source" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Value of the -source command-line switch; will be ignored
+ by all implementations except modern and jikes.]]></short-description>
+        <description><![CDATA[
+          Value of the -source command-line switch; will be ignored
+ by all implementations except modern and jikes.
+
+ If you use this attribute together with jikes, you must
+ make sure that your version of jikes supports the -source switch.
+ Legal values are 1.3 and 1.4 - by default, no -source argument
+ will be used at all.
+        ]]></description>
+      </attribute>
+      <attribute name="sourcepath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Sourcepath to be used for this compilation.]]></short-description>
+        <description><![CDATA[
+          Set the sourcepath to be used for this compilation.
+        ]]></description>
+      </attribute>
+      <attribute name="sourcepathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a source path defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a source path defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Source directories to find the source Java files.]]></short-description>
+        <description><![CDATA[
+          Set the source directories to find the source Java files.
+        ]]></description>
+      </attribute>
+      <attribute name="target" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Target VM that the classes will be compiled for.]]></short-description>
+        <description><![CDATA[
+          Sets the target VM that the classes will be compiled for. Valid
+ strings are "1.1", "1.2", and "1.3".
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, asks the compiler for verbose output.]]></short-description>
+        <description><![CDATA[
+          If true, asks the compiler for verbose output.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="bootclasspath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to the bootclasspath.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to the bootclasspath.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to the classpath.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to the classpath.]]>
+        </description>
+      </element>
+
+      <element name="compilerarg" type="org.apache.tools.ant.taskdefs.Javac.ImplementationSpecificArgument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds an implementation specific command-line argument.]]></short-description>
+        <description>
+          <![CDATA[Adds an implementation specific command-line argument.]]>
+        </description>
+      </element>
+
+      <element name="extdirs" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to extdirs.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to extdirs.]]>
+        </description>
+      </element>
+
+      <element name="sourcepath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to sourcepath.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to sourcepath.]]>
+        </description>
+      </element>
+
+      <element name="src" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path for source compilation.]]></short-description>
+        <description>
+          <![CDATA[Adds a path for source compilation.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="javacc" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.javacc.JavaCC"
+      >
+
+  <short-description><![CDATA[JavaCC compiler compiler task.]]></short-description>
+  <description>
+    <![CDATA[JavaCC compiler compiler task.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="buildparser" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[BUILD_PARSER grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the BUILD_PARSER grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="buildtokenmanager" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[BUILD_TOKEN_MANAGER grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the BUILD_TOKEN_MANAGER grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="cachetokens" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[CACHE_TOKENS grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the CACHE_TOKENS grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="choiceambiguitycheck" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[CHOICE_AMBIGUITY_CHECK grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the CHOICE_AMBIGUITY_CHECK grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="commontokenaction" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[COMMON_TOKEN_ACTION grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the COMMON_TOKEN_ACTION grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="debuglookahead" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[DEBUG_LOOKAHEAD grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the DEBUG_LOOKAHEAD grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="debugparser" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[DEBUG_PARSER grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the DEBUG_PARSER grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="debugtokenmanager" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[DEBUG_TOKEN_MANAGER grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the DEBUG_TOKEN_MANAGER grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="errorreporting" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[ERROR_REPORTING grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the ERROR_REPORTING grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="forcelacheck" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[FORCE_LA_CHECK grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the FORCE_LA_CHECK grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="ignorecase" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[IGNORE_CASE grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the IGNORE_CASE grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="javacchome" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory containing the JavaCC distribution.]]></short-description>
+        <description><![CDATA[
+          The directory containing the JavaCC distribution.
+        ]]></description>
+      </attribute>
+      <attribute name="javaunicodeescape" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[JAVA_UNICODE_ESCAPE grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the JAVA_UNICODE_ESCAPE grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="lookahead" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[LOOKAHEAD grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the LOOKAHEAD grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="optimizetokenmanager" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[OPTIMIZE_TOKEN_MANAGER grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the OPTIMIZE_TOKEN_MANAGER grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="otherambiguitycheck" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[OTHER_AMBIGUITY_CHECK grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the OTHER_AMBIGUITY_CHECK grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="outputdirectory" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory to write the generated files to.]]></short-description>
+        <description><![CDATA[
+          The directory to write the generated files to.
+ If not set, the files are written to the directory
+ containing the grammar file.
+        ]]></description>
+      </attribute>
+      <attribute name="sanitycheck" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[SANITY_CHECK grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the SANITY_CHECK grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="static" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[STATIC grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the STATIC grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="target" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The grammar file to process.]]></short-description>
+        <description><![CDATA[
+          The grammar file to process.
+        ]]></description>
+      </attribute>
+      <attribute name="unicodeinput" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[UNICODE_INPUT grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the UNICODE_INPUT grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="usercharstream" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[USER_CHAR_STREAM grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the USER_CHAR_STREAM grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="usertokenmanager" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[USER_TOKEN_MANAGER grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the USER_TOKEN_MANAGER grammar option.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="javadoc" category="java"
+      classname="org.apache.tools.ant.taskdefs.Javadoc"
+      >
+
+  <!-- javadoc task -->
+<external>
+<description>
+
+<p>Generates code documentation using the javadoc tool.</p>
+
+<p>The source directory will be recursively scanned for Java source files to process
+but only those matching the inclusion rules, and not matching the exclusions rules
+will be passed to the javadoc tool. This
+allows wildcards to be used to choose between package names, reducing verbosity
+and management costs over time. This task, however, has no notion of
+&quot;changed&quot; files, unlike the <a href="javac.html">javac</a> task. This means
+all packages will be processed each time this task is run. In general, however,
+this task is used much less frequently.</p>
+
+<p>This task works seamlessly between different javadoc versions (1.1 and 1.2),
+with the obvious restriction that the 1.2 attributes will be ignored if run in a
+1.1 VM.</p>
+
+<p>NOTE: since javadoc calls System.exit(), javadoc cannot be run inside the
+same VM as ant without breaking functionality. For this reason, this task
+always forks the VM. This overhead is not significant since javadoc is normally a heavy
+application and will be called infrequently.</p>
+
+<p>NOTE: the packagelist attribute allows you to specify the list of packages to
+document outside of the Ant file. It's a much better practice to include everything
+inside the build.xml file. This option was added in order to make it easier to
+migrate from regular makefiles, where you would use this option of javadoc.
+The packages listed in packagelist are not checked, so the task performs even
+if some packages are missing or broken. Use this option if you wish to convert from
+an existing makefile. Once things are running you should then switch to the regular
+notation. </p>
+
+<p><i><b>DEPRECATION:</b> the javadoc2 task simply points to the javadoc task and it's
+there for back compatibility reasons. Since this task will be removed in future
+versions, you are strongly encouraged to use <a href="javadoc.html">javadoc</a>
+instead.</i></p>
+</description>
+
+<section anchor="examples" name="Example">
+<pre>  &lt;javadoc packagenames=&quot;com.dummy.test.*&quot;
+           sourcepath=&quot;src&quot;
+           excludepackagenames=&quot;com.dummy.test.doc-files.*&quot;
+           defaultexcludes=&quot;yes&quot;
+           destdir=&quot;docs/api&quot;
+           author=&quot;true&quot;
+           version=&quot;true&quot;
+           use=&quot;true&quot;
+           windowtitle=&quot;Test API&quot;&gt;
+    &lt;doctitle&gt;&lt;![CDATA[&lt;h1&gt;Test&lt;/h1&gt;]]&gt;&lt;/doctitle&gt;
+    &lt;bottom&gt;&lt;![CDATA[&lt;i&gt;Copyright &amp;#169; 2000 Dummy Corp. All Rights Reserved.&lt;/i&gt;]]&gt;&lt;/bottom&gt;
+    &lt;tag name=&quot;todo&quot; scope=&quot;all&quot; description=&quot;To do:&quot; /&gt;
+    &lt;group title=&quot;Group 1 Packages&quot; packages=&quot;com.dummy.test.a*&quot;/&gt;
+    &lt;group title=&quot;Group 2 Packages&quot; packages=&quot;com.dummy.test.b*:com.dummy.test.c*&quot;/&gt;
+    &lt;link offline=&quot;true&quot; href=&quot;http://java.sun.com/products/jdk/1.2/docs/api/&quot; packagelistLoc=&quot;C:\tmp&quot;/&gt;
+    &lt;link href=&quot;http://developer.java.sun.com/developer/products/xml/docs/api/&quot;/&gt;
+  &lt;/javadoc&gt;</pre>
+</section>
+</external>
+
+  <short-description><![CDATA[Generates Javadoc documentation for a collection of source code.]]></short-description>
+  <description>
+    <![CDATA[Generates Javadoc documentation for a collection
+ of source code.
+
+ <P>Current known limitations are:
+
+ <P><UL>
+    <LI>patterns must be of the form "xxx.*", every other pattern doesn't
+        work.
+    <LI>there is no control on arguments sanity since they are left
+        to the javadoc implementation.
+    <LI>argument J in javadoc1 is not supported (what is that for anyway?)
+ </UL>
+
+ <P>If no <CODE>doclet</CODE> is set, then the <CODE>version</CODE> and
+ <CODE>author</CODE> are by default <CODE>"yes"</CODE>.
+
+ <P>Note: This task is run on another VM because the Javadoc code calls
+ <CODE>System.exit()</CODE> which would break Ant functionality.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="access" type="org.apache.tools.ant.taskdefs.Javadoc.AccessType"
+                 briefType="&quot;protected&quot;, &quot;public&quot;, &quot;package&quot;, &quot;private&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Scope to be processed.]]></short-description>
+        <description><![CDATA[
+          Set the scope to be processed. This is an alternative to the
+ use of the setPublic, setPrivate, etc methods. It gives better build
+ file control over what scope is processed.
+        ]]></description>
+      </attribute>
+      <attribute name="additionalparam" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set an additional parameter on the command line.]]></short-description>
+        <description><![CDATA[
+          Set an additional parameter on the command line
+        ]]></description>
+      </attribute>
+      <attribute name="author" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Include the author tag in the generated documentation.]]></short-description>
+        <description><![CDATA[
+          Include the author tag in the generated documentation.
+        ]]></description>
+      </attribute>
+      <attribute name="bootclasspathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a CLASSPATH defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a CLASSPATH defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="bootclasspath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Boot classpath to use.]]></short-description>
+        <description><![CDATA[
+          Set the boot classpath to use.
+        ]]></description>
+      </attribute>
+      <attribute name="bottom" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Text to be placed at the bottom of each output file.]]></short-description>
+        <description><![CDATA[
+          Set the text to be placed at the bottom of each output file.
+        ]]></description>
+      </attribute>
+      <attribute name="charset" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Charset for cross-platform viewing of generated documentation.]]></short-description>
+        <description><![CDATA[
+          Charset for cross-platform viewing of generated documentation.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for this javadoc run.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used for this javadoc run.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a CLASSPATH defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a CLASSPATH defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="defaultexcludes" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether default exclusions should be used or not.]]></short-description>
+        <description><![CDATA[
+          Sets whether default exclusions should be used or not.
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where the Javadoc output will be generated.]]></short-description>
+        <description><![CDATA[
+          Set the directory where the Javadoc output will be generated.
+        ]]></description>
+      </attribute>
+      <attribute name="docencoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Output file encoding name.]]></short-description>
+        <description><![CDATA[
+          Output file encoding name.
+        ]]></description>
+      </attribute>
+      <attribute name="doclet" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Class that starts the doclet used in generating the 
+ documentation.]]></short-description>
+        <description><![CDATA[
+          Set the class that starts the doclet used in generating the 
+ documentation.
+        ]]></description>
+      </attribute>
+      <attribute name="docletpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath used to find the doclet class.]]></short-description>
+        <description><![CDATA[
+          Set the classpath used to find the doclet class.
+        ]]></description>
+      </attribute>
+      <attribute name="docletpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath used to find the doclet class by reference.]]></short-description>
+        <description><![CDATA[
+          Set the classpath used to find the doclet class by reference.
+        ]]></description>
+      </attribute>
+      <attribute name="doctitle" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Title of the generated overview page.]]></short-description>
+        <description><![CDATA[
+          Set the title of the generated overview page.
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Encoding name of the source files,.]]></short-description>
+        <description><![CDATA[
+          Set the encoding name of the source files,
+        ]]></description>
+      </attribute>
+      <attribute name="excludepackagenames" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[List of packages to be excluded.]]></short-description>
+        <description><![CDATA[
+          Set the list of packages to be excluded.
+        ]]></description>
+      </attribute>
+      <attribute name="extdirs" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Location of the extensions directories.]]></short-description>
+        <description><![CDATA[
+          Set the location of the extensions directories.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Should the build process fail if javadoc fails (as indicated by
+ a non zero return code)?.]]></short-description>
+        <description><![CDATA[
+          Should the build process fail if javadoc fails (as indicated by
+ a non zero return code)?
+
+ <p>Default is false.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="footer" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Footer text to be placed at the bottom of each output file.]]></short-description>
+        <description><![CDATA[
+          Set the footer text to be placed at the bottom of each output file.
+        ]]></description>
+      </attribute>
+      <attribute name="group" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Group specified packages together in overview page.]]></short-description>
+        <description><![CDATA[
+          Group specified packages together in overview page.
+        ]]></description>
+      </attribute>
+      <attribute name="header" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Header text to be placed at the top of each output file.]]></short-description>
+        <description><![CDATA[
+          Set the header text to be placed at the top of each output file.
+        ]]></description>
+      </attribute>
+      <attribute name="helpfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the HTML help file to use.]]></short-description>
+        <description><![CDATA[
+          Specifies the HTML help file to use.
+        ]]></description>
+      </attribute>
+      <attribute name="link" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Create links to javadoc output at the given URL.]]></short-description>
+        <description><![CDATA[
+          Create links to javadoc output at the given URL.
+        ]]></description>
+      </attribute>
+      <attribute name="linkoffline" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Link to docs at "url" using package list at "url2"
+ - separate the URLs by using a space character.]]></short-description>
+        <description><![CDATA[
+          Link to docs at "url" using package list at "url2"
+ - separate the URLs by using a space character.
+        ]]></description>
+      </attribute>
+      <attribute name="locale" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Local to use in documentation generation.]]></short-description>
+        <description><![CDATA[
+          Set the local to use in documentation generation.
+        ]]></description>
+      </attribute>
+      <attribute name="maxmemory" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Maximum memory to be used by the javadoc process.]]></short-description>
+        <description><![CDATA[
+          Set the maximum memory to be used by the javadoc process
+        ]]></description>
+      </attribute>
+      <attribute name="nodeprecated" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, do not include @deprecated information.]]></short-description>
+        <description><![CDATA[
+          If true, do not include @deprecated information.
+        ]]></description>
+      </attribute>
+      <attribute name="nodeprecatedlist" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, do not generate deprecated list.]]></short-description>
+        <description><![CDATA[
+          If true, do not generate deprecated list.
+        ]]></description>
+      </attribute>
+      <attribute name="nohelp" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, do not generate help link.]]></short-description>
+        <description><![CDATA[
+          If true, do not generate help link
+        ]]></description>
+      </attribute>
+      <attribute name="noindex" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, do not generate index.]]></short-description>
+        <description><![CDATA[
+          If true, do not generate index.
+        ]]></description>
+      </attribute>
+      <attribute name="nonavbar" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, do not generate navigation bar.]]></short-description>
+        <description><![CDATA[
+          If true, do not generate navigation bar.
+        ]]></description>
+      </attribute>
+      <attribute name="notree" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, do not generate class hierarchy.]]></short-description>
+        <description><![CDATA[
+          If true, do not generate class hierarchy.
+        ]]></description>
+      </attribute>
+      <attribute name="old" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicate whether Javadoc should produce old style (JDK 1.1) 
+ documentation.]]></short-description>
+        <description><![CDATA[
+          Indicate whether Javadoc should produce old style (JDK 1.1) 
+ documentation.
+
+ This is not supported by JDK 1.1 and has been phased out in JDK 1.4
+        ]]></description>
+      </attribute>
+      <attribute name="overview" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Specify the file containing the overview to be included in the generated
+ documentation.]]></short-description>
+        <description><![CDATA[
+          Specify the file containing the overview to be included in the generated
+ documentation.
+        ]]></description>
+      </attribute>
+      <attribute name="package" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicate whether only package, protected and public classes and 
+ members are to be included in the scope processed.]]></short-description>
+        <description><![CDATA[
+          Indicate whether only package, protected and public classes and 
+ members are to be included in the scope processed
+        ]]></description>
+      </attribute>
+      <attribute name="packagelist" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of a file containing the packages to process.]]></short-description>
+        <description><![CDATA[
+          The name of a file containing the packages to process.
+        ]]></description>
+      </attribute>
+      <attribute name="packagenames" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Package names to be processed.]]></short-description>
+        <description><![CDATA[
+          Set the package names to be processed.
+        ]]></description>
+      </attribute>
+      <attribute name="private" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicate whether all classes and 
+ members are to be included in the scope processed.]]></short-description>
+        <description><![CDATA[
+          Indicate whether all classes and 
+ members are to be included in the scope processed
+        ]]></description>
+      </attribute>
+      <attribute name="protected" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicate whether only protected and public classes and members are to 
+ be included in the scope processed.]]></short-description>
+        <description><![CDATA[
+          Indicate whether only protected and public classes and members are to 
+ be included in the scope processed
+        ]]></description>
+      </attribute>
+      <attribute name="public" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicate whether only public classes and members are to be included in 
+ the scope processed.]]></short-description>
+        <description><![CDATA[
+          Indicate whether only public classes and members are to be included in 
+ the scope processed
+        ]]></description>
+      </attribute>
+      <attribute name="serialwarn" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, generate warning about @serial tag.]]></short-description>
+        <description><![CDATA[
+          If true, generate warning about @serial tag.
+        ]]></description>
+      </attribute>
+      <attribute name="source" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Enables the -source switch, will be ignored if javadoc is not
+ the 1.4 version or a different doclet than the standard doclet
+ is used.]]></short-description>
+        <description><![CDATA[
+          Enables the -source switch, will be ignored if javadoc is not
+ the 1.4 version or a different doclet than the standard doclet
+ is used.
+        ]]></description>
+      </attribute>
+      <attribute name="sourcefiles" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[List of source files to process.]]></short-description>
+        <description><![CDATA[
+          Set the list of source files to process.
+        ]]></description>
+      </attribute>
+      <attribute name="sourcepath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Specify where to find source file.]]></short-description>
+        <description><![CDATA[
+          Specify where to find source file
+        ]]></description>
+      </attribute>
+      <attribute name="sourcepathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a CLASSPATH defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a CLASSPATH defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="splitindex" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Generate a split index.]]></short-description>
+        <description><![CDATA[
+          Generate a split index
+        ]]></description>
+      </attribute>
+      <attribute name="stylesheetfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the CSS stylesheet file to use.]]></short-description>
+        <description><![CDATA[
+          Specifies the CSS stylesheet file to use.
+        ]]></description>
+      </attribute>
+      <attribute name="use" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Generate the &quot;use&quot page for each package.]]></short-description>
+        <description><![CDATA[
+          Generate the &quot;use&quot page for each package.
+        ]]></description>
+      </attribute>
+      <attribute name="useexternalfile" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Work around command line length limit by using an external file
+ for the sourcefiles.]]></short-description>
+        <description><![CDATA[
+          Work around command line length limit by using an external file
+ for the sourcefiles.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Run javadoc in verbose mode.]]></short-description>
+        <description><![CDATA[
+          Run javadoc in verbose mode
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Include the version tag in the generated documentation.]]></short-description>
+        <description><![CDATA[
+          Include the version tag in the generated documentation.
+        ]]></description>
+      </attribute>
+      <attribute name="windowtitle" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Title to be placed in the HTML &lt;title&gt; tag of the 
+ generated documentation.]]></short-description>
+        <description><![CDATA[
+          Set the title to be placed in the HTML &lt;title&gt; tag of the 
+ generated documentation.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="bottom" type="org.apache.tools.ant.taskdefs.Javadoc.Html"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Text to be placed at the bottom of each output file.]]></short-description>
+        <description>
+          <![CDATA[Set the text to be placed at the bottom of each output file.]]>
+        </description>
+      </element>
+
+      <element name="doctitle" type="org.apache.tools.ant.taskdefs.Javadoc.Html"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a document title to use for the overview page.]]></short-description>
+        <description>
+          <![CDATA[Add a document title to use for the overview page.]]>
+        </description>
+      </element>
+
+      <element name="excludepackage" type="org.apache.tools.ant.taskdefs.Javadoc.PackageName"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a package to be excluded from the javadoc run.]]></short-description>
+        <description>
+          <![CDATA[Add a package to be excluded from the javadoc run.]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a fileset.]]></short-description>
+        <description>
+          <![CDATA[Adds a fileset.
+
+ <p>All included files will be added as sourcefiles.  The task
+ will automatically add
+ <code>includes=&quot;**&#47;*.java&quot;</code> to the
+ fileset.</p>]]>
+        </description>
+      </element>
+
+      <element name="footer" type="org.apache.tools.ant.taskdefs.Javadoc.Html"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Footer text to be placed at the bottom of each output file.]]></short-description>
+        <description>
+          <![CDATA[Set the footer text to be placed at the bottom of each output file.]]>
+        </description>
+      </element>
+
+      <element name="header" type="org.apache.tools.ant.taskdefs.Javadoc.Html"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Header text to be placed at the top of each output file.]]></short-description>
+        <description>
+          <![CDATA[Set the header text to be placed at the top of each output file.]]>
+        </description>
+      </element>
+
+      <element name="package" type="org.apache.tools.ant.taskdefs.Javadoc.PackageName"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a single package to be processed.]]></short-description>
+        <description>
+          <![CDATA[Add a single package to be processed.
+
+ If the package name ends with &quot;.*&quot; the Javadoc task
+ will find and process all subpackages.]]>
+        </description>
+      </element>
+
+      <element name="packageset" type="org.apache.tools.ant.types.DirSet"
+               briefType="Dirset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a packageset.]]></short-description>
+        <description>
+          <![CDATA[Adds a packageset.
+
+ <p>All included directories will be translated into package
+ names be converting the directory separator into dots.</p>]]>
+        </description>
+      </element>
+
+      <element name="source" type="org.apache.tools.ant.taskdefs.Javadoc.SourceFile"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a single source file.]]></short-description>
+        <description>
+          <![CDATA[Add a single source file.]]>
+        </description>
+      </element>
+
+      <element name="taglet" type="org.apache.tools.ant.taskdefs.Javadoc.ExtensionInfo"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a taglet.]]></short-description>
+        <description>
+          <![CDATA[Add a taglet]]>
+        </description>
+      </element>
+
+      <element name="bootclasspath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a Path to be configured with the boot classpath.]]></short-description>
+        <description>
+          <![CDATA[Create a Path to be configured with the boot classpath]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a Path to be configured with the classpath to use.]]></short-description>
+        <description>
+          <![CDATA[Create a Path to be configured with the classpath to use]]>
+        </description>
+      </element>
+
+      <element name="doclet" type="org.apache.tools.ant.taskdefs.Javadoc.DocletInfo"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a doclet to be used in the documentation generation.]]></short-description>
+        <description>
+          <![CDATA[Create a doclet to be used in the documentation generation.]]>
+        </description>
+      </element>
+
+      <element name="group" type="org.apache.tools.ant.taskdefs.Javadoc.GroupArgument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Separates packages on the overview page into whatever
+ groups you specify, one group per table.]]></short-description>
+        <description>
+          <![CDATA[Separates packages on the overview page into whatever
+ groups you specify, one group per table.]]>
+        </description>
+      </element>
+
+      <element name="link" type="org.apache.tools.ant.taskdefs.Javadoc.LinkArgument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create link to javadoc output at the given URL.]]></short-description>
+        <description>
+          <![CDATA[Create link to javadoc output at the given URL.]]>
+        </description>
+      </element>
+
+      <element name="sourcepath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a path to be configured with the locations of the source
+ files.]]></short-description>
+        <description>
+          <![CDATA[Create a path to be configured with the locations of the source
+ files.]]>
+        </description>
+      </element>
+
+      <element name="tag" type="org.apache.tools.ant.taskdefs.Javadoc.TagArgument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Creates and adds a -tag argument.]]></short-description>
+        <description>
+          <![CDATA[Creates and adds a -tag argument. This is used to specify
+ custom tags. This argument is only available for JavaDoc 1.4,
+ and will generate a verbose message (and then be ignored)
+ when run on Java versions below 1.4.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="javah" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.Javah"
+      >
+
+  <short-description><![CDATA[Generates JNI header files using javah.]]></short-description>
+  <description>
+    <![CDATA[Generates JNI header files using javah.
+
+ This task can take the following arguments:
+ <ul>
+ <li>classname - the fully-qualified name of a class</li>
+ <li>outputFile - Concatenates the resulting header or source files for all
+     the classes listed into this file</li>
+ <li>destdir - Sets the directory where javah saves the header files or the
+     stub files</li>
+ <li>classpath</li>
+ <li>bootclasspath</li>
+ <li>force - Specifies that output files should always be written
+(JDK1.2 only)</li>
+ <li>old - Specifies that old JDK1.0-style header files should be generated
+     (otherwise output file contain JNI-style native method
+      function prototypes) (JDK1.2 only)</li>
+ <li>stubs - generate C declarations from the Java object file (used with old)</li>
+ <li>verbose - causes javah to print a message to stdout concerning the status
+     of the generated files</li>
+ <li>extdirs - Override location of installed extensions</li>
+ </ul>
+ Of these arguments, either <b>outputFile</b> or <b>destdir</b> is required,
+ but not both. More than one classname may be specified, using a comma-separated
+ list or by using <code>&lt;class name="xxx"&gt;</code> elements within the task.
+ <p>
+ When this task executes, it will generate C header and source files that
+ are needed to implement native methods.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="bootclasspathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a classpath defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a classpath defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="bootclasspath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Location of bootstrap class files.]]></short-description>
+        <description><![CDATA[
+          location of bootstrap class files.
+        ]]></description>
+      </attribute>
+      <attribute name="class" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The fully-qualified name of the class (or classes, separated by commas).]]></short-description>
+        <description><![CDATA[
+          the fully-qualified name of the class (or classes, separated by commas).
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[The classpath to use.]]></short-description>
+        <description><![CDATA[
+          the classpath to use.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a classpath defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a classpath defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory into which the Java source
+ files should be compiled.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory into which the Java source
+ files should be compiled.
+        ]]></description>
+      </attribute>
+      <attribute name="force" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, output files should always be written (JDK1.2 only).]]></short-description>
+        <description><![CDATA[
+          If true, output files should always be written (JDK1.2 only).
+        ]]></description>
+      </attribute>
+      <attribute name="old" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, specifies that old JDK1.0-style header files should be
+ generated.
+ (otherwise output file contain JNI-style native method function prototypes) (JDK1.2 only).]]></short-description>
+        <description><![CDATA[
+          If true, specifies that old JDK1.0-style header files should be
+ generated.
+ (otherwise output file contain JNI-style native method function prototypes) (JDK1.2 only)
+        ]]></description>
+      </attribute>
+      <attribute name="outputfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Concatenates the resulting header or source files for all
+ the classes listed into this file.]]></short-description>
+        <description><![CDATA[
+          Concatenates the resulting header or source files for all
+ the classes listed into this file.
+        ]]></description>
+      </attribute>
+      <attribute name="stubs" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, generate C declarations from the Java object file (used with old).]]></short-description>
+        <description><![CDATA[
+          If true, generate C declarations from the Java object file (used with old).
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, causes Javah to print a message concerning
+ the status of the generated files.]]></short-description>
+        <description><![CDATA[
+          If true, causes Javah to print a message concerning
+ the status of the generated files.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="bootclasspath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds path to bootstrap class files.]]></short-description>
+        <description>
+          <![CDATA[Adds path to bootstrap class files.]]>
+        </description>
+      </element>
+
+      <element name="class" type="org.apache.tools.ant.taskdefs.optional.Javah.ClassArgument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds class to process.]]></short-description>
+        <description>
+          <![CDATA[Adds class to process.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Path to use for classpath.]]></short-description>
+        <description>
+          <![CDATA[Path to use for classpath.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jdepend" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask"
+      >
+
+  <short-description><![CDATA[Runs JDepend tests.]]></short-description>
+  <description>
+    <![CDATA[Runs JDepend tests.
+
+ <p>JDepend is a tool to generate design quality metrics for each Java package.
+ It has been initially created by Mike Clark. JDepend can be found at <a
+ href="http://www.clarkware.com/software/JDepend.html">http://www.clarkware.com/software/JDepend.html</a>.
+
+ The current implementation spawn a new Java VM.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for this compilation.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used for this compilation.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a classpath defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a classpath defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory to invoke the VM in.]]></short-description>
+        <description><![CDATA[
+          The directory to invoke the VM in. Ignored if no JVM is forked.
+        ]]></description>
+      </attribute>
+      <attribute name="fork" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, forks into a new JVM.]]></short-description>
+        <description><![CDATA[
+          If true, forks into a new JVM. Default: false.
+        ]]></description>
+      </attribute>
+      <attribute name="format" type="org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask.FormatAttribute"
+                 briefType="&quot;xml&quot;, &quot;text&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[The format to write the output in, "xml" or "text".]]></short-description>
+        <description><![CDATA[
+          The format to write the output in, "xml" or "text".
+        ]]></description>
+      </attribute>
+      <attribute name="haltonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether or not to halt on failure.]]></short-description>
+        <description><![CDATA[
+          Whether or not to halt on failure. Default: false.
+        ]]></description>
+      </attribute>
+      <attribute name="jvm" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The command used to invoke a forked Java Virtual Machine.]]></short-description>
+        <description><![CDATA[
+          The command used to invoke a forked Java Virtual Machine.
+
+ Default is <tt>java</tt>. Ignored if no JVM is forked.
+        ]]></description>
+      </attribute>
+      <attribute name="outputfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The output file name.]]></short-description>
+        <description><![CDATA[
+          The output file name.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to the classpath.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to the classpath.]]>
+        </description>
+      </element>
+
+      <element name="sourcespath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to source code to analyze.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to source code to analyze.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jjtree" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.javacc.JJTree"
+      >
+
+  <short-description><![CDATA[Runs the JJTree compiler compiler.]]></short-description>
+  <description>
+    <![CDATA[Runs the JJTree compiler compiler.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="buildnodefiles" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[BUILD_NODE_FILES grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the BUILD_NODE_FILES grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="javacchome" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory containing the JavaCC distribution.]]></short-description>
+        <description><![CDATA[
+          The directory containing the JavaCC distribution.
+        ]]></description>
+      </attribute>
+      <attribute name="multi" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[MULTI grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the MULTI grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="nodedefaultvoid" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[NODE_DEFAULT_VOID grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the NODE_DEFAULT_VOID grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="nodefactory" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[NODE_FACTORY grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the NODE_FACTORY grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="nodepackage" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[NODE_PACKAGE grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the NODE_PACKAGE grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="nodeprefix" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[NODE_PREFIX grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the NODE_PREFIX grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="nodescopehook" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[NODE_SCOPE_HOOK grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the NODE_SCOPE_HOOK grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="nodeusesparser" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[NODE_USES_PARSER grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the NODE_USES_PARSER grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="outputdirectory" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory to write the generated file to.]]></short-description>
+        <description><![CDATA[
+          The directory to write the generated file to.
+ If not set, the files are written to the directory
+ containing the grammar file.
+        ]]></description>
+      </attribute>
+      <attribute name="static" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[STATIC grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the STATIC grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="target" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The jjtree grammar file to process.]]></short-description>
+        <description><![CDATA[
+          The jjtree grammar file to process.
+        ]]></description>
+      </attribute>
+      <attribute name="visitor" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[VISITOR grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the VISITOR grammar option.
+        ]]></description>
+      </attribute>
+      <attribute name="visitorexception" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[VISITOR_EXCEPTION grammar option.]]></short-description>
+        <description><![CDATA[
+          Sets the VISITOR_EXCEPTION grammar option.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jpcoverage" category="metrics"
+      classname="org.apache.tools.ant.taskdefs.optional.sitraka.Coverage"
+      >
+
+  <short-description><![CDATA[Runs Sitraka JProbe Coverage.]]></short-description>
+  <description>
+    <![CDATA[Runs Sitraka JProbe Coverage.
+
+ Options are pretty numerous, you'd better check the manual for a full
+ descriptions of options. (not that simple since they differ from the online
+ help, from the usage command line and from the examples...)
+ <p>
+ For additional information, visit <a href="http://www.sitraka.com">www.sitraka.com</a>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="applet" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, run an applet.]]></short-description>
+        <description><![CDATA[
+          If true, run an applet.
+        ]]></description>
+      </attribute>
+      <attribute name="classname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Classname to run as standalone or runner for filesets.]]></short-description>
+        <description><![CDATA[
+          classname to run as standalone or runner for filesets.
+        ]]></description>
+      </attribute>
+      <attribute name="exitprompt" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Toggles display of the console prompt: always, error, never.]]></short-description>
+        <description><![CDATA[
+          Toggles display of the console prompt: always, error, never
+        ]]></description>
+      </attribute>
+      <attribute name="finalsnapshot" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Type of snapshot to send at program termination: none, coverage, all.]]></short-description>
+        <description><![CDATA[
+          Type of snapshot to send at program termination: none, coverage, all.
+ Can be null, default to none
+        ]]></description>
+      </attribute>
+      <attribute name="home" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory where JProbe is installed.]]></short-description>
+        <description><![CDATA[
+          The directory where JProbe is installed.
+        ]]></description>
+      </attribute>
+      <attribute name="javaexe" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the java executable.]]></short-description>
+        <description><![CDATA[
+          Path to the java executable.
+        ]]></description>
+      </attribute>
+      <attribute name="recordfromstart" type="org.apache.tools.ant.taskdefs.optional.sitraka.Coverage.Recordfromstart"
+                 briefType="&quot;coverage&quot;, &quot;none&quot;, &quot;all&quot;" required="NOTDEFINED">
+        <short-description><![CDATA["all", "coverage",  or "none".]]></short-description>
+        <description><![CDATA[
+          "all", "coverage",  or "none".
+        ]]></description>
+      </attribute>
+      <attribute name="seedname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Seed name for snapshot file.]]></short-description>
+        <description><![CDATA[
+          seed name for snapshot file. Can be null, default to snap
+        ]]></description>
+      </attribute>
+      <attribute name="snapshotdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The path to the directory where snapshot files are stored.]]></short-description>
+        <description><![CDATA[
+          The path to the directory where snapshot files are stored.
+ Choose a directory that is reachable by both the remote
+ and local computers, and enter the same path on the command-line
+ and in the viewer.
+        ]]></description>
+      </attribute>
+      <attribute name="tracknatives" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, track native methods.]]></short-description>
+        <description><![CDATA[
+          If true, track native methods.
+        ]]></description>
+      </attribute>
+      <attribute name="vm" type="org.apache.tools.ant.taskdefs.optional.sitraka.Coverage.Javavm"
+                 briefType="&quot;java2&quot;, &quot;jdk118&quot;, &quot;jdk117&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates which virtual machine to run: "jdk117", "jdk118" or "java2".]]></short-description>
+        <description><![CDATA[
+          Indicates which virtual machine to run: "jdk117", "jdk118" or "java2".
+ Can be null, default to "java2".
+        ]]></description>
+      </attribute>
+      <attribute name="warnlevel" type="java.lang.Integer"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Set warning level (0-3, where 0 is the least amount of warnings).]]></short-description>
+        <description><![CDATA[
+          Set warning level (0-3, where 0 is the least amount of warnings).
+        ]]></description>
+      </attribute>
+      <attribute name="workingdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The physical path to the working directory for the VM.]]></short-description>
+        <description><![CDATA[
+          The physical path to the working directory for the VM.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[The classnames to execute.]]></short-description>
+        <description>
+          <![CDATA[the classnames to execute.]]>
+        </description>
+      </element>
+
+      <element name="arg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a command argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a command argument.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to run the files.]]></short-description>
+        <description>
+          <![CDATA[classpath to run the files.]]>
+        </description>
+      </element>
+
+      <element name="filters" type="org.apache.tools.ant.taskdefs.optional.sitraka.Filters"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Defines class/method filters based on pattern matching.]]></short-description>
+        <description>
+          <![CDATA[Defines class/method filters based on pattern matching.
+ The syntax is filters is similar to a fileset.]]>
+        </description>
+      </element>
+
+      <element name="jvmarg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a JVM argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a JVM argument.]]>
+        </description>
+      </element>
+
+      <element name="socket" type="org.apache.tools.ant.taskdefs.optional.sitraka.Socket"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Define a host and port to connect to if you want to do
+ remote viewing.]]></short-description>
+        <description>
+          <![CDATA[Define a host and port to connect to if you want to do
+ remote viewing.]]>
+        </description>
+      </element>
+
+      <element name="triggers" type="org.apache.tools.ant.taskdefs.optional.sitraka.Triggers"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Defines events to use for interacting with the
+ collection of data performed during coverage.]]></short-description>
+        <description>
+          <![CDATA[Defines events to use for interacting with the
+ collection of data performed during coverage.
+
+ For example you may run a whole application but only decide
+ to collect data once it reaches a certain method and once it
+ exits another one.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jpcovmerge" category="metrics"
+      classname="org.apache.tools.ant.taskdefs.optional.sitraka.CovMerge"
+      >
+
+  <short-description><![CDATA[Runs the snapshot merge utility for JProbe Coverage.]]></short-description>
+  <description>
+    <![CDATA[Runs the snapshot merge utility for JProbe Coverage.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="home" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory where JProbe is installed.]]></short-description>
+        <description><![CDATA[
+          The directory where JProbe is installed.
+        ]]></description>
+      </attribute>
+      <attribute name="tofile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Output snapshot file.]]></short-description>
+        <description><![CDATA[
+          Set the output snapshot file.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, perform the merge in verbose mode giving details
+ about the snapshot processing.]]></short-description>
+        <description><![CDATA[
+          If true, perform the merge in verbose mode giving details
+ about the snapshot processing.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a fileset containing the snapshots to include.]]></short-description>
+        <description>
+          <![CDATA[add a fileset containing the snapshots to include.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jpcovreport" category="metrics"
+      classname="org.apache.tools.ant.taskdefs.optional.sitraka.CovReport"
+      >
+
+  <short-description><![CDATA[Runs the JProbe Coverage 3.0 snapshot merge utility.]]></short-description>
+  <description>
+    <![CDATA[Runs the JProbe Coverage 3.0 snapshot merge utility.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="format" type="org.apache.tools.ant.taskdefs.optional.sitraka.CovReport.ReportFormat"
+                 briefType="&quot;html&quot;, &quot;text&quot;, &quot;xml&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Format of the report: "html", "text", or "xml".]]></short-description>
+        <description><![CDATA[
+          set the format of the report: "html", "text", or "xml"
+        ]]></description>
+      </attribute>
+      <attribute name="home" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory where JProbe is installed.]]></short-description>
+        <description><![CDATA[
+          The directory where JProbe is installed.
+        ]]></description>
+      </attribute>
+      <attribute name="includesource" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, include text of the source code lines.]]></short-description>
+        <description><![CDATA[
+          If true, include text of the source code lines.
+ Only applies to format="xml" and type="verydetailed"
+        ]]></description>
+      </attribute>
+      <attribute name="percent" type="java.lang.Integer"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[A numeric value for the threshold for printing methods.]]></short-description>
+        <description><![CDATA[
+          A numeric value for the threshold for printing methods.
+ Must be between 0 and 100.
+        ]]></description>
+      </attribute>
+      <attribute name="snapshot" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the snapshot file that is the source to the report.]]></short-description>
+        <description><![CDATA[
+          The name of the snapshot file that is the source to the report.
+        ]]></description>
+      </attribute>
+      <attribute name="tofile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the generated output file.]]></short-description>
+        <description><![CDATA[
+          The name of the generated output file.
+        ]]></description>
+      </attribute>
+      <attribute name="type" type="org.apache.tools.ant.taskdefs.optional.sitraka.CovReport.ReportType"
+                 briefType="&quot;executive&quot;, &quot;summary&quot;, &quot;detailed&quot;, &quot;verydetailed&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[The type of report to be generated: "executive", "summary",
+ "detailed" or "verydetailed".]]></short-description>
+        <description><![CDATA[
+          The type of report to be generated: "executive", "summary",
+ "detailed" or "verydetailed".
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="reference" type="org.apache.tools.ant.taskdefs.optional.sitraka.CovReport.Reference"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of classes whose coverage information will be
+ checked against.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of classes whose coverage information will be
+ checked against.]]>
+        </description>
+      </element>
+
+      <element name="sourcepath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to source files.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to source files.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="jspc" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.jsp.JspC"
+      matchingTask="true">
+
+  <short-description><![CDATA[Runs a JSP compiler.]]></short-description>
+  <description>
+    <![CDATA[Runs a JSP compiler.
+
+ <p> This task takes the given jsp files and compiles them into java
+ files. It is then up to the user to compile the java files into classes.
+
+ <p> The task requires the srcdir and destdir attributes to be
+ set. This Task is a MatchingTask, so the files to be compiled can be
+ specified using includes/excludes attributes or nested include/exclude
+ elements. Optional attributes are verbose (set the verbosity level passed
+ to jasper), package (name of the destination package for generated java
+ classes and classpath (the classpath to use when running the jsp
+ compiler).
+ <p> This task supports the nested elements classpath (A Path) and
+ classpathref (A Reference) which can be used in preference to the
+ attribute classpath, if the jsp compiler is not already in the ant
+ classpath.
+
+ <p><h4>Usage</h4>
+ <pre>
+ &lt;jspc srcdir="${basedir}/src/war"
+       destdir="${basedir}/gensrc"
+       package="com.i3sp.jsp"
+       verbose="9"&gt;
+   &lt;include name="**\/*.jsp" /&gt;
+ &lt;/jspc&gt;
+ </pre>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for this compilation.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used for this compilation.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a classpath defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a classpath defined elsewhere
+        ]]></description>
+      </attribute>
+      <attribute name="compiler" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Class name of a JSP compiler adapter.]]></short-description>
+        <description><![CDATA[
+          Class name of a JSP compiler adapter.
+        ]]></description>
+      </attribute>
+      <attribute name="compilerclasspath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used to find this compiler adapter.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used to find this compiler adapter
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory into which the JSP source
+ files should be compiled.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory into which the JSP source
+ files should be compiled.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether or not the build should halt if compilation fails.]]></short-description>
+        <description><![CDATA[
+          Whether or not the build should halt if compilation fails.
+ Defaults to <code>true</code>.
+        ]]></description>
+      </attribute>
+      <attribute name="ieplugin" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Java Plugin CLASSID for Internet Explorer.]]></short-description>
+        <description><![CDATA[
+          Java Plugin CLASSID for Internet Explorer
+        ]]></description>
+      </attribute>
+      <attribute name="mapped" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, generate separate write() calls for each HTML line
+ in the JSP.]]></short-description>
+        <description><![CDATA[
+          If true, generate separate write() calls for each HTML line
+ in the JSP.
+        ]]></description>
+      </attribute>
+      <attribute name="package" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the package the compiled jsp files should be in.]]></short-description>
+        <description><![CDATA[
+          Set the name of the package the compiled jsp files should be in.
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Path for source JSP files.]]></short-description>
+        <description><![CDATA[
+          Path for source JSP files.
+        ]]></description>
+      </attribute>
+      <attribute name="uribase" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The URI context of relative URI references in the JSP pages.]]></short-description>
+        <description><![CDATA[
+          The URI context of relative URI references in the JSP pages.
+ If it does not exist then it is derived from the location
+ of the file relative to the declared or derived value of uriroot.
+        ]]></description>
+      </attribute>
+      <attribute name="uriroot" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The root directory that uri files should be resolved
+  against.]]></short-description>
+        <description><![CDATA[
+          The root directory that uri files should be resolved
+  against. (Default is the directory jspc is invoked from)
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Verbose level of the compiler.]]></short-description>
+        <description><![CDATA[
+          Set the verbose level of the compiler
+        ]]></description>
+      </attribute>
+      <attribute name="webinc" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Output filename for the fraction of web.xml that lists
+  servlets.]]></short-description>
+        <description><![CDATA[
+          output filename for the fraction of web.xml that lists
+  servlets.
+        ]]></description>
+      </attribute>
+      <attribute name="webxml" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Filename for web.xml.]]></short-description>
+        <description><![CDATA[
+          Filename for web.xml.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="webapp" type="org.apache.tools.ant.taskdefs.optional.jsp.JspC.WebAppParameter"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a single webapp.]]></short-description>
+        <description>
+          <![CDATA[Adds a single webapp.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to the classpath.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to the classpath.]]>
+        </description>
+      </element>
+
+      <element name="compilerclasspath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Support nested compiler classpath, used to locate compiler adapter.]]></short-description>
+        <description>
+          <![CDATA[Support nested compiler classpath, used to locate compiler adapter]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="junit" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask"
+      >
+
+  <short-description><![CDATA[Runs JUnit tests.]]></short-description>
+  <description>
+    <![CDATA[Runs JUnit tests.
+
+ <p> JUnit is a framework to create unit test. It has been initially
+ created by Erich Gamma and Kent Beck.  JUnit can be found at <a
+ href="http://www.junit.org">http://www.junit.org</a>.
+
+ <p> <code>JUnitTask</code> can run a single specific
+ <code>JUnitTest</code> using the <code>test</code> element.</p>
+ For example, the following target <code><pre>
+   &lt;target name="test-int-chars" depends="jar-test"&gt;
+       &lt;echo message="testing international characters"/&gt;
+       &lt;junit printsummary="no" haltonfailure="yes" fork="false"&gt;
+           &lt;classpath refid="classpath"/&gt;
+           &lt;formatter type="plain" usefile="false" /&gt;
+           &lt;test name="org.apache.ecs.InternationalCharTest" /&gt;
+       &lt;/junit&gt;
+   &lt;/target&gt;
+ </pre></code>
+ <p>runs a single junit test
+ (<code>org.apache.ecs.InternationalCharTest</code>) in the current
+ VM using the path with id <code>classpath</code> as classpath and
+ presents the results formatted using the standard
+ <code>plain</code> formatter on the command line.</p>
+
+ <p> This task can also run batches of tests.  The
+ <code>batchtest</code> element creates a <code>BatchTest</code>
+ based on a fileset.  This allows, for example, all classes found in
+ directory to be run as testcases.</p>
+
+ <p>For example,</p><code><pre>
+ &lt;target name="run-tests" depends="dump-info,compile-tests" if="junit.present"&gt;
+   &lt;junit printsummary="no" haltonfailure="yes" fork="${junit.fork}"&gt;
+     &lt;jvmarg value="-classic"/&gt;
+     &lt;classpath refid="tests-classpath"/&gt;
+     &lt;sysproperty key="build.tests" value="${build.tests}"/&gt;
+     &lt;formatter type="brief" usefile="false" /&gt;
+     &lt;batchtest&gt;
+       &lt;fileset dir="${tests.dir}"&gt;
+         &lt;include name="**&#047;*Test*" /&gt;
+       &lt;/fileset&gt;
+     &lt;/batchtest&gt;
+   &lt;/junit&gt;
+ &lt;/target&gt;
+ </pre></code>
+ <p>this target finds any classes with a <code>test</code> directory
+ anywhere in their path (under the top <code>${tests.dir}</code>, of
+ course) and creates <code>JUnitTest</code>'s for each one.</p>
+
+ <p> Of course, <code>&lt;junit&gt;</code> and
+ <code>&lt;batch&gt;</code> elements can be combined for more
+ complex tests. For an example, see the ant <code>build.xml</code>
+ target <code>run-tests</code> (the second example is an edited
+ version).</p>
+
+ <p> To spawn a new Java VM to prevent interferences between
+ different testcases, you need to enable <code>fork</code>.  A
+ number of attributes and elements allow you to set up how this JVM
+ runs.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory to invoke the VM in.]]></short-description>
+        <description><![CDATA[
+          The directory to invoke the VM in. Ignored if no JVM is forked.
+        ]]></description>
+      </attribute>
+      <attribute name="errorproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Property to set to "true" if there is a error in a test.]]></short-description>
+        <description><![CDATA[
+          Property to set to "true" if there is a error in a test.
+
+ <p>This property is applied on all BatchTest (batchtest) and
+ JUnitTest (test), however, it can possibly be overriden by
+ their own properties.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="failureproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Property to set to "true" if there is a failure in a test.]]></short-description>
+        <description><![CDATA[
+          Property to set to "true" if there is a failure in a test.
+
+ <p>This property is applied on all BatchTest (batchtest) and
+ JUnitTest (test), however, it can possibly be overriden by
+ their own properties.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="filtertrace" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, smartly filter the stack frames of
+ JUnit errors and failures before reporting them.]]></short-description>
+        <description><![CDATA[
+          If true, smartly filter the stack frames of
+ JUnit errors and failures before reporting them.
+
+ <p>This property is applied on all BatchTest (batchtest) and
+ JUnitTest (test) however it can possibly be overridden by their
+ own properties.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="fork" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, JVM should be forked for each test.]]></short-description>
+        <description><![CDATA[
+          If true, JVM should be forked for each test.
+
+ <p>It avoids interference between testcases and possibly avoids
+ hanging the build.  this property is applied on all BatchTest
+ (batchtest) and JUnitTest (test) however it can possibly be
+ overridden by their own properties.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="haltonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, stop the build process when there is an error in a test.]]></short-description>
+        <description><![CDATA[
+          If true, stop the build process when there is an error in a test.
+ This property is applied on all BatchTest (batchtest) and JUnitTest
+ (test) however it can possibly be overridden by their own
+ properties.
+        ]]></description>
+      </attribute>
+      <attribute name="haltonfailure" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, stop the build process if a test fails
+ (errors are considered failures as well).]]></short-description>
+        <description><![CDATA[
+          If true, stop the build process if a test fails
+ (errors are considered failures as well).
+ This property is applied on all BatchTest (batchtest) and
+ JUnitTest (test) however it can possibly be overridden by their
+ own properties.
+        ]]></description>
+      </attribute>
+      <attribute name="includeantruntime" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, include ant.jar, optional.jar and junit.jar in the forked VM.]]></short-description>
+        <description><![CDATA[
+          If true, include ant.jar, optional.jar and junit.jar in the forked VM.
+        ]]></description>
+      </attribute>
+      <attribute name="jvm" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The command used to invoke the Java Virtual Machine,
+ default is 'java'.]]></short-description>
+        <description><![CDATA[
+          The command used to invoke the Java Virtual Machine,
+ default is 'java'. The command is resolved by
+ java.lang.Runtime.exec(). Ignored if fork is disabled.
+        ]]></description>
+      </attribute>
+      <attribute name="maxmemory" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Maximum memory to be used by all forked JVMs.]]></short-description>
+        <description><![CDATA[
+          Set the maximum memory to be used by all forked JVMs.
+        ]]></description>
+      </attribute>
+      <attribute name="newenvironment" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, use a new environment when forked.]]></short-description>
+        <description><![CDATA[
+          If true, use a new environment when forked.
+
+ <p>Will be ignored if we are not forking a new VM.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="printsummary" type="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.SummaryAttribute"
+                 briefType="&quot;true&quot;, &quot;yes&quot;, &quot;false&quot;, &quot;no&quot;, &quot;on&quot;, &quot;off&quot;, &quot;withOutAndErr&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[If true, print one-line statistics for each test, or "withOutAndErr"
+ to also show standard output and error.]]></short-description>
+        <description><![CDATA[
+          If true, print one-line statistics for each test, or "withOutAndErr"
+ to also show standard output and error.
+
+ Can take the values on, off, and withOutAndErr.
+        ]]></description>
+      </attribute>
+      <attribute name="showoutput" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, send any output generated by tests to Ant's logging system
+ as well as to the formatters.]]></short-description>
+        <description><![CDATA[
+          If true, send any output generated by tests to Ant's logging system
+ as well as to the formatters.
+ By default only the formatters receive the output.
+
+ <p>Output will always be passed to the formatters and not by
+ shown by default.  This option should for example be set for
+ tests that are interactive and prompt the user to do
+ something.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="timeout" type="java.lang.Integer"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Timeout value (in milliseconds).]]></short-description>
+        <description><![CDATA[
+          Set the timeout value (in milliseconds).
+
+ <p>If the test is running for more than this value, the test
+ will be canceled. (works only when in 'fork' mode).</p>
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="env" type="org.apache.tools.ant.types.Environment.Variable"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds an environment variable; used when forking.]]></short-description>
+        <description>
+          <![CDATA[Adds an environment variable; used when forking.
+
+ <p>Will be ignored if we are not forking a new VM.</p>]]>
+        </description>
+      </element>
+
+      <element name="formatter" type="org.apache.tools.ant.taskdefs.optional.junit.FormatterElement"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a new formatter to all tests of this task.]]></short-description>
+        <description>
+          <![CDATA[Add a new formatter to all tests of this task.]]>
+        </description>
+      </element>
+
+      <element name="sysproperty" type="org.apache.tools.ant.types.Environment.Variable"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a system property that tests can access.]]></short-description>
+        <description>
+          <![CDATA[Adds a system property that tests can access.
+ This might be useful to tranfer Ant properties to the
+ testcases when JVM forking is not enabled.]]>
+        </description>
+      </element>
+
+      <element name="test" type="org.apache.tools.ant.taskdefs.optional.junit.JUnitTest"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a new single testcase.]]></short-description>
+        <description>
+          <![CDATA[Add a new single testcase.]]>
+        </description>
+      </element>
+
+      <element name="batchtest" type="org.apache.tools.ant.taskdefs.optional.junit.BatchTest"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of tests based on pattern matching.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of tests based on pattern matching.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds path to classpath used for tests.]]></short-description>
+        <description>
+          <![CDATA[Adds path to classpath used for tests.]]>
+        </description>
+      </element>
+
+      <element name="jvmarg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a JVM argument; ignored if not forking.]]></short-description>
+        <description>
+          <![CDATA[Adds a JVM argument; ignored if not forking.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="junitreport" category="testing"
+      classname="org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator"
+      >
+
+  <short-description><![CDATA[Aggregates all &lt;junit&gt; XML formatter testsuite data under a specific directory and transforms the results via XSLT.]]></short-description>
+  <description>
+    <![CDATA[Aggregates all &lt;junit&gt; XML formatter testsuite data under
+ a specific directory and transforms the results via XSLT.
+ It is not particulary clean but
+ should be helpful while I am thinking about another technique.
+
+ <p> The main problem is due to the fact that a JVM can be forked for a testcase
+ thus making it impossible to aggregate all testcases since the listener is
+ (obviously) in the forked JVM. A solution could be to write a
+ TestListener that will receive events from the TestRunner via sockets. This
+ is IMHO the simplest way to do it to avoid this file hacking thing.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="todir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory where the results should be written.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory where the results should be written. If not
+ set if will use {@link #DEFAULT_DIR}. When given a relative directory
+ it will resolve it from the project directory.
+        ]]></description>
+      </attribute>
+      <attribute name="tofile" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the aggregegated results file.]]></short-description>
+        <description><![CDATA[
+          Set the name of the aggregegated results file. It must be relative
+ from the <tt>todir</tt> attribute. If not set it will use {@link #DEFAULT_FILENAME}
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a new fileset containing the XML results to aggregate.]]></short-description>
+        <description>
+          <![CDATA[Add a new fileset containing the XML results to aggregate]]>
+        </description>
+      </element>
+
+      <element name="report" type="org.apache.tools.ant.taskdefs.optional.junit.AggregateTransformer"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Generate a report based on the document created by the merge.]]></short-description>
+        <description>
+          <![CDATA[Generate a report based on the document created by the merge.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="keysubst" category="other"
+      classname="org.apache.tools.ant.taskdefs.KeySubst"
+      deprecated="true"
+      >
+
+  <short-description><![CDATA[Keyword substitution.]]></short-description>
+  <description>
+    <![CDATA[Keyword substitution. Input file is written to output file.
+ Do not make input file same as output file.
+ Keywords in input files look like this: @foo@. See the docs for the 
+ setKeys method to understand how to do the substitutions.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination file.]]></short-description>
+        <description><![CDATA[
+          Set the destination file.
+        ]]></description>
+      </attribute>
+      <attribute name="keys" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Keys.]]></short-description>
+        <description><![CDATA[
+          Sets the keys.
+Format string is like this:
+<p>
+name=value*name2=value
+<p>
+Names are case sensitive.
+<p>
+Use the setSep() method to change the * to something else
+if you need to use * as a name or value.
+        ]]></description>
+      </attribute>
+      <attribute name="sep" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Seperator between name=value arguments
+in setKeys().]]></short-description>
+        <description><![CDATA[
+          Sets the seperator between name=value arguments
+in setKeys(). By default it is "*".
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source file.]]></short-description>
+        <description><![CDATA[
+          Set the source file.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="loadfile" category="utility"
+      classname="org.apache.tools.ant.taskdefs.LoadFile"
+      >
+
+  <short-description><![CDATA[Load a file into a property]]></short-description>
+  <description>
+    <![CDATA[Load a file into a property]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Encoding to use for input, defaults to the platform's default
+ encoding.]]></short-description>
+        <description><![CDATA[
+          Encoding to use for input, defaults to the platform's default
+ encoding. <p>
+
+ For a list of possible values see <a href="http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html">
+ http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html
+ </a>.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, fail on load error.]]></short-description>
+        <description><![CDATA[
+          If true, fail on load error.
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Property name to save to.]]></short-description>
+        <description><![CDATA[
+          Property name to save to.
+        ]]></description>
+      </attribute>
+      <attribute name="srcfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File to load.]]></short-description>
+        <description><![CDATA[
+          Sets the file to load.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="filterchain" type="org.apache.tools.ant.types.FilterChain"
+               briefType="FilterChain"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add the FilterChain element.]]></short-description>
+        <description>
+          <![CDATA[Add the FilterChain element.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="loadproperties" category="utility"
+      classname="org.apache.tools.ant.taskdefs.LoadProperties"
+      >
+
+  <short-description><![CDATA[Load a file's contents as Ant properties.]]></short-description>
+  <description>
+    <![CDATA[Load a file's contents as Ant properties.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="srcfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File to load.]]></short-description>
+        <description><![CDATA[
+          Sets the file to load.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="filterchain" type="org.apache.tools.ant.types.FilterChain"
+               briefType="FilterChain"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a FilterChain.]]></short-description>
+        <description>
+          <![CDATA[Adds a FilterChain.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="mail" category="network"
+      classname="org.apache.tools.ant.taskdefs.email.EmailTask"
+      >
+
+  <short-description><![CDATA[A task to send SMTP email.]]></short-description>
+  <description>
+    <![CDATA[A task to send SMTP email. This is a refactoring of the SendMail and
+ MimeMail tasks such that both are within a single task.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="bcclist" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Adds "bcc" address elements.]]></short-description>
+        <description><![CDATA[
+          Adds "bcc" address elements
+        ]]></description>
+      </attribute>
+      <attribute name="cclist" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Adds "cc" address elements.]]></short-description>
+        <description><![CDATA[
+          Adds "cc" address elements
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="org.apache.tools.ant.taskdefs.email.EmailTask.Encoding"
+                 briefType="&quot;auto&quot;, &quot;mime&quot;, &quot;uu&quot;, &quot;plain&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Allows the build writer to choose the preferred encoding method.]]></short-description>
+        <description><![CDATA[
+          Allows the build writer to choose the preferred encoding method
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates whether BuildExceptions should be passed back to the core.]]></short-description>
+        <description><![CDATA[
+          Indicates whether BuildExceptions should be passed back to the core
+        ]]></description>
+      </attribute>
+      <attribute name="files" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a list of files to be attached.]]></short-description>
+        <description><![CDATA[
+          Adds a list of files to be attached
+        ]]></description>
+      </attribute>
+      <attribute name="from" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Shorthand to set the from address element.]]></short-description>
+        <description><![CDATA[
+          Shorthand to set the from address element
+        ]]></description>
+      </attribute>
+      <attribute name="includefilenames" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets Includefilenames attribute.]]></short-description>
+        <description><![CDATA[
+          Sets Includefilenames attribute
+        ]]></description>
+      </attribute>
+      <attribute name="mailhost" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Host.]]></short-description>
+        <description><![CDATA[
+          Sets the host
+        ]]></description>
+      </attribute>
+      <attribute name="mailport" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Mail server port.]]></short-description>
+        <description><![CDATA[
+          Sets the mail server port
+        ]]></description>
+      </attribute>
+      <attribute name="message" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Shorthand method to set the message.]]></short-description>
+        <description><![CDATA[
+          Shorthand method to set the message
+        ]]></description>
+      </attribute>
+      <attribute name="messagefile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Shorthand method to set the message from a file.]]></short-description>
+        <description><![CDATA[
+          Shorthand method to set the message from a file
+        ]]></description>
+      </attribute>
+      <attribute name="messagemimetype" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Shorthand method to set type of the text message, text/plain by default
+ but text/html or text/xml is quite feasible.]]></short-description>
+        <description><![CDATA[
+          Shorthand method to set type of the text message, text/plain by default
+ but text/html or text/xml is quite feasible.
+        ]]></description>
+      </attribute>
+      <attribute name="subject" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Subject line of the email.]]></short-description>
+        <description><![CDATA[
+          Sets the subject line of the email
+        ]]></description>
+      </attribute>
+      <attribute name="tolist" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Adds "to" address elements.]]></short-description>
+        <description><![CDATA[
+          Adds "to" address elements
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="bcc" type="org.apache.tools.ant.taskdefs.email.EmailAddress"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds "bcc" address elements.]]></short-description>
+        <description>
+          <![CDATA[Adds "bcc" address elements]]>
+        </description>
+      </element>
+
+      <element name="cc" type="org.apache.tools.ant.taskdefs.email.EmailAddress"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds "cc" address element.]]></short-description>
+        <description>
+          <![CDATA[Adds "cc" address element]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files (nested fileset attribute).]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files (nested fileset attribute).]]>
+        </description>
+      </element>
+
+      <element name="from" type="org.apache.tools.ant.taskdefs.email.EmailAddress"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a from address element.]]></short-description>
+        <description>
+          <![CDATA[Adds a from address element]]>
+        </description>
+      </element>
+
+      <element name="message" type="org.apache.tools.ant.taskdefs.email.Message"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a message elemnt.]]></short-description>
+        <description>
+          <![CDATA[Add a message elemnt]]>
+        </description>
+      </element>
+
+      <element name="to" type="org.apache.tools.ant.taskdefs.email.EmailAddress"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a to address element.]]></short-description>
+        <description>
+          <![CDATA[Adds a to address element]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="manifest" category="java"
+      classname="org.apache.tools.ant.taskdefs.ManifestTask"
+      >
+
+  <short-description><![CDATA[Creates a manifest file for inclusion in a JAR, Ant task wrapper around]]></short-description>
+  <description>
+    <![CDATA[Creates a manifest file for inclusion in a JAR, Ant task wrapper
+ around {@link Manifest Manifest}.  This task can be used to write a
+ Manifest file, optionally replacing or updating an existing file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the manifest file to create/update.]]></short-description>
+        <description><![CDATA[
+          The name of the manifest file to create/update.
+ Required if used as a task.
+        ]]></description>
+      </attribute>
+      <attribute name="mode" type="org.apache.tools.ant.taskdefs.ManifestTask.Mode"
+                 briefType="&quot;update&quot;, &quot;replace&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Update policy: either "update" or "replace"; default is "replace".]]></short-description>
+        <description><![CDATA[
+          Update policy: either "update" or "replace"; default is "replace".
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="attribute" type="org.apache.tools.ant.taskdefs.Manifest.Attribute"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an attribute to the manifest - it is added to the main section.]]></short-description>
+        <description>
+          <![CDATA[Add an attribute to the manifest - it is added to the main section.]]>
+        </description>
+      </element>
+
+      <element name="section" type="org.apache.tools.ant.taskdefs.Manifest.Section"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a section to the manifest.]]></short-description>
+        <description>
+          <![CDATA[Add a section to the manifest]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="maudit" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.metamata.MAudit"
+      >
+
+  <short-description><![CDATA[Invokes the Metamata Audit/ Webgain Quality Analyzer on a set of Java files.]]></short-description>
+  <description>
+    <![CDATA[Invokes the Metamata Audit/ Webgain Quality Analyzer on a set of Java files.
+ <p>
+ <i>maudit</i> performs static analysis of the Java source code and byte code files to find and report
+ errors of style and potential problems related to performance, maintenance and robustness.
+  As a convenience, a stylesheet is given in <tt>etc</tt> directory, so that an HTML report 
+ can be generated from the XML file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="fix" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Automatically fix certain errors 
+ (those marked as fixable in the manual);
+ optional, default=false.]]></short-description>
+        <description><![CDATA[
+          Automatically fix certain errors 
+ (those marked as fixable in the manual);
+ optional, default=false
+        ]]></description>
+      </attribute>
+      <attribute name="list" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Creates listing file for each audited file; optional, default false.]]></short-description>
+        <description><![CDATA[
+          Creates listing file for each audited file; optional, default false. 
+ When set, a .maudit file will be generated in the
+ same location as the source file.
+        ]]></description>
+      </attribute>
+      <attribute name="maxmemory" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Maximum memory for the JVM; optional.]]></short-description>
+        <description><![CDATA[
+          Set the maximum memory for the JVM; optional.
+ -mx or -Xmx depending on VM version
+        ]]></description>
+      </attribute>
+      <attribute name="metamatahome" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The home directory containing the Metamata distribution; required.]]></short-description>
+        <description><![CDATA[
+          The home directory containing the Metamata distribution; required
+        ]]></description>
+      </attribute>
+      <attribute name="tofile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The XML file to which the Audit result should be written to; required.]]></short-description>
+        <description><![CDATA[
+          The XML file to which the Audit result should be written to; required
+        ]]></description>
+      </attribute>
+      <attribute name="unused" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Finds declarations unused in search paths; optional, default false.]]></short-description>
+        <description><![CDATA[
+          Finds declarations unused in search paths; optional, default false. 
+ It will look for unused global declarations
+ in the source code within a use domain specified by the 
+ <tt>searchpath</tt> element.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[The java files or directory to audit.]]></short-description>
+        <description>
+          <![CDATA[The java files or directory to audit.
+ Whatever the filter is, only the files that end 
+ with .java will be included for processing. 
+ Note that the base directory used for the fileset 
+ MUST be the root of the source files otherwise package names
+ deduced from the file path will be incorrect.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Class path (also source path unless one explicitly set).]]></short-description>
+        <description>
+          <![CDATA[Sets the class path (also source path unless one explicitly set).
+ Overrides METAPATH/CLASSPATH environment variables.]]>
+        </description>
+      </element>
+
+      <element name="jvmarg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Additional optional parameters to pass to the JVM.]]></short-description>
+        <description>
+          <![CDATA[Additional optional parameters to pass to the JVM. 
+ You can avoid using the  <code>&lt;jvmarg&gt;</code> by adding these empty 
+ entries to <code>metamata.properties</code> located at <code>${metamata.home}/bin</code>
+
+ <pre>metamata.classpath=
+ metamata.sourcepath=
+ metamata.baseclasspath=
+ </pre>]]>
+        </description>
+      </element>
+
+      <element name="rulespath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Classpath for additional audit rules
+ these must be placed before metamata.jar !!.]]></short-description>
+        <description>
+          <![CDATA[classpath for additional audit rules
+ these must be placed before metamata.jar !!]]>
+        </description>
+      </element>
+
+      <element name="searchpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Search path to use for unused global declarations; 
+ required when <tt>unused</tt> is set.]]></short-description>
+        <description>
+          <![CDATA[search path to use for unused global declarations; 
+ required when <tt>unused</tt> is set.]]>
+        </description>
+      </element>
+
+      <element name="sourcepath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Source path.]]></short-description>
+        <description>
+          <![CDATA[Sets the source path. 
+ Overrides the SOURCEPATH environment variable.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="mimemail" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.net.MimeMail"
+      deprecated="true"
+      >
+
+  <short-description><![CDATA[A task to send SMTP email; Use <tt>mail</tt> instead]]></short-description>
+  <description>
+    <![CDATA[A task to send SMTP email; Use <tt>mail</tt> instead]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="bcclist" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Adds "bcc" address elements.]]></short-description>
+        <description><![CDATA[
+          Adds "bcc" address elements
+        ]]></description>
+      </attribute>
+      <attribute name="cclist" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Adds "cc" address elements.]]></short-description>
+        <description><![CDATA[
+          Adds "cc" address elements
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="org.apache.tools.ant.taskdefs.email.EmailTask.Encoding"
+                 briefType="&quot;auto&quot;, &quot;mime&quot;, &quot;uu&quot;, &quot;plain&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Allows the build writer to choose the preferred encoding method.]]></short-description>
+        <description><![CDATA[
+          Allows the build writer to choose the preferred encoding method
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates whether BuildExceptions should be passed back to the core.]]></short-description>
+        <description><![CDATA[
+          Indicates whether BuildExceptions should be passed back to the core
+        ]]></description>
+      </attribute>
+      <attribute name="files" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a list of files to be attached.]]></short-description>
+        <description><![CDATA[
+          Adds a list of files to be attached
+        ]]></description>
+      </attribute>
+      <attribute name="from" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Shorthand to set the from address element.]]></short-description>
+        <description><![CDATA[
+          Shorthand to set the from address element
+        ]]></description>
+      </attribute>
+      <attribute name="includefilenames" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets Includefilenames attribute.]]></short-description>
+        <description><![CDATA[
+          Sets Includefilenames attribute
+        ]]></description>
+      </attribute>
+      <attribute name="mailhost" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Host.]]></short-description>
+        <description><![CDATA[
+          Sets the host
+        ]]></description>
+      </attribute>
+      <attribute name="mailport" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Mail server port.]]></short-description>
+        <description><![CDATA[
+          Sets the mail server port
+        ]]></description>
+      </attribute>
+      <attribute name="message" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Shorthand method to set the message.]]></short-description>
+        <description><![CDATA[
+          Shorthand method to set the message
+        ]]></description>
+      </attribute>
+      <attribute name="messagefile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Shorthand method to set the message from a file.]]></short-description>
+        <description><![CDATA[
+          Shorthand method to set the message from a file
+        ]]></description>
+      </attribute>
+      <attribute name="messagemimetype" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Shorthand method to set type of the text message, text/plain by default
+ but text/html or text/xml is quite feasible.]]></short-description>
+        <description><![CDATA[
+          Shorthand method to set type of the text message, text/plain by default
+ but text/html or text/xml is quite feasible.
+        ]]></description>
+      </attribute>
+      <attribute name="subject" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Subject line of the email.]]></short-description>
+        <description><![CDATA[
+          Sets the subject line of the email
+        ]]></description>
+      </attribute>
+      <attribute name="tolist" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Adds "to" address elements.]]></short-description>
+        <description><![CDATA[
+          Adds "to" address elements
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="bcc" type="org.apache.tools.ant.taskdefs.email.EmailAddress"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds "bcc" address elements.]]></short-description>
+        <description>
+          <![CDATA[Adds "bcc" address elements]]>
+        </description>
+      </element>
+
+      <element name="cc" type="org.apache.tools.ant.taskdefs.email.EmailAddress"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds "cc" address element.]]></short-description>
+        <description>
+          <![CDATA[Adds "cc" address element]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files (nested fileset attribute).]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files (nested fileset attribute).]]>
+        </description>
+      </element>
+
+      <element name="from" type="org.apache.tools.ant.taskdefs.email.EmailAddress"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a from address element.]]></short-description>
+        <description>
+          <![CDATA[Adds a from address element]]>
+        </description>
+      </element>
+
+      <element name="message" type="org.apache.tools.ant.taskdefs.email.Message"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a message elemnt.]]></short-description>
+        <description>
+          <![CDATA[Add a message elemnt]]>
+        </description>
+      </element>
+
+      <element name="to" type="org.apache.tools.ant.taskdefs.email.EmailAddress"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a to address element.]]></short-description>
+        <description>
+          <![CDATA[Adds a to address element]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="mkdir" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.Mkdir"
+      >
+
+  <short-description><![CDATA[Creates a given directory.]]></short-description>
+  <description>
+    <![CDATA[Creates a given directory.
+ Creates a directory and any non-existent parent directories, when
+ necessary]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory to create; required.]]></short-description>
+        <description><![CDATA[
+          the directory to create; required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="mmetrics" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.metamata.MMetrics"
+      >
+
+  <short-description><![CDATA[Computes the metrics of a set of Java files and write the results to an XML file.]]></short-description>
+  <description>
+    <![CDATA[Computes the metrics of a set of Java files and write the results to an XML
+ file. As a convenience, a stylesheet is given in <tt>etc</tt> directory,
+ so that an HTML report can be generated from the XML file.
+ <p>
+ You will not be able to use this task with the evaluation version since
+ as of Metamata 2.0, Metrics does not support command line :-(]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="granularity" type="org.apache.tools.ant.taskdefs.optional.metamata.MMetrics.GranularityAttribute"
+                 briefType="&quot;compilation-units&quot;, &quot;files&quot;, &quot;methods&quot;, &quot;types&quot;, &quot;packages&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Granularity of the audit.]]></short-description>
+        <description><![CDATA[
+          set the granularity of the audit. Should be one of 'files', 'methods'
+ or 'types'.
+        ]]></description>
+      </attribute>
+      <attribute name="maxmemory" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Maximum memory for the JVM; optional.]]></short-description>
+        <description><![CDATA[
+          Set the maximum memory for the JVM; optional.
+ -mx or -Xmx depending on VM version
+        ]]></description>
+      </attribute>
+      <attribute name="metamatahome" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The home directory containing the Metamata distribution; required.]]></short-description>
+        <description><![CDATA[
+          The home directory containing the Metamata distribution; required
+        ]]></description>
+      </attribute>
+      <attribute name="tofile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Output XML file.]]></short-description>
+        <description><![CDATA[
+          Set the output XML file
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[The java files or directory to audit.]]></short-description>
+        <description>
+          <![CDATA[The java files or directory to audit.
+ Whatever the filter is, only the files that end 
+ with .java will be included for processing. 
+ Note that the base directory used for the fileset 
+ MUST be the root of the source files otherwise package names
+ deduced from the file path will be incorrect.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Class path (also source path unless one explicitly set).]]></short-description>
+        <description>
+          <![CDATA[Sets the class path (also source path unless one explicitly set).
+ Overrides METAPATH/CLASSPATH environment variables.]]>
+        </description>
+      </element>
+
+      <element name="jvmarg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Additional optional parameters to pass to the JVM.]]></short-description>
+        <description>
+          <![CDATA[Additional optional parameters to pass to the JVM. 
+ You can avoid using the  <code>&lt;jvmarg&gt;</code> by adding these empty 
+ entries to <code>metamata.properties</code> located at <code>${metamata.home}/bin</code>
+
+ <pre>metamata.classpath=
+ metamata.sourcepath=
+ metamata.baseclasspath=
+ </pre>]]>
+        </description>
+      </element>
+
+      <element name="path" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[New path (directory) to measure metrics from.]]></short-description>
+        <description>
+          <![CDATA[Set a new path (directory) to measure metrics from.]]>
+        </description>
+      </element>
+
+      <element name="sourcepath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Source path.]]></short-description>
+        <description>
+          <![CDATA[Sets the source path. 
+ Overrides the SOURCEPATH environment variable.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="move" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.Move"
+      >
+
+  <short-description><![CDATA[Moves a file or directory to a new file or directory.]]></short-description>
+  <description>
+    <![CDATA[Moves a file or directory to a new file or directory.
+ By default, the
+ destination file is overwritten if it already exists.
+ When <i>overwrite</i> is
+ turned off, then files are only moved if the source file is
+ newer than the destination file, or when the destination file does
+ not exist.
+
+ <p>Source files and directories are only deleted when the file or
+ directory has been copied to the destination successfully.  Filtering
+ also works.</p>
+
+ <p>This implementation is based on Arnout Kuiper's initial design
+ document, the following mailing list discussions, and the
+ copyfile/copydir tasks.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Character encoding.]]></short-description>
+        <description><![CDATA[
+          Sets the character encoding
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If false, note errors to the output but keep going.]]></short-description>
+        <description><![CDATA[
+          If false, note errors to the output but keep going.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Single source file to copy.]]></short-description>
+        <description><![CDATA[
+          Sets a single source file to copy.
+        ]]></description>
+      </attribute>
+      <attribute name="filtering" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, enables filtering.]]></short-description>
+        <description><![CDATA[
+          If true, enables filtering.
+        ]]></description>
+      </attribute>
+      <attribute name="flatten" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[When copying directory trees, the files can be "flattened"
+ into a single directory.]]></short-description>
+        <description><![CDATA[
+          When copying directory trees, the files can be "flattened"
+ into a single directory.  If there are multiple files with
+ the same name in the source directory tree, only the first
+ file will be copied into the "flattened" directory, unless
+ the forceoverwrite attribute is true.
+        ]]></description>
+      </attribute>
+      <attribute name="includeemptydirs" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Used to copy empty directories.]]></short-description>
+        <description><![CDATA[
+          Used to copy empty directories.
+        ]]></description>
+      </attribute>
+      <attribute name="overwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Overwrite any existing destination file(s).]]></short-description>
+        <description><![CDATA[
+          Overwrite any existing destination file(s).
+        ]]></description>
+      </attribute>
+      <attribute name="preservelastmodified" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Give the copied files the same last modified time as the original files.]]></short-description>
+        <description><![CDATA[
+          Give the copied files the same last modified time as the original files.
+        ]]></description>
+      </attribute>
+      <attribute name="todir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory.]]></short-description>
+        <description><![CDATA[
+          Sets the destination directory.
+        ]]></description>
+      </attribute>
+      <attribute name="tofile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination file.]]></short-description>
+        <description><![CDATA[
+          Sets the destination file.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Used to force listing of all names of copied files.]]></short-description>
+        <description><![CDATA[
+          Used to force listing of all names of copied files.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files to copy.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files to copy.]]>
+        </description>
+      </element>
+
+      <element name="filterchain" type="org.apache.tools.ant.types.FilterChain"
+               briefType="FilterChain"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a FilterChain.]]></short-description>
+        <description>
+          <![CDATA[Adds a FilterChain.]]>
+        </description>
+      </element>
+
+      <element name="filterset" type="org.apache.tools.ant.types.FilterSet"
+               briefType="Filterset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a filterset.]]></short-description>
+        <description>
+          <![CDATA[Adds a filterset.]]>
+        </description>
+      </element>
+
+      <element name="mapper" type="org.apache.tools.ant.types.Mapper"
+               briefType="Mapper"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Defines the mapper to map source to destination files.]]></short-description>
+        <description>
+          <![CDATA[Defines the mapper to map source to destination files.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="mparse" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.metamata.MParse"
+      >
+
+  <short-description><![CDATA[Simple Metamata MParse task.]]></short-description>
+  <description>
+    <![CDATA[Simple Metamata MParse task.
+ Based on the original written by
+ <a href="mailto:thomas.haas@softwired-inc.com">Thomas Haas</a>.
+ This version was written for Metamata 2.0 available at
+ <a href="http://www.metamata.com">http://www.metamata.com</a>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="cleanup" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Remove the intermediate Sun JavaCC file 
+ ; optional, default false.]]></short-description>
+        <description><![CDATA[
+          Remove the intermediate Sun JavaCC file 
+ ; optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="debugparser" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set parser debug mode; optional, default false.]]></short-description>
+        <description><![CDATA[
+          set parser debug mode; optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="debugscanner" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set scanner debug mode; optional, default false.]]></short-description>
+        <description><![CDATA[
+          set scanner debug mode; optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="maxmemory" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Maximum memory for the JVM; optional.]]></short-description>
+        <description><![CDATA[
+          Set the maximum memory for the JVM; optional.
+ -mx or -Xmx depending on VM version
+        ]]></description>
+      </attribute>
+      <attribute name="metamatahome" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The home directory containing the Metamata distribution; required.]]></short-description>
+        <description><![CDATA[
+          The home directory containing the Metamata distribution; required
+        ]]></description>
+      </attribute>
+      <attribute name="target" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The .jj file to process; required.]]></short-description>
+        <description><![CDATA[
+          The .jj file to process; required.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set verbose mode; optional, default false.]]></short-description>
+        <description><![CDATA[
+          set verbose mode; optional, default false
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a classpath entry.]]></short-description>
+        <description>
+          <![CDATA[create a classpath entry]]>
+        </description>
+      </element>
+
+      <element name="jvmarg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Additional optional parameters to pass to the JVM.]]></short-description>
+        <description>
+          <![CDATA[Additional optional parameters to pass to the JVM.]]>
+        </description>
+      </element>
+
+      <element name="sourcepath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Creates a sourcepath entry.]]></short-description>
+        <description>
+          <![CDATA[creates a sourcepath entry]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="native2ascii" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.Native2Ascii"
+      matchingTask="true">
+
+  <short-description><![CDATA[Converts files from native encodings to ASCII.]]></short-description>
+  <description>
+    <![CDATA[Converts files from native encodings to ASCII.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory to place converted files into.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory to place converted files into.
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Encoding to translate to/from.]]></short-description>
+        <description><![CDATA[
+          Set the encoding to translate to/from.
+ If unset, the default encoding for the JVM is used.
+        ]]></description>
+      </attribute>
+      <attribute name="ext" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Extension which converted files should have.]]></short-description>
+        <description><![CDATA[
+          Set the extension which converted files should have.
+ If unset, files will not be renamed.
+        ]]></description>
+      </attribute>
+      <attribute name="reverse" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag the conversion to run in the reverse sense,
+ that is Ascii to Native encoding.]]></short-description>
+        <description><![CDATA[
+          Flag the conversion to run in the reverse sense,
+ that is Ascii to Native encoding.
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source directory in which to find files to convert.]]></short-description>
+        <description><![CDATA[
+          Set the source directory in which to find files to convert.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="mapper" type="org.apache.tools.ant.types.Mapper"
+               briefType="Mapper"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Defines the FileNameMapper to use (nested mapper element).]]></short-description>
+        <description>
+          <![CDATA[Defines the FileNameMapper to use (nested mapper element).]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="netrexxc" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.NetRexxC"
+      matchingTask="true">
+
+  <short-description><![CDATA[Compiles NetRexx source files.]]></short-description>
+  <description>
+    <![CDATA[Compiles NetRexx source files.
+ This task can take the following
+ arguments:
+ <ul>
+ <li>binary</li>
+ <li>classpath</li>
+ <li>comments</li>
+ <li>compile</li>
+ <li>console</li>
+ <li>crossref</li>
+ <li>decimal</li>
+ <li>destdir</li>
+ <li>diag</li>
+ <li>explicit</li>
+ <li>format</li>
+ <li>keep</li>
+ <li>logo</li>
+ <li>replace</li>
+ <li>savelog</li>
+ <li>srcdir</li>
+ <li>sourcedir</li>
+ <li>strictargs</li>
+ <li>strictassign</li>
+ <li>strictcase</li>
+ <li>strictimport</li>
+ <li>symbols</li>
+ <li>time</li>
+ <li>trace</li>
+ <li>utf8</li>
+ <li>verbose</li>
+ <li>suppressMethodArgumentNotUsed</li>
+ <li>suppressPrivatePropertyNotUsed</li>
+ <li>suppressVariableNotUsed</li>
+ <li>suppressExceptionNotSignalled</li>
+ <li>suppressDeprecation</li>
+ </ul>
+ Of these arguments, the <b>srcdir</b> argument is required.
+
+ <p>When this task executes, it will recursively scan the srcdir
+ looking for NetRexx source files to compile. This task makes its
+ compile decision based on timestamp.
+ <p>Before files are compiled they and any other file in the
+ srcdir will be copied to the destdir allowing support files to be
+ located properly in the classpath. The reason for copying the source files
+ before the compile is that NetRexxC has only two destinations for classfiles:
+ <ol>
+ <li>The current directory, and,</li>
+ <li>The directory the source is in (see sourcedir option)
+ </ol>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="binary" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether literals are treated as binary, rather than NetRexx types.]]></short-description>
+        <description><![CDATA[
+          Set whether literals are treated as binary, rather than NetRexx types
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath used for NetRexx compilation.]]></short-description>
+        <description><![CDATA[
+          Set the classpath used for NetRexx compilation
+        ]]></description>
+      </attribute>
+      <attribute name="comments" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether comments are passed through to the generated java source.]]></short-description>
+        <description><![CDATA[
+          Set whether comments are passed through to the generated java source.
+ Valid true values are "on" or "true". Anything else sets the flag to
+ false. The default value is false
+        ]]></description>
+      </attribute>
+      <attribute name="compact" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether error messages come out in compact or verbose format.]]></short-description>
+        <description><![CDATA[
+          Set whether error messages come out in compact or verbose format. Valid
+ true values are "on" or "true". Anything else sets the flag to false.
+ The default value is false
+        ]]></description>
+      </attribute>
+      <attribute name="compile" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether the NetRexx compiler should compile the generated java code
+ Valid true values are "on" or "true".]]></short-description>
+        <description><![CDATA[
+          Set whether the NetRexx compiler should compile the generated java code
+ Valid true values are "on" or "true". Anything else sets the flag to
+ false. The default value is true. Setting this flag to false, will
+ automatically set the keep flag to true.
+        ]]></description>
+      </attribute>
+      <attribute name="console" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether or not messages should be displayed on the 'console' Valid
+ true values are "on" or "true".]]></short-description>
+        <description><![CDATA[
+          Set whether or not messages should be displayed on the 'console' Valid
+ true values are "on" or "true". Anything else sets the flag to false.
+ The default value is true.
+        ]]></description>
+      </attribute>
+      <attribute name="crossref" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether variable cross references are generated.]]></short-description>
+        <description><![CDATA[
+          Whether variable cross references are generated
+        ]]></description>
+      </attribute>
+      <attribute name="decimal" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether decimal arithmetic should be used for the netrexx code.]]></short-description>
+        <description><![CDATA[
+          Set whether decimal arithmetic should be used for the netrexx code.
+ Binary arithmetic is used when this flag is turned off. Valid true
+ values are "on" or "true". Anything else sets the flag to false. The
+ default value is true.
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory into which the NetRexx source files
+ should be copied and then compiled.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory into which the NetRexx source files
+ should be copied and then compiled.
+        ]]></description>
+      </attribute>
+      <attribute name="diag" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether diagnostic information about the compile is generated.]]></short-description>
+        <description><![CDATA[
+          Whether diagnostic information about the compile is generated
+        ]]></description>
+      </attribute>
+      <attribute name="explicit" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether variables must be declared explicitly before use.]]></short-description>
+        <description><![CDATA[
+          Sets whether variables must be declared explicitly before use. Valid
+ true values are "on" or "true". Anything else sets the flag to false.
+ The default value is false.
+        ]]></description>
+      </attribute>
+      <attribute name="format" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the generated java code is formatted nicely or left to match
+ NetRexx line numbers for call stack debugging.]]></short-description>
+        <description><![CDATA[
+          Whether the generated java code is formatted nicely or left to match
+ NetRexx line numbers for call stack debugging
+        ]]></description>
+      </attribute>
+      <attribute name="java" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the generated java code is produced Valid true values are "on"
+ or "true".]]></short-description>
+        <description><![CDATA[
+          Whether the generated java code is produced Valid true values are "on"
+ or "true". Anything else sets the flag to false. The default value is
+ false.
+        ]]></description>
+      </attribute>
+      <attribute name="keep" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether the generated java source file should be kept after
+ compilation.]]></short-description>
+        <description><![CDATA[
+          Sets whether the generated java source file should be kept after
+ compilation. The generated files will have an extension of .java.keep,
+ <b>not</b> .java Valid true values are "on" or "true". Anything else
+ sets the flag to false. The default value is false.
+        ]]></description>
+      </attribute>
+      <attribute name="logo" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the compiler text logo is displayed when compiling.]]></short-description>
+        <description><![CDATA[
+          Whether the compiler text logo is displayed when compiling
+        ]]></description>
+      </attribute>
+      <attribute name="replace" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the generated .java file should be replaced when compiling
+ Valid true values are "on" or "true".]]></short-description>
+        <description><![CDATA[
+          Whether the generated .java file should be replaced when compiling
+ Valid true values are "on" or "true". Anything else sets the flag to
+ false. The default value is false.
+        ]]></description>
+      </attribute>
+      <attribute name="savelog" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether the compiler messages will be written to NetRexxC.log as
+ well as to the console Valid true values are "on" or "true".]]></short-description>
+        <description><![CDATA[
+          Sets whether the compiler messages will be written to NetRexxC.log as
+ well as to the console Valid true values are "on" or "true". Anything
+ else sets the flag to false. The default value is false.
+        ]]></description>
+      </attribute>
+      <attribute name="sourcedir" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Tells the NetRexx compiler to store the class files in the same
+ directory as the source files.]]></short-description>
+        <description><![CDATA[
+          Tells the NetRexx compiler to store the class files in the same
+ directory as the source files. The alternative is the working directory
+ Valid true values are "on" or "true". Anything else sets the flag to
+ false. The default value is true.
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source dir to find the source Java files.]]></short-description>
+        <description><![CDATA[
+          Set the source dir to find the source Java files.
+        ]]></description>
+      </attribute>
+      <attribute name="strictargs" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Tells the NetRexx compiler that method calls always need parentheses,
+ even if no arguments are needed, e.g.]]></short-description>
+        <description><![CDATA[
+          Tells the NetRexx compiler that method calls always need parentheses,
+ even if no arguments are needed, e.g. <code>aStringVar.getBytes</code>
+ vs. <code>aStringVar.getBytes()</code> Valid true values are "on" or
+ "true". Anything else sets the flag to false. The default value is
+ false.
+        ]]></description>
+      </attribute>
+      <attribute name="strictassign" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Tells the NetRexx compile that assignments must match exactly on type.]]></short-description>
+        <description><![CDATA[
+          Tells the NetRexx compile that assignments must match exactly on type
+        ]]></description>
+      </attribute>
+      <attribute name="strictcase" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies whether the NetRexx compiler should be case sensitive or not.]]></short-description>
+        <description><![CDATA[
+          Specifies whether the NetRexx compiler should be case sensitive or not
+        ]]></description>
+      </attribute>
+      <attribute name="strictimport" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether classes need to be imported explicitly using an <code>import</code>
+ statement.]]></short-description>
+        <description><![CDATA[
+          Sets whether classes need to be imported explicitly using an <code>import</code>
+ statement. By default the NetRexx compiler will import certain packages
+ automatically Valid true values are "on" or "true". Anything else sets
+ the flag to false. The default value is false.
+        ]]></description>
+      </attribute>
+      <attribute name="strictprops" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether local properties need to be qualified explicitly using
+ <code>this</code> Valid true values are "on" or "true".]]></short-description>
+        <description><![CDATA[
+          Sets whether local properties need to be qualified explicitly using
+ <code>this</code> Valid true values are "on" or "true". Anything else
+ sets the flag to false. The default value is false.
+        ]]></description>
+      </attribute>
+      <attribute name="strictsignal" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the compiler should force catching of exceptions by explicitly
+ named types.]]></short-description>
+        <description><![CDATA[
+          Whether the compiler should force catching of exceptions by explicitly
+ named types
+        ]]></description>
+      </attribute>
+      <attribute name="suppressdeprecation" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Tells whether we should filter out any deprecation-messages
+ of the compiler out.]]></short-description>
+        <description><![CDATA[
+          Tells whether we should filter out any deprecation-messages
+ of the compiler out.
+        ]]></description>
+      </attribute>
+      <attribute name="suppressexceptionnotsignalled" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the task should suppress the "FooException is in SIGNALS list
+ but is not signalled within the method", which is sometimes rather
+ useless.]]></short-description>
+        <description><![CDATA[
+          Whether the task should suppress the "FooException is in SIGNALS list
+ but is not signalled within the method", which is sometimes rather
+ useless. The warning is logged as verbose message, though.
+        ]]></description>
+      </attribute>
+      <attribute name="suppressmethodargumentnotused" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the task should suppress the "Method argument is not used" in
+ strictargs-Mode, which can not be suppressed by the compiler itself.]]></short-description>
+        <description><![CDATA[
+          Whether the task should suppress the "Method argument is not used" in
+ strictargs-Mode, which can not be suppressed by the compiler itself.
+ The warning is logged as verbose message, though.
+        ]]></description>
+      </attribute>
+      <attribute name="suppressprivatepropertynotused" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the task should suppress the "Private property is defined but
+ not used" in strictargs-Mode, which can be quite annoying while
+ developing.]]></short-description>
+        <description><![CDATA[
+          Whether the task should suppress the "Private property is defined but
+ not used" in strictargs-Mode, which can be quite annoying while
+ developing. The warning is logged as verbose message, though.
+        ]]></description>
+      </attribute>
+      <attribute name="suppressvariablenotused" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether the task should suppress the "Variable is set but not used" in
+ strictargs-Mode.]]></short-description>
+        <description><![CDATA[
+          Whether the task should suppress the "Variable is set but not used" in
+ strictargs-Mode. Be careful with this one! The warning is logged as
+ verbose message, though.
+        ]]></description>
+      </attribute>
+      <attribute name="symbols" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether debug symbols should be generated into the class file
+ Valid true values are "on" or "true".]]></short-description>
+        <description><![CDATA[
+          Sets whether debug symbols should be generated into the class file
+ Valid true values are "on" or "true". Anything else sets the flag to
+ false. The default value is false.
+        ]]></description>
+      </attribute>
+      <attribute name="time" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Asks the NetRexx compiler to print compilation times to the console
+ Valid true values are "on" or "true".]]></short-description>
+        <description><![CDATA[
+          Asks the NetRexx compiler to print compilation times to the console
+ Valid true values are "on" or "true". Anything else sets the flag to
+ false. The default value is false.
+        ]]></description>
+      </attribute>
+      <attribute name="trace" type="org.apache.tools.ant.taskdefs.optional.NetRexxC.TraceAttr"
+                 briefType="&quot;trace&quot;, &quot;trace1&quot;, &quot;trace2&quot;, &quot;notrace&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+      <attribute name="utf8" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Tells the NetRexx compiler that the source is in UTF8 Valid true values
+ are "on" or "true".]]></short-description>
+        <description><![CDATA[
+          Tells the NetRexx compiler that the source is in UTF8 Valid true values
+ are "on" or "true". Anything else sets the flag to false. The default
+ value is false.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="org.apache.tools.ant.taskdefs.optional.NetRexxC.VerboseAttr"
+                 briefType="&quot;verbose&quot;, &quot;verbose0&quot;, &quot;verbose1&quot;, &quot;verbose2&quot;, &quot;verbose3&quot;, &quot;verbose4&quot;, &quot;verbose5&quot;, &quot;noverbose&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Whether lots of warnings and error messages should be generated.]]></short-description>
+        <description><![CDATA[
+          Whether lots of warnings and error messages should be generated
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4add" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Add"
+      >
+
+  <short-description><![CDATA[Adds specified files to Perforce.]]></short-description>
+  <description>
+    <![CDATA[Adds specified files to Perforce.
+
+ <b>Example Usage:</b>
+ <table border="1">
+ <th>Function</th><th>Command</th>
+ <tr><td>Add files using P4USER, P4PORT and P4CLIENT settings specified</td><td>&lt;P4add <br>P4view="//projects/foo/main/source/..." <br>P4User="fbloggs" <br>P4Port="km01:1666" <br>P4Client="fbloggsclient"&gt;<br>&lt;fileset basedir="dir" includes="**&#47;*.java"&gt;<br>&lt;/p4add&gt;</td></tr>
+ <tr><td>Add files using P4USER, P4PORT and P4CLIENT settings defined in environment</td><td>&lt;P4add P4view="//projects/foo/main/source/..." /&gt;<br>&lt;fileset basedir="dir" includes="**&#47;*.java"&gt;<br>&lt;/p4add&gt;</td></tr>
+ <tr><td>Specify the length of command line arguments to pass to each invocation of p4</td><td>&lt;p4add Commandlength="450"&gt;</td></tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="changelist" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[If specified the open files are associated with the
+ specified pending changelist number; otherwise the open files are
+ associated with the default changelist.]]></short-description>
+        <description><![CDATA[
+          If specified the open files are associated with the
+ specified pending changelist number; otherwise the open files are
+ associated with the default changelist.
+        ]]></description>
+      </attribute>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="commandlength" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Positive integer specifying the maximum length
+   of the commandline when calling Perforce to add the files.]]></short-description>
+        <description><![CDATA[
+          positive integer specifying the maximum length
+   of the commandline when calling Perforce to add the files. 
+   Defaults to 450, higher values mean faster execution,
+   but also possible failures.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Files to add.]]></short-description>
+        <description>
+          <![CDATA[files to add]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4change" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Change"
+      >
+
+  <short-description><![CDATA[Requests a new changelist from the Perforce server.]]></short-description>
+  <description>
+    <![CDATA[Requests a new changelist from the Perforce server.
+ P4Change creates a new changelist in perforce. P4Change sets the property
+ ${p4.change} with the new changelist number. This should then be passed into
+ p4edit and p4submit.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="description" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Description for ChangeList;optional.]]></short-description>
+        <description><![CDATA[
+          Description for ChangeList;optional.
+ If none is specified, it will default to "AutoSubmit By Ant"
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4counter" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Counter"
+      >
+
+  <short-description><![CDATA[Obtains or sets the value of a counter.]]></short-description>
+  <description>
+    <![CDATA[Obtains or sets the value of a counter.
+
+ <p> When used in its base form
+ (where only the counter name is provided), the counter value will be
+ printed to the output stream. When the value is provided, the counter
+ will be set to the value provided. When a property name is provided,
+ the property will be filled with the value of the counter. You may
+ not specify to both get and set the value of the counter in the same
+ Task.
+ </p>
+ <P>
+ The user performing this task must have Perforce &quot;review&quot; permissions
+ as defined by Perforce protections in order for this task to succeed.
+</P>
+
+ Example Usage:<br>
+ &lt;p4counter name="${p4.counter}" property=${p4.change}"/&gt;]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="name" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the counter; required.]]></short-description>
+        <description><![CDATA[
+          The name of the counter; required
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[A property to be set with the value of the counter.]]></short-description>
+        <description><![CDATA[
+          A property to be set with the value of the counter
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="value" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[The new value for the counter; optional.]]></short-description>
+        <description><![CDATA[
+          The new value for the counter; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4delete" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Delete"
+      >
+
+  <short-description><![CDATA[Checkout files for deletion.]]></short-description>
+  <description>
+    <![CDATA[Checkout files for deletion.
+
+ Example Usage:<br>
+ &lt;p4delete change="${p4.change}" view="//depot/project/foo.txt" /&gt;<br>
+
+ Simple re-write of P4Edit changing 'edit' to 'delete'.<br>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="change" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[An existing changelist number for the deletion; optional
+ but strongly recommended.]]></short-description>
+        <description><![CDATA[
+          An existing changelist number for the deletion; optional
+ but strongly recommended.
+        ]]></description>
+      </attribute>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4edit" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Edit"
+      >
+
+  <short-description><![CDATA[Open file(s) for edit.]]></short-description>
+  <description>
+    <![CDATA[Open file(s) for edit. 
+ P4Change should be used to obtain a new changelist for P4Edit as,
+ although P4Edit can open files to the default change,  
+ P4Submit cannot yet submit to it.
+ Example Usage:<br>
+ &lt;p4edit change="${p4.change}" view="//depot/project/foo.txt" /&gt;]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="change" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[An existing changelist number to assign files to; optional
+ but strongly recommended.]]></short-description>
+        <description><![CDATA[
+          An existing changelist number to assign files to; optional
+ but strongly recommended.
+        ]]></description>
+      </attribute>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4have" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Have"
+      >
+
+  <short-description><![CDATA[Lists Perforce files currently on client.]]></short-description>
+  <description>
+    <![CDATA[Lists Perforce files currently on client.
+
+ P4Have simply dumps the current file version info into
+ the Ant log (or stdout).]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4label" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Label"
+      >
+
+  <short-description><![CDATA[Creates a new Perforce label and set contents to reflect current client file revisions.]]></short-description>
+  <description>
+    <![CDATA[Creates a new Perforce label and set contents to reflect current
+  client file revisions.
+
+  Label name defaults to AntLabel if none set.
+
+ Example Usage:
+ <pre>
+   &lt;P4Label name="MyLabel-${TSTAMP}-${DSTAMP}" desc="Auto Build Label" /&gt;
+ </pre>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="desc" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Label Description; optional.]]></short-description>
+        <description><![CDATA[
+          Label Description; optional
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="lock" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[When set to "locked", Perforce will lock the label once created; optional.]]></short-description>
+        <description><![CDATA[
+          when set to "locked", Perforce will lock the label once created; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="name" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the label; optional, default "AntLabel".]]></short-description>
+        <description><![CDATA[
+          The name of the label; optional, default "AntLabel"
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4reopen" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Reopen"
+      >
+
+  <short-description><![CDATA[No Description.]]></short-description>
+  <description>
+    <![CDATA[]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="tochange" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The changelist to move files to; required.]]></short-description>
+        <description><![CDATA[
+          The changelist to move files to; required.
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4revert" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Revert"
+      >
+
+  <short-description><![CDATA[Revert Perforce open files or files in a changelist]]></short-description>
+  <description>
+    <![CDATA[Revert Perforce open files or files in a changelist]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="change" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The changelist to revert; optional.]]></short-description>
+        <description><![CDATA[
+          The changelist to revert; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="revertonlyunchanged" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to revert only unchanged files (p4 revert -a); optional, default false.]]></short-description>
+        <description><![CDATA[
+          flag to revert only unchanged files (p4 revert -a); optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4submit" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Submit"
+      >
+
+  <short-description><![CDATA[Submits a numbered changelist to Perforce.]]></short-description>
+  <description>
+    <![CDATA[Submits a numbered changelist to Perforce.
+
+ <B>Note:</B> P4Submit cannot (yet) submit the default changelist.
+ This shouldn't be a problem with the ANT task as the usual flow is
+ P4Change to create a new numbered change followed by P4Edit then P4Submit.
+
+ Example Usage:-<br>
+ &lt;p4submit change="${p4.change}" /&gt;]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="change" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The changelist number to submit; required.]]></short-description>
+        <description><![CDATA[
+          The changelist number to submit; required.
+        ]]></description>
+      </attribute>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="p4sync" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Sync"
+      >
+
+  <short-description><![CDATA[Synchronize client space to a Perforce depot view.]]></short-description>
+  <description>
+    <![CDATA[Synchronize client space to a Perforce depot view.
+
+  The API allows additional functionality of the "p4 sync" command
+ (such as "p4 sync -f //...#have" or other exotic invocations).</P>
+
+ <b>Example Usage:</b>
+ <table border="1">
+ <th>Function</th><th>Command</th>
+ <tr><td>Sync to head using P4USER, P4PORT and P4CLIENT settings specified</td><td>&lt;P4Sync <br>P4view="//projects/foo/main/source/..." <br>P4User="fbloggs" <br>P4Port="km01:1666" <br>P4Client="fbloggsclient" /&gt;</td></tr>
+ <tr><td>Sync to head using P4USER, P4PORT and P4CLIENT settings defined in environment</td><td>&lt;P4Sync P4view="//projects/foo/main/source/..." /&gt;</td></tr>
+ <tr><td>Force a re-sync to head, refreshing all files</td><td>&lt;P4Sync force="yes" P4view="//projects/foo/main/source/..." /&gt;</td></tr>
+ <tr><td>Sync to a label</td><td>&lt;P4Sync label="myPerforceLabel" /&gt;</td></tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="client" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 client spec to use;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 client spec to use;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="cmdopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set extra command options; only used on some
+ of the Perforce tasks.]]></short-description>
+        <description><![CDATA[
+          Set extra command options; only used on some
+ of the Perforce tasks.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command.]]></short-description>
+        <description><![CDATA[
+          whether to stop the build (true, default) 
+ or keep going if an error is returned from the p4 command
+        ]]></description>
+      </attribute>
+      <attribute name="force" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Force a refresh of files, if this attribute is set; false by default.]]></short-description>
+        <description><![CDATA[
+          force a refresh of files, if this attribute is set; false by default.
+        ]]></description>
+      </attribute>
+      <attribute name="label" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Label to sync client to; optional.]]></short-description>
+        <description><![CDATA[
+          Label to sync client to; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4d server and port to connect to;
+ optional, default "perforce:1666".]]></short-description>
+        <description><![CDATA[
+          The p4d server and port to connect to;
+ optional, default "perforce:1666"
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The p4 username;
+ optional, defaults to the current user.]]></short-description>
+        <description><![CDATA[
+          The p4 username;
+ optional, defaults to the current user
+        ]]></description>
+      </attribute>
+      <attribute name="view" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The client, branch or label view to operate upon;
+ optional default "//...".]]></short-description>
+        <description><![CDATA[
+          The client, branch or label view to operate upon;
+ optional default "//..."
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="parallel" category="control"
+      classname="org.apache.tools.ant.taskdefs.Parallel"
+      >
+
+  <short-description><![CDATA[Executes the contained tasks in separate threads, continuing once all are completed.]]></short-description>
+  <description>
+    <![CDATA[Executes the contained tasks in separate threads, continuing
+ once all are completed.
+ <p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="patch" category="utility"
+      classname="org.apache.tools.ant.taskdefs.Patch"
+      >
+
+  <short-description><![CDATA[Patches a file by applying a 'diff' file to it; requires "patch" to be on the execution path.]]></short-description>
+  <description>
+    <![CDATA[Patches a file by applying a 'diff' file to it; requires "patch" to be
+ on the execution path.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="backups" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to create backups; optional, default=false.]]></short-description>
+        <description><![CDATA[
+          flag to create backups; optional, default=false
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory to run the patch command in, defaults to the
+ project's base directory.]]></short-description>
+        <description><![CDATA[
+          The directory to run the patch command in, defaults to the
+ project's base directory.
+        ]]></description>
+      </attribute>
+      <attribute name="ignorewhitespace" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to ignore whitespace differences; default=false.]]></short-description>
+        <description><![CDATA[
+          flag to ignore whitespace differences; default=false
+        ]]></description>
+      </attribute>
+      <attribute name="originalfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to patch; optional if it can be inferred from
+ the diff file.]]></short-description>
+        <description><![CDATA[
+          The file to patch; optional if it can be inferred from
+ the diff file
+        ]]></description>
+      </attribute>
+      <attribute name="patchfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file containing the diff output; required.]]></short-description>
+        <description><![CDATA[
+          The file containing the diff output; required.
+        ]]></description>
+      </attribute>
+      <attribute name="quiet" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Work silently unless an error occurs; optional, default=false.]]></short-description>
+        <description><![CDATA[
+          Work silently unless an error occurs; optional, default=false
+        ]]></description>
+      </attribute>
+      <attribute name="reverse" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Assume patch was created with old and new files swapped; optional,
+ default=false.]]></short-description>
+        <description><![CDATA[
+          Assume patch was created with old and new files swapped; optional,
+ default=false
+        ]]></description>
+      </attribute>
+      <attribute name="strip" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Strip the smallest prefix containing <i>num</i> leading slashes
+ from filenames.]]></short-description>
+        <description><![CDATA[
+          Strip the smallest prefix containing <i>num</i> leading slashes
+ from filenames.
+
+ <p>patch's <i>-p</i> option.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="pathconvert" category="utility"
+      classname="org.apache.tools.ant.taskdefs.PathConvert"
+      >
+
+  <short-description><![CDATA[Converts path and classpath information to a specific target OS format.]]></short-description>
+  <description>
+    <![CDATA[Converts path and classpath information to a specific target OS
+ format. The resulting formatted path is placed into the specified property.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dirsep" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Default directory separator string;
+ defaults to current JVM.]]></short-description>
+        <description><![CDATA[
+          Set the default directory separator string;
+ defaults to current JVM {@link java.io.File#separator File.separator}
+        ]]></description>
+      </attribute>
+      <attribute name="pathsep" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Default path separator string;
+ defaults to current JVM.]]></short-description>
+        <description><![CDATA[
+          Set the default path separator string;
+ defaults to current JVM
+ {@link java.io.File#pathSeparator File.pathSeparator}
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The property into which the converted path will be placed.]]></short-description>
+        <description><![CDATA[
+          The property into which the converted path will be placed.
+        ]]></description>
+      </attribute>
+      <attribute name="refid" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds a reference to a Path, FileSet, DirSet, or FileList defined
+ elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds a reference to a Path, FileSet, DirSet, or FileList defined
+ elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="setonempty" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set setonempty
+
+ If false, don't set the new property if the result is the empty string.]]></short-description>
+        <description><![CDATA[
+          Set setonempty
+
+ If false, don't set the new property if the result is the empty string.
+        ]]></description>
+      </attribute>
+      <attribute name="targetos" type="org.apache.tools.ant.taskdefs.PathConvert.TargetOs"
+                 briefType="&quot;windows&quot;, &quot;unix&quot;, &quot;netware&quot;, &quot;os/2&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Set targetos to a platform to one of
+ "windows", "unix", "netware", or "os/2"; required unless
+ unless pathsep and/or dirsep are specified.]]></short-description>
+        <description><![CDATA[
+          Set targetos to a platform to one of
+ "windows", "unix", "netware", or "os/2"; required unless
+ unless pathsep and/or dirsep are specified.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="map" type="org.apache.tools.ant.taskdefs.PathConvert.MapEntry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a nested MAP element.]]></short-description>
+        <description>
+          <![CDATA[Create a nested MAP element]]>
+        </description>
+      </element>
+
+      <element name="path" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a nested PATH element.]]></short-description>
+        <description>
+          <![CDATA[Create a nested PATH element]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="property" category="other"
+      classname="org.apache.tools.ant.taskdefs.Property"
+      >
+
+  <short-description><![CDATA[Sets a property by name, or set of properties (from file or resource) in the project.]]></short-description>
+  <description>
+    <![CDATA[Sets a property by name, or set of properties (from file or
+ resource) in the project.  </p>
+ Properties are immutable: whoever sets a property first freezes it for the
+ rest of the build; they are most definately not variable. 
+ <p>There are five ways to set properties:</p>
+ <ul>
+   <li>By supplying both the <i>name</i> and <i>value</i> attribute.</li>
+   <li>By supplying both the <i>name</i> and <i>refid</i> attribute.</li>
+   <li>By setting the <i>file</i> attribute with the filename of the property
+     file to load. This property file has the format as defined by the file used
+     in the class java.util.Properties.</li>
+   <li>By setting the <i>resource</i> attribute with the resource name of the
+     property file to load. This property file has the format as defined by the
+     file used in the class java.util.Properties.</li>
+   <li>By setting the <i>environment</i> attribute with a prefix to use.
+     Properties will be defined for every environment variable by
+     prefixing the supplied name and a period to the name of the variable.</li>
+ </ul>
+ <p>Although combinations of these ways are possible, only one should be used
+ at a time. Problems might occur with the order in which properties are set, for
+ instance.</p>
+ <p>The value part of the properties being set, might contain references to other
+ properties. These references are resolved at the time these properties are set.
+ This also holds for properties loaded from a property file.</p>
+ Properties are case sensitive.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[The classpath to use when looking up a resource.]]></short-description>
+        <description><![CDATA[
+          The classpath to use when looking up a resource.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[The classpath to use when looking up a resource,
+ given as reference to a &lt;path&gt; defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          the classpath to use when looking up a resource,
+ given as reference to a &lt;path&gt; defined elsewhere
+        ]]></description>
+      </attribute>
+      <attribute name="environment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The prefix to use when retrieving environment variables.]]></short-description>
+        <description><![CDATA[
+          the prefix to use when retrieving environment variables. 
+ Thus if you specify environment=&quot;myenv&quot; 
+ you will be able to access OS-specific 
+ environment variables via property names &quot;myenv.PATH&quot; or 
+ &quot;myenv.TERM&quot;. 
+ <p>
+ Note that if you supply a property name with a final 
+ &quot;.&quot; it will not be doubled. ie environment=&quot;myenv.&quot; will still 
+ allow access of environment variables through &quot;myenv.PATH&quot; and 
+ &quot;myenv.TERM&quot;. This functionality is currently only implemented 
+ on select platforms. Feel free to send patches to increase the number of platforms
+ this functionality is supported on ;).<br>
+ Note also that properties are case sensitive, even if the
+ environment variables on your operating system are not, e.g. it
+ will be ${env.Path} not ${env.PATH} on Windows 2000.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The filename of a property file to load.]]></short-description>
+        <description><![CDATA[
+          the filename of a property file to load.
+        ]]></description>
+      </attribute>
+      <attribute name="location" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Property to the absolute filename of the
+ given file.]]></short-description>
+        <description><![CDATA[
+          Sets the property to the absolute filename of the
+ given file. If the value of this attribute is an absolute path, it
+ is left unchanged (with / and \ characters converted to the
+ current platforms conventions). Otherwise it is taken as a path
+ relative to the project's basedir and expanded.
+        ]]></description>
+      </attribute>
+      <attribute name="name" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the property to set.]]></short-description>
+        <description><![CDATA[
+          sets the name of the property to set.
+        ]]></description>
+      </attribute>
+      <attribute name="prefix" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Prefix to apply to properties loaded using <code>file</code>
+ or <code>resource</code>.]]></short-description>
+        <description><![CDATA[
+          Prefix to apply to properties loaded using <code>file</code>
+ or <code>resource</code>. 
+ A "." is appended to the prefix if not specified.
+        ]]></description>
+      </attribute>
+      <attribute name="refid" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Reference to an Ant datatype
+ declared elsewhere.]]></short-description>
+        <description><![CDATA[
+          Sets a reference to an Ant datatype
+ declared elsewhere. 
+ Only yields reasonable results for references
+ PATH like structures or properties.
+        ]]></description>
+      </attribute>
+      <attribute name="resource" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The resource name of a property file to load.]]></short-description>
+        <description><![CDATA[
+          the resource name of a property file to load
+        ]]></description>
+      </attribute>
+      <attribute name="value" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Value of the property.]]></short-description>
+        <description><![CDATA[
+          Sets the value of the property.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[The classpath to use when looking up a resource.]]></short-description>
+        <description>
+          <![CDATA[The classpath to use when looking up a resource.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="propertyfile" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.PropertyFile"
+      >
+
+  <short-description><![CDATA[Modifies settings in a property file.]]></short-description>
+  <description>
+    <![CDATA[Modifies settings in a property file.
+
+ <p>
+The following is an example of its usage:
+    <ul>&lt;target name="setState"&gt;<br>
+    <ul>&lt;property<br>
+        <ul>name="header"<br>
+        value="##Generated file - do not modify!"/&gt;<br>
+      &lt;propertyfile file="apropfile.properties" comment="${header}"&gt;<br>
+        &lt;entry key="product.version.major" type="int"  value="5"/&gt;<br>
+        &lt;entry key="product.version.minor" type="int"  value="0"/&gt;<br>
+        &lt;entry key="product.build.major"   type="int"  value="0" /&gt;<br>
+        &lt;entry key="product.build.minor"   type="int"  operation="+" /&gt;<br>
+        &lt;entry key="product.build.date"    type="date" value="now" /&gt;<br>
+        &lt;entry key="intSet" type="int" operation="=" value="681"/&gt;<br>
+        &lt;entry key="intDec" type="int" operation="-"/&gt;<br>
+        &lt;entry key="StringEquals" type="string" value="testValue"/&gt;<br>
+     &lt;/propertyfile&gt;<br></ul>
+   &lt;/target&gt;</ul><p>
+
+The &lt;propertyfile&gt; task must have:<br>
+    <ul><li>file</li></ul>
+Other parameters are:<br>
+    <ul><li>comment, key, operation, type and value (the final four being eliminated shortly)</li></ul>
+
+The &lt;entry&gt; task must have:<br>
+    <ul><li>key</li></ul>
+Other parameters are:<br>
+    <ul><li>operation</li>
+        <li>type</li>
+        <li>value</li>
+        <li>default</li>
+        <li>unit</li>
+    </ul>
+
+If type is unspecified, it defaults to string
+
+Parameter values:<br>
+    <ul><li>operation:</li>
+        <ul><li>"=" (set -- default)</li>
+        <li>"-" (dec)</li>
+        <li>"+" (inc)</li>
+
+    <li>type:</li>
+        <ul><li>"int"</li>
+        <li>"date"</li>
+        <li>"string"</li></ul></ul>
+
+    <li>value:</li>
+      <ul><li>holds the default value, if the property
+              was not found in property file</li>
+          <li>"now" In case of type "date", the
+              value "now" will be replaced by the current
+              date/time and used even if a valid date was
+              found in the property file.</li></ul>
+
+String property types can only use the "=" operation.
+Int property types can only use the "=", "-" or "+" operations.<p>
+
+The message property is used for the property file header, with "\\" being
+a newline delimiter character.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Optional header comment for the file.]]></short-description>
+        <description><![CDATA[
+          optional header comment for the file
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Location of the property file to be edited; required.]]></short-description>
+        <description><![CDATA[
+          Location of the property file to be edited; required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="entry" type="org.apache.tools.ant.taskdefs.optional.PropertyFile.Entry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description>
+          <![CDATA[]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="pvcs" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.pvcs.Pvcs"
+      >
+
+  <short-description><![CDATA[Extracts the latest edition of the source code from a PVCS repository.]]></short-description>
+  <description>
+    <![CDATA[Extracts the latest edition of the source code from a PVCS repository.
+ PVCS is a version control system
+ developed by <a href="http://www.merant.com/products/pvcs">Merant</a>.
+ <br>
+ Before using this tag, the user running ant must have access to the commands 
+ of PVCS (get and pcli) and must have access to the repository. Note that the way to specify
+ the repository is platform dependent so use property to specify location of repository.
+ <br>
+ This version has been tested agains PVCS version 6.5 and 6.6 under Windows and Solaris.
+
+ <b>19-04-2001</b> <p>The task now has a more robust
+ parser. It allows for platform independant file paths
+ and supports file names with <i>()</i>. Thanks to Erik Husby for
+ bringing the bug to my attention.
+
+ <b>27-04-2001</b> <p>UNC paths are now handled properly.
+ Fix provided by Don Jeffery. He also added an <i>UpdateOnly</i> flag
+ that, when true, conditions the PVCS get using the -U option to only
+ update those files that have a modification time (in PVCS) that is newer
+ than the existing workfile.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="filenameformat" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The format of the folder names; optional.]]></short-description>
+        <description><![CDATA[
+          The format of the folder names; optional.
+ This must be in a format suitable for 
+ <code>java.text.MessageFormat</code>.
+  Index 1 of the format will be used as the file name.
+  Defaults to <code>{0}-arc({1})</code>
+        ]]></description>
+      </attribute>
+      <attribute name="force" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the value of the force argument; optional.]]></short-description>
+        <description><![CDATA[
+          Specifies the value of the force argument; optional.
+ If set to <i>yes</i> all files that exists and are 
+ writable are overwritten. Default <i>no</i> causes the files 
+ that are writable to be ignored. This stops the PVCS command 
+ <i>get</i> to stop asking questions!
+        ]]></description>
+      </attribute>
+      <attribute name="ignorereturncode" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If set to true the return value from executing the pvcs
+ commands are ignored; optional, default false.]]></short-description>
+        <description><![CDATA[
+          If set to true the return value from executing the pvcs
+ commands are ignored; optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="label" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Only files marked with this label are extracted; optional.]]></short-description>
+        <description><![CDATA[
+          Only files marked with this label are extracted; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="linestart" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[What a valid return value from PVCS looks like
+  when it describes a file.]]></short-description>
+        <description><![CDATA[
+          What a valid return value from PVCS looks like
+  when it describes a file.  Defaults to <code>&quot;P:</code>.
+ If you are not using an UNC name for your repository and the
+ drive letter <code>P</code> is incorrect for your setup, you may
+ need to change this value, UNC names will always be
+ accepted.
+        ]]></description>
+      </attribute>
+      <attribute name="promotiongroup" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the name of the promotiongroup argument.]]></short-description>
+        <description><![CDATA[
+          Specifies the name of the promotiongroup argument
+        ]]></description>
+      </attribute>
+      <attribute name="pvcsbin" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the location of the PVCS bin directory; optional if on the PATH.]]></short-description>
+        <description><![CDATA[
+          Specifies the location of the PVCS bin directory; optional if on the PATH.
+ On some systems the PVCS executables <i>pcli</i>
+ and <i>get</i> are not found in the PATH. In such cases this attribute
+ should be set to the bin directory of the PVCS installation containing
+ the executables mentioned before. If this attribute isn't specified the
+ tag expects the executables to be found using the PATH environment variable.
+        ]]></description>
+      </attribute>
+      <attribute name="pvcsproject" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The project within the PVCS repository to extract files from;
+ optional, default &quot;/&quot;.]]></short-description>
+        <description><![CDATA[
+          The project within the PVCS repository to extract files from;
+ optional, default &quot;/&quot;
+        ]]></description>
+      </attribute>
+      <attribute name="repository" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The network name of the PVCS repository; required.]]></short-description>
+        <description><![CDATA[
+          The network name of the PVCS repository; required.
+        ]]></description>
+      </attribute>
+      <attribute name="updateonly" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If set to <i>true</i> files are fetched only if 
+ newer than existing local files; optional, default false.]]></short-description>
+        <description><![CDATA[
+          If set to <i>true</i> files are fetched only if 
+ newer than existing local files; optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="workspace" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Workspace to use; optional.]]></short-description>
+        <description><![CDATA[
+          Workspace to use; optional.  
+ By specifying a workspace, the files are extracted to that location.
+ A PVCS workspace is a name for a location of the workfiles and 
+ isn't as such the location itself. 
+ You define the location for a workspace using the PVCS GUI clients.
+ If this isn't specified the default workspace for the current user is used.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="pvcsproject" type="org.apache.tools.ant.taskdefs.optional.pvcs.PvcsProject"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Specify a project within the PVCS repository to extract files from.]]></short-description>
+        <description>
+          <![CDATA[Specify a project within the PVCS repository to extract files from.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="record" category="utility"
+      classname="org.apache.tools.ant.taskdefs.Recorder"
+      >
+
+  <short-description><![CDATA[Adds a listener to the current build process that records the output to a file.]]></short-description>
+  <description>
+    <![CDATA[Adds a listener to the current build process that records the
+ output to a file.
+ <p>Several recorders can exist at the same time.  Each recorder is
+ associated with a file.  The filename is used as a unique identifier for
+ the recorders.  The first call to the recorder task with an unused filename
+ will create a recorder (using the parameters provided) and add it to the
+ listeners of the build.  All subsequent calls to the recorder task using
+ this filename will modify that recorders state (recording or not) or other
+ properties (like logging level).</p>
+ <p>Some technical issues: the file's print stream is flushed for &quot;finished&quot;
+ events (buildFinished, targetFinished and taskFinished), and is closed on
+ a buildFinished event.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="action" type="org.apache.tools.ant.taskdefs.Recorder.ActionChoices"
+                 briefType="&quot;start&quot;, &quot;stop&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Action for the associated recorder entry.]]></short-description>
+        <description><![CDATA[
+          Sets the action for the associated recorder entry.
+        ]]></description>
+      </attribute>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether or not the logger should append to a previous file.]]></short-description>
+        <description><![CDATA[
+          Whether or not the logger should append to a previous file.
+        ]]></description>
+      </attribute>
+      <attribute name="emacsmode" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description><![CDATA[
+        ]]></description>
+      </attribute>
+      <attribute name="loglevel" type="org.apache.tools.ant.taskdefs.Recorder.VerbosityLevelChoices"
+                 briefType="&quot;error&quot;, &quot;warn&quot;, &quot;info&quot;, &quot;verbose&quot;, &quot;debug&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Level to which this recorder entry should log to.]]></short-description>
+        <description><![CDATA[
+          Sets the level to which this recorder entry should log to.
+        ]]></description>
+      </attribute>
+      <attribute name="name" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the file to log to, and the name of the recorder
+ entry.]]></short-description>
+        <description><![CDATA[
+          Sets the name of the file to log to, and the name of the recorder
+ entry.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="rename" category="other"
+      classname="org.apache.tools.ant.taskdefs.Rename"
+      deprecated="true"
+      >
+
+  <short-description><![CDATA[Renames a file.]]></short-description>
+  <description>
+    <![CDATA[Renames a file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[New name of the file.]]></short-description>
+        <description><![CDATA[
+          Sets the new name of the file.
+        ]]></description>
+      </attribute>
+      <attribute name="replace" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether an existing file should be replaced.]]></short-description>
+        <description><![CDATA[
+          Sets whether an existing file should be replaced.
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File to be renamed.]]></short-description>
+        <description><![CDATA[
+          Sets the file to be renamed.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="renameextensions" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.RenameExtensions"
+      deprecated="true"
+      matchingTask="true">
+
+  <short-description><![CDATA[No Description.]]></short-description>
+  <description>
+    <![CDATA[]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="fromextension" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The string that files must end in to be renamed.]]></short-description>
+        <description><![CDATA[
+          The string that files must end in to be renamed
+        ]]></description>
+      </attribute>
+      <attribute name="replace" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Store replace attribute - this determines whether the target file
+ should be overwritten if present.]]></short-description>
+        <description><![CDATA[
+          store replace attribute - this determines whether the target file
+ should be overwritten if present
+        ]]></description>
+      </attribute>
+      <attribute name="srcdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source dir to find the files to be renamed.]]></short-description>
+        <description><![CDATA[
+          Set the source dir to find the files to be renamed.
+        ]]></description>
+      </attribute>
+      <attribute name="toextension" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The string that renamed files will end with on
+ completion.]]></short-description>
+        <description><![CDATA[
+          The string that renamed files will end with on
+ completion
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="replace" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.Replace"
+      matchingTask="true">
+
+  <short-description><![CDATA[Replaces all occurrences of one or more string tokens with given values in the indicated files.]]></short-description>
+  <description>
+    <![CDATA[Replaces all occurrences of one or more string tokens with given
+ values in the indicated files. Each value can be either a string 
+ or the value of a property available in a designated property file.
+ If you want to replace a text that crosses line boundaries, you
+ must use a nested <code>&lt;replacetoken&gt;</code> element.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The base directory to use when replacing a token in multiple files;
+ required if <code>file</code> is not defined.]]></short-description>
+        <description><![CDATA[
+          The base directory to use when replacing a token in multiple files;
+ required if <code>file</code> is not defined.
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[File encoding to use on the files read and written by the task;
+ optional, defaults to default JVM encoding.]]></short-description>
+        <description><![CDATA[
+          Set the file encoding to use on the files read and written by the task;
+ optional, defaults to default JVM encoding
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Source file; required unless <code>dir</code> is set.]]></short-description>
+        <description><![CDATA[
+          Set the source file; required unless <code>dir</code> is set.
+        ]]></description>
+      </attribute>
+      <attribute name="propertyfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The name of a property file from which properties specified using
+ nested <code>&lt;replacefilter&gt;</code> elements are drawn;
+ Required only if <i>property</i> attribute of
+ <code>&lt;replacefilter&gt;</code> is used.]]></short-description>
+        <description><![CDATA[
+          The name of a property file from which properties specified using
+ nested <code>&lt;replacefilter&gt;</code> elements are drawn;
+ Required only if <i>property</i> attribute of
+ <code>&lt;replacefilter&gt;</code> is used.
+        ]]></description>
+      </attribute>
+      <attribute name="replacefilterfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of a property file containing filters; optional.]]></short-description>
+        <description><![CDATA[
+          Sets the name of a property file containing filters; optional.
+ Each property will be treated as a
+ replacefilter where token is the name of the property and value
+ is the value of the property.
+        ]]></description>
+      </attribute>
+      <attribute name="summary" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates whether a summary of the replace operation should be
+ produced, detailing how many token occurrences and files were
+ processed; optional, default=false.]]></short-description>
+        <description><![CDATA[
+          Indicates whether a summary of the replace operation should be
+ produced, detailing how many token occurrences and files were
+ processed; optional, default=false
+        ]]></description>
+      </attribute>
+      <attribute name="token" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[String token to replace;
+ required unless a nested
+ <code>replacetoken</code> element or the <code>replacefilterfile</code>
+ attribute is used.]]></short-description>
+        <description><![CDATA[
+          Set the string token to replace;
+ required unless a nested
+ <code>replacetoken</code> element or the <code>replacefilterfile</code>
+ attribute is used.
+        ]]></description>
+      </attribute>
+      <attribute name="value" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[String value to use as token replacement;
+ optional, default is the empty string "".]]></short-description>
+        <description><![CDATA[
+          Set the string value to use as token replacement;
+ optional, default is the empty string ""
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="replacetoken" type="org.apache.tools.ant.taskdefs.Replace.NestedString"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[The token to filter as the text of a nested element.]]></short-description>
+        <description>
+          <![CDATA[the token to filter as the text of a nested element]]>
+        </description>
+      </element>
+
+      <element name="replacevalue" type="org.apache.tools.ant.taskdefs.Replace.NestedString"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[The string to replace the token as the text of a nested element.]]></short-description>
+        <description>
+          <![CDATA[the string to replace the token as the text of a nested element]]>
+        </description>
+      </element>
+
+      <element name="replacefilter" type="org.apache.tools.ant.taskdefs.Replace.Replacefilter"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a nested &lt;replacefilter&gt; element.]]></short-description>
+        <description>
+          <![CDATA[Add a nested &lt;replacefilter&gt; element.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="replaceregexp" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ReplaceRegExp"
+      >
+
+  <short-description><![CDATA[Performs regular expression string replacements in a text file.]]></short-description>
+  <description>
+    <![CDATA[Performs regular expression string replacements in a text
+ file.  The input file(s) must be able to be properly processed by
+ a Reader instance.  That is, they must be text only, no binary.
+
+ The syntax of the regular expression depends on the implemtation that
+ you choose to use. The system property <code>ant.regexp.regexpimpl</code>
+ will be the classname of the implementation that will be used (the default
+ is <code>org.apache.tools.ant.util.regexp.JakartaOroRegexp</code> and
+ requires the Jakarta Oro Package).
+
+ <pre>
+ For jdk  &lt;= 1.3, there are two available implementations:
+   org.apache.tools.ant.util.regexp.JakartaOroRegexp (the default)
+        Requires  the jakarta-oro package
+
+   org.apache.tools.ant.util.regexp.JakartaRegexpRegexp
+        Requires the jakarta-regexp package
+
+ For jdk &gt;= 1.4 an additional implementation is available:
+   org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp
+        Requires the jdk 1.4 built in regular expression package.
+
+ Usage:
+
+   Call Syntax:
+
+     &lt;replaceregexp file="file"
+                    match="pattern" 
+                    replace="pattern" 
+                    flags="options"?
+                    byline="true|false"? &gt;
+       regexp?
+       substitution?
+       fileset*
+     &lt;/replaceregexp&gt;
+
+    NOTE: You must have either the file attribute specified, or at least one fileset subelement
+    to operation on.  You may not have the file attribute specified if you nest fileset elements
+    inside this task.  Also, you cannot specify both match and a regular expression subelement at
+    the same time, nor can you specify the replace attribute and the substitution subelement at
+    the same time.
+
+   Attributes:
+
+     file    --&gt; A single file to operation on (mutually exclusive with the fileset subelements)
+     match   --&gt; The Regular expression to match 
+     replace --&gt; The Expression replacement string 
+     flags   --&gt; The options to give to the replacement 
+                 g = Substitute all occurrences. default is to replace only the first one
+                 i = Case insensitive match
+
+     byline  --&gt; Should this file be processed a single line at a time (default is false)
+                 "true" indicates to perform replacement on a line by line basis
+                 "false" indicates to perform replacement on the whole file at once.
+
+  Example:
+
+     The following call could be used to replace an old property name in a ".properties"
+     file with a new name.  In the replace attribute, you can refer to any part of the
+     match expression in parenthesis using backslash followed by a number like '\1'.
+
+     &lt;replaceregexp file="test.properties"
+                    match="MyProperty=(.*)"
+                    replace="NewProperty=\1"
+                    byline="true" /&gt;
+
+ </pre>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="byline" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Process the file(s) one line at a time, executing the replacement
+ on one line at a time.]]></short-description>
+        <description><![CDATA[
+          Process the file(s) one line at a time, executing the replacement
+ on one line at a time.  This is useful if you
+ want to only replace the first occurence of a regular expression on
+ each line, which is not easy to do when processing the file as a whole.
+ Defaults to <i>false</i>.</td>
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File for which the regular expression should be replaced;
+ required unless a nested fileset is supplied.]]></short-description>
+        <description><![CDATA[
+          file for which the regular expression should be replaced;
+ required unless a nested fileset is supplied.
+        ]]></description>
+      </attribute>
+      <attribute name="flags" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The flags to use when matching the regular expression.]]></short-description>
+        <description><![CDATA[
+          The flags to use when matching the regular expression.  For more
+ information, consult the Perl5 syntax.
+ <ul>
+  <li>g : Global replacement.  Replace all occurences found
+  <li>i : Case Insensitive.  Do not consider case in the match
+  <li>m : Multiline.  Treat the string as multiple lines of input, 
+         using "^" and "$" as the start or end of any line, respectively, rather than start or end of string.
+  <li> s : Singleline.  Treat the string as a single line of input, using
+        "." to match any character, including a newline, which normally, it would not match.
+</ul>
+        ]]></description>
+      </attribute>
+      <attribute name="match" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The regular expression pattern to match in the file(s);
+ required if no nested &lt;regexp&gt; is used.]]></short-description>
+        <description><![CDATA[
+          the regular expression pattern to match in the file(s);
+ required if no nested &lt;regexp&gt; is used
+        ]]></description>
+      </attribute>
+      <attribute name="replace" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The substitution pattern to place in the file(s) in place
+ of the regular expression.]]></short-description>
+        <description><![CDATA[
+          The substitution pattern to place in the file(s) in place
+ of the regular expression.
+ Required if no nested &lt;substitution&gt; is used
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[List files to apply the replacement to.]]></short-description>
+        <description>
+          <![CDATA[list files to apply the replacement to]]>
+        </description>
+      </element>
+
+      <element name="regexp" type="org.apache.tools.ant.types.RegularExpression"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[A regular expression.]]></short-description>
+        <description>
+          <![CDATA[A regular expression.
+ You can use this element to refer to a previously
+ defined regular expression datatype instance]]>
+        </description>
+      </element>
+
+      <element name="substitution" type="org.apache.tools.ant.types.Substitution"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[A substitution pattern.]]></short-description>
+        <description>
+          <![CDATA[A substitution pattern.  You can use this element to refer to a previously
+ defined substitution pattern datatype instance.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="rmic" category="java"
+      classname="org.apache.tools.ant.taskdefs.Rmic"
+      matchingTask="true">
+
+  <short-description><![CDATA[Runs the rmic compiler against classes.</p> <p>Rmic can be run on a single class (as specified with the classname attribute) or a number of classes at once (all classes below base that are neither _Stub nor _Skel classes).]]></short-description>
+  <description>
+    <![CDATA[Runs the rmic compiler against classes.</p>
+ <p>Rmic can be run on a single class (as specified with the classname
+ attribute) or a number of classes at once (all classes below base that
+ are neither _Stub nor _Skel classes).  If you want to rmic a single
+ class and this class is a class nested into another class, you have to
+ specify the classname in the form <code>Outer$$Inner</code> instead of
+ <code>Outer.Inner</code>.</p>
+ <p>It is possible to refine the set of files that are being rmiced. This can be
+ done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, 
+ <i>excludesfile</i> and <i>defaultexcludes</i>
+ attributes. With the <i>includes</i> or <i>includesfile</i> attribute you specify the files you want to
+ have included by using patterns. The <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
+ the files you want to have excluded. This is also done with patterns. And
+ finally with the <i>defaultexcludes</i> attribute, you can specify whether you
+ want to use default exclusions or not. See the section on 
+ directory based tasks</a>, on how the
+ inclusion/exclusion of files works, and how to write patterns.</p>
+ <p>This task forms an implicit FileSet and
+ supports all attributes of <code>&lt;fileset&gt;</code>
+ (<code>dir</code> becomes <code>base</code>) as well as the nested
+ <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+ <code>&lt;patternset&gt;</code> elements.</p>
+ <p>It is possible to use different compilers. This can be selected
+ with the &quot;build.rmic&quot; property or the <code>compiler</code>
+ attribute. <a name="compilervalues">There are three choices</a>:</p>
+ <ul>
+   <li>sun (the standard compiler of the JDK)</li>
+   <li>kaffe (the standard compiler of 
+       {@link <a href="http://www.kaffe.org">Kaffe</a>})</li>
+   <li>weblogic</li>
+ </ul>
+ <p> The <a href="http://dione.zcu.cz/~toman40/miniRMI/">miniRMI</a>
+ project contains a compiler implementation for this task as well,
+ please consult miniRMI's documentation to learn how to use it.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="base" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Location to store the compiled files; required.]]></short-description>
+        <description><![CDATA[
+          Sets the location to store the compiled files; required
+        ]]></description>
+      </attribute>
+      <attribute name="classname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The class to run <code>rmic</code> against;
+ optional.]]></short-description>
+        <description><![CDATA[
+          Sets the the class to run <code>rmic</code> against;
+ optional
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for this compilation.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used for this compilation.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Adds to the classpath a reference to 
+ a &lt;path&gt; defined elsewhere.]]></short-description>
+        <description><![CDATA[
+          Adds to the classpath a reference to 
+ a &lt;path&gt; defined elsewhere.
+        ]]></description>
+      </attribute>
+      <attribute name="compiler" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Compiler implementation to use; optional,
+ defaults to the value of the <code>build.rmic</code> property,
+ or failing that, default compiler for the current VM.]]></short-description>
+        <description><![CDATA[
+          Sets the compiler implementation to use; optional,
+ defaults to the value of the <code>build.rmic</code> property,
+ or failing that, default compiler for the current VM
+        ]]></description>
+      </attribute>
+      <attribute name="debug" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Generate debug info (passes -g to rmic);
+ optional, defaults to false.]]></short-description>
+        <description><![CDATA[
+          generate debug info (passes -g to rmic);
+ optional, defaults to false
+        ]]></description>
+      </attribute>
+      <attribute name="extdirs" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Extension directories that will be used during the
+ compilation; optional.]]></short-description>
+        <description><![CDATA[
+          Sets the extension directories that will be used during the
+ compilation; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="filtering" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates whether token filtering should take place;
+ optional, default=false.]]></short-description>
+        <description><![CDATA[
+          indicates whether token filtering should take place;
+ optional, default=false
+        ]]></description>
+      </attribute>
+      <attribute name="idl" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates that IDL output should be 
+ generated.]]></short-description>
+        <description><![CDATA[
+          Indicates that IDL output should be 
+ generated.  This defaults to false 
+ if not set.
+        ]]></description>
+      </attribute>
+      <attribute name="idlopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Pass additional arguments for idl compile.]]></short-description>
+        <description><![CDATA[
+          pass additional arguments for idl compile
+        ]]></description>
+      </attribute>
+      <attribute name="iiop" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Indicates that IIOP compatible stubs should
+ be generated; optional, defaults to false 
+ if not set.]]></short-description>
+        <description><![CDATA[
+          Indicates that IIOP compatible stubs should
+ be generated; optional, defaults to false 
+ if not set.
+        ]]></description>
+      </attribute>
+      <attribute name="iiopopts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set additional arguments for iiop.]]></short-description>
+        <description><![CDATA[
+          Set additional arguments for iiop
+        ]]></description>
+      </attribute>
+      <attribute name="includeantruntime" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether or not to include ant's own classpath in this task's 
+ classpath.]]></short-description>
+        <description><![CDATA[
+          Sets whether or not to include ant's own classpath in this task's 
+ classpath.
+ Optional; default is <code>true</code>.
+        ]]></description>
+      </attribute>
+      <attribute name="includejavaruntime" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Task's classpath.]]></short-description>
+        <description><![CDATA[
+          task's classpath.
+ Enables or disables including the default run-time
+ libraries from the executing VM; optional,
+ defaults to false
+        ]]></description>
+      </attribute>
+      <attribute name="sourcebase" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Optional directory to save generated source files to.]]></short-description>
+        <description><![CDATA[
+          optional directory to save generated source files to.
+        ]]></description>
+      </attribute>
+      <attribute name="stubversion" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specify the JDK version for the generated stub code.]]></short-description>
+        <description><![CDATA[
+          Specify the JDK version for the generated stub code.
+ Specify &quot;1.1&quot; to pass the &quot;-v1.1&quot; option to rmic.</td>
+        ]]></description>
+      </attribute>
+      <attribute name="verify" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to enable verification so that the classes 
+ found by the directory match are
+ checked to see if they implement java.rmi.Remote.]]></short-description>
+        <description><![CDATA[
+          Flag to enable verification so that the classes 
+ found by the directory match are
+ checked to see if they implement java.rmi.Remote.
+ Optional; his defaults to false if not set.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Creates a nested classpath element.]]></short-description>
+        <description>
+          <![CDATA[Creates a nested classpath element.]]>
+        </description>
+      </element>
+
+      <element name="compilerarg" type="org.apache.tools.ant.taskdefs.Rmic.ImplementationSpecificArgument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds an implementation specific command line argument.]]></short-description>
+        <description>
+          <![CDATA[Adds an implementation specific command line argument.]]>
+        </description>
+      </element>
+
+      <element name="extdirs" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Maybe creates a nested extdirs element.]]></short-description>
+        <description>
+          <![CDATA[Maybe creates a nested extdirs element.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="rpm" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.Rpm"
+      >
+
+  <short-description><![CDATA[Invokes the rpm tool to build a Linux installation file.]]></short-description>
+  <description>
+    <![CDATA[Invokes the rpm tool to build a Linux installation file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="cleanbuilddir" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag (optional, default=false) to remove 
+ the generated files in the BUILD directory.]]></short-description>
+        <description><![CDATA[
+          Flag (optional, default=false) to remove 
+ the generated files in the BUILD directory
+        ]]></description>
+      </attribute>
+      <attribute name="command" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[What command to issue to the rpm tool; optional.]]></short-description>
+        <description><![CDATA[
+          What command to issue to the rpm tool; optional.
+ The default is "-bb"
+        ]]></description>
+      </attribute>
+      <attribute name="error" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Optional file to save stderr to.]]></short-description>
+        <description><![CDATA[
+          Optional file to save stderr to
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Optional file to save stdout to.]]></short-description>
+        <description><![CDATA[
+          Optional file to save stdout to.
+        ]]></description>
+      </attribute>
+      <attribute name="removesource" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag (optional, default=false) 
+ to remove the sources after the build.]]></short-description>
+        <description><![CDATA[
+          Flag (optional, default=false) 
+ to remove the sources after the build.
+ See the the <tt>--rmsource</tt>  option of rpmbuild.
+        ]]></description>
+      </attribute>
+      <attribute name="removespec" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag (optional, default=false) to remove the spec file from SPECS.]]></short-description>
+        <description><![CDATA[
+          Flag (optional, default=false) to remove the spec file from SPECS
+        ]]></description>
+      </attribute>
+      <attribute name="specfile" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the spec File to use; required.]]></short-description>
+        <description><![CDATA[
+          The name of the spec File to use; required.
+        ]]></description>
+      </attribute>
+      <attribute name="topdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory which will have the expected
+ subdirectories, SPECS, SOURCES, BUILD, SRPMS ; optional.]]></short-description>
+        <description><![CDATA[
+          The directory which will have the expected
+ subdirectories, SPECS, SOURCES, BUILD, SRPMS ; optional. 
+ If this isn't specified,
+ the <tt>baseDir</tt> value is used
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="script" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.Script"
+      >
+
+  <short-description><![CDATA[Executes a script.]]></short-description>
+  <description>
+    <![CDATA[Executes a script.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="language" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Defines the language (required).]]></short-description>
+        <description><![CDATA[
+          Defines the language (required).
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Load the script from an external file ; optional.]]></short-description>
+        <description><![CDATA[
+          Load the script from an external file ; optional.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+      <body >
+        <description><![CDATA[
+          The script text.
+        ]]></description>
+      </body>
+
+  </structure>
+
+</task>
+
+
+<task name="sequential" category="control"
+      classname="org.apache.tools.ant.taskdefs.Sequential"
+      >
+
+  <short-description><![CDATA[Sequential is a container task - it can contain other Ant tasks.]]></short-description>
+  <description>
+    <![CDATA[Sequential is a container task - it can contain other Ant tasks. The nested 
+ tasks are simply executed in sequence. Sequential's primary use is to support 
+ the sequential execution of a subset of tasks within the
+{@link Parallel Parallel Task} 
+
+ <p>
+ The sequential task has no attributes and does not support any nested 
+ elements apart from Ant tasks. Any valid Ant task may be embedded within the 
+ sequential task.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="serverdeploy" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.j2ee.ServerDeploy"
+      >
+
+  <short-description><![CDATA[Controls hot deployment tools for J2EE servers.]]></short-description>
+  <description>
+    <![CDATA[Controls hot deployment tools for J2EE servers.
+
+  This class is used as a framework for the creation of vendor specific
+  hot deployment tools.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="action" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The action to be performed, usually "deploy"; required.]]></short-description>
+        <description><![CDATA[
+          The action to be performed, usually "deploy"; required.
+   Some tools support additional actions, such as "delete", "list", "undeploy", "update"...
+        ]]></description>
+      </attribute>
+      <attribute name="source" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The filename of the component to be deployed; optional
+  depending upon the tool and the action.]]></short-description>
+        <description><![CDATA[
+          The filename of the component to be deployed; optional
+  depending upon the tool and the action.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="generic" type="org.apache.tools.ant.taskdefs.optional.j2ee.GenericHotDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Creates a generic deployment tool.]]></short-description>
+        <description>
+          <![CDATA[Creates a generic deployment tool.
+  <p>Ant calls this method on creation to handle embedded "generic" elements
+  in the ServerDeploy task.]]>
+        </description>
+      </element>
+
+      <element name="jonas" type="org.apache.tools.ant.taskdefs.optional.j2ee.JonasHotDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Creates a JOnAS deployment tool, for deployment to JOnAS servers.]]></short-description>
+        <description>
+          <![CDATA[Creates a JOnAS deployment tool, for deployment to JOnAS servers.
+  <p>Ant calls this method on creation to handle embedded "jonas" elements
+  in the ServerDeploy task.]]>
+        </description>
+      </element>
+
+      <element name="weblogic" type="org.apache.tools.ant.taskdefs.optional.j2ee.WebLogicHotDeploymentTool"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Creates a WebLogic deployment tool, for deployment to WebLogic servers.]]></short-description>
+        <description>
+          <![CDATA[Creates a WebLogic deployment tool, for deployment to WebLogic servers.
+  <p>Ant calls this method on creation to handle embedded "weblogic" elements
+  in the ServerDeploy task.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="setproxy" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.net.SetProxy"
+      >
+
+  <short-description><![CDATA[Sets Java's web proxy properties, so that tasks and code run in the same JVM can have through-the-firewall access to remote web sites, and remote ftp sites.]]></short-description>
+  <description>
+    <![CDATA[Sets Java's web proxy properties, so that tasks and code run in
+ the same JVM can have through-the-firewall access to remote web sites,
+ and remote ftp sites.
+ You can nominate an http and ftp proxy, or a socks server, reset the server 
+ settings, or do nothing at all.
+ <p> 
+ Examples
+ <pre>&lt;setproxy/&gt;</pre>
+ do nothing
+ <pre>&lt;setproxy proxyhost="firewall"/&gt;</pre>
+ set the proxy to firewall:80
+ <pre>&lt;setproxy proxyhost="firewall" proxyport="81"/&gt;</pre>
+ set the proxy to firewall:81
+ <pre>&lt;setproxy proxyhost=""/&gt;</pre>
+ stop using the http proxy; don't change the socks settings
+ <pre>&lt;setproxy socksproxyhost="socksy"/&gt;</pre>
+ use socks via socksy:1080
+ <pre>&lt;setproxy socksproxyhost=""/&gt;</pre>
+ stop using the socks server]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="nonproxyhosts" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[A list of hosts to bypass the proxy on.]]></short-description>
+        <description><![CDATA[
+          A list of hosts to bypass the proxy on. These should be separated
+ with the vertical bar character '|'. Only in Java 1.4 does ftp use
+ this list.
+ e.g. fozbot.corp.sun.com|*.eng.sun.com
+        ]]></description>
+      </attribute>
+      <attribute name="proxyhost" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The HTTP/ftp proxy host.]]></short-description>
+        <description><![CDATA[
+          the HTTP/ftp proxy host. Set this to "" for the http proxy
+ option to be disabled
+        ]]></description>
+      </attribute>
+      <attribute name="proxyport" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[The HTTP/ftp proxy port number; default is 80.]]></short-description>
+        <description><![CDATA[
+          the HTTP/ftp proxy port number; default is 80
+        ]]></description>
+      </attribute>
+      <attribute name="socksproxyhost" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of a Socks server.]]></short-description>
+        <description><![CDATA[
+          The name of a Socks server. Set to "" to turn socks
+ proxying off.
+        ]]></description>
+      </attribute>
+      <attribute name="socksproxyport" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[ProxyPort for socks connections.]]></short-description>
+        <description><![CDATA[
+          Set the ProxyPort for socks connections. The default value is 1080
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="signjar" category="java"
+      classname="org.apache.tools.ant.taskdefs.SignJar"
+      >
+
+  <short-description><![CDATA[Signs jar or zip files with the javasign command line tool.]]></short-description>
+  <description>
+    <![CDATA[Signs jar or zip files with the javasign command line tool. The
+ tool detailed dependency checking: files are only signed if they
+ are not signed. The <tt>signjar</tt> attribute can point to the file to
+ generate; if this file exists then
+ its modification date is used as a cue as to whether to resign any JAR file.
+ <br>  
+ <strong>Note:</strong> Requires Java 1.2 or later. </p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="alias" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The alias to sign under; required.]]></short-description>
+        <description><![CDATA[
+          the alias to sign under; required
+        ]]></description>
+      </attribute>
+      <attribute name="internalsf" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to include the .SF file inside the signature;
+ optional; default false.]]></short-description>
+        <description><![CDATA[
+          Flag to include the .SF file inside the signature;
+ optional; default false
+        ]]></description>
+      </attribute>
+      <attribute name="jar" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The jar file to sign; required.]]></short-description>
+        <description><![CDATA[
+          the jar file to sign; required
+        ]]></description>
+      </attribute>
+      <attribute name="keypass" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Password for private key (if different); optional.]]></short-description>
+        <description><![CDATA[
+          password for private key (if different); optional
+        ]]></description>
+      </attribute>
+      <attribute name="keystore" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Keystore location; required.]]></short-description>
+        <description><![CDATA[
+          keystore location; required
+        ]]></description>
+      </attribute>
+      <attribute name="lazy" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to control whether the presence of a signature
+ file means a JAR is signed;
+ optional, default false.]]></short-description>
+        <description><![CDATA[
+          flag to control whether the presence of a signature
+ file means a JAR is signed;
+ optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="sectionsonly" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to compute hash of entire manifest;
+ optional, default false.]]></short-description>
+        <description><![CDATA[
+          flag to compute hash of entire manifest;
+ optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="sigfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of .SF/.DSA file; optional.]]></short-description>
+        <description><![CDATA[
+          name of .SF/.DSA file; optional
+        ]]></description>
+      </attribute>
+      <attribute name="signedjar" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of signed JAR file; optional.]]></short-description>
+        <description><![CDATA[
+          name of signed JAR file; optional
+        ]]></description>
+      </attribute>
+      <attribute name="storepass" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Password for keystore integrity; required.]]></short-description>
+        <description><![CDATA[
+          password for keystore integrity; required
+        ]]></description>
+      </attribute>
+      <attribute name="storetype" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Keystore type; optional.]]></short-description>
+        <description><![CDATA[
+          keystore type; optional
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Enable verbose output when signing
+ ; optional: default false.]]></short-description>
+        <description><![CDATA[
+          Enable verbose output when signing
+ ; optional: default false
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files to sign.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files to sign]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="sleep" category="utility"
+      classname="org.apache.tools.ant.taskdefs.Sleep"
+      >
+
+  <short-description><![CDATA[Sleep, or pause, for a period of time.]]></short-description>
+  <description>
+    <![CDATA[Sleep, or pause, for a period of time.
+
+ A task for sleeping a short period of time, useful when a
+ build or deployment process requires an interval between tasks.
+<p>
+ A negative value can be supplied to any of attributes provided the total sleep time 
+ is positive, pending fundamental changes in physics and JVM
+ execution tims</p>
+ Note that sleep times are always hints to be interpred by the OS how it feels 
+ small times may either be ignored or rounded up to a minimum timeslice. Note 
+ also that the system clocks often have a fairly low granularity too, which complicates 
+ measuring how long a sleep actually took.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag controlling whether to break the build on an error.]]></short-description>
+        <description><![CDATA[
+          flag controlling whether to break the build on an error.
+        ]]></description>
+      </attribute>
+      <attribute name="hours" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Hours to add to the sleep time.]]></short-description>
+        <description><![CDATA[
+          hours to add to the sleep time.
+        ]]></description>
+      </attribute>
+      <attribute name="milliseconds" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Milliseconds to add to the sleep time.]]></short-description>
+        <description><![CDATA[
+          milliseconds to add to the sleep time
+        ]]></description>
+      </attribute>
+      <attribute name="minutes" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Minutes to add to the sleep time.]]></short-description>
+        <description><![CDATA[
+          minutes to add to the sleep time
+        ]]></description>
+      </attribute>
+      <attribute name="seconds" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Seconds to add to the sleep time.]]></short-description>
+        <description><![CDATA[
+          seconds to add to the sleep time
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="soscheckin" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.sos.SOSCheckin"
+      >
+
+  <short-description><![CDATA[Commits and unlocks files in Visual SourceSafe via a SourceOffSite server.]]></short-description>
+  <description>
+    <![CDATA[Commits and unlocks files in Visual SourceSafe via a SourceOffSite server.
+
+ <p>
+ The following attributes are interpretted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+     <td>soscmddir</td>
+     <td>Directory which contains soscmd(.exe) <br>
+     soscmd(.exe) must be in the path if this is not specified</td>
+     <td>No</td>
+   </tr>
+   <tr>
+      <td>vssserverpath</td>
+      <td>path to the srcsafe.ini  - eg. \\server\vss\srcsafe.ini</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>sosserverpath</td>
+      <td>address and port of the SOS server  - eg. 192.168.0.1:8888</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>projectpath</td>
+      <td>SourceSafe project path without the "$"</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>file</td>
+      <td>Filename to act upon<br> If no file is specified then act upon the project</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>username</td>
+      <td>SourceSafe username</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>password</td>
+      <td>SourceSafe password</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>localpath</td>
+      <td>Override the working directory and get to the specified path</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>soshome</td>
+      <td>The path to the SourceOffSite home directory</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>nocompression</td>
+      <td>true or false - disable compression</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>recursive</td>
+      <td>true or false - Only works with the CheckOutProject command</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>nocache</td>
+      <td>true or false - Only needed if SOSHOME is set as an enviroment variable</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>verbose</td>
+      <td>true or false - Status messages are displayed</td>
+      <td>No</td>
+   </tr>
+   <td>comment</td>
+      <td>A comment to be applied to all files being checked in</td>
+      <td>No</td>
+   </tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Comment to apply to all files being labelled;
+ optional, only valid in SOSLabel.]]></short-description>
+        <description><![CDATA[
+          Set the comment to apply to all files being labelled;
+ optional, only valid in SOSLabel
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Filename to act upon; optional.]]></short-description>
+        <description><![CDATA[
+          Set the Filename to act upon; optional.
+ If no file is specified then the tasks 
+ act upon the project
+        ]]></description>
+      </attribute>
+      <attribute name="label" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Labeled version to operate on in SourceSafe.]]></short-description>
+        <description><![CDATA[
+          Set the labeled version to operate on in SourceSafe
+        ]]></description>
+      </attribute>
+      <attribute name="localpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Override the working directory and get to the specified path; optional.]]></short-description>
+        <description><![CDATA[
+          Override the working directory and get to the specified path; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="nocache" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to disable the cache when set;
+ optional needed if SOSHOME is set as an environment variable.]]></short-description>
+        <description><![CDATA[
+          flag to disable the cache when set;
+ optional needed if SOSHOME is set as an environment variable.
+        ]]></description>
+      </attribute>
+      <attribute name="nocompress" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag that disables compression when set; optional, default.]]></short-description>
+        <description><![CDATA[
+          Flag that disables compression when set; optional, default
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe password; optional.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe password; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="projectpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe project path without the "$" prefix; required.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe project path without the "$" prefix; required
+        ]]></description>
+      </attribute>
+      <attribute name="recursive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to recursively apply the action (not valid
+ on all SOS tasks ); optional, default false.]]></short-description>
+        <description><![CDATA[
+          Flag to recursively apply the action (not valid
+ on all SOS tasks ); optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="soscmd" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where soscmd(.exe) is located;
+ optional, soscmd must be on the path if omitted.]]></short-description>
+        <description><![CDATA[
+          Set the directory where soscmd(.exe) is located;
+ optional, soscmd must be on the path if omitted.
+        ]]></description>
+      </attribute>
+      <attribute name="soshome" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The path to the SourceOffSite home directory.]]></short-description>
+        <description><![CDATA[
+          The path to the SourceOffSite home directory
+        ]]></description>
+      </attribute>
+      <attribute name="sosserverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Address and port of SourceOffSite Server,
+ eg. 192.168.0.1:8888 ; required.]]></short-description>
+        <description><![CDATA[
+          Set the address and port of SourceOffSite Server,
+ eg. 192.168.0.1:8888 ; required.
+        ]]></description>
+      </attribute>
+      <attribute name="username" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe username; required.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe username; required.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Enable verbose output; optional, default false.]]></short-description>
+        <description><![CDATA[
+          Enable verbose output; optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[A version number to get - 
+ only works with the SOSGet on a file; optional.]]></short-description>
+        <description><![CDATA[
+          Set the a version number to get - 
+ only works with the SOSGet on a file; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="vssserverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the location of the ss.ini file; 
+ required.]]></short-description>
+        <description><![CDATA[
+          Set the path to the location of the ss.ini file; 
+ required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="soscheckout" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.sos.SOSCheckout"
+      >
+
+  <short-description><![CDATA[Retrieves and locks files in Visual SourceSafe via a SourceOffSite server.]]></short-description>
+  <description>
+    <![CDATA[Retrieves and locks files in Visual SourceSafe via a SourceOffSite server.
+
+ <p>
+ The following attributes are interpretted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+     <td>soscmddir</td>
+     <td>Directory which contains soscmd(.exe) <br>
+     soscmd(.exe) must be in the path if this is not specified</td>
+     <td>No</td>
+   </tr>
+   <tr>
+      <td>vssserverpath</td>
+      <td>path to the srcsafe.ini  - eg. \\server\vss\srcsafe.ini</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>sosserverpath</td>
+      <td>address and port of the SOS server  - eg. 192.168.0.1:8888</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>projectpath</td>
+      <td>SourceSafe project path without the "$"</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>file</td>
+      <td>Filename to act upon<br> If no file is specified then act upon the project</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>username</td>
+      <td>SourceSafe username</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>password</td>
+      <td>SourceSafe password</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>localpath</td>
+      <td>Override the working directory and get to the specified path</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>soshome</td>
+      <td>The path to the SourceOffSite home directory</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>nocompression</td>
+      <td>true or false - disable compression</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>recursive</td>
+      <td>true or false - Only works with the CheckOutProject command</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>nocache</td>
+      <td>true or false - Only needed if SOSHOME is set as an enviroment variable</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>verbose</td>
+      <td>true or false - Status messages are displayed</td>
+      <td>No</td>
+   </tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Comment to apply to all files being labelled;
+ optional, only valid in SOSLabel.]]></short-description>
+        <description><![CDATA[
+          Set the comment to apply to all files being labelled;
+ optional, only valid in SOSLabel
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Filename to act upon; optional.]]></short-description>
+        <description><![CDATA[
+          Set the Filename to act upon; optional.
+ If no file is specified then the tasks 
+ act upon the project
+        ]]></description>
+      </attribute>
+      <attribute name="label" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Labeled version to operate on in SourceSafe.]]></short-description>
+        <description><![CDATA[
+          Set the labeled version to operate on in SourceSafe
+        ]]></description>
+      </attribute>
+      <attribute name="localpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Override the working directory and get to the specified path; optional.]]></short-description>
+        <description><![CDATA[
+          Override the working directory and get to the specified path; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="nocache" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to disable the cache when set;
+ optional needed if SOSHOME is set as an environment variable.]]></short-description>
+        <description><![CDATA[
+          flag to disable the cache when set;
+ optional needed if SOSHOME is set as an environment variable.
+        ]]></description>
+      </attribute>
+      <attribute name="nocompress" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag that disables compression when set; optional, default.]]></short-description>
+        <description><![CDATA[
+          Flag that disables compression when set; optional, default
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe password; optional.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe password; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="projectpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe project path without the "$" prefix; required.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe project path without the "$" prefix; required
+        ]]></description>
+      </attribute>
+      <attribute name="recursive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to recursively apply the action (not valid
+ on all SOS tasks ); optional, default false.]]></short-description>
+        <description><![CDATA[
+          Flag to recursively apply the action (not valid
+ on all SOS tasks ); optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="soscmd" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where soscmd(.exe) is located;
+ optional, soscmd must be on the path if omitted.]]></short-description>
+        <description><![CDATA[
+          Set the directory where soscmd(.exe) is located;
+ optional, soscmd must be on the path if omitted.
+        ]]></description>
+      </attribute>
+      <attribute name="soshome" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The path to the SourceOffSite home directory.]]></short-description>
+        <description><![CDATA[
+          The path to the SourceOffSite home directory
+        ]]></description>
+      </attribute>
+      <attribute name="sosserverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Address and port of SourceOffSite Server,
+ eg. 192.168.0.1:8888 ; required.]]></short-description>
+        <description><![CDATA[
+          Set the address and port of SourceOffSite Server,
+ eg. 192.168.0.1:8888 ; required.
+        ]]></description>
+      </attribute>
+      <attribute name="username" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe username; required.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe username; required.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Enable verbose output; optional, default false.]]></short-description>
+        <description><![CDATA[
+          Enable verbose output; optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[A version number to get - 
+ only works with the SOSGet on a file; optional.]]></short-description>
+        <description><![CDATA[
+          Set the a version number to get - 
+ only works with the SOSGet on a file; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="vssserverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the location of the ss.ini file; 
+ required.]]></short-description>
+        <description><![CDATA[
+          Set the path to the location of the ss.ini file; 
+ required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="sosget" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.sos.SOSGet"
+      >
+
+  <short-description><![CDATA[Retrieves a read-only copy of the specified project or file from Visual SourceSafe via a SourceOffSite server.]]></short-description>
+  <description>
+    <![CDATA[Retrieves a read-only copy of the specified project or file
+ from Visual SourceSafe via a SourceOffSite server.
+ <p>
+ The following attributes are interpretted:
+ <table border="1">
+    <tbody>
+      <tr>
+         <th>Attribute</th>
+         <th>Values</th>
+         <th>Required</th>
+       </tr>
+       <tr>
+         <td>soscmddir</td>
+         <td>Directory which contains soscmd(.exe) <br>
+         soscmd(.exe) must be in the path if this is not specified</td>
+         <td>No</td>
+       </tr>
+       <tr>
+          <td>vssserverpath</td>
+          <td>path to the srcsafe.ini  - eg. \\server\vss\srcsafe.ini</td>
+          <td>Yes</td>
+       </tr>
+       <tr>
+          <td>sosserverpath</td>
+          <td>address and port of the SOS server  - eg. 192.168.0.1:8888</td>
+          <td>Yes</td>
+       </tr>
+       <tr>
+          <td>projectpath</td>
+          <td>SourceSafe project path without the "$"</td>
+          <td>Yes</td>
+       </tr>
+       <tr>
+          <td>file</td>
+          <td>Filename to act upon<br>
+              If no file is specified then act upon the project</td>
+          <td>No</td>
+       </tr>
+       <tr>
+          <td>username</td>
+          <td>SourceSafe username</td>
+          <td>Yes</td>
+       </tr>
+       <tr>
+          <td>password</td>
+          <td>SourceSafe password</td>
+          <td>No</td>
+       </tr>
+       <tr>
+          <td>localpath</td>
+          <td>Override the working directory and get to the specified path</td>
+          <td>No</td>
+       </tr>
+       <tr>
+          <td>soshome</td>
+          <td>The path to the SourceOffSite home directory</td>
+          <td>No</td>
+       </tr>
+       <tr>
+          <td>nocompression</td>
+          <td>true or false - disable compression</td>
+          <td>No</td>
+       </tr>
+       <tr>
+          <td>recursive</td>
+          <td>true or false - Only works with the GetProject command</td>
+          <td>No</td>
+       </tr>
+       <tr>
+          <td>version</td>
+          <td>a version number to get - Only works with the GetFile command</td>
+          <td>No</td>
+       </tr>
+       <tr>
+          <td>label</td>
+          <td>a label version to get - Only works with the GetProject command</td>
+          <td>No</td>
+       </tr>
+       <tr>
+          <td>nocache</td>
+          <td>true or false - Only needed if SOSHOME is set as an enviroment variable</td>
+          <td>No</td>
+       </tr>
+       <tr>
+          <td>verbose</td>
+         <td>true or false - Status messages are displayed</td>
+        <td>No</td>
+      </tr>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Comment to apply to all files being labelled;
+ optional, only valid in SOSLabel.]]></short-description>
+        <description><![CDATA[
+          Set the comment to apply to all files being labelled;
+ optional, only valid in SOSLabel
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Filename to act upon; optional.]]></short-description>
+        <description><![CDATA[
+          Set the Filename to act upon; optional.
+ If no file is specified then the tasks 
+ act upon the project
+        ]]></description>
+      </attribute>
+      <attribute name="label" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Labeled version to operate on in SourceSafe.]]></short-description>
+        <description><![CDATA[
+          Set the labeled version to operate on in SourceSafe
+        ]]></description>
+      </attribute>
+      <attribute name="localpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Override the working directory and get to the specified path; optional.]]></short-description>
+        <description><![CDATA[
+          Override the working directory and get to the specified path; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="nocache" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to disable the cache when set;
+ optional needed if SOSHOME is set as an environment variable.]]></short-description>
+        <description><![CDATA[
+          flag to disable the cache when set;
+ optional needed if SOSHOME is set as an environment variable.
+        ]]></description>
+      </attribute>
+      <attribute name="nocompress" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag that disables compression when set; optional, default.]]></short-description>
+        <description><![CDATA[
+          Flag that disables compression when set; optional, default
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe password; optional.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe password; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="projectpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe project path without the "$" prefix; required.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe project path without the "$" prefix; required
+        ]]></description>
+      </attribute>
+      <attribute name="recursive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to recursively apply the action (not valid
+ on all SOS tasks ); optional, default false.]]></short-description>
+        <description><![CDATA[
+          Flag to recursively apply the action (not valid
+ on all SOS tasks ); optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="soscmd" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where soscmd(.exe) is located;
+ optional, soscmd must be on the path if omitted.]]></short-description>
+        <description><![CDATA[
+          Set the directory where soscmd(.exe) is located;
+ optional, soscmd must be on the path if omitted.
+        ]]></description>
+      </attribute>
+      <attribute name="soshome" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The path to the SourceOffSite home directory.]]></short-description>
+        <description><![CDATA[
+          The path to the SourceOffSite home directory
+        ]]></description>
+      </attribute>
+      <attribute name="sosserverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Address and port of SourceOffSite Server,
+ eg. 192.168.0.1:8888 ; required.]]></short-description>
+        <description><![CDATA[
+          Set the address and port of SourceOffSite Server,
+ eg. 192.168.0.1:8888 ; required.
+        ]]></description>
+      </attribute>
+      <attribute name="username" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe username; required.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe username; required.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Enable verbose output; optional, default false.]]></short-description>
+        <description><![CDATA[
+          Enable verbose output; optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[A version number to get - 
+ only works with the SOSGet on a file; optional.]]></short-description>
+        <description><![CDATA[
+          Set the a version number to get - 
+ only works with the SOSGet on a file; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="vssserverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the location of the ss.ini file; 
+ required.]]></short-description>
+        <description><![CDATA[
+          Set the path to the location of the ss.ini file; 
+ required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="soslabel" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.sos.SOSLabel"
+      >
+
+  <short-description><![CDATA[Labels Visual SourceSafe files via a SourceOffSite server.]]></short-description>
+  <description>
+    <![CDATA[Labels Visual SourceSafe files via a SourceOffSite server.
+ <p>
+ The following attributes are interpreted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+     <td>soscmddir</td>
+     <td>Directory which contains soscmd(.exe) <br>
+     soscmd(.exe) must be in the path if this is not specified</td>
+     <td>No</td>
+   </tr>
+   <tr>
+      <td>vssserverpath</td>
+      <td>path to the srcsafe.ini  - eg. \\server\vss\srcsafe.ini</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>sosserverpath</td>
+      <td>address and port of the SOS server  - eg. 192.168.0.1:8888</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>projectpath</td>
+      <td>SourceSafe project path without the "$"</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>username</td>
+      <td>SourceSafe username</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>password</td>
+      <td>SourceSafe password</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>label</td>
+      <td>The label to apply to a project</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>comment</td>
+      <td>A comment to be applied to all files being labeled</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>verbose</td>
+      <td>true or false - Status messages are displayed</td>
+      <td>No</td>
+   </tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Comment to apply to all files being labelled;
+ optional, only valid in SOSLabel.]]></short-description>
+        <description><![CDATA[
+          Set the comment to apply to all files being labelled;
+ optional, only valid in SOSLabel
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Filename to act upon; optional.]]></short-description>
+        <description><![CDATA[
+          Set the Filename to act upon; optional.
+ If no file is specified then the tasks 
+ act upon the project
+        ]]></description>
+      </attribute>
+      <attribute name="label" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Labeled version to operate on in SourceSafe.]]></short-description>
+        <description><![CDATA[
+          Set the labeled version to operate on in SourceSafe
+        ]]></description>
+      </attribute>
+      <attribute name="localpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Override the working directory and get to the specified path; optional.]]></short-description>
+        <description><![CDATA[
+          Override the working directory and get to the specified path; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="nocache" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to disable the cache when set;
+ optional needed if SOSHOME is set as an environment variable.]]></short-description>
+        <description><![CDATA[
+          flag to disable the cache when set;
+ optional needed if SOSHOME is set as an environment variable.
+        ]]></description>
+      </attribute>
+      <attribute name="nocompress" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag that disables compression when set; optional, default.]]></short-description>
+        <description><![CDATA[
+          Flag that disables compression when set; optional, default
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe password; optional.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe password; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="projectpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe project path without the "$" prefix; required.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe project path without the "$" prefix; required
+        ]]></description>
+      </attribute>
+      <attribute name="recursive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to recursively apply the action (not valid
+ on all SOS tasks ); optional, default false.]]></short-description>
+        <description><![CDATA[
+          Flag to recursively apply the action (not valid
+ on all SOS tasks ); optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="soscmd" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where soscmd(.exe) is located;
+ optional, soscmd must be on the path if omitted.]]></short-description>
+        <description><![CDATA[
+          Set the directory where soscmd(.exe) is located;
+ optional, soscmd must be on the path if omitted.
+        ]]></description>
+      </attribute>
+      <attribute name="soshome" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The path to the SourceOffSite home directory.]]></short-description>
+        <description><![CDATA[
+          The path to the SourceOffSite home directory
+        ]]></description>
+      </attribute>
+      <attribute name="sosserverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Address and port of SourceOffSite Server,
+ eg. 192.168.0.1:8888 ; required.]]></short-description>
+        <description><![CDATA[
+          Set the address and port of SourceOffSite Server,
+ eg. 192.168.0.1:8888 ; required.
+        ]]></description>
+      </attribute>
+      <attribute name="username" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe username; required.]]></short-description>
+        <description><![CDATA[
+          Set the SourceSafe username; required.
+        ]]></description>
+      </attribute>
+      <attribute name="verbose" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Enable verbose output; optional, default false.]]></short-description>
+        <description><![CDATA[
+          Enable verbose output; optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[A version number to get - 
+ only works with the SOSGet on a file; optional.]]></short-description>
+        <description><![CDATA[
+          Set the a version number to get - 
+ only works with the SOSGet on a file; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="vssserverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Path to the location of the ss.ini file; 
+ required.]]></short-description>
+        <description><![CDATA[
+          Set the path to the location of the ss.ini file; 
+ required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="sound" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.sound.SoundTask"
+      >
+
+  <short-description><![CDATA[Plays a sound file at the end of the build, according to whether the build failed or succeeded.]]></short-description>
+  <description>
+    <![CDATA[Plays a sound file at the end of the build, according to whether the build failed or succeeded.
+
+ There are three attributes to be set:
+
+ <code>source</code>: the location of the audio file to be played
+ <code>duration</code>: play the sound file continuously until "duration" milliseconds has expired
+ <code>loops</code>: the number of times the sound file should be played until stopped
+
+ I have only tested this with .WAV and .AIFF sound file formats. Both seem
+ to work fine.
+
+ plans for the future:
+ - use the midi api to define sounds (or drum beat etc) in xml and have
+   Ant play them back]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+    </attributes>
+
+    <elements>
+      <element name="fail" type="org.apache.tools.ant.taskdefs.optional.sound.SoundTask.BuildAlert"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a sound when the build fails.]]></short-description>
+        <description>
+          <![CDATA[add a sound when the build fails]]>
+        </description>
+      </element>
+
+      <element name="success" type="org.apache.tools.ant.taskdefs.optional.sound.SoundTask.BuildAlert"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a sound when the build succeeds.]]></short-description>
+        <description>
+          <![CDATA[add a sound when the build succeeds]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="splash" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.splash.SplashTask"
+      >
+
+  <short-description><![CDATA[Creates a splash screen.]]></short-description>
+  <description>
+    <![CDATA[Creates a splash screen. The splash screen is displayed
+ for the duration of the build and includes a handy progress bar as
+ well. Use in conjunction with the sound task to provide interest
+ whilst waiting for your builds to complete...]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="imageurl" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[A URL pointing to an image to display; optional, default antlogo.gif
+ from the classpath.]]></short-description>
+        <description><![CDATA[
+          A URL pointing to an image to display; optional, default antlogo.gif
+ from the classpath.
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Proxy password; required if <tt>user</tt> is set.]]></short-description>
+        <description><![CDATA[
+          Proxy password; required if <tt>user</tt> is set.
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Proxy port; optional, default 80.]]></short-description>
+        <description><![CDATA[
+          Proxy port; optional, default 80.
+        ]]></description>
+      </attribute>
+      <attribute name="proxy" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of proxy; optional.]]></short-description>
+        <description><![CDATA[
+          name of proxy; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="showduration" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[How long to show the splash screen in milliseconds,
+ optional; default 5000 ms.]]></short-description>
+        <description><![CDATA[
+          how long to show the splash screen in milliseconds,
+ optional; default 5000 ms.
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Proxy user; optional, default =none.]]></short-description>
+        <description><![CDATA[
+          Proxy user; optional, default =none.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="sql" category="database"
+      classname="org.apache.tools.ant.taskdefs.SQLExec"
+      >
+
+  <short-description><![CDATA[Executes a series of SQL statements on a database using JDBC.]]></short-description>
+  <description>
+    <![CDATA[Executes a series of SQL statements on a database using JDBC.
+
+ <p>Statements can
+ either be read in from a text file using the <i>src</i> attribute or from 
+ between the enclosing SQL tags.</p>
+ <p>Multiple statements can be provided, separated by semicolons (or the 
+ defined <i>delimiter</i>). Individual lines within the statements can be 
+ commented using either --, // or REM at the start of the line.</p>
+ <p>The <i>autocommit</i> attribute specifies whether auto-commit should be 
+ turned on or off whilst executing the statements. If auto-commit is turned 
+ on each statement will be executed and committed. If it is turned off the 
+ statements will all be executed as one transaction.</p>
+ <p>The <i>onerror</i> attribute specifies how to proceed when an error occurs 
+ during the execution of one of the statements. 
+ The possible values are: <b>continue</b> execution, only show the error;
+ <b>stop</b> execution and commit transaction;
+ and <b>abort</b> execution and transaction and fail task.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether output should be appended to or overwrite
+ an existing file.]]></short-description>
+        <description><![CDATA[
+          whether output should be appended to or overwrite
+ an existing file.  Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="autocommit" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Auto commit flag for database connection;
+ optional, default false.]]></short-description>
+        <description><![CDATA[
+          Auto commit flag for database connection;
+ optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="caching" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Caching loaders / driver.]]></short-description>
+        <description><![CDATA[
+          Caching loaders / driver. This is to avoid
+ getting an OutOfMemoryError when calling this task
+ multiple times in a row; default: true
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath for loading the driver.]]></short-description>
+        <description><![CDATA[
+          Sets the classpath for loading the driver.
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath for loading the driver 
+ using the classpath reference.]]></short-description>
+        <description><![CDATA[
+          Set the classpath for loading the driver 
+ using the classpath reference.
+        ]]></description>
+      </attribute>
+      <attribute name="delimiter" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Delimiter that separates SQL statements; 
+ optional, default &quot;;&quot;
+
+ <p>For example, set this to "go" and delimitertype to "ROW" for
+ Sybase ASE or MS SQL Server.</p>.]]></short-description>
+        <description><![CDATA[
+          Set the delimiter that separates SQL statements; 
+ optional, default &quot;;&quot;
+
+ <p>For example, set this to "go" and delimitertype to "ROW" for
+ Sybase ASE or MS SQL Server.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="delimitertype" type="org.apache.tools.ant.taskdefs.SQLExec.DelimiterType"
+                 briefType="&quot;normal&quot;, &quot;row&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Delimiter type: "normal" or "row" (default "normal").]]></short-description>
+        <description><![CDATA[
+          Set the delimiter type: "normal" or "row" (default "normal").
+
+ <p>The delimiter type takes two values - normal and row. Normal
+ means that any occurence of the delimiter terminate the SQL
+ command whereas with row, only a line containing just the
+ delimiter is recognized as the end of the command.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="driver" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Class name of the JDBC driver; required.]]></short-description>
+        <description><![CDATA[
+          Class name of the JDBC driver; required.
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[File encoding to use on the SQL files read in.]]></short-description>
+        <description><![CDATA[
+          Set the file encoding to use on the SQL files read in
+        ]]></description>
+      </attribute>
+      <attribute name="onerror" type="org.apache.tools.ant.taskdefs.SQLExec.OnError"
+                 briefType="&quot;continue&quot;, &quot;stop&quot;, &quot;abort&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Action to perform when statement fails: continue, stop, or abort
+ optional; default &quot;abort&quot;.]]></short-description>
+        <description><![CDATA[
+          Action to perform when statement fails: continue, stop, or abort
+ optional; default &quot;abort&quot;
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Output file; 
+ optional, defaults to the Ant log.]]></short-description>
+        <description><![CDATA[
+          Set the output file; 
+ optional, defaults to the Ant log.
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Password; required.]]></short-description>
+        <description><![CDATA[
+          Sets the password; required.
+        ]]></description>
+      </attribute>
+      <attribute name="print" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Print result sets from the statements;
+ optional, default false.]]></short-description>
+        <description><![CDATA[
+          Print result sets from the statements;
+ optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="rdbms" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Execute task only if the lower case product name 
+ of the DB matches this.]]></short-description>
+        <description><![CDATA[
+          Execute task only if the lower case product name 
+ of the DB matches this
+        ]]></description>
+      </attribute>
+      <attribute name="showheaders" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Print headers for result sets from the 
+ statements; optional, default true.]]></short-description>
+        <description><![CDATA[
+          Print headers for result sets from the 
+ statements; optional, default true.
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the SQL file to be run.]]></short-description>
+        <description><![CDATA[
+          Set the name of the SQL file to be run.
+ Required unless statements are enclosed in the buildfile
+        ]]></description>
+      </attribute>
+      <attribute name="url" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Database connection URL; required.]]></short-description>
+        <description><![CDATA[
+          Sets the database connection URL; required.
+        ]]></description>
+      </attribute>
+      <attribute name="userid" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[User name for the connection; required.]]></short-description>
+        <description><![CDATA[
+          Set the user name for the connection; required.
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Version string, execute task only if 
+ rdbms version match; optional.]]></short-description>
+        <description><![CDATA[
+          Sets the version string, execute task only if 
+ rdbms version match; optional.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files (nested fileset attribute).]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files (nested fileset attribute).]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a path to the classpath for loading the driver.]]></short-description>
+        <description>
+          <![CDATA[Add a path to the classpath for loading the driver.]]>
+        </description>
+      </element>
+
+      <element name="transaction" type="org.apache.tools.ant.taskdefs.SQLExec.Transaction"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a SQL transaction to execute.]]></short-description>
+        <description>
+          <![CDATA[Add a SQL transaction to execute]]>
+        </description>
+      </element>
+
+    </elements>
+
+      <body >
+        <description><![CDATA[
+          Set an inline SQL command to execute. 
+ NB: Properties are not expanded in this text.
+        ]]></description>
+      </body>
+
+  </structure>
+
+</task>
+
+
+<task name="stylebook" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.StyleBook"
+      >
+
+  <short-description><![CDATA[Executes the Apache Stylebook documentation generator.]]></short-description>
+  <description>
+    <![CDATA[Executes the Apache Stylebook documentation generator.
+ Unlike the commandline version of this tool, all three arguments
+ are required to run stylebook.
+ <p>
+ Being extended from &lt;Java&gt;, all the parent's attributes
+ and options are available. Do not set any apart from the <tt>classpath</tt>
+ as they are not guaranteed to be there in future.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="append" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, append output to existing file.]]></short-description>
+        <description><![CDATA[
+          If true, append output to existing file.
+        ]]></description>
+      </attribute>
+      <attribute name="book" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The book xml file that the documentation generation starts from; 
+ required.]]></short-description>
+        <description><![CDATA[
+          The book xml file that the documentation generation starts from; 
+ required.
+        ]]></description>
+      </attribute>
+      <attribute name="classname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Java class to execute.]]></short-description>
+        <description><![CDATA[
+          Sets the Java class to execute.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used when running the Java class.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used when running the Java class
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to use, by reference.]]></short-description>
+        <description><![CDATA[
+          Classpath to use, by reference.
+        ]]></description>
+      </attribute>
+      <attribute name="dir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The working directory of the process.]]></short-description>
+        <description><![CDATA[
+          The working directory of the process
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, then fail if the command exits with a
+ returncode other than 0.]]></short-description>
+        <description><![CDATA[
+          If true, then fail if the command exits with a
+ returncode other than 0
+        ]]></description>
+      </attribute>
+      <attribute name="fork" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, execute in a new VM.]]></short-description>
+        <description><![CDATA[
+          If true, execute in a new VM.
+        ]]></description>
+      </attribute>
+      <attribute name="jvmversion" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[JVM version.]]></short-description>
+        <description><![CDATA[
+          Sets the JVM version.
+        ]]></description>
+      </attribute>
+      <attribute name="jar" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The location of the JAR file to execute.]]></short-description>
+        <description><![CDATA[
+          The location of the JAR file to execute.
+        ]]></description>
+      </attribute>
+      <attribute name="jvm" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Command used to start the VM (only if not forking).]]></short-description>
+        <description><![CDATA[
+          Set the command used to start the VM (only if not forking).
+        ]]></description>
+      </attribute>
+      <attribute name="jvmargs" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Command line arguments for the JVM.]]></short-description>
+        <description><![CDATA[
+          Set the command line arguments for the JVM.
+        ]]></description>
+      </attribute>
+      <attribute name="loaderconfig" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[A loader configuration to send to stylebook; optional.]]></short-description>
+        <description><![CDATA[
+          A loader configuration to send to stylebook; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="maxmemory" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Corresponds to -mx or -Xmx depending on VM version.]]></short-description>
+        <description><![CDATA[
+          Corresponds to -mx or -Xmx depending on VM version.
+        ]]></description>
+      </attribute>
+      <attribute name="newenvironment" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, use a completely new environment.]]></short-description>
+        <description><![CDATA[
+          If true, use a completely new environment.
+
+ <p>Will be ignored if we are not forking a new VM.
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[File the output of the process is redirected to.]]></short-description>
+        <description><![CDATA[
+          File the output of the process is redirected to.
+        ]]></description>
+      </attribute>
+      <attribute name="skindirectory" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The directory that contains the stylebook skin;
+ required.]]></short-description>
+        <description><![CDATA[
+          the directory that contains the stylebook skin;
+ required.
+        ]]></description>
+      </attribute>
+      <attribute name="targetdirectory" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The destination directory where the documentation is generated;
+ required.]]></short-description>
+        <description><![CDATA[
+          the destination directory where the documentation is generated;
+ required.
+        ]]></description>
+      </attribute>
+      <attribute name="timeout" type="java.lang.Long"
+                 briefType="long" required="NOTDEFINED">
+        <short-description><![CDATA[Timeout in milliseconds after which the process will be killed.]]></short-description>
+        <description><![CDATA[
+          Timeout in milliseconds after which the process will be killed.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="env" type="org.apache.tools.ant.types.Environment.Variable"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds an environment variable.]]></short-description>
+        <description>
+          <![CDATA[Adds an environment variable.
+
+ <p>Will be ignored if we are not forking a new VM.]]>
+        </description>
+      </element>
+
+      <element name="sysproperty" type="org.apache.tools.ant.types.Environment.Variable"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a system property.]]></short-description>
+        <description>
+          <![CDATA[Adds a system property.]]>
+        </description>
+      </element>
+
+      <element name="arg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a command-line argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a command-line argument.]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a path to the classpath.]]></short-description>
+        <description>
+          <![CDATA[Adds a path to the classpath.]]>
+        </description>
+      </element>
+
+      <element name="jvmarg" type="org.apache.tools.ant.types.Commandline.Argument"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a JVM argument.]]></short-description>
+        <description>
+          <![CDATA[Adds a JVM argument.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="tar" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.Tar"
+      matchingTask="true">
+
+  <!-- tar task -->
+<external>
+<description>
+<p>Creates a tar archive.</p>
+
+<p>The <i>basedir</i> attribute is the reference directory from where to tar.</p>
+
+<p>This task is a <a href="../dirtasks.html#directorybasedtasks">directory based task</a>
+and, as such, forms an implicit <a href="../CoreTypes/fileset.html">Fileset</a>. This
+defines which files, relative to the <i>basedir</i>, will be included in the
+archive. The tar task supports all the attributes of Fileset to refine the
+set of files to be included in the implicit fileset.</p>
+
+<p>In addition to the implicit fileset, the tar task supports nested filesets. These
+filesets are extended to allow control over the access mode, username and groupname
+to be applied to the tar entries. This is useful, for example, when preparing archives for
+Unix systems where some files need to have execute permission.</p>
+
+<p>Early versions of tar did not support path lengths greater than 100
+characters. Modern versions of tar do so, but in incompatible ways.
+The behaviour of the tar task when it encounters such paths is
+controlled by the <i>longfile</i> attribute.
+If the longfile attribute is set to <code>fail</code>, any long paths will
+cause the tar task to fail.  If the longfile attribute is set to
+<code>truncate</code>, any long paths will be truncated to the 100 character
+maximum length prior to adding to the archive. If the value of the longfile
+attribute is set to <code>omit</code> then files containing long paths will be
+omitted from the archive.  Either option ensures that the archive can be
+untarred by any compliant version of tar. If the loss of path or file
+information is not acceptable, and it rarely is, longfile may be set to the
+value <code>gnu</code>. The tar task will then produce a GNU tar file which
+can have arbitrary length paths. Note however, that the resulting archive will
+only be able to be untarred with GNU tar.  The default for the longfile
+attribute is <code>warn</code> which behaves just like the gnu option except
+that it produces a warning for each file path encountered that does not match
+the limit.</p>
+
+<p>Note that this task does not perform compression. You might want to use the
+<a href="gzip.html">GZip</a> task to prepare a .tar.gz package.</p>
+</description>
+
+<section anchor="examples" name="Examples">
+<pre>  &lt;tar tarfile=&quot;${dist}/manual.tar&quot; basedir=&quot;htdocs/manual&quot;/&gt;
+  &lt;gzip zipfile=&quot;${dist}/manual.tar.gz&quot; src=&quot;${dist}/manual.tar&quot;/&gt;</pre>
+<p>tars all files in the <code>htdocs/manual</code> directory into a file called <code>manual.tar</code>
+in the <code>${dist}</code>  directory, then applies the gzip task to compress
+it.</p>
+<pre>  &lt;tar destfile=&quot;${dist}/manual.tar&quot;
+       basedir=&quot;htdocs/manual&quot;
+       excludes=&quot;mydocs/**, **/todo.html&quot;
+  /&gt;</pre>
+<p>tars all files in the <code>htdocs/manual</code> directory into a file called <code>manual.tar</code>
+in the <code>${dist}</code> directory. Files in the directory <code>mydocs</code>,
+or files with the name <code>todo.html</code> are excluded.</p>
+
+<pre>
+&lt;tar destfile=&quot;${basedir}/docs.tar&quot;&gt;
+  &lt;tarfileset dir=&quot;${dir.src}/docs&quot;
+              fullpath=&quot;/usr/doc/ant/README&quot;
+              preserveLeadingSlashes=&quot;true&quot;&gt;
+    &lt;include name=&quot;readme.txt&quot;/&gt;
+  &lt;/tarfileset&gt;
+  &lt;tarfileset dir=&quot;${dir.src}/docs&quot;
+              prefix=&quot;/usr/doc/ant&quot;
+              preserveLeadingSlashes=&quot;true&quot;&gt;
+    &lt;include name=&quot;*.html&quot;/&gt;
+  &lt;/tarfileset&gt;
+&lt;/tar&gt;</pre>
+
+<p>
+  Writes the file <code>docs/readme.txt</code> as
+  <code>/usr/doc/ant/README</code> into the archive. All
+  <code>*.html</code> files in the <code>docs</code> directory are
+  prefixed by <code>/usr/doc/ant</code>, so for example
+  <code>docs/index.html</code> is written as
+  <code>/usr/doc/ant/index.html</code> to the archive.
+</p>
+
+<pre>&lt;tar longfile=&quot;gnu&quot;
+     destfile=&quot;${dist.base}/${dist.name}-src.tar&quot; &gt;
+  &lt;tarfileset dir=&quot;${dist.name}/..&quot; mode=&quot;755&quot; username=&quot;ant&quot; group=&quot;ant&quot;&gt;
+    &lt;include name=&quot;${dist.name}/bootstrap.sh&quot;/&gt;
+    &lt;include name=&quot;${dist.name}/build.sh&quot;/&gt;
+  &lt;/tarfileset&gt;
+  &lt;tarfileset dir=&quot;${dist.name}/..&quot; username=&quot;ant&quot; group=&quot;ant&quot;&gt;
+    &lt;include name=&quot;${dist.name}/**&quot;/&gt;
+    &lt;exclude name=&quot;${dist.name}/bootstrap.sh&quot;/&gt;
+    &lt;exclude name=&quot;${dist.name}/build.sh&quot;/&gt;
+  &lt;/tarfileset&gt;
+&lt;/tar&gt; </pre>
+
+<p>This example shows building a tar which uses the GNU extensions for long paths and
+where some files need to be marked as executable (mode 755)
+and the rest are use the default mode (read-write by owner). The first
+fileset selects just the executable files. The second fileset must exclude
+the executable files and include all others. </p>
+
+<p><strong>Note: </strong> The tar task does not ensure that a file is only selected
+by one fileset. If the same file is selected by more than one fileset, it will be included in the
+tar file twice, with the same path.</p>
+
+<p><strong>Note:</strong> The patterns in the include and exclude
+elements are considered to be relative to the corresponding dir
+attribute as with all other filesets.  In the example above,
+<code>${dist.name}</code> is not an absolute path, but a simple name
+of a directory, so <code>${dist.name}</code> is a valid path relative
+to <code>${dist.name}/..</code>.</p>
+
+</section>
+</external>
+
+  <short-description><![CDATA[Creates a tar archive.]]></short-description>
+  <description>
+    <![CDATA[Creates a tar archive.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="basedir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[This is the base directory to look in for things to tar.]]></short-description>
+        <description><![CDATA[
+          This is the base directory to look in for things to tar.
+        ]]></description>
+      </attribute>
+      <attribute name="compression" type="org.apache.tools.ant.taskdefs.Tar.TarCompressionMethod"
+                 briefType="&quot;none&quot;, &quot;gzip&quot;, &quot;bzip2&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Set compression method.]]></short-description>
+        <description><![CDATA[
+          Set compression method.
+ Allowable values are
+ <ul>
+ <li>  none - no compression
+ <li>  gzip - Gzip compression
+ <li>  bzip2 - Bzip2 compression
+ </ul>
+        ]]></description>
+      </attribute>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Set is the name/location of where to create the tar file.]]></short-description>
+        <description><![CDATA[
+          Set is the name/location of where to create the tar file.
+        ]]></description>
+      </attribute>
+      <attribute name="longfile" type="org.apache.tools.ant.taskdefs.Tar.TarLongFileMode"
+                 briefType="&quot;warn&quot;, &quot;fail&quot;, &quot;truncate&quot;, &quot;gnu&quot;, &quot;omit&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Set how to handle long files, those with a path&gt;100 chars.]]></short-description>
+        <description><![CDATA[
+          Set how to handle long files, those with a path&gt;100 chars.
+ Optional, default=warn.
+ <p>
+ Allowable values are
+ <ul>
+ <li>  truncate - paths are truncated to the maximum length
+ <li>  fail - paths greater than the maximim cause a build exception
+ <li>  warn - paths greater than the maximum cause a warning and GNU is used
+ <li>  gnu - GNU extensions are used for any paths greater than the maximum.
+ <li>  omit - paths greater than the maximum are omitted from the archive
+ </ul>
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="tarfileset" type="org.apache.tools.ant.taskdefs.Tar.TarFileSet"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a new fileset with the option to specify permissions.]]></short-description>
+        <description>
+          <![CDATA[Add a new fileset with the option to specify permissions]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="taskdef" category="internal"
+      classname="org.apache.tools.ant.taskdefs.Taskdef"
+      >
+
+  <short-description><![CDATA[Adds a task definition to the current project, such that this new task can be used in the current project.]]></short-description>
+  <description>
+    <![CDATA[Adds a task definition to the current project, such that this new task can be
+ used in the current project. Two attributes are needed, the name that identifies
+ this task uniquely, and the full name of the class (including the packages) that
+ implements this task.</p>
+ <p>You can also define a group of tasks at once using the file or
+ resource attributes.  These attributes point to files in the format of
+ Java property files.  Each line defines a single task in the
+ format:</p>
+ <pre>
+ taskname=fully.qualified.java.classname
+ </pre>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The full class name of the object being defined.]]></short-description>
+        <description><![CDATA[
+          the full class name of the object being defined.
+ Required, unless file or resource have
+ been specified.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used when searching for component being defined.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used when searching for component being defined
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Reference to a classpath to use when loading the files.]]></short-description>
+        <description><![CDATA[
+          reference to a classpath to use when loading the files.
+ To actually share the same loader, set loaderref as well
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the property file  to load
+ ant name/classname pairs from.]]></short-description>
+        <description><![CDATA[
+          Name of the property file  to load
+ ant name/classname pairs from.
+        ]]></description>
+      </attribute>
+      <attribute name="loaderref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Use the reference to locate the loader.]]></short-description>
+        <description><![CDATA[
+          Use the reference to locate the loader. If the loader is not
+ found, taskdef will use the specified classpath and register it
+ with the specified name.
+ This allow multiple taskdef/typedef to use the same class loader,
+ so they can be used together. It eliminate the need to
+ put them in the CLASSPATH.
+        ]]></description>
+      </attribute>
+      <attribute name="name" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the property resource to load
+ ant name/classname pairs from.]]></short-description>
+        <description><![CDATA[
+          Name of the property resource to load
+ ant name/classname pairs from.
+        ]]></description>
+      </attribute>
+      <attribute name="resource" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the property resource to load
+ ant name/classname pairs from.]]></short-description>
+        <description><![CDATA[
+          Name of the property resource to load
+ ant name/classname pairs from.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create the classpath to be used when searching for component being defined.]]></short-description>
+        <description>
+          <![CDATA[Create the classpath to be used when searching for component being defined]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="telnet" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.net.TelnetTask"
+      >
+
+  <short-description><![CDATA[Automates the telnet protocol.]]></short-description>
+  <description>
+    <![CDATA[Automates the telnet protocol.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="initialcr" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Send a carriage return after connecting; optional, defaults to false.]]></short-description>
+        <description><![CDATA[
+          send a carriage return after connecting; optional, defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login password to use
+ required if <tt>userid</tt> is set.]]></short-description>
+        <description><![CDATA[
+          Set the the login password to use
+ required if <tt>userid</tt> is set.
+        ]]></description>
+      </attribute>
+      <attribute name="port" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Tcp port to connect to; default is 23.]]></short-description>
+        <description><![CDATA[
+          Set the tcp port to connect to; default is 23.
+        ]]></description>
+      </attribute>
+      <attribute name="server" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Hostname or address of the remote server.]]></short-description>
+        <description><![CDATA[
+          Set the hostname or address of the remote server.
+        ]]></description>
+      </attribute>
+      <attribute name="timeout" type="java.lang.Integer"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Default timeout in seconds to wait for a response, 
+ zero means forever (the default).]]></short-description>
+        <description><![CDATA[
+          set a default timeout in seconds to wait for a response, 
+ zero means forever (the default)
+        ]]></description>
+      </attribute>
+      <attribute name="userid" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login id to use on the server; 
+ required if <tt>password</tt> is set.]]></short-description>
+        <description><![CDATA[
+          Set the the login id to use on the server; 
+ required if <tt>password</tt> is set.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="read" type="org.apache.tools.ant.taskdefs.optional.net.TelnetTask.TelnetSubTask"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[A string to wait for from the server.]]></short-description>
+        <description>
+          <![CDATA[A string to wait for from the server. 
+  A subTask &lt;read&gt; tag was found.  Create the object, 
+  Save it in our list, and return it.]]>
+        </description>
+      </element>
+
+      <element name="write" type="org.apache.tools.ant.taskdefs.optional.net.TelnetTask.TelnetSubTask"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add text to send to the server
+  A subTask &lt;write&gt; tag was found.]]></short-description>
+        <description>
+          <![CDATA[Add text to send to the server
+  A subTask &lt;write&gt; tag was found.  Create the object, 
+  Save it in our list, and return it.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="tempfile" category="other"
+      classname="org.apache.tools.ant.taskdefs.TempFile"
+      >
+
+  <short-description><![CDATA[This task sets a property to  the name of a temporary file.]]></short-description>
+  <description>
+    <![CDATA[This task sets a property to  the name of a temporary file. 
+  Unlike the Java1.2 method to create a temporary file, this task
+  does work on Java1.1. Also, it does not actually create the
+  temporary file, but it does guarantee that the file did not
+  exist when the task was executed. 
+ <p>  
+ Examples
+ <pre>&lt;tempfile property="temp.file" /&gt;</pre>
+ create a temporary file
+ <pre>&lt;tempfile property="temp.file" suffix=".xml" /&gt;</pre>
+ create a temporary file with the .xml suffix.
+ <pre>&lt;tempfile property="temp.file" destDir="build"/&gt;</pre>
+ create a temp file in the build subdir]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory.]]></short-description>
+        <description><![CDATA[
+          destination directory. If null, 
+the parent directory is used instead
+        ]]></description>
+      </attribute>
+      <attribute name="prefix" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Optional prefix string.]]></short-description>
+        <description><![CDATA[
+          optional prefix string
+        ]]></description>
+      </attribute>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The property you wish to assign the temporary file to.]]></short-description>
+        <description><![CDATA[
+          The property you wish to assign the temporary file to
+        ]]></description>
+      </attribute>
+      <attribute name="suffix" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Suffix string for the temp file (optional).]]></short-description>
+        <description><![CDATA[
+          Suffix string for the temp file (optional)
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="touch" category="filesystem"
+      classname="org.apache.tools.ant.taskdefs.Touch"
+      >
+
+  <short-description><![CDATA[Touch a file and/or fileset(s); corresponds to the Unix touch command.]]></short-description>
+  <description>
+    <![CDATA[Touch a file and/or fileset(s); corresponds to the Unix touch command.
+
+ <p>If the file to touch doesn't exist, an empty one is
+ created. </p>
+
+ <p>Note: Setting the modification time of files is not supported in
+ JDK 1.1.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="datetime" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The new modification time of the file
+ in the format MM/DD/YYYY HH:MM AM <i>or</i> PM;
+ Optional, default=now.]]></short-description>
+        <description><![CDATA[
+          the new modification time of the file
+ in the format MM/DD/YYYY HH:MM AM <i>or</i> PM;
+ Optional, default=now
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Single source file to touch.]]></short-description>
+        <description><![CDATA[
+          Sets a single source file to touch.  If the file does not exist
+ an empty file will be created.
+        ]]></description>
+      </attribute>
+      <attribute name="millis" type="long"
+                 briefType="long" required="NOTDEFINED">
+        <short-description><![CDATA[The new modification time of the file
+ in milliseconds since midnight Jan 1 1970.]]></short-description>
+        <description><![CDATA[
+          the new modification time of the file
+ in milliseconds since midnight Jan 1 1970.
+ Optional, default=now
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a set of files to touch.]]></short-description>
+        <description>
+          <![CDATA[Add a set of files to touch]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="translate" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.i18n.Translate"
+      matchingTask="true">
+
+  <short-description><![CDATA[Translates text embedded in files using Resource Bundle files.]]></short-description>
+  <description>
+    <![CDATA[Translates text embedded in files using Resource Bundle files.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="bundle" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets Family name of resource bundle; required.]]></short-description>
+        <description><![CDATA[
+          Sets Family name of resource bundle; required.
+        ]]></description>
+      </attribute>
+      <attribute name="bundlecountry" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets locale specific country of resource bundle; optional.]]></short-description>
+        <description><![CDATA[
+          Sets locale specific country of resource bundle; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="bundleencoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets Resource Bundle file encoding scheme; optional.]]></short-description>
+        <description><![CDATA[
+          Sets Resource Bundle file encoding scheme; optional.  Defaults to source file
+ encoding
+        ]]></description>
+      </attribute>
+      <attribute name="bundlelanguage" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets locale specific language of resource bundle; optional.]]></short-description>
+        <description><![CDATA[
+          Sets locale specific language of resource bundle; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="bundlevariant" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets locale specific variant of resource bundle; optional.]]></short-description>
+        <description><![CDATA[
+          Sets locale specific variant of resource bundle; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="destencoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets destination file encoding scheme; optional.]]></short-description>
+        <description><![CDATA[
+          Sets destination file encoding scheme; optional.  Defaults to source file
+ encoding
+        ]]></description>
+      </attribute>
+      <attribute name="endtoken" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets ending token to identify keys; required.]]></short-description>
+        <description><![CDATA[
+          Sets ending token to identify keys; required.
+        ]]></description>
+      </attribute>
+      <attribute name="forceoverwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether or not to overwrite existing file irrespective of
+ whether it is newer than the source file as well as the
+ resource bundle file.]]></short-description>
+        <description><![CDATA[
+          Whether or not to overwrite existing file irrespective of
+ whether it is newer than the source file as well as the
+ resource bundle file.
+ Defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="srcencoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets source file encoding scheme; optional,
+ defaults to encoding of local system.]]></short-description>
+        <description><![CDATA[
+          Sets source file encoding scheme; optional,
+ defaults to encoding of local system.
+        ]]></description>
+      </attribute>
+      <attribute name="starttoken" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Sets starting token to identify keys; required.]]></short-description>
+        <description><![CDATA[
+          Sets starting token to identify keys; required.
+        ]]></description>
+      </attribute>
+      <attribute name="todir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Sets Destination directory; required.]]></short-description>
+        <description><![CDATA[
+          Sets Destination directory; required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files to translate as a nested fileset element.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files to translate as a nested fileset element.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="tstamp" category="utility"
+      classname="org.apache.tools.ant.taskdefs.Tstamp"
+      >
+
+  <short-description><![CDATA[Sets properties to the current time, or offsets from the current time.]]></short-description>
+  <description>
+    <![CDATA[Sets properties to the current time, or offsets from the current time.
+ The default properties are TSTAMP, DSTAMP and TODAY;]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="prefix" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Prefix for the properties.]]></short-description>
+        <description><![CDATA[
+          Set a prefix for the properties. If the prefix does not end with a "."
+ one is automatically added
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="format" type="org.apache.tools.ant.taskdefs.Tstamp.CustomFormat"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a custom format with the the current prefix.]]></short-description>
+        <description>
+          <![CDATA[create a custom format with the the current prefix.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="typedef" category="internal"
+      classname="org.apache.tools.ant.taskdefs.Typedef"
+      >
+
+  <short-description><![CDATA[Adds a data type definition to the current project.]]></short-description>
+  <description>
+    <![CDATA[Adds a data type definition to the current project.
+ Two attributes are
+ needed, the name that identifies this data type uniquely, and the full
+ name of the class (including the packages) that implements this
+ type.
+ <p>You can also define a group of data types at once using the file or
+ resource attributes.  These attributes point to files in the format of
+ Java property files.   Each line defines a single data type in the
+ format:</p>
+ <pre>
+ typename=fully.qualified.java.classname
+ </pre>
+ <p>Typedef should be used to add your own types to the system. Data
+ types are things likepaths or filesets that can be defined at
+ the project level and referenced via their ID attribute.</p>
+ <p>Custom data types usually need custom tasks to put them to good use.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The full class name of the object being defined.]]></short-description>
+        <description><![CDATA[
+          the full class name of the object being defined.
+ Required, unless file or resource have
+ been specified.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used when searching for component being defined.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used when searching for component being defined
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Reference to a classpath to use when loading the files.]]></short-description>
+        <description><![CDATA[
+          reference to a classpath to use when loading the files.
+ To actually share the same loader, set loaderref as well
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the property file  to load
+ ant name/classname pairs from.]]></short-description>
+        <description><![CDATA[
+          Name of the property file  to load
+ ant name/classname pairs from.
+        ]]></description>
+      </attribute>
+      <attribute name="loaderref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Use the reference to locate the loader.]]></short-description>
+        <description><![CDATA[
+          Use the reference to locate the loader. If the loader is not
+ found, taskdef will use the specified classpath and register it
+ with the specified name.
+ This allow multiple taskdef/typedef to use the same class loader,
+ so they can be used together. It eliminate the need to
+ put them in the CLASSPATH.
+        ]]></description>
+      </attribute>
+      <attribute name="name" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the property resource to load
+ ant name/classname pairs from.]]></short-description>
+        <description><![CDATA[
+          Name of the property resource to load
+ ant name/classname pairs from.
+        ]]></description>
+      </attribute>
+      <attribute name="resource" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the property resource to load
+ ant name/classname pairs from.]]></short-description>
+        <description><![CDATA[
+          Name of the property resource to load
+ ant name/classname pairs from.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create the classpath to be used when searching for component being defined.]]></short-description>
+        <description>
+          <![CDATA[Create the classpath to be used when searching for component being defined]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="untar" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.Untar"
+      >
+
+  <short-description><![CDATA[Untar a file.]]></short-description>
+  <description>
+    <![CDATA[Untar a file.
+ <p>For JDK 1.1 &quot;last modified time&quot; field is set to current time instead of being
+ carried from the archive file.</p>
+ <p>PatternSets are used to select files to extract
+ <I>from</I> the archive.  If no patternset is used, all files are extracted.
+ </p>
+ <p>FileSet>s may be used used to select archived files
+ to perform unarchival upon.
+ </p>
+ <p>File permissions will not be restored on extracted files.</p>
+ <p>The untar task recognizes the long pathname entries used by GNU tar.<p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="compression" type="org.apache.tools.ant.taskdefs.Untar.UntarCompressionMethod"
+                 briefType="&quot;none&quot;, &quot;gzip&quot;, &quot;bzip2&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Set decompression algorithm to use; default=none.]]></short-description>
+        <description><![CDATA[
+          Set decompression algorithm to use; default=none.
+
+ Allowable values are
+ <ul>
+   <li>none - no compression
+   <li>gzip - Gzip compression
+   <li>bzip2 - Bzip2 compression
+ </ul>
+        ]]></description>
+      </attribute>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory. File will be unzipped into the
+ destination directory.
+        ]]></description>
+      </attribute>
+      <attribute name="overwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Should we overwrite files in dest, even if they are newer than
+ the corresponding entries in the archive?.]]></short-description>
+        <description><![CDATA[
+          Should we overwrite files in dest, even if they are newer than
+ the corresponding entries in the archive?
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Path to zip-file.]]></short-description>
+        <description><![CDATA[
+          Set the path to zip-file.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a fileset.]]></short-description>
+        <description>
+          <![CDATA[Add a fileset]]>
+        </description>
+      </element>
+
+      <element name="patternset" type="org.apache.tools.ant.types.PatternSet"
+               briefType="Patternset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a patternset.]]></short-description>
+        <description>
+          <![CDATA[Add a patternset]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="unzip" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.Expand"
+      >
+
+  <short-description><![CDATA[Unzip a file.]]></short-description>
+  <description>
+    <![CDATA[Unzip a file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory. File will be unzipped into the
+ destination directory.
+        ]]></description>
+      </attribute>
+      <attribute name="overwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Should we overwrite files in dest, even if they are newer than
+ the corresponding entries in the archive?.]]></short-description>
+        <description><![CDATA[
+          Should we overwrite files in dest, even if they are newer than
+ the corresponding entries in the archive?
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Path to zip-file.]]></short-description>
+        <description><![CDATA[
+          Set the path to zip-file.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a fileset.]]></short-description>
+        <description>
+          <![CDATA[Add a fileset]]>
+        </description>
+      </element>
+
+      <element name="patternset" type="org.apache.tools.ant.types.PatternSet"
+               briefType="Patternset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a patternset.]]></short-description>
+        <description>
+          <![CDATA[Add a patternset]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="uptodate" category="control"
+      classname="org.apache.tools.ant.taskdefs.UpToDate"
+      >
+
+  <short-description><![CDATA[Sets the given property if the specified target has a timestamp greater than all of the source files.]]></short-description>
+  <description>
+    <![CDATA[Sets the given property if the specified target has a timestamp
+ greater than all of the source files.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="property" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The property to set if the target file is more up-to-date than
+ (each of) the source file(s).]]></short-description>
+        <description><![CDATA[
+          The property to set if the target file is more up-to-date than
+ (each of) the source file(s).
+        ]]></description>
+      </attribute>
+      <attribute name="srcfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file that must be older than the target file
+ if the property is to be set.]]></short-description>
+        <description><![CDATA[
+          The file that must be older than the target file
+ if the property is to be set.
+        ]]></description>
+      </attribute>
+      <attribute name="targetfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file which must be more up-to-date than (each of) the source file(s)
+ if the property is to be set.]]></short-description>
+        <description><![CDATA[
+          The file which must be more up-to-date than (each of) the source file(s)
+ if the property is to be set.
+        ]]></description>
+      </attribute>
+      <attribute name="value" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The value to set the named property to if the target file is more
+ up-to-date than (each of) the source file(s).]]></short-description>
+        <description><![CDATA[
+          The value to set the named property to if the target file is more
+ up-to-date than (each of) the source file(s). Defaults to 'true'.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="srcfiles" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Nested &lt;srcfiles&gt; element.]]></short-description>
+        <description>
+          <![CDATA[Nested &lt;srcfiles&gt; element.]]>
+        </description>
+      </element>
+
+      <element name="mapper" type="org.apache.tools.ant.types.Mapper"
+               briefType="Mapper"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Defines the FileNameMapper to use (nested mapper element).]]></short-description>
+        <description>
+          <![CDATA[Defines the FileNameMapper to use (nested mapper element).]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vajexport" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ide.VAJExport"
+      >
+
+  <short-description><![CDATA[Export packages from the Visual Age for Java workspace.]]></short-description>
+  <description>
+    <![CDATA[Export packages from the Visual Age for Java workspace.
+ The packages are specified similar to all other MatchingTasks.
+ Since the VA Workspace is not file based, this task is simulating
+ a directory hierarchy for the workspace:
+ The 'root' contains all project 'dir's, and the projects contain
+ their respective package 'dir's.
+ Example:
+ <blockquote>
+ &lt;vajexport destdir="C:/builddir/source">
+ &nbsp;&lt;include name="/MyVAProject/org/foo/subsystem1/**" />
+ &nbsp;&lt;exclude name="/MyVAProject/org/foo/subsystem1/test/**"/>
+ &lt;/vajexport>
+ </blockquote>
+ exports all packages in the project MyVAProject which start with
+ 'org.foo.subsystem1' except of these starting with
+ 'org.foo.subsystem1.test'.
+
+ There are flags to choose which items to export:
+ exportSources:   export Java sources
+ exportResources: export project resources
+ exportClasses:   export class files
+ exportDebugInfo: export class files with debug info (use with exportClasses)
+ default is exporting Java files and resources.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="defaultexcludes" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether default exclusions should be used or not; default true.]]></short-description>
+        <description><![CDATA[
+          Sets whether default exclusions should be used or not; default true.
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory into which the selected
+ items should be exported; required.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory into which the selected
+ items should be exported; required.
+        ]]></description>
+      </attribute>
+      <attribute name="excludes" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set of exclude patterns.]]></short-description>
+        <description><![CDATA[
+          Sets the set of exclude patterns. Patterns may be separated by a comma
+ or a space. Currently only patterns denoting packages are
+ supported
+        ]]></description>
+      </attribute>
+      <attribute name="exportclasses" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Optional flag to export the class files; default false.]]></short-description>
+        <description><![CDATA[
+          optional flag to export the class files; default false.
+        ]]></description>
+      </attribute>
+      <attribute name="exportdebuginfo" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Optional flag to export the debug info; default false.
+ debug info.]]></short-description>
+        <description><![CDATA[
+          optional flag to export the debug info; default false.
+ debug info
+        ]]></description>
+      </attribute>
+      <attribute name="exportresources" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Optional flag to export the resource file; default true.]]></short-description>
+        <description><![CDATA[
+          optional flag to export the resource file; default true.
+        ]]></description>
+      </attribute>
+      <attribute name="exportsources" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Optional flag to export the Java files; default true.]]></short-description>
+        <description><![CDATA[
+          optional flag to export the Java files; default true.
+        ]]></description>
+      </attribute>
+      <attribute name="includes" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Set of include patterns.]]></short-description>
+        <description><![CDATA[
+          Sets the set of include patterns. Patterns may be separated by a comma
+ or a space. Currently only patterns denoting packages are
+ supported
+        ]]></description>
+      </attribute>
+      <attribute name="overwrite" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If Overwrite is set, files will be overwritten during export.]]></short-description>
+        <description><![CDATA[
+          if Overwrite is set, files will be overwritten during export
+        ]]></description>
+      </attribute>
+      <attribute name="remote" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name and port of a remote tool server, optiona.]]></short-description>
+        <description><![CDATA[
+          Name and port of a remote tool server, optiona.
+ Format: &lt;servername&gt;:&lt;port no&gt;.
+ If this attribute is set, the tasks will be executed on the specified tool
+ server.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="exclude" type="org.apache.tools.ant.types.PatternSet.NameEntry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a name entry on the exclude list.]]></short-description>
+        <description>
+          <![CDATA[add a name entry on the exclude list]]>
+        </description>
+      </element>
+
+      <element name="include" type="org.apache.tools.ant.types.PatternSet.NameEntry"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a name entry on the include list.]]></short-description>
+        <description>
+          <![CDATA[add a name entry on the include list]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vajimport" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ide.VAJImport"
+      >
+
+  <short-description><![CDATA[Import source, class files, and resources to the Visual Age for Java workspace.]]></short-description>
+  <description>
+    <![CDATA[Import source, class files, and resources to the Visual Age for Java
+ workspace.
+ <p>
+ Example:
+ <pre>
+ &lt;vajimport project="MyVAProject"&gt;
+   &lt;fileset dir="src"&gt;
+     &lt;include name="org/foo/subsystem1/**" /&gt;
+     &lt;exclude name="/org/foo/subsystem1/test/**" /&gt;
+  &lt;/fileset&gt;
+ &lt;/vajexport&gt;
+ </pre>
+ import all source and resource files from the "src" directory
+ which start with 'org.foo.subsystem1', except of these starting with
+ 'org.foo.subsystem1.test' into the project MyVAProject.
+ </p>
+ <p>If MyVAProject isn't loaded into the Workspace, a new edition is
+ created in the repository and automatically loaded into the Workspace.
+ There has to be at least one nested FileSet element.
+ </p>
+ <p>There are attributes to choose which items to export:
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+   <td valign="top"><b>Attribute</b></td>
+   <td valign="top"><b>Description</b></td>
+   <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+   <td valign="top">project</td>
+   <td valign="top">the name of the Project to import to</td>
+   <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+   <td valign="top">importSources</td>
+   <td valign="top">import Java sources, defaults to "yes"</td>
+   <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+   <td valign="top">importResources</td>
+   <td valign="top">import resource files (anything that doesn't
+                    end with .java or .class), defaults to "yes"</td>
+   <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+   <td valign="top">importClasses</td>
+   <td valign="top">import class files, defaults to "no"</td>
+   <td align="center" valign="top">No</td>
+ </tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="defaultexcludes" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether default exclusions should be used or not.]]></short-description>
+        <description><![CDATA[
+          Sets whether default exclusions should be used or not.
+        ]]></description>
+      </attribute>
+      <attribute name="importclasses" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to import .class files; optional, default false.]]></short-description>
+        <description><![CDATA[
+          Flag to import .class files; optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="importresources" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Import resource files (anything that doesn't end in
+ .class or .java); optional, default true.]]></short-description>
+        <description><![CDATA[
+          Import resource files (anything that doesn't end in
+ .class or .java); optional, default true.
+        ]]></description>
+      </attribute>
+      <attribute name="importsources" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Import .java files; optional, default true.]]></short-description>
+        <description><![CDATA[
+          Import .java files; optional, default true.
+        ]]></description>
+      </attribute>
+      <attribute name="project" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The VisualAge for Java Project name to import into.]]></short-description>
+        <description><![CDATA[
+          The VisualAge for Java Project name to import into.
+        ]]></description>
+      </attribute>
+      <attribute name="remote" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name and port of a remote tool server, optiona.]]></short-description>
+        <description><![CDATA[
+          Name and port of a remote tool server, optiona.
+ Format: &lt;servername&gt;:&lt;port no&gt;.
+ If this attribute is set, the tasks will be executed on the specified tool
+ server.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files (nested fileset attribute).]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files (nested fileset attribute).]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vajload" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ide.VAJLoad"
+      >
+
+  <short-description><![CDATA[Load specific project versions into the Visual Age for Java workspace.]]></short-description>
+  <description>
+    <![CDATA[Load specific project versions into the Visual Age for Java workspace.
+ Each project and version name has to be specified completely.
+ Example:  
+ <blockquote> 
+ &lt;vajload>
+ &nbsp;&lt;project name="MyVAProject" version="2.1"/>
+ &nbsp;&lt;project name="Apache Xerces" version="1.2.0"/>
+ &lt;/vajload>
+ </blockquote>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="remote" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name and port of a remote tool server, optiona.]]></short-description>
+        <description><![CDATA[
+          Name and port of a remote tool server, optiona.
+ Format: &lt;servername&gt;:&lt;port no&gt;.
+ If this attribute is set, the tasks will be executed on the specified tool
+ server.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="vajproject" type="org.apache.tools.ant.taskdefs.optional.ide.VAJProjectDescription"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a project description entry on the project list.]]></short-description>
+        <description>
+          <![CDATA[Add a project description entry on the project list.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vssadd" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSADD"
+      >
+
+  <short-description><![CDATA[Performs Add commands to Microsoft Visual SourceSafe.]]></short-description>
+  <description>
+    <![CDATA[Performs Add commands to Microsoft Visual SourceSafe.
+ Based on the VSS Checkin code by Martin Poeschl]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="autoresponse" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[What to respond with (sets the -I option).]]></short-description>
+        <description><![CDATA[
+          What to respond with (sets the -I option). By default, -I- is
+ used; values of Y or N will be appended to this.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Comment to apply; optional.]]></short-description>
+        <description><![CDATA[
+          Sets the comment to apply; optional.
+ <p>
+ If this is null or empty, it will be replaced with "-" which
+ is what SourceSafe uses for an empty comment.
+        ]]></description>
+      </attribute>
+      <attribute name="localpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Local path.]]></short-description>
+        <description><![CDATA[
+          Set the local path.
+        ]]></description>
+      </attribute>
+      <attribute name="login" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login to use when accessing VSS, formatted as "username,password";
+ optional.]]></short-description>
+        <description><![CDATA[
+          The login to use when accessing VSS, formatted as "username,password";
+ optional.
+ <p>
+ You can omit the password if your database is not password protected.
+  if you have a password and omit it, Ant/VSS will hang.
+        ]]></description>
+      </attribute>
+      <attribute name="recursive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set behaviour recursive or non-recursive.]]></short-description>
+        <description><![CDATA[
+          Set behaviour recursive or non-recursive
+        ]]></description>
+      </attribute>
+      <attribute name="serverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>srssafe.ini</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          Set the directory where <code>srssafe.ini</code> resides; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="ssdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>ss.exe</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          directory where <code>ss.exe</code> resides; optional.
+ By default the task expects it to be in the PATH.
+        ]]></description>
+      </attribute>
+      <attribute name="vsspath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required.]]></short-description>
+        <description><![CDATA[
+          SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required. You should not specify the leading dollar-sign - 
+ it is prepended by Ant automatically.
+ <p>
+ Ant can't cope with a '$' sign in an attribute so we have to add it here.
+ Also we strip off any 'vss://' prefix which is an XMS special and should probably be removed!
+        ]]></description>
+      </attribute>
+      <attribute name="writable" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Leave added files writable?.]]></short-description>
+        <description><![CDATA[
+          Leave added files writable? Default: false.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vsscheckin" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKIN"
+      >
+
+  <short-description><![CDATA[Performs CheckIn commands to Microsoft Visual SourceSafe.]]></short-description>
+  <description>
+    <![CDATA[Performs CheckIn commands to Microsoft Visual SourceSafe.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="autoresponse" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[What to respond with (sets the -I option).]]></short-description>
+        <description><![CDATA[
+          What to respond with (sets the -I option). By default, -I- is
+ used; values of Y or N will be appended to this.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Comment to apply; optional.]]></short-description>
+        <description><![CDATA[
+          Set the comment to apply; optional.
+ <p>
+ If this is null or empty, it will be replaced with "-" which
+ is what SourceSafe uses for an empty comment.
+        ]]></description>
+      </attribute>
+      <attribute name="localpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Local path.]]></short-description>
+        <description><![CDATA[
+          Set the local path.
+        ]]></description>
+      </attribute>
+      <attribute name="login" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login to use when accessing VSS, formatted as "username,password";
+ optional.]]></short-description>
+        <description><![CDATA[
+          The login to use when accessing VSS, formatted as "username,password";
+ optional.
+ <p>
+ You can omit the password if your database is not password protected.
+  if you have a password and omit it, Ant/VSS will hang.
+        ]]></description>
+      </attribute>
+      <attribute name="recursive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to tell the task to recurse down the tree;
+ optional, default false.]]></short-description>
+        <description><![CDATA[
+          Flag to tell the task to recurse down the tree;
+ optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="serverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>srssafe.ini</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          Set the directory where <code>srssafe.ini</code> resides; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="ssdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>ss.exe</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          directory where <code>ss.exe</code> resides; optional.
+ By default the task expects it to be in the PATH.
+        ]]></description>
+      </attribute>
+      <attribute name="vsspath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required.]]></short-description>
+        <description><![CDATA[
+          SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required. You should not specify the leading dollar-sign - 
+ it is prepended by Ant automatically.
+ <p>
+ Ant can't cope with a '$' sign in an attribute so we have to add it here.
+ Also we strip off any 'vss://' prefix which is an XMS special and should probably be removed!
+        ]]></description>
+      </attribute>
+      <attribute name="writable" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Leave checked in files writable?.]]></short-description>
+        <description><![CDATA[
+          Leave checked in files writable? Default: false.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vsscheckout" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKOUT"
+      >
+
+  <short-description><![CDATA[Performs CheckOut commands to Microsoft Visual SourceSafe.]]></short-description>
+  <description>
+    <![CDATA[Performs CheckOut commands to Microsoft Visual SourceSafe.
+ <p>If you specify two or more attributes from version, date and 
+ label only one will be used in the order version, date, label.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="autoresponse" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[What to respond with (sets the -I option).]]></short-description>
+        <description><![CDATA[
+          What to respond with (sets the -I option). By default, -I- is
+ used; values of Y or N will be appended to this.
+        ]]></description>
+      </attribute>
+      <attribute name="date" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Date to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.]]></short-description>
+        <description><![CDATA[
+          Set the date to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.
+        ]]></description>
+      </attribute>
+      <attribute name="label" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Label to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.]]></short-description>
+        <description><![CDATA[
+          Set the label to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.
+        ]]></description>
+      </attribute>
+      <attribute name="localpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Local path.]]></short-description>
+        <description><![CDATA[
+          Set the local path.
+        ]]></description>
+      </attribute>
+      <attribute name="login" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login to use when accessing VSS, formatted as "username,password";
+ optional.]]></short-description>
+        <description><![CDATA[
+          The login to use when accessing VSS, formatted as "username,password";
+ optional.
+ <p>
+ You can omit the password if your database is not password protected.
+  if you have a password and omit it, Ant/VSS will hang.
+        ]]></description>
+      </attribute>
+      <attribute name="recursive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to tell the task to recurse down the tree;
+ optional, default false.]]></short-description>
+        <description><![CDATA[
+          Flag to tell the task to recurse down the tree;
+ optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="serverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>srssafe.ini</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          Set the directory where <code>srssafe.ini</code> resides; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="ssdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>ss.exe</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          directory where <code>ss.exe</code> resides; optional.
+ By default the task expects it to be in the PATH.
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Version to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.]]></short-description>
+        <description><![CDATA[
+          Set the version to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.
+        ]]></description>
+      </attribute>
+      <attribute name="vsspath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required.]]></short-description>
+        <description><![CDATA[
+          SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required. You should not specify the leading dollar-sign - 
+ it is prepended by Ant automatically.
+ <p>
+ Ant can't cope with a '$' sign in an attribute so we have to add it here.
+ Also we strip off any 'vss://' prefix which is an XMS special and should probably be removed!
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vsscp" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCP"
+      >
+
+  <short-description><![CDATA[Performs CP (Change Project) commands to Microsoft Visual SourceSafe.]]></short-description>
+  <description>
+    <![CDATA[Performs CP (Change Project) commands to Microsoft Visual SourceSafe.
+ <p>This task is typically used before a VssAdd in order to set the target project</p>
+ Based on the VSS Checkin code by Martin Poeschl]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="autoresponse" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[What to respond with (sets the -I option).]]></short-description>
+        <description><![CDATA[
+          What to respond with (sets the -I option). By default, -I- is
+ used; values of Y or N will be appended to this.
+        ]]></description>
+      </attribute>
+      <attribute name="login" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login to use when accessing VSS, formatted as "username,password";
+ optional.]]></short-description>
+        <description><![CDATA[
+          The login to use when accessing VSS, formatted as "username,password";
+ optional.
+ <p>
+ You can omit the password if your database is not password protected.
+  if you have a password and omit it, Ant/VSS will hang.
+        ]]></description>
+      </attribute>
+      <attribute name="serverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>srssafe.ini</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          Set the directory where <code>srssafe.ini</code> resides; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="ssdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>ss.exe</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          directory where <code>ss.exe</code> resides; optional.
+ By default the task expects it to be in the PATH.
+        ]]></description>
+      </attribute>
+      <attribute name="vsspath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required.]]></short-description>
+        <description><![CDATA[
+          SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required. You should not specify the leading dollar-sign - 
+ it is prepended by Ant automatically.
+ <p>
+ Ant can't cope with a '$' sign in an attribute so we have to add it here.
+ Also we strip off any 'vss://' prefix which is an XMS special and should probably be removed!
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vsscreate" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCREATE"
+      >
+
+  <short-description><![CDATA[Creates a new project in Microsoft Visual SourceSafe.]]></short-description>
+  <description>
+    <![CDATA[Creates a new project in Microsoft Visual SourceSafe.
+ <p>
+ The following attributes are interpreted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+      <td>login</td>
+      <td>username,password</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>vsspath</td>
+      <td>SourceSafe path of project to be created</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>ssdir</td>
+      <td>directory where <code>ss.exe</code> resides. By default the task
+      expects it to be in the PATH.</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>quiet</td>
+      <td>suppress output (off by default)</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>failOnError</td>
+      <td>fail if there is an error creating the project (true by default)</td>
+      <td>No</td>
+   </tr>   
+   <tr>
+      <td>autoresponse</td>
+      <td>What to respond with (sets the -I option). By default, -I- is
+      used; values of Y or N will be appended to this.</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>comment</td>
+      <td>The comment to use for this label. Empty or '-' for no comment.</td>
+      <td>No</td>
+   </tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="autoresponse" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[What to respond with (sets the -I option).]]></short-description>
+        <description><![CDATA[
+          What to respond with (sets the -I option). By default, -I- is
+ used; values of Y or N will be appended to this.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Comment to apply in SourceSafe.]]></short-description>
+        <description><![CDATA[
+          Sets the comment to apply in SourceSafe.
+ <p>
+ If this is null or empty, it will be replaced with "-" which
+ is what SourceSafe uses for an empty comment.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets whether task should fail if there is an error creating the project;
+ optional, default true.]]></short-description>
+        <description><![CDATA[
+          Sets whether task should fail if there is an error creating the project;
+ optional, default true.
+        ]]></description>
+      </attribute>
+      <attribute name="login" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login to use when accessing VSS, formatted as "username,password";
+ optional.]]></short-description>
+        <description><![CDATA[
+          The login to use when accessing VSS, formatted as "username,password";
+ optional.
+ <p>
+ You can omit the password if your database is not password protected.
+  if you have a password and omit it, Ant/VSS will hang.
+        ]]></description>
+      </attribute>
+      <attribute name="quiet" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Sets/clears quiet mode; optional, default false.]]></short-description>
+        <description><![CDATA[
+          Sets/clears quiet mode; optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="serverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>srssafe.ini</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          Set the directory where <code>srssafe.ini</code> resides; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="ssdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>ss.exe</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          directory where <code>ss.exe</code> resides; optional.
+ By default the task expects it to be in the PATH.
+        ]]></description>
+      </attribute>
+      <attribute name="vsspath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required.]]></short-description>
+        <description><![CDATA[
+          SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required. You should not specify the leading dollar-sign - 
+ it is prepended by Ant automatically.
+ <p>
+ Ant can't cope with a '$' sign in an attribute so we have to add it here.
+ Also we strip off any 'vss://' prefix which is an XMS special and should probably be removed!
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vssget" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSGET"
+      >
+
+  <short-description><![CDATA[Perform Get commands to Microsoft Visual SourceSafe.]]></short-description>
+  <description>
+    <![CDATA[Perform Get commands to Microsoft Visual SourceSafe.
+ <p>
+ The following attributes are interpreted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+      <td>login</td>
+      <td>username,password</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>vsspath</td>
+      <td>SourceSafe path</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>localpath</td>
+      <td>Override the working directory and get to the specified path</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>writable</td>
+      <td>true or false</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>recursive</td>
+      <td>true or false</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>version</td>
+      <td>a version number to get</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>date</td>
+      <td>a date stamp to get at</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>label</td>
+      <td>a label to get for</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>quiet</td>
+      <td>suppress output (off by default)</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>autoresponse</td>
+      <td>What to respond with (sets the -I option). By default, -I- is
+      used; values of Y or N will be appended to this.</td>
+      <td>No</td>
+   </tr>
+ </table>
+ <p>Note that only one of version, date or label should be specified</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="autoresponse" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[What to respond with (sets the -I option).]]></short-description>
+        <description><![CDATA[
+          What to respond with (sets the -I option). By default, -I- is
+ used; values of Y or N will be appended to this.
+        ]]></description>
+      </attribute>
+      <attribute name="date" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Date to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.]]></short-description>
+        <description><![CDATA[
+          Set the date to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.
+ <p>
+ ORIGINAL COMMENT THAT DOES NOT SEEM AT ALL VALID:
+ Note we assume that if the supplied string has the value "null" that something
+ went wrong and that the string value got populated from a null object. This
+ happens if a ant variable is used e.g. date="${date}" when date
+ has not been defined to ant!
+        ]]></description>
+      </attribute>
+      <attribute name="label" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Label to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.]]></short-description>
+        <description><![CDATA[
+          Set the label to get;
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.
+ <p>
+ Note we assume that if the supplied string has the value "null" that something
+ went wrong and that the string value got populated from a null object. This
+ happens if a ant variable is used e.g. label="${label_server}" when label_server
+ has not been defined to ant!
+        ]]></description>
+      </attribute>
+      <attribute name="localpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Override the working directory and get to the specified path; optional.]]></short-description>
+        <description><![CDATA[
+          Override the working directory and get to the specified path; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="login" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login to use when accessing VSS, formatted as "username,password";
+ optional.]]></short-description>
+        <description><![CDATA[
+          The login to use when accessing VSS, formatted as "username,password";
+ optional.
+ <p>
+ You can omit the password if your database is not password protected.
+  if you have a password and omit it, Ant/VSS will hang.
+        ]]></description>
+      </attribute>
+      <attribute name="quiet" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to suppress output when true ; false by default.]]></short-description>
+        <description><![CDATA[
+          Flag to suppress output when true ; false by default.
+        ]]></description>
+      </attribute>
+      <attribute name="recursive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to tell the task to recurse down the tree;
+ optional, default false.]]></short-description>
+        <description><![CDATA[
+          Flag to tell the task to recurse down the tree;
+ optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="serverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>srssafe.ini</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          Set the directory where <code>srssafe.ini</code> resides; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="ssdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>ss.exe</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          directory where <code>ss.exe</code> resides; optional.
+ By default the task expects it to be in the PATH.
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Version number to get; 
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.]]></short-description>
+        <description><![CDATA[
+          Set a version number to get; 
+ optional, only one of <tt>version</tt>, <tt>label</tt>, or <tt>date</tt>
+ allowed.
+ <p>
+ ORIGINAL COMMENT THAT DOES NOT SEEM AT ALL VALID:
+ Note we assume that if the supplied string has the value "null" that something
+ went wrong and that the string value got populated from a null object. This
+ happens if a ant variable is used e.g. version="${ver_server}" when ver_server
+ has not been defined to ant!
+ NO, in this case the version string is "${ver_server}".
+        ]]></description>
+      </attribute>
+      <attribute name="vsspath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required.]]></short-description>
+        <description><![CDATA[
+          SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required. You should not specify the leading dollar-sign - 
+ it is prepended by Ant automatically.
+ <p>
+ Ant can't cope with a '$' sign in an attribute so we have to add it here.
+ Also we strip off any 'vss://' prefix which is an XMS special and should probably be removed!
+        ]]></description>
+      </attribute>
+      <attribute name="writable" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Make fetched files  writable; optional, default false.]]></short-description>
+        <description><![CDATA[
+          make fetched files  writable; optional, default false.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vsshistory" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSHISTORY"
+      >
+
+  <short-description><![CDATA[Performs History commands to Microsoft Visual SourceSafe.]]></short-description>
+  <description>
+    <![CDATA[Performs History commands to Microsoft Visual SourceSafe.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="dateformat" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Format of dates in fromDate and toDate; optional.]]></short-description>
+        <description><![CDATA[
+          Format of dates in fromDate and toDate; optional.
+ Used when calculating dates with 
+ the numdays attribute. 
+ This string uses the formatting rules of SimpleDateFormat. 
+  Defaults to DateFormat.SHORT.
+        ]]></description>
+      </attribute>
+      <attribute name="fromdate" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Start Date for the Comparison of two versions; optional.]]></short-description>
+        <description><![CDATA[
+          Set the Start Date for the Comparison of two versions; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="fromlabel" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Start Label; optional.]]></short-description>
+        <description><![CDATA[
+          Set the Start Label; optional
+        ]]></description>
+      </attribute>
+      <attribute name="login" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login to use when accessing VSS, formatted as "username,password";
+ optional.]]></short-description>
+        <description><![CDATA[
+          The login to use when accessing VSS, formatted as "username,password";
+ optional.
+ <p>
+ You can omit the password if your database is not password protected.
+  if you have a password and omit it, Ant/VSS will hang.
+        ]]></description>
+      </attribute>
+      <attribute name="numdays" type="int"
+                 briefType="int" required="NOTDEFINED">
+        <short-description><![CDATA[Number of days for comparison; 
+ optional.]]></short-description>
+        <description><![CDATA[
+          Set the number of days for comparison; 
+ optional.
+ <p>
+ The default value is 2 days. (maybe)
+        ]]></description>
+      </attribute>
+      <attribute name="output" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Output file name for the history; optional.]]></short-description>
+        <description><![CDATA[
+          Set the output file name for the history; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="recursive" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to tell the task to recurse down the tree;
+ optional, default false.]]></short-description>
+        <description><![CDATA[
+          Flag to tell the task to recurse down the tree;
+ optional, default false.
+        ]]></description>
+      </attribute>
+      <attribute name="serverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>srssafe.ini</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          Set the directory where <code>srssafe.ini</code> resides; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="ssdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>ss.exe</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          directory where <code>ss.exe</code> resides; optional.
+ By default the task expects it to be in the PATH.
+        ]]></description>
+      </attribute>
+      <attribute name="style" type="org.apache.tools.ant.taskdefs.optional.vss.MSVSSHISTORY.BriefCodediffNofile"
+                 briefType="&quot;brief&quot;, &quot;codediff&quot;, &quot;nofile&quot;, &quot;default&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Specify the output style; optional.]]></short-description>
+        <description><![CDATA[
+          Specify the output style; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="todate" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[End Date for the Comparison of two versions; optional.]]></short-description>
+        <description><![CDATA[
+          Set the End Date for the Comparison of two versions; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="tolabel" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[End Label ; optional.]]></short-description>
+        <description><![CDATA[
+          Set the End Label ; optional
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name the user whose changes we would like to see; optional.]]></short-description>
+        <description><![CDATA[
+          Name the user whose changes we would like to see; optional
+        ]]></description>
+      </attribute>
+      <attribute name="vsspath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required.]]></short-description>
+        <description><![CDATA[
+          SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required. You should not specify the leading dollar-sign - 
+ it is prepended by Ant automatically.
+ <p>
+ Ant can't cope with a '$' sign in an attribute so we have to add it here.
+ Also we strip off any 'vss://' prefix which is an XMS special and should probably be removed!
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="vsslabel" category="scm"
+      classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSLABEL"
+      >
+
+  <short-description><![CDATA[Performs Label commands to Microsoft Visual SourceSafe.]]></short-description>
+  <description>
+    <![CDATA[Performs Label commands to Microsoft Visual SourceSafe.
+
+ <p>
+ The following attributes are interpreted:
+ <table border="1">
+   <tr>
+     <th>Attribute</th>
+     <th>Values</th>
+     <th>Required</th>
+   </tr>
+   <tr>
+      <td>login</td>
+      <td>username,password</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>vsspath</td>
+      <td>SourceSafe path</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>ssdir</td>
+      <td>directory where <code>ss.exe</code> resides. By default the task
+      expects it to be in the PATH.</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>label</td>
+      <td>A label to apply to the hierarchy</td>
+      <td>Yes</td>
+   </tr>
+   <tr>
+      <td>version</td>
+      <td>An existing file or project version to label</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>autoresponse</td>
+      <td>What to respond with (sets the -I option). By default, -I- is
+      used; values of Y or N will be appended to this.</td>
+      <td>No</td>
+   </tr>
+   <tr>
+      <td>comment</td>
+      <td>The comment to use for this label. Empty or '-' for no comment.</td>
+      <td>No</td>
+   </tr>
+ </table>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="autoresponse" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[What to respond with (sets the -I option).]]></short-description>
+        <description><![CDATA[
+          What to respond with (sets the -I option). By default, -I- is
+ used; values of Y or N will be appended to this.
+        ]]></description>
+      </attribute>
+      <attribute name="comment" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The comment to use for this label; optional.]]></short-description>
+        <description><![CDATA[
+          The comment to use for this label; optional.
+ Empty or '-' for no comment.
+ <p>
+ If this is null or empty, it will be replaced with "-" which
+ is what SourceSafe uses for an empty comment.
+        ]]></description>
+      </attribute>
+      <attribute name="label" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Label to apply; required.]]></short-description>
+        <description><![CDATA[
+          Set the label to apply; required.
+ <p>
+ Note we assume that if the supplied string has the value "null" that something
+ went wrong and that the string value got populated from a null object. This
+ happens if a ant variable is used e.g. label="${label_server}" when label_server
+ has not been defined to ant!
+        ]]></description>
+      </attribute>
+      <attribute name="login" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The login to use when accessing VSS, formatted as "username,password";
+ optional.]]></short-description>
+        <description><![CDATA[
+          The login to use when accessing VSS, formatted as "username,password";
+ optional.
+ <p>
+ You can omit the password if your database is not password protected.
+  if you have a password and omit it, Ant/VSS will hang.
+        ]]></description>
+      </attribute>
+      <attribute name="serverpath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>srssafe.ini</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          Set the directory where <code>srssafe.ini</code> resides; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="ssdir" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Directory where <code>ss.exe</code> resides; optional.]]></short-description>
+        <description><![CDATA[
+          directory where <code>ss.exe</code> resides; optional.
+ By default the task expects it to be in the PATH.
+        ]]></description>
+      </attribute>
+      <attribute name="version" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name an existing file or project version to label; optional.]]></short-description>
+        <description><![CDATA[
+          Name an existing file or project version to label; optional.
+ By default the current version is labelled.
+ <p>
+ Note we assume that if the supplied string has the value "null" that something
+ went wrong and that the string value got populated from a null object. This
+ happens if a ant variable is used e.g. version="${ver_server}" when ver_server
+ has not been defined to ant!
+        ]]></description>
+      </attribute>
+      <attribute name="vsspath" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required.]]></short-description>
+        <description><![CDATA[
+          SourceSafe path which specifies the project/file(s) you wish to 
+ perform the action on; required. You should not specify the leading dollar-sign - 
+ it is prepended by Ant automatically.
+ <p>
+ Ant can't cope with a '$' sign in an attribute so we have to add it here.
+ Also we strip off any 'vss://' prefix which is an XMS special and should probably be removed!
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="waitfor" category="control"
+      classname="org.apache.tools.ant.taskdefs.WaitFor"
+      >
+
+  <short-description><![CDATA[Wait for an external event to occur.]]></short-description>
+  <description>
+    <![CDATA[Wait for an external event to occur.
+
+ Wait for an external process to start or to complete some
+ task. This is useful with the <code>parallel</code> task to
+ syncronize the execution of tests with server startup.
+
+ The following attributes can be specified on a waitfor task:
+ <ul>
+ <li>maxwait - maximum length of time to wait before giving up</li>
+ <li>maxwaitunit - The unit to be used to interpret maxwait attribute</li>
+ <li>checkevery - amount of time to sleep between each check</li>
+ <li>checkeveryunit - The unit to be used to interpret checkevery attribute</li>
+ <li>timeoutproperty - name of a property to set if maxwait has been exceeded.</li>
+ </ul>
+
+ The maxwaitunit and checkeveryunit are allowed to have the following values:
+ millesond, second, minute, hour, day and week. The default is millisecond.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="checkevery" type="long"
+                 briefType="long" required="NOTDEFINED">
+        <short-description><![CDATA[Time between each check.]]></short-description>
+        <description><![CDATA[
+          Set the time between each check
+        ]]></description>
+      </attribute>
+      <attribute name="checkeveryunit" type="org.apache.tools.ant.taskdefs.WaitFor.Unit"
+                 briefType="&quot;millisecond&quot;, &quot;second&quot;, &quot;minute&quot;, &quot;hour&quot;, &quot;day&quot;, &quot;week&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Check every time unit.]]></short-description>
+        <description><![CDATA[
+          Set the check every time unit
+        ]]></description>
+      </attribute>
+      <attribute name="maxwait" type="long"
+                 briefType="long" required="NOTDEFINED">
+        <short-description><![CDATA[Maximum length of time to wait.]]></short-description>
+        <description><![CDATA[
+          Set the maximum length of time to wait
+        ]]></description>
+      </attribute>
+      <attribute name="maxwaitunit" type="org.apache.tools.ant.taskdefs.WaitFor.Unit"
+                 briefType="&quot;millisecond&quot;, &quot;second&quot;, &quot;minute&quot;, &quot;hour&quot;, &quot;day&quot;, &quot;week&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Max wait time unit.]]></short-description>
+        <description><![CDATA[
+          Set the max wait time unit
+        ]]></description>
+      </attribute>
+      <attribute name="timeoutproperty" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name the property to set after a timeout.]]></short-description>
+        <description><![CDATA[
+          Name the property to set after a timeout.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="and" type="org.apache.tools.ant.taskdefs.condition.And"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;and&gt; condition "container".]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;and&gt; condition "container".]]>
+        </description>
+      </element>
+
+      <element name="available" type="org.apache.tools.ant.taskdefs.Available"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;available&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;available&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="checksum" type="org.apache.tools.ant.taskdefs.Checksum"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;checksum&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;checksum&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="contains" type="org.apache.tools.ant.taskdefs.condition.Contains"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;contains&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;contains&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="equals" type="org.apache.tools.ant.taskdefs.condition.Equals"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;equals&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;equals&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="filesmatch" type="org.apache.tools.ant.taskdefs.condition.FilesMatch"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;filesmatch&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;filesmatch&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="http" type="org.apache.tools.ant.taskdefs.condition.Http"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;http&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;http&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="isfalse" type="org.apache.tools.ant.taskdefs.condition.IsFalse"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;isfalse&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;isfalse&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="isset" type="org.apache.tools.ant.taskdefs.condition.IsSet"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;isset&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;isset&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="istrue" type="org.apache.tools.ant.taskdefs.condition.IsTrue"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;istrue&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;istrue&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="not" type="org.apache.tools.ant.taskdefs.condition.Not"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;not&gt; condition "container".]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;not&gt; condition "container".]]>
+        </description>
+      </element>
+
+      <element name="or" type="org.apache.tools.ant.taskdefs.condition.Or"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;or&gt; condition "container".]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;or&gt; condition "container".]]>
+        </description>
+      </element>
+
+      <element name="os" type="org.apache.tools.ant.taskdefs.condition.Os"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;os&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;os&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="socket" type="org.apache.tools.ant.taskdefs.condition.Socket"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add a &lt;socket&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add a &lt;socket&gt; condition.]]>
+        </description>
+      </element>
+
+      <element name="uptodate" type="org.apache.tools.ant.taskdefs.UpToDate"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an &lt;uptodate&gt; condition.]]></short-description>
+        <description>
+          <![CDATA[Add an &lt;uptodate&gt; condition.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="war" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.War"
+      matchingTask="true">
+
+  <short-description><![CDATA[An extension of &lt;jar&gt; to create a WAR archive.]]></short-description>
+  <description>
+    <![CDATA[An extension of &lt;jar&gt; to create a WAR archive.
+ Contains special treatment for files that should end up in the
+ <code>WEB-INF/lib</code>, <code>WEB-INF/classes</code> or
+ <code>WEB-INF</code> directories of the Web Application Archive.</p>
+ <p>(The War task is a shortcut for specifying the particular layout of a WAR file. 
+ The same thing can be accomplished by using the <i>prefix</i> and <i>fullpath</i>
+ attributes of zipfilesets in a Zip or Jar task.)</p>
+ <p>The extended zipfileset element from the zip task (with attributes <i>prefix</i>, <i>fullpath</i>, and <i>src</i>) is available in the War task.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="basedir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Directory from which to archive files; optional.]]></short-description>
+        <description><![CDATA[
+          Directory from which to archive files; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="compress" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether we want to compress the files or only store them;
+ optional, default=true;.]]></short-description>
+        <description><![CDATA[
+          Whether we want to compress the files or only store them;
+ optional, default=true;
+        ]]></description>
+      </attribute>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to create; required.]]></short-description>
+        <description><![CDATA[
+          The file to create; required.
+        ]]></description>
+      </attribute>
+      <attribute name="duplicate" type="org.apache.tools.ant.taskdefs.Zip.Duplicate"
+                 briefType="&quot;add&quot;, &quot;preserve&quot;, &quot;fail&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Sets behavior for when a duplicate file is about to be added -
+ one of <code>keep</code>, <code>skip</code> or <code>overwrite</code>.]]></short-description>
+        <description><![CDATA[
+          Sets behavior for when a duplicate file is about to be added -
+ one of <code>keep</code>, <code>skip</code> or <code>overwrite</code>.
+ Possible values are: <code>keep</code> (keep both
+ of the files); <code>skip</code> (keep the first version
+ of the file found); <code>overwrite</code> overwrite the file
+ with the new file
+ Default for zip tasks is <code>keep</code>
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Encoding to use for filenames, defaults to the platform's
+ default encoding.]]></short-description>
+        <description><![CDATA[
+          Encoding to use for filenames, defaults to the platform's
+ default encoding.
+
+ <p>For a list of possible values see <a
+ href="http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html">http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html</a>.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="filesonly" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, emulate Sun's jar utility by not adding parent directories;
+ optional, defaults to false.]]></short-description>
+        <description><![CDATA[
+          If true, emulate Sun's jar utility by not adding parent directories;
+ optional, defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="index" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether or not to create an index list for classes.]]></short-description>
+        <description><![CDATA[
+          Set whether or not to create an index list for classes.
+ This may speed up classloading in some cases.
+        ]]></description>
+      </attribute>
+      <attribute name="manifest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The manifest file to use.]]></short-description>
+        <description><![CDATA[
+          The manifest file to use. This can be either the location of a manifest,
+ or the name of a jar added through a fileset. If its the name of an added
+ jar, the task expects the manifest to be in the jar at META-INF/MANIFEST.MF.
+        ]]></description>
+      </attribute>
+      <attribute name="update" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, updates an existing file, otherwise overwrite
+ any existing one; optional defaults to false.]]></short-description>
+        <description><![CDATA[
+          If true, updates an existing file, otherwise overwrite
+ any existing one; optional defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="webxml" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Deployment descriptor to use (WEB-INF/web.xml);
+ required unless <tt>update=true</tt>.]]></short-description>
+        <description><![CDATA[
+          set the deployment descriptor to use (WEB-INF/web.xml);
+ required unless <tt>update=true</tt>
+        ]]></description>
+      </attribute>
+      <attribute name="whenempty" type="org.apache.tools.ant.taskdefs.Zip.WhenEmpty"
+                 briefType="&quot;fail&quot;, &quot;skip&quot;, &quot;create&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Sets behavior of the task when no files match.]]></short-description>
+        <description><![CDATA[
+          Sets behavior of the task when no files match.
+ Possible values are: <code>fail</code> (throw an exception
+ and halt the build); <code>skip</code> (do not create
+ any archive, but issue a warning); <code>create</code>
+ (make an archive with no entries).
+ Default for zip tasks is <code>skip</code>;
+ for jar tasks, <code>create</code>.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classes" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add files under WEB-INF/classes.]]></short-description>
+        <description>
+          <![CDATA[add files under WEB-INF/classes]]>
+        </description>
+      </element>
+
+      <element name="manifest" type="org.apache.tools.ant.taskdefs.Manifest"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Allows the manifest for the archive file to be provided inline
+ in the buildfile rather than in an external file.]]></short-description>
+        <description>
+          <![CDATA[Allows the manifest for the archive file to be provided inline
+ in the buildfile rather than in an external file.]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files.]]>
+        </description>
+      </element>
+
+      <element name="lib" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add files under WEB-INF/lib/.]]></short-description>
+        <description>
+          <![CDATA[add files under WEB-INF/lib/]]>
+        </description>
+      </element>
+
+      <element name="metainf" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a zipfileset to include in the META-INF directory.]]></short-description>
+        <description>
+          <![CDATA[Adds a zipfileset to include in the META-INF directory.]]>
+        </description>
+      </element>
+
+      <element name="webinf" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Files to add under WEB-INF;.]]></short-description>
+        <description>
+          <![CDATA[files to add under WEB-INF;]]>
+        </description>
+      </element>
+
+      <element name="zipgroupfileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a group of zip files.]]></short-description>
+        <description>
+          <![CDATA[Adds a group of zip files.]]>
+        </description>
+      </element>
+
+      <element name="zipfileset" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files that can be
+ read from an archive and be given a prefix/fullpath.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files that can be
+ read from an archive and be given a prefix/fullpath.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="wljspc" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.jsp.WLJspc"
+      matchingTask="true">
+
+  <short-description><![CDATA[Precompiles JSP's using WebLogic's JSP compiler (weblogic.jspc).]]></short-description>
+  <description>
+    <![CDATA[Precompiles JSP's using WebLogic's JSP compiler (weblogic.jspc).]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Classpath to be used for this compilation.]]></short-description>
+        <description><![CDATA[
+          Set the classpath to be used for this compilation.
+        ]]></description>
+      </attribute>
+      <attribute name="dest" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Directory containing the source jsp's.]]></short-description>
+        <description><![CDATA[
+          Set the directory containing the source jsp's
+        ]]></description>
+      </attribute>
+      <attribute name="package" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Package under which the compiled classes go.]]></short-description>
+        <description><![CDATA[
+          Set the package under which the compiled classes go
+        ]]></description>
+      </attribute>
+      <attribute name="src" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Directory containing the source jsp's.]]></short-description>
+        <description><![CDATA[
+          Set the directory containing the source jsp's
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Maybe creates a nested classpath element.]]></short-description>
+        <description>
+          <![CDATA[Maybe creates a nested classpath element.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="wlrun" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ejb.WLRun"
+      >
+
+  <short-description><![CDATA[Starts a WebLogic server.]]></short-description>
+  <description>
+    <![CDATA[Starts a WebLogic server.
+ A number of parameters are used to control the operation of the weblogic instance. Note that the task,
+ and hence ant, will not complete until the weblogic instance is stopped.</p>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="args" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Additional argument string passed to the Weblogic instance;
+ optional.]]></short-description>
+        <description><![CDATA[
+          Additional argument string passed to the Weblogic instance;
+ optional.
+        ]]></description>
+      </attribute>
+      <attribute name="beahome" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The location of the BEA Home; implicitly
+ selects Weblogic 6.0; optional.]]></short-description>
+        <description><![CDATA[
+          The location of the BEA Home; implicitly
+ selects Weblogic 6.0; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[The classpath to be used with the Java Virtual Machine that runs the Weblogic
+ Server; required.]]></short-description>
+        <description><![CDATA[
+          The classpath to be used with the Java Virtual Machine that runs the Weblogic
+ Server; required. Prior to Weblogic 6.0, this is typically set to the Weblogic
+ boot classpath. Under Weblogic 6.0 this should include all the
+ weblogic jars
+        ]]></description>
+      </attribute>
+      <attribute name="domain" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Domain to run in; required for WL6.0.]]></short-description>
+        <description><![CDATA[
+          Set the Domain to run in; required for WL6.0
+        ]]></description>
+      </attribute>
+      <attribute name="home" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The location where weblogic lives.]]></short-description>
+        <description><![CDATA[
+          The location where weblogic lives.
+ Required. This is the absolute location, not relative to
+  BEA home.
+        ]]></description>
+      </attribute>
+      <attribute name="jvmargs" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Additional arguments to pass to the weblogic JVM.]]></short-description>
+        <description><![CDATA[
+          Set the additional arguments to pass to the weblogic JVM
+        ]]></description>
+      </attribute>
+      <attribute name="name" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the weblogic server within the weblogic home which is to be run.]]></short-description>
+        <description><![CDATA[
+          The name of the weblogic server within the weblogic home which is to be run.
+ Optiona, defaults to &quot;myserver&quot;
+        ]]></description>
+      </attribute>
+      <attribute name="pkpassword" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Private key password so the server can decrypt the SSL private key file;
+ optional and only applicable to WL6.0.]]></short-description>
+        <description><![CDATA[
+          Set the private key password so the server can decrypt the SSL private key file;
+ optional and only applicable to WL6.0.
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Management password of the server;
+ optional and only applicable to WL6.0.]]></short-description>
+        <description><![CDATA[
+          Set the management password of the server;
+ optional and only applicable to WL6.0.
+        ]]></description>
+      </attribute>
+      <attribute name="policy" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the security policy file within the weblogic home directory that
+ is to be used.]]></short-description>
+        <description><![CDATA[
+          The name of the security policy file within the weblogic home directory that
+ is to be used. If not specified, the default policy file <code>weblogic.policy</code>
+ is used.
+        ]]></description>
+      </attribute>
+      <attribute name="properties" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The name of the server's properties file within the weblogic home directory
+ used to control the weblogic instance;
+ required for WL4.5.1.]]></short-description>
+        <description><![CDATA[
+          The name of the server's properties file within the weblogic home directory
+ used to control the weblogic instance;
+ required for WL4.5.1
+        ]]></description>
+      </attribute>
+      <attribute name="username" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Management username to run the server;
+ optional and only applicable to WL6.0.]]></short-description>
+        <description><![CDATA[
+          Set the management username to run the server;
+ optional and only applicable to WL6.0.
+        ]]></description>
+      </attribute>
+      <attribute name="weblogicmainclass" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the main class for weblogic; optional.]]></short-description>
+        <description><![CDATA[
+          name of the main class for weblogic; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="wlclasspath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Weblogic classpath used by the Weblogic Server;
+ optional, and only applicable to WL4.5.1
+
+ The weblogic classpath is used by weblogic to support dynamic class loading.]]></short-description>
+        <description><![CDATA[
+          Set the weblogic classpath used by the Weblogic Server;
+ optional, and only applicable to WL4.5.1
+
+ The weblogic classpath is used by weblogic to support dynamic class loading.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add the classpath for the user classes.]]></short-description>
+        <description>
+          <![CDATA[Add the classpath for the user classes]]>
+        </description>
+      </element>
+
+      <element name="wlclasspath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Get the classpath to the weblogic classpaths.]]></short-description>
+        <description>
+          <![CDATA[Get the classpath to the weblogic classpaths]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="wlstop" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.ejb.WLStop"
+      >
+
+  <short-description><![CDATA[Shuts down a WebLogic server.]]></short-description>
+  <description>
+    <![CDATA[Shuts down a WebLogic server.
+ To shut down an instance you must supply both a username and
+ a password.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="beahome" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The location of the BEA Home; implicitly
+ selects Weblogic 6.0 shutdown; optional.]]></short-description>
+        <description><![CDATA[
+          The location of the BEA Home; implicitly
+ selects Weblogic 6.0 shutdown; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[The classpath to be used with the Java Virtual Machine that runs the Weblogic
+ Shutdown command;.]]></short-description>
+        <description><![CDATA[
+          The classpath to be used with the Java Virtual Machine that runs the Weblogic
+ Shutdown command;
+        ]]></description>
+      </attribute>
+      <attribute name="delay" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Delay (in seconds) before shutting down the server;
+ optional.]]></short-description>
+        <description><![CDATA[
+          Set the delay (in seconds) before shutting down the server;
+ optional.
+        ]]></description>
+      </attribute>
+      <attribute name="password" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The password for the account specified in the
+ user parameter; required.]]></short-description>
+        <description><![CDATA[
+          The password for the account specified in the
+ user parameter; required
+        ]]></description>
+      </attribute>
+      <attribute name="url" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[URL to which the weblogic server is listening
+ for T3 connections; required.]]></short-description>
+        <description><![CDATA[
+          Set the URL to which the weblogic server is listening
+ for T3 connections; required.
+        ]]></description>
+      </attribute>
+      <attribute name="user" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The username of the account which will be used to shutdown the server;
+ required.]]></short-description>
+        <description><![CDATA[
+          The username of the account which will be used to shutdown the server;
+ required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[The classpath to be used with the Java Virtual Machine that runs the Weblogic
+ Shutdown command;.]]></short-description>
+        <description>
+          <![CDATA[The classpath to be used with the Java Virtual Machine that runs the Weblogic
+ Shutdown command;]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="wsdltodotnet" category="dotnet"
+      classname="org.apache.tools.ant.taskdefs.optional.dotnet.WsdlToDotnet"
+      >
+
+  <short-description><![CDATA[Converts a WSDL file or URL resource into a .NET language.]]></short-description>
+  <description>
+    <![CDATA[Converts a WSDL file or URL resource into a .NET language.
+
+ See "Creating an XML Web Service Proxy", "wsdl.exe" docs in
+ the framework SDK documentation]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the file to generate.]]></short-description>
+        <description><![CDATA[
+          Name of the file to generate. Required
+        ]]></description>
+      </attribute>
+      <attribute name="extraoptions" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Any extra WSDL.EXE options which aren't explicitly
+  supported by the ant wrapper task; optional.]]></short-description>
+        <description><![CDATA[
+          Any extra WSDL.EXE options which aren't explicitly
+  supported by the ant wrapper task; optional
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Should failure halt the build?.]]></short-description>
+        <description><![CDATA[
+          Should failure halt the build? optional, default=true
+        ]]></description>
+      </attribute>
+      <attribute name="language" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Language; one of "CS", "JS", or "VB"
+ optional, default is CS for C# source.]]></short-description>
+        <description><![CDATA[
+          set the language; one of "CS", "JS", or "VB"
+ optional, default is CS for C# source
+        ]]></description>
+      </attribute>
+      <attribute name="namespace" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Namespace to place  the source in.
+ optional; default "".]]></short-description>
+        <description><![CDATA[
+          namespace to place  the source in.
+ optional; default ""
+        ]]></description>
+      </attribute>
+      <attribute name="server" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to enable server side code generation;
+ optional, default=false.]]></short-description>
+        <description><![CDATA[
+          flag to enable server side code generation;
+ optional, default=false
+        ]]></description>
+      </attribute>
+      <attribute name="srcfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The local WSDL file to parse; either url or srcFile is required.]]></short-description>
+        <description><![CDATA[
+          The local WSDL file to parse; either url or srcFile is required.
+        ]]></description>
+      </attribute>
+      <attribute name="url" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[URL to fetch.]]></short-description>
+        <description><![CDATA[
+          Sets the URL to fetch. Fetching is by wsdl.exe; Ant proxy settings
+ are ignored; either url or srcFile is required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="xmlproperty" category="xml"
+      classname="org.apache.tools.ant.taskdefs.XmlProperty"
+      >
+
+  <short-description><![CDATA[Loads property values from a valid XML file, generating the property names from the file's element and attribute names.]]></short-description>
+  <description>
+    <![CDATA[Loads property values from a valid XML file,
+ generating the property names from the file's element and attribute names.
+
+ Example:
+ <pre>
+   &lt;root-tag myattr="true"&gt;
+     &lt;inner-tag someattr="val"&gt;Text&lt;/inner-tag&gt;
+     &lt;a2&gt;&lt;a3&gt;&lt;a4&gt;false&lt;/a4&gt;&lt;/a3&gt;&lt;/a2&gt;
+   &lt;/root-tag&gt;
+</pre>
+ this generates
+ <pre>
+  root-tag(myattr)=true
+  root-tag.inner-tag=Text
+  root-tag.inner-tag(someattr)=val
+  root-tag.a2.a3.a4=false
+ </pre>]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="collapseattributes" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to treat attributes as nested elements;
+ optional, default false.]]></short-description>
+        <description><![CDATA[
+          flag to treat attributes as nested elements;
+ optional, default false
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The XML file to parse; required.]]></short-description>
+        <description><![CDATA[
+          The XML file to parse; required.
+        ]]></description>
+      </attribute>
+      <attribute name="keeproot" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to include the xml root tag as a 
+ first value in the property name; optional, 
+ default is true.]]></short-description>
+        <description><![CDATA[
+          flag to include the xml root tag as a 
+ first value in the property name; optional, 
+ default is true
+        ]]></description>
+      </attribute>
+      <attribute name="prefix" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[The prefix to prepend to each property.]]></short-description>
+        <description><![CDATA[
+          the prefix to prepend to each property
+        ]]></description>
+      </attribute>
+      <attribute name="validate" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Flag to validate the XML file; optional, default false.]]></short-description>
+        <description><![CDATA[
+          flag to validate the XML file; optional, default false
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="xmlvalidate" category="other"
+      classname="org.apache.tools.ant.taskdefs.optional.XMLValidateTask"
+      >
+
+  <short-description><![CDATA[Checks XML files are valid (or only well formed).]]></short-description>
+  <description>
+    <![CDATA[Checks XML files are valid (or only well formed). The
+ task uses the SAX2 parser implementation provided by JAXP by default
+ (probably the one that is used by Ant itself), but one can specify any
+ SAX1/2 parser if needed]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="classname" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Specify the class name of the SAX parser to be used. (optional).]]></short-description>
+        <description><![CDATA[
+          Specify the class name of the SAX parser to be used. (optional)
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Specify the classpath to be searched to load the parser (optional).]]></short-description>
+        <description><![CDATA[
+          Specify the classpath to be searched to load the parser (optional)
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Where to find the parser class; optional.]]></short-description>
+        <description><![CDATA[
+          Where to find the parser class; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="failonerror" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Specify how parser error are to be handled; 
+ optional, default=true
+ <p>
+ If set to <code>true</code> (default), throw a buildException if the parser yields an error.]]></short-description>
+        <description><![CDATA[
+          Specify how parser error are to be handled; 
+ optional, default=true
+ <p>
+ If set to <code>true</code> (default), throw a buildException if the parser yields an error.
+        ]]></description>
+      </attribute>
+      <attribute name="file" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Specify the file to be checked; optional.]]></short-description>
+        <description><![CDATA[
+          specify the file to be checked; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="lenient" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Specify whether the parser should be validating.]]></short-description>
+        <description><![CDATA[
+          Specify whether the parser should be validating. Default is <code>true</code>.
+ <p>
+ If set to false, the validation will fail only if the parsed document is not well formed XML.
+ <p>
+ this option is ignored if the specified class with {@link #setClassName(String)} is not a SAX2
+ XMLReader.
+        ]]></description>
+      </attribute>
+      <attribute name="warn" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Specify how parser error are to be handled.]]></short-description>
+        <description><![CDATA[
+          Specify how parser error are to be handled.
+ <p>
+ If set to <code>true</true> (default), log a warn message for each SAX warn event.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="xmlcatalog" type="org.apache.tools.ant.types.XMLCatalog"
+               briefType="XMLCatalog"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add an XMLCatalog as a nested element; optional.]]></short-description>
+        <description>
+          <![CDATA[add an XMLCatalog as a nested element; optional.]]>
+        </description>
+      </element>
+
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Specify a set of file to be checked.]]></short-description>
+        <description>
+          <![CDATA[specify a set of file to be checked]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[No description.]]></short-description>
+        <description>
+          <![CDATA[]]>
+        </description>
+      </element>
+
+      <element name="dtd" type="org.apache.tools.ant.types.DTDLocation"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create a DTD location record; optional.]]></short-description>
+        <description>
+          <![CDATA[Create a DTD location record; optional.
+ This stores the location of a DTD. The DTD is identified
+ by its public Id.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="xslt" category="xml"
+      classname="org.apache.tools.ant.taskdefs.XSLTProcess"
+      matchingTask="true">
+
+  <short-description><![CDATA[Processes a set of XML documents via XSLT.]]></short-description>
+  <description>
+    <![CDATA[Processes a set of XML documents via XSLT. This is
+ useful for building views of XML based documentation.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="basedir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Base directory; 
+ optional, default is the project's basedir.]]></short-description>
+        <description><![CDATA[
+          Set the base directory; 
+ optional, default is the project's basedir.
+        ]]></description>
+      </attribute>
+      <attribute name="classpath" type="org.apache.tools.ant.types.Path"
+                 briefType="Path" required="NOTDEFINED">
+        <short-description><![CDATA[Optional classpath to the XSL processor.]]></short-description>
+        <description><![CDATA[
+          Set the optional classpath to the XSL processor
+        ]]></description>
+      </attribute>
+      <attribute name="classpathref" type="org.apache.tools.ant.types.Reference"
+                 briefType="Reference" required="NOTDEFINED">
+        <short-description><![CDATA[Reference to an optional classpath to the XSL processor.]]></short-description>
+        <description><![CDATA[
+          Set the reference to an optional classpath to the XSL processor
+        ]]></description>
+      </attribute>
+      <attribute name="destdir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Destination directory into which the XSL result
+ files should be copied to; 
+ required, unless <tt>in</tt> and <tt>out</tt> are
+ specified.]]></short-description>
+        <description><![CDATA[
+          Set the destination directory into which the XSL result
+ files should be copied to; 
+ required, unless <tt>in</tt> and <tt>out</tt> are
+ specified.
+        ]]></description>
+      </attribute>
+      <attribute name="extension" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Desired file extension to be used for the target;
+ optional, default is html.]]></short-description>
+        <description><![CDATA[
+          Set the desired file extension to be used for the target;
+ optional, default is html.
+        ]]></description>
+      </attribute>
+      <attribute name="force" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Set whether to check dependencies, or always generate;
+ optional, default is false.]]></short-description>
+        <description><![CDATA[
+          Set whether to check dependencies, or always generate;
+ optional, default is false.
+        ]]></description>
+      </attribute>
+      <attribute name="in" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies a single XML document to be styled.]]></short-description>
+        <description><![CDATA[
+          specifies a single XML document to be styled. Should be used 
+ with the <tt>out</tt> attribute; ; required if <tt>out</tt> is set
+        ]]></description>
+      </attribute>
+      <attribute name="out" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Specifies the output name for the styled result from the 
+ <tt>in</tt> attribute; required if <tt>in</tt> is set.]]></short-description>
+        <description><![CDATA[
+          Specifies the output name for the styled result from the 
+ <tt>in</tt> attribute; required if <tt>in</tt> is set
+        ]]></description>
+      </attribute>
+      <attribute name="processor" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the XSL processor to use; optional, default trax.]]></short-description>
+        <description><![CDATA[
+          Set the name of the XSL processor to use; optional, default trax.
+ Other values are "xalan" for Xalan1 and "xslp" for XSL:P, though the
+ later is strongly deprecated.
+        ]]></description>
+      </attribute>
+      <attribute name="scanincludeddirectories" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether to style all files in the included directories as well;
+ optional, default is true.]]></short-description>
+        <description><![CDATA[
+          Whether to style all files in the included directories as well;
+ optional, default is true.
+        ]]></description>
+      </attribute>
+      <attribute name="style" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Name of the stylesheet to use - given either relative
+ to the project's basedir or as an absolute path; required.]]></short-description>
+        <description><![CDATA[
+          Name of the stylesheet to use - given either relative
+ to the project's basedir or as an absolute path; required.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="xmlcatalog" type="org.apache.tools.ant.types.XMLCatalog"
+               briefType="XMLCatalog"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Add the catalog to our internal catalog.]]></short-description>
+        <description>
+          <![CDATA[Add the catalog to our internal catalog]]>
+        </description>
+      </element>
+
+      <element name="classpath" type="org.apache.tools.ant.types.Path"
+               briefType="Path"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Optional classpath to the XSL processor.]]></short-description>
+        <description>
+          <![CDATA[Set the optional classpath to the XSL processor]]>
+        </description>
+      </element>
+
+      <element name="outputproperty" type="org.apache.tools.ant.taskdefs.XSLTProcess.OutputProperty"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create an instance of an output property to be configured.]]></short-description>
+        <description>
+          <![CDATA[Create an instance of an output property to be configured.]]>
+        </description>
+      </element>
+
+      <element name="param" type="org.apache.tools.ant.taskdefs.XSLTProcess.Param"
+               briefType=""
+               required="NOTDEFINED">
+        <short-description><![CDATA[Create an instance of an XSL parameter for configuration by Ant.]]></short-description>
+        <description>
+          <![CDATA[Create an instance of an XSL parameter for configuration by Ant.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+
+
+<task name="zip" category="packaging"
+      classname="org.apache.tools.ant.taskdefs.Zip"
+      matchingTask="true">
+
+  <short-description><![CDATA[Create a Zip file.]]></short-description>
+  <description>
+    <![CDATA[Create a Zip file.]]>
+  </description>
+
+  <structure>
+
+    <attributes>
+      <attribute name="basedir" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[Directory from which to archive files; optional.]]></short-description>
+        <description><![CDATA[
+          Directory from which to archive files; optional.
+        ]]></description>
+      </attribute>
+      <attribute name="compress" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[Whether we want to compress the files or only store them;
+ optional, default=true;.]]></short-description>
+        <description><![CDATA[
+          Whether we want to compress the files or only store them;
+ optional, default=true;
+        ]]></description>
+      </attribute>
+      <attribute name="destfile" type="java.io.File"
+                 briefType="File" required="NOTDEFINED">
+        <short-description><![CDATA[The file to create; required.]]></short-description>
+        <description><![CDATA[
+          The file to create; required.
+        ]]></description>
+      </attribute>
+      <attribute name="duplicate" type="org.apache.tools.ant.taskdefs.Zip.Duplicate"
+                 briefType="&quot;add&quot;, &quot;preserve&quot;, &quot;fail&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Sets behavior for when a duplicate file is about to be added -
+ one of <code>keep</code>, <code>skip</code> or <code>overwrite</code>.]]></short-description>
+        <description><![CDATA[
+          Sets behavior for when a duplicate file is about to be added -
+ one of <code>keep</code>, <code>skip</code> or <code>overwrite</code>.
+ Possible values are: <code>keep</code> (keep both
+ of the files); <code>skip</code> (keep the first version
+ of the file found); <code>overwrite</code> overwrite the file
+ with the new file
+ Default for zip tasks is <code>keep</code>
+        ]]></description>
+      </attribute>
+      <attribute name="encoding" type="java.lang.String"
+                 briefType="String" required="NOTDEFINED">
+        <short-description><![CDATA[Encoding to use for filenames, defaults to the platform's
+ default encoding.]]></short-description>
+        <description><![CDATA[
+          Encoding to use for filenames, defaults to the platform's
+ default encoding.
+
+ <p>For a list of possible values see <a
+ href="http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html">http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html</a>.</p>
+        ]]></description>
+      </attribute>
+      <attribute name="filesonly" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, emulate Sun's jar utility by not adding parent directories;
+ optional, defaults to false.]]></short-description>
+        <description><![CDATA[
+          If true, emulate Sun's jar utility by not adding parent directories;
+ optional, defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="update" type="boolean"
+                 briefType="boolean" required="NOTDEFINED">
+        <short-description><![CDATA[If true, updates an existing file, otherwise overwrite
+ any existing one; optional defaults to false.]]></short-description>
+        <description><![CDATA[
+          If true, updates an existing file, otherwise overwrite
+ any existing one; optional defaults to false.
+        ]]></description>
+      </attribute>
+      <attribute name="whenempty" type="org.apache.tools.ant.taskdefs.Zip.WhenEmpty"
+                 briefType="&quot;fail&quot;, &quot;skip&quot;, &quot;create&quot;" required="NOTDEFINED">
+        <short-description><![CDATA[Sets behavior of the task when no files match.]]></short-description>
+        <description><![CDATA[
+          Sets behavior of the task when no files match.
+ Possible values are: <code>fail</code> (throw an exception
+ and halt the build); <code>skip</code> (do not create
+ any archive, but issue a warning); <code>create</code>
+ (make an archive with no entries).
+ Default for zip tasks is <code>skip</code>;
+ for jar tasks, <code>create</code>.
+        ]]></description>
+      </attribute>
+    </attributes>
+
+    <elements>
+      <element name="fileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files.]]>
+        </description>
+      </element>
+
+      <element name="zipgroupfileset" type="org.apache.tools.ant.types.FileSet"
+               briefType="Fileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a group of zip files.]]></short-description>
+        <description>
+          <![CDATA[Adds a group of zip files.]]>
+        </description>
+      </element>
+
+      <element name="zipfileset" type="org.apache.tools.ant.types.ZipFileSet"
+               briefType="ZipFileset"
+               required="NOTDEFINED">
+        <short-description><![CDATA[Adds a set of files that can be
+ read from an archive and be given a prefix/fullpath.]]></short-description>
+        <description>
+          <![CDATA[Adds a set of files that can be
+ read from an archive and be given a prefix/fullpath.]]>
+        </description>
+      </element>
+
+    </elements>
+
+  </structure>
+
+</task>
+</tasks>
diff --git a/ant/org.eclipse.ant.ui/Ant Editor Content Assist Dev/tasks.xml b/ant/org.eclipse.ant.ui/Ant Editor Content Assist Dev/tasks.xml
new file mode 100644
index 0000000..626f04e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor Content Assist Dev/tasks.xml
@@ -0,0 +1,5139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TASKS>
+	<TASK NAME="ant">
+		<DESCRIPTION>&lt;p&gt;Runs Ant on a supplied buildfile. This can be used to build subprojects.&lt;/p&gt;
+&lt;p&gt;When the &lt;i&gt;antfile&lt;/i&gt; attribute is omitted, the file &amp;quot;build.xml&amp;quot;
+in the supplied directory (&lt;i&gt;dir&lt;/i&gt; attribute) is used.&lt;/p&gt;
+&lt;p&gt;If no target attribute is supplied, the default target of the new project is
+used.&lt;/p&gt;
+&lt;p&gt;By default, all of the properties of the current project will be
+available in the new project.   Alternatively, you can
+set the &lt;i&gt;inheritAll&lt;/i&gt; attribute to &lt;code&gt;false&lt;/code&gt; and only
+&amp;quot;user&amp;quot; properties (i.e., those passed on the command-line)
+will be passed to the new project.  In either case, the set of
+properties passed to the new project will override the properties that 
+are set in the new project (See also the &lt;a href=&quot;property.html&quot;&gt;property task&lt;/a&gt;).&lt;/p&gt;
+&lt;p&gt;You can also set properties in the new project from the old project by
+using nested property tags. These properties are always passed regardless of the
+setting of &lt;i&gt;inheritAll&lt;/i&gt;.  This allows you to parameterize your subprojects.&lt;/p&gt;
+&lt;p&gt;References to data types can also be passed to the new project, but
+by default they are not.  If you set the inheritrefs attribute to
+true, all references will be copied, but they will not override
+references defined in the new project.&lt;/p&gt;
+&lt;p&gt;Nested &lt;a href=&quot;#reference&quot;&gt;&lt;i&gt;&amp;lt;reference&amp;gt;&lt;/i&gt;&lt;/a&gt; elements
+can also be used to copy references from the calling project to the
+new project, optionally under a different id.  References taken from
+nested elements will override existing references in the new
+project.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="antfile" REQUIRED="no">
+			<DESCRIPTION>the buildfile to use. Defaults to&quot;build.xml&quot;.  This file is expected to be a filenamerelative to the dir attribute given</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="no">
+			<DESCRIPTION>the directory to use as a basedir for the new Ant project. Defaults to the current project's basedir, unlessinheritall has been set to false, in which case it doesn'thave a default value.  This will override the basedirsetting of the called project</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="target" REQUIRED="no">
+			<DESCRIPTION>the target of the new Ant project that should be executed.Defaults to the new project's default target</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="output" REQUIRED="no">
+			<DESCRIPTION>Filename to write the ant output to.  This isrelative to the value of the dir attribute if it has been set orto the base directory of the current project otherwise.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="inheritall" REQUIRED="no">
+			<DESCRIPTION>If true, pass all properties to thenew Ant project.  Defaults to true</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="inheritrefs" REQUIRED="no">
+			<DESCRIPTION>If true, pass all references to thenew Ant project.  Defaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="antcall">
+		<DESCRIPTION>&lt;p&gt;Call another target within the same build-file optionally specifying some
+properties (param's in this context)&lt;/p&gt;
+&lt;p&gt;By default, all of the properties of the current project will be
+available in the new project.   Alternatively, you can
+set the &lt;i&gt;inheritAll&lt;/i&gt; attribute to &lt;code&gt;false&lt;/code&gt; and only
+&amp;quot;user&amp;quot; properties (i.e., those passed on the command-line)
+will be passed to the new project.  In either case, the set of
+properties passed to the new project will override the properties that 
+are set in the new project (See also the &lt;a href=&quot;property.html&quot;&gt;property task&lt;/a&gt;).&lt;/p&gt;
+&lt;p&gt;You can also set properties in the new project from the old project by
+using nested param tags. These properties are always passed regardless of the
+setting of &lt;i&gt;inheritAll&lt;/i&gt;.  This allows you to parameterize your subprojects.&lt;/p&gt;
+&lt;p&gt;Nested &lt;a href=&quot;#reference&quot;&gt;&lt;i&gt;&amp;lt;reference&amp;gt;&lt;/i&gt;&lt;/a&gt; elements can
+be used to copy references from the calling project to the new
+project, optionally under a different id.  References taken from
+nested elements will override existing references in the new
+project.&lt;/p&gt;
+&lt;p&gt;
+When a target is invoked by antcall, all of its dependent targets will
+also be called within the context of any new parameters. For example. if
+the target &amp;quot;doSomethingElse&amp;quot; depended on the target &amp;quot;init&amp;quot;, then the 
+&lt;i&gt;antcall&lt;/i&gt; of &amp;quot;doSomethingElse&amp;quot; will call &amp;quot;init&amp;quot; during the call. 
+Of course, any properties defined in the antcall task or inherited from the calling target 
+will be fixed and not overridable in the init task -or indeed in the &amp;quot;doSomethingElse&amp;quot; task.  
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="target" REQUIRED="yes">
+			<DESCRIPTION>The target to execute</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="inheritall" REQUIRED="no">
+			<DESCRIPTION>If true, pass all properties to the new Antproject.  Defaults to true.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="inheritrefs" REQUIRED="no">
+			<DESCRIPTION>If true, pass all references to thenew Ant project.  Defaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="antstructure">
+		<DESCRIPTION>&lt;p&gt;Generates a DTD for Ant buildfiles which contains information
+about all tasks currently known to Ant.&lt;/p&gt; 
+&lt;p&gt;Note that the DTD generated by this task is incomplete, you can
+always add XML entities using &lt;a
+href=&quot;taskdef.html&quot;&gt;&lt;code&gt;&amp;lt;taskdef&amp;gt;&lt;/code&gt;&lt;/a&gt; or &lt;a
+href=&quot;typedef.html&quot;&gt;&lt;code&gt;&amp;lt;typedef&amp;gt;&lt;/code&gt;&lt;/a&gt;. See &lt;a
+href=&quot;http://www.sdv.fr/pages/casa/html/ant-dtd.en.html&quot;
+target=&quot;_top&quot;&gt;here&lt;/a&gt; for a way to get around this problem.&lt;/p&gt;
+&lt;p&gt;This task doesn't know about required attributes, all will be
+listed as &lt;code&gt;#IMPLIED&lt;/code&gt;.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="output" REQUIRED="yes">
+			<DESCRIPTION>file to write the DTD to</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="apply">
+		<DESCRIPTION>&lt;p&gt;Executes a system command. When the &lt;i&gt;os&lt;/i&gt; attribute is specified, then
+the command is only executed when Ant is run on one of the specified operating
+systems.&lt;/p&gt;
+&lt;p&gt;The files and/or directories of a number of &lt;a
+href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt;s are passed as arguments
+to the system command.&lt;/p&gt;
+&lt;p&gt;If you specify a nested &lt;a
+href=&quot;../CoreTypes/mapper.html&quot;&gt;mapper&lt;/a&gt; and the &lt;i&gt;dest&lt;/i&gt; attribute,
+the timestamp of each source file is compared to the timestamp of a
+target file which is defined by the nested mapper element and searched
+for in the given dest.&lt;/p&gt;
+&lt;p&gt;At least one fileset is required, and you must not specify more than
+one mapper.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="executable" REQUIRED="yes">
+			<DESCRIPTION>the command to execute without any command linearguments</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dest" REQUIRED="yes, if you specify a nested mapper">
+			<DESCRIPTION>the directory where the &lt;apply&gt; expects the target files will be placed by the command, when it is executed. </DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="no">
+			<DESCRIPTION>the directory in which the command should be executed</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="relative" REQUIRED="no, default is false">
+			<DESCRIPTION>whether the filenames should be passed on thecommand line as absolute or relative pathnames (relative to thebase directory of the corresponding fileset for source files orthe dest attribute for target files)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="os" REQUIRED="no">
+			<DESCRIPTION>list of Operating Systems on which the command may beexecuted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="output" REQUIRED="no">
+			<DESCRIPTION>the file to which the output of the command should beredirected</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="outputproperty" REQUIRED="no">
+			<DESCRIPTION>the name of a property in which the output of the command should be stored</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="timeout" REQUIRED="no">
+			<DESCRIPTION>Stop the command if it doesn't finish within thespecified time (given in milliseconds)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>Stop the buildprocess if the command exits with areturncode other than 0</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="skipemptyfilesets" REQUIRED="no, default is false">
+			<DESCRIPTION>Don't run the command, if no source files havebeen found or are newer than their corresponding targetfiles</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="parallel" REQUIRED="no">
+			<DESCRIPTION>Run the command only once, appending all files asarguments. If false, command will be executed once for every file. Defaults to false.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="type" REQUIRED="no, default is file">
+			<DESCRIPTION>One of file, dir orboth. If set to file, only the names of plainfiles will be sent to the command. If set to dir, onlythe names of directories are considered</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="newenvironment" REQUIRED="no, default is false">
+			<DESCRIPTION>Do not propagate old environment when new environmentvariables are specified</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="vmlauncher" REQUIRED="no, default is true">
+			<DESCRIPTION>Run command using the Java VM's execution facilitieswhere available. If set to false the underlying OS's shell,either directly or through the antRun scripts, will be used.Under some operating systems, this gives access to facilitiesnot normally available through the VM including, under Windows,being able to execute scripts, rather than their associatedinterpreter.  If you want to specify the name of theexecutable as a relative path to the directory given by thedir attribute, it may become necessary to set vmlauncher tofalse as well</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="available">
+		<DESCRIPTION>&lt;p&gt;Sets a property if a resource is available at runtime. This resource can be a
+file, a directory, a class in the classpath, or a JVM system resource.&lt;/p&gt;
+&lt;p&gt;If the resource is present, the property value is set to true by
+default; otherwise, the property is not set. You can set the value to
+something other than the default by specifying the &lt;code&gt;value&lt;/code&gt; attribute.&lt;/p&gt;
+&lt;p&gt;Normally, this task is used to set properties that are useful to avoid target
+execution depending on system parameters.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="property" REQUIRED="yes">
+			<DESCRIPTION>The name of the property to set</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="value" REQUIRED="no">
+			<DESCRIPTION>The value to set the property to. Defaults to &quot;true&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classname" REQUIRED="yes">
+			<DESCRIPTION>The class to look for in the classpath</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="file" REQUIRED="">
+			<DESCRIPTION>The file to look for</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="resource" REQUIRED="">
+			<DESCRIPTION>The resource to look for in the JVM</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>The classpath to use when looking up classname or resource</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filepath" REQUIRED="no">
+			<DESCRIPTION>The path to use when looking up file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>The classpath to use, given as a reference to a path defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="type" REQUIRED="no">
+			<DESCRIPTION>The type of file to look for, either a directory (type=&quot;dir&quot;) or a file(type=&quot;file&quot;). If not set, the property will be set if the name specified in the fileattribute exists as either a file or a directory</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="ignoresystemclasses" REQUIRED="no">
+			<DESCRIPTION>Ignore Ant's runtime classes, using only the specifiedclasspath.  Only affects the &quot;classname&quot; attribute.  Defaults to &quot;false</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="basename">
+		<DESCRIPTION>&lt;p&gt;
+Task to determine the basename of a specified file, optionally minus a
+specified suffix.
+&lt;/p&gt;
+&lt;p&gt;
+When this task executes, it will set the specified property to the
+value of the last path element of the specified file. If &lt;code&gt;file&lt;/code&gt; is a
+directory, the basename will be the last directory element. If
+&lt;code&gt;file&lt;/code&gt; is a full-path, relative-path, or simple filename,
+the basename will be the simple file name, without any directory elements.
+&lt;/p&gt;
+&lt;p&gt; 
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="yes">
+			<DESCRIPTION>The path to take the basename of</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="property" REQUIRED="yes">
+			<DESCRIPTION>The name of the property to set</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="suffix" REQUIRED="no">
+			<DESCRIPTION>The suffix to remove from the resulting basename(specified either with or without the &quot;.&quot;)</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="buildnumber">
+		<DESCRIPTION>&lt;p&gt;This is a basic task that can be used to track build numbers.&lt;/p&gt;
+&lt;p&gt;It will first attempt to read a build number from a file (by default,
+&lt;code&gt;build.number&lt;/code&gt; in the current directory), then
+set the property &lt;code&gt;build.number&lt;/code&gt; to the value that was read in
+(or to &lt;code&gt;0&lt;/code&gt;, if no such value). It will then increment the
+number by one and write it back out to the file.
+(See the
+&lt;a href=&quot;../OptionalTasks/propertyfile.html&quot;&gt;PropertyFile&lt;/a&gt; task
+if you need finer control over things such as the property name or
+the number format.)
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="no; defaults to &quot;build.number&quot;">
+			<DESCRIPTION>The file to read and write the build number from/to</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="changelog">
+		<DESCRIPTION>&lt;p&gt;Generates an XML-formatted report file of the change logs recorded in a
+&lt;a href=&quot;http://www.cvshome.org/&quot; target=&quot;_top&quot;&gt;CVS&lt;/a&gt; repository. &lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="dir" REQUIRED="no; defaults to ${basedir}.">
+			<DESCRIPTION>The directory from which to run the CVS logcommand</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destfile" REQUIRED="yes">
+			<DESCRIPTION>The file in which to write the change log report</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="usersfile" REQUIRED="no">
+			<DESCRIPTION>Property file that contains name-value pairs mappinguser IDs and names that should be used in the report in place ofthe user ID</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="daysinpast" REQUIRED="no">
+			<DESCRIPTION>Sets the number of days into the past for which thechange log information should be retrieved</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="start" REQUIRED="no">
+			<DESCRIPTION>The earliest date from which change logs are to beincluded in the report</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="end" REQUIRED="no">
+			<DESCRIPTION>The latest date to which change logs are to beincluded in the report</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="checksum">
+		<DESCRIPTION>&lt;p&gt;
+Generates checksum for files.  This task can also be used to
+perform checksum verifications.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="one of either file or
+     at least one nested fileset element.">
+			<DESCRIPTION>The file to generate checksum for</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="algorithm" REQUIRED="no">
+			<DESCRIPTION>Specifies the algorithm to be used tocompute the checksum. Defaults to &quot;MD5&quot;.Other popular algorithms like &quot;SHA&quot; may be usedas well.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="provider" REQUIRED="no">
+			<DESCRIPTION>Specifies the provider of the algorithm</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="fileext" REQUIRED="no">
+			<DESCRIPTION>The generated checksum file's name will be theoriginal filename with &quot;.&quot; and fileext added to it.Defaults to the algorithm name being used.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="property" REQUIRED="no">
+			<DESCRIPTION>Specifies the name of the property to be setwith the generated checksum value.  This cannot be specifiedwhen fileext is being used or when the number of filesfor which checksums is to be generated is greater than 1.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="forceoverwrite" REQUIRED="no">
+			<DESCRIPTION>Overwrite existing files even if the destinationfiles are newer. Defaults to &quot;no&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verifyproperty" REQUIRED="no">
+			<DESCRIPTION>Specifies the name of the property to be setwith &quot;true&quot; or &quot;false&quot; depending upon whetherthe generated checksum matches the existing checksum.  Whenthis is set, the generated checksum is not written to a file orproperty, but rather, the content of the file or property is used tocheck against the generated checksum.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="readbuffersize" REQUIRED="no">
+			<DESCRIPTION>The size of the buffer )in bytes) to use whenreading a file. Defaults to &quot;8192&quot; - you may get abetter performance on big files if you increase this value</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="chmod">
+		<DESCRIPTION>&lt;p&gt;Changes the permissions of a file or all files inside specified directories. Right now it has effect only under Unix.
+The permissions are also UNIX style, like the argument for the chmod command.&lt;/p&gt;
+&lt;p&gt;See the section on &lt;a href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based
+tasks&lt;/a&gt;, on how the inclusion/exclusion of files works, and how to
+write patterns.&lt;/p&gt;
+&lt;p&gt;This task holds an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and
+supports all of FileSet's attributes and nested elements
+directly. More FileSets can be specified using nested
+&lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="exactly one of the two or nested &lt;fileset&gt; elements.">
+			<DESCRIPTION>the file or single directory of which the permissions must be changed</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="">
+			<DESCRIPTION>the directory which holds the files whose permissions must be changed</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="perm" REQUIRED="yes">
+			<DESCRIPTION>the new permissions</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="parallel" REQUIRED="no">
+			<DESCRIPTION>process all specified files using a singlechmod command. Defaults to true</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="type" REQUIRED="no, default is file">
+			<DESCRIPTION>One of file, dir orboth. If set to file, only the permissions ofplain files are going to be changed. If set to dir, onlythe directories are considered</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="concat">
+		<DESCRIPTION>&lt;p&gt;
+Concatenates a file, or a series of files, to a single file or
+the console. The destination file will be created if it does
+not exist, though the the &lt;var&gt;append&lt;/var&gt; attribute may be
+used to alter this behavior.
+&lt;/p&gt;
+&lt;p&gt;
+&lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt;s and/or &lt;a
+href=&quot;../CoreTypes/filelist.html&quot;&gt;FileList&lt;/a&gt;s are used to
+select which files are to be concatenated. There is no
+singular 'file' attribute to specify a single file to cat -- a
+fileset or filelist must also be used in these cases.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="destfile" REQUIRED="no
+ 	  ">
+			<DESCRIPTION>The destination file for the concatenated stream.If not specified the console will be used instead.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="append" REQUIRED="no">
+			<DESCRIPTION>Specifies whether or not the file specified by 'destfile'should be overwritten. Defaults to &quot;no&quot;.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>Specifies the encoding for the input files. Please see http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.htmlfor a list of possible values. Defaults to the platform'sdefault character encoding.</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="condition">
+		<DESCRIPTION>&lt;p&gt;Sets a property if a certain condition holds true - this is a
+generalization of &lt;a href=&quot;available.html&quot;&gt;Available&lt;/a&gt; and &lt;a
+href=&quot;uptodate.html&quot;&gt;Uptodate&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;If the condition holds true, the property value is set to true by
+default; otherwise, the property is not set. You can set the value to
+something other than the default by specifying the &lt;code&gt;value&lt;/code&gt;
+attribute.&lt;/p&gt;
+&lt;p&gt;Conditions are specified as &lt;a href=&quot;#nested&quot;&gt;nested elements&lt;/a&gt;,
+you must specify exactly one condition.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="property" REQUIRED="yes">
+			<DESCRIPTION>The name of the property to set</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="value" REQUIRED="no">
+			<DESCRIPTION>The value to set the property to. Defaults to&quot;true&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="conditions">
+		<DESCRIPTION></DESCRIPTION>	</TASK>
+	<TASK NAME="copy">
+		<DESCRIPTION>&lt;p&gt;Copies a file or FileSet to a new file or directory.  By default, files are
+only copied if the source file is newer than the destination file,
+or when the destination file does not exist.  However, you can explicitly
+overwrite files with the &lt;code&gt;overwrite&lt;/code&gt; attribute.&lt;/p&gt;
+&lt;p&gt;&lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt;s are used to select a
+set of files to copy.
+To use a &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;, the &lt;code&gt;todir&lt;/code&gt; attribute
+must be set.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="yes, unless a nested
+     &lt;fileset&gt; element is used.">
+			<DESCRIPTION>The file to copy</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="preservelastmodified" REQUIRED="no; defaults to false.">
+			<DESCRIPTION>Give the copied files the same last modifiedtime as the original source files.(Note: Ignored on Java 1.1</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tofile" REQUIRED="with the file
+       attribute, either tofile or todir can be used.
+       with nested &lt;fileset&gt; elements, if the set of files
+       is greater than 1, or if only the dir attribute is
+       specified in the &lt;fileset&gt;, or if the
+       file attribute is also specified, then only
+       todir is allowed.">
+			<DESCRIPTION>The file to copy to</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="todir" REQUIRED="">
+			<DESCRIPTION>The directory to copy to</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="overwrite" REQUIRED="no; defaults to false.">
+			<DESCRIPTION>Overwrite existing files even if the destinationfiles are newer</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filtering" REQUIRED="no; defaults to false.">
+			<DESCRIPTION>Indicates whether token filtering using the globalbuild-file filters should take place during the copy.Note: Nested &lt;filterset&gt; elements willalways be used, even if this attribute is not specified, or its value isfalse (no, or off)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="flatten" REQUIRED="no; defaults to false.">
+			<DESCRIPTION>Ignore the directory structure of the source files,and copy all files into the directory specified by the todirattribute.  Note that you can achieve the same effect by using aflatten mapper</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includeemptydirs" REQUIRED="no; defaults to true.">
+			<DESCRIPTION>Copy any empty directories included in the FileSet(s).</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no; defaults to true.">
+			<DESCRIPTION>Log a warning message, but do not stop the build,when the file to copy does not exist.Only meaningful when copying a single file.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no; defaults to false.">
+			<DESCRIPTION>Log the files that are being copied</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="copydir">
+		<DESCRIPTION>&lt;p&gt;Copies a directory tree from the source to the destination.&lt;/p&gt;
+&lt;p&gt;It is possible to refine the set of files that are being copied. This can be
+done with the &lt;i&gt;includes&lt;/i&gt;, &lt;i&gt;includesfile&lt;/i&gt;, &lt;i&gt;excludes&lt;/i&gt;, &lt;i&gt;excludesfile&lt;/i&gt; and &lt;i&gt;defaultexcludes&lt;/i&gt;
+attributes. With the &lt;i&gt;includes&lt;/i&gt; or &lt;i&gt;includesfile&lt;/i&gt; attribute you specify the files you want to
+have included by using patterns. The &lt;i&gt;exclude&lt;/i&gt; or &lt;i&gt;excludesfile&lt;/i&gt; attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the &lt;i&gt;defaultexcludes&lt;/i&gt; attribute, you can specify whether you
+want to use default exclusions or not. See the section on &lt;a
+href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based tasks&lt;/a&gt;, on how the
+inclusion/exclusion of files works, and how to write patterns.&lt;/p&gt;
+&lt;p&gt;This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and
+supports all attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;
+(&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;src&lt;/code&gt;) as well as the nested
+&lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt; and
+&lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="src" REQUIRED="yes">
+			<DESCRIPTION>the directory to copy</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dest" REQUIRED="yes">
+			<DESCRIPTION>the directory to copy to</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filtering" REQUIRED="no">
+			<DESCRIPTION>indicates whether token filtering should take place duringthe cop</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="flatten" REQUIRED="no">
+			<DESCRIPTION>ignore directory structure of source directory,copy all files into a single directory, specified by the destattribute (default is false)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="forceoverwrite" REQUIRED="no">
+			<DESCRIPTION>overwrite existing files even if the destinationfiles are newer (default is false)</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="copyfile">
+		<DESCRIPTION>&lt;p&gt;Copies a file from the source to the destination. The file is only copied if
+the source file is newer than the destination file, or when the destination file
+does not exist.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="src" REQUIRED="yes">
+			<DESCRIPTION>the filename of the file to copy</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dest" REQUIRED="yes">
+			<DESCRIPTION>the filename of the file where to copy to</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filtering" REQUIRED="no">
+			<DESCRIPTION>indicates whether token filtering should take place duringthe cop</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="forceoverwrite" REQUIRED="no">
+			<DESCRIPTION>overwrite existing files even if the destinationfiles are newer (default is false)</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="cvs">
+		<DESCRIPTION>&lt;p&gt;Handles packages/modules retrieved from a
+&lt;a href=&quot;http://www.cvshome.org/&quot; target=&quot;_top&quot;&gt;CVS&lt;/a&gt; repository.&lt;/p&gt;
+&lt;p&gt;When doing automated builds, the &lt;a href=&quot;get.html&quot;&gt;get task&lt;/a&gt; should be
+preferred over the &lt;i&gt;checkout&lt;/i&gt; command, because of speed.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="command" REQUIRED="no, default &quot;checkout&quot;.">
+			<DESCRIPTION>the CVS command to execute</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compression" REQUIRED="no. defaults to false.">
+			<DESCRIPTION>true or false - if setto true, this is the same as compressionlevel=&quot;3</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compressionlevel" REQUIRED="no. defaults to no compression.">
+			<DESCRIPTION>A number between 1 and 9 (corresponding topossible values for CVS' -z# argument). Anyother value is treated as compression=&quot;false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="cvsroot" REQUIRED="no">
+			<DESCRIPTION>the CVSROOT variable</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="cvsrsh" REQUIRED="no">
+			<DESCRIPTION>the CVS_RSH variable</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dest" REQUIRED="no, default is project's basedir.">
+			<DESCRIPTION>the directory where the checked out files should be placed</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="package" REQUIRED="no">
+			<DESCRIPTION>the package/module to check out</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tag" REQUIRED="no">
+			<DESCRIPTION>the tag of the package/module to check out</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="date" REQUIRED="no">
+			<DESCRIPTION>Use the most recent revision no later than the given dat</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="quiet" REQUIRED="no, default &quot;false&quot;">
+			<DESCRIPTION>suppress informational messages</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="noexec" REQUIRED="no, default to &quot;false&quot;">
+			<DESCRIPTION>report only, don't change any files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="output" REQUIRED="no, default output to ant log as msg_info.">
+			<DESCRIPTION>the file to direct standard output from the command</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="error" REQUIRED="no, default error to ant log as msg_warn.">
+			<DESCRIPTION>the file to direct standard error from the command</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="append" REQUIRED="no, default to &quot;false&quot;.">
+			<DESCRIPTION>whether to append output/error when redirecting to a file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="port" REQUIRED="no, default port 2401.">
+			<DESCRIPTION>Port used by CVS to communicate with the server</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="passfile" REQUIRED="no, default file ~/.cvspass.">
+			<DESCRIPTION>Password file to read passwords from</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>Stop the build process if the command exits with areturn code other than 0. Defaults to fals</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="cvspass">
+		<DESCRIPTION>&lt;p&gt;Adds entries to a .cvspass file. Adding entries to this file has the same affect as a cvs login command.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="cvsroot" REQUIRED="yes">
+			<DESCRIPTION>the CVS repository to add an entry for</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="password" REQUIRED="yes">
+			<DESCRIPTION>Password to be added to the password file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="passfile" REQUIRED="no, default is ~/.cvspass.">
+			<DESCRIPTION>Password file to add the entry to</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="cvstagdiff">
+		<DESCRIPTION>&lt;p&gt;Generates an XML-formatted report file of the changes between two tags or dates recorded in a
+&lt;a href=&quot;http://www.cvshome.org/&quot; target=&quot;_top&quot;&gt;CVS&lt;/a&gt; repository. &lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="starttag" REQUIRED="exactly one of the two.">
+			<DESCRIPTION>The earliest tag from which diffs are to beincluded in the report</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="startdate" REQUIRED="">
+			<DESCRIPTION>The earliest date from which diffs are to beincluded in the report</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="endtag" REQUIRED="exactly one of the two.">
+			<DESCRIPTION>The latest tag from which diffs are to beincluded in the report</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="enddate" REQUIRED="">
+			<DESCRIPTION>The latest date from which diffs are to beincluded in the report</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destfile" REQUIRED="yes">
+			<DESCRIPTION>The file in which to write the diff report</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="rootdir" REQUIRED="no">
+			<DESCRIPTION>Root directory for the package, if different from the package name</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="delete">
+		<DESCRIPTION>&lt;p&gt;Deletes a single file, a specified directory and all its files and
+subdirectories, or a set of files specified by one or more
+&lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt;s.
+When specifying a set of files, empty directories are &lt;i&gt;not&lt;/i&gt; removed by
+default.
+To remove empty directories, use the &lt;code&gt;includeEmptyDirs&lt;/code&gt; attribute.
+&lt;/p&gt;
+&lt;p&gt;
+If you use this task to delete temporary files created by editors
+and it doesn't seem to work, read up on the 
+&lt;a href=&quot;../dirtasks.html#defaultexcludes&quot;&gt;default exclusion set&lt;/a&gt;
+in &lt;strong&gt;Directory-based Tasks&lt;/strong&gt;, and see the
+&lt;code&gt;defaultexcludes&lt;/code&gt; attribute below.
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="at least one of the two,
+      unless a &lt;fileset&gt; is specified.">
+			<DESCRIPTION>The file to delete, specified as either the simplefilename (if the file exists in the current base directory), arelative-path filename, or a full-path filename</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="">
+			<DESCRIPTION>The directory to delete, including all its files andsubdirectoriesNote: dir is not usedto specify a directory name for file; fileand dir are independent of each otherWARNING: Do not set dir to&quot;.&quot;, &quot;${basedir}&quot;,or the full-pathname equivalent unless you truly intend torecursively remove the entire contents of the current base directory(and the base directory itself, if different from the current workingdirectory)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>Show the name of each deleted file(&quot;true&quot;/&quot;false&quot;).Default is &quot;false&quot; when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="quiet" REQUIRED="no">
+			<DESCRIPTION>If the specified file or directory does not exist,do not display a diagnostic message (unless Anthas been invoked with the &amp;#x2011;verbose or&amp;#x2011;debug switches) or modify the exit status toreflect an error.When set to &quot;true&quot;, if a file or directory cannot be deleted,no error is reported. This setting emulates the -f option to the Unix rm command.Default is &quot;false&quot;.Setting this to &quot;true&quot; implies settingfailonerror to &quot;false&quot;.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>Controls whether an error (such as a failure to delete a file)stops the build or is merely reported to the screen.Only relevant if quiet is &quot;false&quot;.Default is &quot;true&quot;.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includeemptydirs" REQUIRED="no">
+			<DESCRIPTION>Set to &quot;true&quot; to delete empty directories whenusing filesets.  Default is &quot;false&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>Deprecated.  Use &lt;fileset&gt;.Comma- or space-separated list of patterns offiles that must be deleted. All files are relative to the directoryspecified in dir.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>Deprecated.  Use &lt;fileset&gt;.The name of a file. Each line ofthis file is taken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>Deprecated.  Use &lt;fileset&gt;.Comma- or space-separated list of patterns offiles that must be excluded from the deletion list.All files are relative to the directory specified in dir.No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>Deprecated.  Use &lt;fileset&gt;.The name of a file. Each line ofthis file is taken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>Indicates whether default excludesshould be used or not (&quot;yes&quot;/&quot;no&quot;).Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="deltree">
+		<DESCRIPTION>&lt;p&gt;Deletes a directory with all its files and subdirectories.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="dir" REQUIRED="yes">
+			<DESCRIPTION>the directory to delete</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="dependset">
+		<DESCRIPTION>&lt;p&gt;
+The dependset task compares a set of source files with a set of target
+files.  If any of the source files is more recent than any of
+the target files, all of the target files are removed.  
+&lt;/p&gt;
+&lt;p&gt;
+Source files and target files are specified via nested &lt;a
+href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSets&lt;/a&gt; and/or nested &lt;a
+href=&quot;../CoreTypes/filelist.html&quot;&gt;FileLists&lt;/a&gt;.  Arbitrarily many
+source and target filesets/filelists may be specified, but at 
+least one filelist/fileset is required for both sources and targets.
+&lt;/p&gt;
+&lt;p&gt;
+Use a FileSet when you want to use wildcard include or exclude
+patterns and don't care about missing files.  Use a FileList when you
+want to consider the non-existence of a file as if it were out of
+date.  If there are any non-existing files in any source or target
+FileList, all target files will be removed.
+&lt;/p&gt;
+&lt;p&gt;
+DependSet is useful to capture dependencies that are not or cannot be
+determined algorithmically.  For example, the &amp;lt;style&amp;gt; task only
+compares the source XML file and XSLT stylesheet against the target
+file to determined whether to restyle the source.  Using dependset you
+can extend this dependency checking to include a DTD or XSD file as
+well as other stylesheets imported by the main stylesheet.
+&lt;/p&gt;
+</DESCRIPTION>	</TASK>
+	<TASK NAME="dirname">
+		<DESCRIPTION>&lt;p&gt;
+Task to determine the directory path of a specified file.
+&lt;/p&gt;
+&lt;p&gt; 
+When this task executes, it will set the specified property to the
+value of the specified file up to, but not including, the last path
+element. If the specified file is a path that ends in a filename,
+the filename will be dropped. If the specified file is just a filename,
+the directory will be the current directory.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="yes">
+			<DESCRIPTION>The path to take the dirname of</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="property" REQUIRED="yes">
+			<DESCRIPTION>The name of the property to set</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="ear">
+		<DESCRIPTION>&lt;p&gt;An extension of the &lt;a href=&quot;jar.html&quot;&gt;Jar&lt;/a&gt; task with special
+treatment for files that should end up in an Enterprise Application archive.&lt;/p&gt;
+&lt;p&gt;(The Ear task is a shortcut for specifying the particular layout of a EAR file. 
+The same thing can be accomplished by using the &lt;i&gt;prefix&lt;/i&gt; and &lt;i&gt;fullpath&lt;/i&gt;
+attributes of zipfilesets in a Zip or Jar task.)&lt;/p&gt;
+&lt;p&gt;The extended zipfileset element from the zip task (with attributes &lt;i&gt;prefix&lt;/i&gt;, &lt;i&gt;fullpath&lt;/i&gt;, and &lt;i&gt;src&lt;/i&gt;) is available in the Ear task.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="destfile" REQUIRED="yes">
+			<DESCRIPTION>the EAR file to create</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="appxml" REQUIRED="yes, unless update is set to true">
+			<DESCRIPTION>The deployment descriptor to use (META-INF/application.xml)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="basedir" REQUIRED="no">
+			<DESCRIPTION>the directory from which to jar the files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compress" REQUIRED="no">
+			<DESCRIPTION>Not only store data but also compress them, defaults to tru</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>The character encoding to use for filenamesinside the archive.  Defaults to UTF8. It is notrecommended to change this value as the created archive will mostlikely be unreadable for Java otherwise</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filesonly" REQUIRED="no">
+			<DESCRIPTION>Store only file entries, defaults to fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="manifest" REQUIRED="no">
+			<DESCRIPTION>the manifest file to use</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="update" REQUIRED="no">
+			<DESCRIPTION>indicates whether to update or overwritethe destination file if it already exists</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="duplicate" REQUIRED="no">
+			<DESCRIPTION>behavior when a duplicate file is found.  Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;.  The default value is &quot;add&quot;. </DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="echo">
+		<DESCRIPTION>&lt;p&gt;Echoes a message to the current loggers and listeners which
+means &lt;tt&gt;System.out&lt;/tt&gt; unless overridden. A &lt;tt&gt;level&lt;/tt&gt;
+can be specified, which controls at what logging level the message is
+filtered at. 
+&lt;p&gt; 
+The task can also echo to a file, in which case the option to append rather
+than overwrite the file is available, and the &lt;tt&gt;level&lt;/tt&gt; option is 
+ignored&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="message" REQUIRED="yes, unless data is included in a
+       character section within this element.">
+			<DESCRIPTION>the message to echo</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="file" REQUIRED="no">
+			<DESCRIPTION>the file to write the message to</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="append" REQUIRED="no - default is false.">
+			<DESCRIPTION>Append to an existing file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="level" REQUIRED="no - default is &quot;warning&quot;.">
+			<DESCRIPTION>Control the level at which this message is reported.One of &quot;error&quot;, &quot;warning&quot;, &quot;info&quot;, &quot;verbose&quot;, &quot;debug</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="exec">
+		<DESCRIPTION>&lt;p&gt;Executes a system command. When the &lt;i&gt;os&lt;/i&gt; attribute is specified, then
+the command is only executed when Ant is run on one of the specified operating
+systems.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="command" REQUIRED="exactly one of the two.">
+			<DESCRIPTION>the command to execute with all command linearguments. deprecated, use executable and nested&lt;arg&gt; elements instead</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="executable" REQUIRED="">
+			<DESCRIPTION>the command to execute without any command linearguments</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="no">
+			<DESCRIPTION>the directory in which the command should be executed</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="os" REQUIRED="no">
+			<DESCRIPTION>list of Operating Systems on which the command may beexecuted. If the current OS's name is contained in this list, the command willbe executed. The OS's name is determined by the Java Virtual machine and is setin the &quot;os.name&quot; system property</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="output" REQUIRED="no">
+			<DESCRIPTION>the file to which the output of the command should beredirected</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="append" REQUIRED="no">
+			<DESCRIPTION>whether output should be appended to or overwritean existing file.  Defaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="outputproperty" REQUIRED="no">
+			<DESCRIPTION>the name of a property in which the output of the command should be stored</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="resultproperty" REQUIRED="no">
+			<DESCRIPTION>the name of a property in which the return code of the command should be stored. Only of interest if failonerror=fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="timeout" REQUIRED="no">
+			<DESCRIPTION>Stop the command if it doesn't finish within thespecified time (given in milliseconds)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>Stop the buildprocess if the command exits with areturncode other than 0. Defaults to fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failifexecutionfails" REQUIRED="no">
+			<DESCRIPTION>Stop the build if we can't start the program.Defaults to true.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="newenvironment" REQUIRED="no, default is false">
+			<DESCRIPTION>Do not propagate old environment when new environmentvariables are specified</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="vmlauncher" REQUIRED="no, default is true">
+			<DESCRIPTION>Run command using the Java VM's execution facilitieswhere available. If set to false the underlying OS's shell,either directly or through the antRun scripts, will be used.Under some operating systems, this gives access to facilitiesnot normally available through the VM including, under Windows,being able to execute scripts, rather than their associatedinterpreter.  If you want to specify the name of theexecutable as a relative path to the directory given by thedir attribute, it may become necessary to set vmlauncher tofalse as well</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="fail">
+		<DESCRIPTION>&lt;p&gt;Exits the current build (just throwing a BuildException), optionally printing additional information.&lt;/p&gt;
+&lt;p&gt;The message of the Exception can be set via the message attribute
+or character data nested into the element.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="message" REQUIRED="no">
+			<DESCRIPTION>A message giving further information on why the build exite</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="if" REQUIRED="no">
+			<DESCRIPTION>Only fail if a property of the given name existsin the current projec</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="unless" REQUIRED="no">
+			<DESCRIPTION>Only fail if a property of the given name doesn'texist in the current projec</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="filter">
+		<DESCRIPTION>&lt;p&gt;Sets a token filter for this project or read multiple token filter from
+an input file and sets these as filters.
+Token filters are used by all tasks that perform file copying operations
+through the Project commodity methods.&lt;/p&gt;
+&lt;p&gt;Note 1: the token string must not contain the separators chars (@).&lt;br&gt;
+Note 2: Either token and value attributes must be provided, or only the
+filtersfile attribute.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="token" REQUIRED="yes*">
+			<DESCRIPTION>the token string without </DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="value" REQUIRED="yes*">
+			<DESCRIPTION>the string that should be put to replace the token when the file is copie</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filtersfile" REQUIRED="yes*">
+			<DESCRIPTION>The file from which the filters must be read. This file must be a formatted as a property file.</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="fixcrlf">
+		<DESCRIPTION>&lt;p&gt;
+Adjusts a text file to local conventions.
+&lt;/p&gt;
+&lt;p&gt;
+The set of files to be adjusted can be refined with the
+&lt;i&gt;includes&lt;/i&gt;, &lt;i&gt;includesfile&lt;/i&gt;, &lt;i&gt;excludes&lt;/i&gt;,
+&lt;i&gt;excludesfile&lt;/i&gt; and &lt;i&gt;defaultexcludes&lt;/i&gt;
+attributes. Patterns provided through the &lt;i&gt;includes&lt;/i&gt; or
+&lt;i&gt;includesfile&lt;/i&gt; attributes specify files to be
+included. Patterns provided through the &lt;i&gt;exclude&lt;/i&gt; or
+&lt;i&gt;excludesfile&lt;/i&gt; attribute specify files to be
+excluded. Additionally, default exclusions can be specified with
+the &lt;i&gt;defaultexcludes&lt;/i&gt; attribute. See the section on &lt;a
+href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based
+tasks&lt;/a&gt;, for details of file inclusion/exclusion patterns
+and their usage.
+&lt;/p&gt;
+&lt;p&gt;This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and
+supports all attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;
+(&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;srcdir&lt;/code&gt;) as well as the nested
+&lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt; and
+&lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+&lt;p&gt;
+The output file is only written if it is a new file, or if it
+differs from the existing file.  This prevents spurious
+rebuilds based on unchanged files which have been regenerated
+by this task.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="srcdir" REQUIRED="yes">
+			<DESCRIPTION>Where to find the files to be fixed up</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destdir" REQUIRED="no">
+			<DESCRIPTION>Where to place the corrected files.  Defaults tosrcDir (replacing the original file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="eol" REQUIRED="no">
+			<DESCRIPTION>Specifies how end-of-line (EOL) characters are to behandled.  The EOL characters are CR, LF and the pair CRLF.Valid values for this property are:asis: leave EOL characters alonecr: convert all EOLs to a single CRlf: convert all EOLs to a single LFcrlf: convert all EOLs to the pair CRLFDefault is based on the platform on which you are runningthis task.  For Unix platforms, the default is &quot;lf&quot;.For DOS based systems (including Windows), the default is&quot;crlf&quot;.  For Mac OS, the default is &quot;cr&quot;.This is the preferred method for specifying EOL.  The&quot;cr&quot; attribute (see below) isnow deprecated.N.B.: One special case is recognized. The threecharacters CR-CR-LF are regarded as a single EOL.Unless this property is specified as &quot;asis&quot;,this sequence will be converted into the specified EOLtype.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="cr" REQUIRED="no">
+			<DESCRIPTION>Deprecated. Specifies how CR characters areto be handled at end-of-line (EOL).  Valid values for thisproperty are:asis: leave EOL characters alone.add: add a CR before any single LF characters. Theintent is to convert all EOLs to the pair CRLF.remove: remove all CRs from the file.  The intent isto convert all EOLs to a single LF.Default is based on the platform on which you are runningthis task.  For Unix platforms, the default is &quot;remove&quot;.For DOS based systems (including Windows), the default is&quot;add&quot;.N.B.: One special case is recognized. The threecharacters CR-CR-LF are regarded as a single EOL.Unless this property is specified as &quot;asis&quot;,this sequence will be converted into the specified EOLtype.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="javafiles" REQUIRED="no">
+			<DESCRIPTION>Used only in association with the&quot;tab&quot; attribute (see below), thisboolean attribute indicates whether the fileset is a setof java source files(&quot;yes&quot;/&quot;no&quot;). Defaults to&quot;no&quot;.  See notes in section on &quot;tab&quot;.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tab" REQUIRED="no">
+			<DESCRIPTION>Specifies how tab characters are to be handled.  Validvalues for this property are:add: convert sequences of spaces which span a tab stop to tabsasis: leave tab and space characters aloneremove: convert tabs to spacesDefault for this parameter is &quot;asis&quot;.N.B.: When the attribute&quot;javafiles&quot; (see above) is&quot;true&quot;, literal TAB characters occurringwithin Java string or character constants are nevermodified.  This functionality also requires therecognition of Java-style comments.N.B.: There is an incompatibility between thisand the previous version in the handling of whitespace at the end of lines.  This version doesnot remove trailing whitespace on lines.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tablength" REQUIRED="no">
+			<DESCRIPTION>TAB character interval. Valid values are between2 and 80 inclusive.  The default for this parameter is 8</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="eof" REQUIRED="no">
+			<DESCRIPTION>Specifies how DOS end of file (control-Z) characters areto be handled.  Valid values for this property are:add: ensure that there is an EOF character at the end of the fileasis: leave EOF characters aloneremove: remove any EOF character found at the endDefault is based on the platform on which you are running this task.For Unix platforms, the default is remove.  For DOS based systems(including Windows), the default is asis.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no - defaults to default jvm encoding">
+			<DESCRIPTION>The encoding of the file</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="genkey">
+		<DESCRIPTION>&lt;p&gt;Generates a key in keystore. This task needs Java1.2 or later&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="alias" REQUIRED="yes.">
+			<DESCRIPTION>the alias to add unde</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="storepass" REQUIRED="yes.">
+			<DESCRIPTION>password for keystore integrity. Mustbe at least 6 characters lon</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="keystore" REQUIRED="no">
+			<DESCRIPTION>keystore locatio</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="storetype" REQUIRED="no">
+			<DESCRIPTION>keystore typ</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="keypass" REQUIRED="no">
+			<DESCRIPTION>password for private key (if different</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sigalg" REQUIRED="no">
+			<DESCRIPTION>the algorithm to use in signin</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="keyalg" REQUIRED="no">
+			<DESCRIPTION>the method to use when generating name-value pai</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>(true | false) verbose output when signin</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dname" REQUIRED="yes if dname element unspecified">
+			<DESCRIPTION>The distinguished name for entit</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="validity" REQUIRED="no">
+			<DESCRIPTION>(integer) indicates how many days certificate is vali</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="keysize" REQUIRED="no">
+			<DESCRIPTION>(integer) indicates the size of key generate</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="get">
+		<DESCRIPTION>&lt;p&gt;Gets a file from a URL. When the verbose option is &amp;quot;on&amp;quot;, this task
+displays a '.' for every 100 Kb retrieved. Any URL schema supported by
+the runtime is valid here, including http:, ftp: and jar:; 
+https: is only valid if the appropriate support is added to the pre-1.4 Java
+runtimes. 
+&lt;/p&gt;
+&lt;p&gt;This task should be preferred above the &lt;a href=&quot;cvs.html&quot;&gt;CVS task&lt;/a&gt; when
+fetching remote content. CVS is significantly slower than loading a compressed
+archive compared to http/ftp.&lt;/p&gt;
+The &lt;i&gt;usetimestamp&lt;/i&gt; option enables you to control downloads so that the remote file is
+only fetched if newer than the local copy. If there is no local copy, the download always takes 
+place. When a file is downloaded, the timestamp of the downloaded file is set to the remote timestamp,
+if  the JVM is Java1.2 or later. 
+NB: This timestamp facility only works on downloads using the HTTP protocol. 
+&lt;p&gt;
+A username and password can be specified, in which case basic 'slightly encoded
+plain text' authentication is used. This is only a secure authentication
+mechanism over an HTTPS link.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="src" REQUIRED="yes">
+			<DESCRIPTION>the URL from which to retrieve a file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dest" REQUIRED="yes">
+			<DESCRIPTION>the file where to store the retrieved file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no; default &quot;false&quot;">
+			<DESCRIPTION>show verbose progress information (&quot;on&quot;/&quot;off&quot;)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="ignoreerrors" REQUIRED="no; default &quot;false&quot;">
+			<DESCRIPTION>Log errors but don't treat as fatal</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="usetimestamp" REQUIRED="no; default &quot;false&quot;">
+			<DESCRIPTION>conditionally download a file based on the timestamp of thelocal copy. HTTP onl</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="username" REQUIRED="if password is set">
+			<DESCRIPTION>username for 'BASIC' http authenticatio</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="password" REQUIRED="if username is set">
+			<DESCRIPTION>password: required</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="input">
+		<DESCRIPTION>&lt;p&gt;Allows user interaction during the build process by prompting for
+input.  To do so, it uses the configured 
+&lt;a href=&quot;../inputhandler.html&quot;&gt;InputHandler&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;The prompt can be set via the message attribute or as character
+data nested into the element.&lt;/p&gt;
+&lt;p&gt;Optinonally a set of valid imput arguments can be defined via the
+validargs attribute. Input task will no accept value that don't match
+one of the predefined.&lt;/p&gt;
+&lt;p&gt;Optionally a property can be created from the value entered by the
+user. This property can then be used during the following build
+run. Input behaves according to &lt;a href=&quot;property.html&quot;&gt;property
+task&lt;/a&gt; which means that existing properties cannot be overriden.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="message" REQUIRED="no">
+			<DESCRIPTION>the Message which gets displayed to the userduring the build run</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="validargs" REQUIRED="no">
+			<DESCRIPTION>comma separated String containing valid inputarguments. If set, input task will reject any input not definedhere.  Validargs are compared case sensitive. If you want 'a' and'A' to be accepted you will need to define both arguments withinvalidargs</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="addproperty" REQUIRED="no">
+			<DESCRIPTION>the name of a property to be created frominput. Behaviour is equal to propertytask which means that existing properties cannot beoverriden</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="jar">
+		<DESCRIPTION>&lt;p&gt;Jars a set of files.&lt;/p&gt;
+&lt;p&gt;The &lt;i&gt;basedir&lt;/i&gt; attribute is the reference directory from where to jar.&lt;/p&gt;
+&lt;p&gt;Note that file permissions will not be stored in the resulting jarfile.&lt;/p&gt;
+&lt;p&gt;It is possible to refine the set of files that are being jarred. This can be
+done with the &lt;i&gt;includes&lt;/i&gt;, &lt;i&gt;includesfile&lt;/i&gt;, &lt;i&gt;excludes&lt;/i&gt;, &lt;i&gt;excludesfile&lt;/i&gt; and &lt;i&gt;defaultexcludes&lt;/i&gt;
+attributes. With the &lt;i&gt;includes&lt;/i&gt; or &lt;i&gt;includesfile&lt;/i&gt; attribute you specify the files you want to
+have included by using patterns. The &lt;i&gt;exclude&lt;/i&gt; or &lt;i&gt;excludesfile&lt;/i&gt; attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the &lt;i&gt;defaultexcludes&lt;/i&gt; attribute, you can specify whether you
+want to use default exclusions or not. See the section on &lt;a
+href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based tasks&lt;/a&gt;, on how the
+inclusion/exclusion of files works, and how to write patterns.&lt;/p&gt;
+&lt;p&gt;This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and
+supports all attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;
+(&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;basedir&lt;/code&gt;) as well as the nested
+&lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt; and
+&lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+&lt;p&gt;You can also use nested file sets for more flexibility, and specify
+multiple ones to merge together different trees of files into one JAR.
+The extended fileset and groupfileset attributes from the zip task are
+also available in the jar task.
+See the &lt;a href=&quot;zip.html&quot;&gt;Zip&lt;/a&gt; task for more details and examples.&lt;/p&gt;
+&lt;p&gt;If the manifest is omitted, a simple one will be supplied by Ant.&lt;/p&gt;
+&lt;p&gt;The &lt;code&gt;update&lt;/code&gt; parameter controls what happens if the
+JAR file already exists. When set to &lt;code&gt;yes&lt;/code&gt;, the JAR file is
+updated with the files specified. When set to &lt;code&gt;no&lt;/code&gt; (the
+default) the JAR file is overwritten. An example use of this is
+provided in the &lt;a href=&quot;zip.html&quot;&gt;Zip task documentation&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;(The Jar task is a shortcut for specifying the manifest file of a JAR file.
+The same thing can be accomplished by using the &lt;i&gt;fullpath&lt;/i&gt;
+attribute of a zipfileset in a Zip task. The one difference is that if the
+&lt;i&gt;manifest&lt;/i&gt; attribute is not specified, the Jar task will
+include an empty one for you.)&lt;/p&gt;
+&lt;p&gt;Manifests are processed by the Jar task according to the
+&lt;a href=&quot;http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html&quot;&gt;Jar file specification.&lt;/a&gt;
+Note in particular that this may result in manifest lines greater than 72 bytes
+being wrapped and continued on the next line.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="destfile" REQUIRED="yes">
+			<DESCRIPTION>the JAR file to create</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="basedir" REQUIRED="no">
+			<DESCRIPTION>the directory from which to jar the files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compress" REQUIRED="no">
+			<DESCRIPTION>Not only store data but also compress them, defaults to tru</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>The character encoding to use for filenamesinside the archive.  Defaults to UTF8. It is notrecommended to change this value as the created archive will mostlikely be unreadable for Java otherwise</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filesonly" REQUIRED="no">
+			<DESCRIPTION>Store only file entries, defaults to fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="manifest" REQUIRED="no">
+			<DESCRIPTION>the manifest file to use.  This can be either the location of a manifest, or the name of a jar added through a fileset.  If its the name of an added jar, the task expects the manifest to be in the jar at META-INF/MANIFEST.M</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="update" REQUIRED="no">
+			<DESCRIPTION>indicates whether to update or overwritethe destination file if it already exists</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="whenempty" REQUIRED="no">
+			<DESCRIPTION>behavior when no files match.  Valid values are &quot;fail&quot;, &quot;skip&quot;, and &quot;create&quot;.  Default is &quot;skip&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="duplicate" REQUIRED="no">
+			<DESCRIPTION>behavior when a duplicate file is found.  Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;.  The default value is &quot;add&quot;. </DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="index" REQUIRED="no">
+			<DESCRIPTION>whether to create an index list to speed up classloading.  This is a JDK 1.3+ specific feature.  Defaults to false.</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="java">
+		<DESCRIPTION>&lt;p&gt;Executes a Java class within the running (Ant) VM or forks another VM if
+specified.&lt;/p&gt;
+&lt;p&gt;
+If odd things go wrong when you run this task, set fork=&quot;true&quot; to use a new
+JVM.
+</DESCRIPTION>
+		<ATTRIBUTE NAME="classname" REQUIRED="either jar or classname">
+			<DESCRIPTION>the Java class to execute</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="jar" REQUIRED="either jar or classname">
+			<DESCRIPTION>the location of the jar file to execute (must have a Main-Class entry in the manifest). Fork must be set to true if this option is selected</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="args" REQUIRED="no">
+			<DESCRIPTION>the arguments for the class that isexecuted. deprecated, use nested &lt;arg&gt;elements instead</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>the classpath to use</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>the classpath to use, given as reference to a PATH defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="fork" REQUIRED="no">
+			<DESCRIPTION>if enabled triggers the class execution in another VM(disabled by default</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="jvm" REQUIRED="no">
+			<DESCRIPTION>the command used to invoke the Java Virtual Machine,default is 'java'.  The command is resolved by java.lang.Runtime.exec().Ignored if fork is disabled.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="jvmargs" REQUIRED="no">
+			<DESCRIPTION>the arguments to pass to the forked VM (ignoredif fork is disabled). deprecated, use nested&lt;jvmarg&gt; elements instead</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="maxmemory" REQUIRED="no">
+			<DESCRIPTION>Max amount of memory to allocate to the forked VM(ignored if fork is disabled</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>Stop the buildprocess if the command exits with areturncode other than 0. Default is &quot;false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="no">
+			<DESCRIPTION>The directory to invoke the VM in.  (ignored iffork is disabled</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="output" REQUIRED="no">
+			<DESCRIPTION>Name of a file to write the output to</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="append" REQUIRED="no">
+			<DESCRIPTION>whether output should be appended to or overwritean existing file.  Defaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="newenvironment" REQUIRED="no">
+			<DESCRIPTION>Do not propagate old environment when newenvironment variables are specified. Default is &quot;false&quot;(ignored if fork is disabled)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="timeout" REQUIRED="no">
+			<DESCRIPTION>Stop the command if it doesn't finish within thespecified time (given in milliseconds).  It is highlyrecommended to use this feature only if fork is enabled</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="javac">
+		<DESCRIPTION>&lt;p&gt;Compiles a Java source tree.&lt;/p&gt;
+&lt;p&gt;The source and destination directory will be recursively scanned for Java
+source files to compile. Only Java files that have no corresponding
+&lt;code&gt;.class&lt;/code&gt; file
+or where the class file is older than the
+&lt;code&gt;.java&lt;/code&gt; file will be compiled.&lt;/p&gt;
+&lt;p&gt;Note: Ant uses only the names of the source and class files to find
+the classes that need a rebuild. It will not scan the source and therefore
+will have no knowledge about nested classes, classes that are named different
+from the source file, and so on. See the
+&lt;a href=&quot;../OptionalTasks/depend.html&quot;&gt;&lt;code&gt;&amp;lt;depend&amp;gt;&lt;/code&gt;&lt;/a&gt; task
+for dependency checking based on other than just
+existence/modification times.&lt;/p&gt;
+&lt;p&gt;When the source files are part of a package, the directory structure of
+the source tree should follow the package
+hierarchy.&lt;/p&gt;
+&lt;p&gt;It is possible to refine the set of files that are being compiled.
+This can be done with the &lt;code&gt;includes&lt;/code&gt;, &lt;code&gt;includesfile&lt;/code&gt;,
+&lt;code&gt;excludes&lt;/code&gt;, and &lt;code&gt;excludesfile&lt;/code&gt;
+attributes. With the &lt;code&gt;includes&lt;/code&gt; or
+&lt;code&gt;includesfile&lt;/code&gt; attribute, you specify the files you want to
+have included.
+The &lt;code&gt;exclude&lt;/code&gt; or &lt;code&gt;excludesfile&lt;/code&gt; attribute is used
+to specify
+the files you want to have excluded. In both cases, the list of files 
+can be specified by either the filename, relative to the directory(s) specified
+in the &lt;code&gt;srcdir&lt;/code&gt; attribute or nested &lt;code&gt;&amp;lt;src&amp;gt;&lt;/code&gt;
+element(s), or by using wildcard patterns. See the section on
+&lt;a href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory-based tasks&lt;/a&gt;,
+for information on how the
+inclusion/exclusion of files works, and how to write wildcard patterns.&lt;/p&gt;
+&lt;p&gt;It is possible to use different compilers. This can be specified by
+either setting the global &lt;code&gt;build.compiler&lt;/code&gt; property, which will
+affect all &lt;code&gt;&amp;lt;javac&amp;gt;&lt;/code&gt; tasks throughout the build, or by
+setting the &lt;code&gt;compiler&lt;/code&gt; attribute, specific to the current
+&lt;code&gt;&amp;lt;javac&amp;gt;&lt;/code&gt; task.
+&lt;a name=&quot;compilervalues&quot;&gt;Valid values for either the
+&lt;code&gt;build.compiler&lt;/code&gt; property or the &lt;code&gt;compiler&lt;/code&gt;
+attribute are:&lt;/a&gt;&lt;/p&gt;
+&lt;ul&gt;
+&lt;li&gt;&lt;code&gt;classic&lt;/code&gt; (the standard compiler of JDK 1.1/1.2) &amp;ndash;
+&lt;code&gt;javac1.1&lt;/code&gt; and
+&lt;code&gt;javac1.2&lt;/code&gt; can be used as aliases.&lt;/li&gt;
+&lt;li&gt;&lt;code&gt;modern&lt;/code&gt; (the standard compiler of JDK 1.3/1.4) &amp;ndash;
+&lt;code&gt;javac1.3&lt;/code&gt; and
+&lt;code&gt;javac1.4&lt;/code&gt; can be used as aliases.&lt;/li&gt;
+&lt;li&gt;&lt;code&gt;jikes&lt;/code&gt; (the &lt;a
+href=&quot;http://oss.software.ibm.com/developerworks/opensource/jikes/&quot; target=&quot;_top&quot;&gt;Jikes&lt;/a&gt;
+compiler).&lt;/li&gt;
+&lt;li&gt;&lt;code&gt;jvc&lt;/code&gt; (the Command-Line Compiler from Microsoft's SDK
+for Java / Visual J++) &amp;ndash; &lt;code&gt;microsoft&lt;/code&gt; can be used
+as an alias.&lt;/li&gt;
+&lt;li&gt;&lt;code&gt;kjc&lt;/code&gt; (the &lt;a href=&quot;http://www.dms.at/kopi/&quot; target=&quot;_top&quot;&gt;kopi&lt;/a&gt;
+compiler).&lt;/li&gt;
+&lt;li&gt;&lt;code&gt;gcj&lt;/code&gt; (the gcj compiler from gcc).&lt;/li&gt;
+&lt;li&gt;&lt;code&gt;sj&lt;/code&gt; (Symantec java compiler) &amp;ndash;
+&lt;code&gt;symantec&lt;/code&gt; can be used as an alias.&lt;/li&gt;
+&lt;li&gt;&lt;code&gt;extJavac&lt;/code&gt; (run either modern or classic in a JVM of
+its own).&lt;/li&gt;
+&lt;/ul&gt;
+&lt;p&gt;The default is &lt;code&gt;javac1.x&lt;/code&gt; with &lt;code&gt;x&lt;/code&gt; depending
+on the JDK version you use while you are running Ant.
+If you wish to use a different compiler interface than those
+supplied, you can write a class that implements the CompilerAdapter interface
+(&lt;code&gt;package org.apache.tools.ant.taskdefs.compilers&lt;/code&gt;). Supply the full
+classname in the &lt;code&gt;build.compiler&lt;/code&gt; property or the
+&lt;code&gt;compiler&lt;/code&gt; attribute.
+&lt;/p&gt;
+&lt;p&gt;The fork attribute overrides the &lt;code&gt;build.compiler&lt;/code&gt; property
+or &lt;code&gt;compiler&lt;/code&gt; attribute setting and
+expects a JDK1.1 or higher to be set in &lt;code&gt;JAVA_HOME&lt;/code&gt;.
+&lt;/p&gt;
+&lt;p&gt;You can also use the &lt;code&gt;compiler&lt;/code&gt; attribute to tell Ant
+which JDK version it shall assume when it puts together the command
+line switches - even if you set &lt;code&gt;fork=&amp;quot;true&amp;quot;&lt;/code&gt;.
+This is useful if you want to run the compiler of JDK 1.1 while you
+current JDK is 1.2+.  If you use
+&lt;code&gt;compiler=&amp;quot;javac1.1&amp;quot;&lt;/code&gt; and (for example)
+&lt;code&gt;depend=&amp;quot;true&amp;quot;&lt;/code&gt; Ant will use the command line
+switch &lt;code&gt;-depend&lt;/code&gt; instead of &lt;code&gt;-Xdepend&lt;/code&gt;.&lt;/p&gt;
+&lt;p&gt;This task will drop all entries that point to non-existent
+files/directories from the classpath it passes to the compiler.&lt;/p&gt;
+&lt;p&gt;&lt;strong&gt;Windows Note:&lt;/strong&gt;When the modern compiler is used
+in unforked mode on Windows, it locks up the files present in the
+classpath of the &lt;code&gt;&amp;lt;javac&amp;gt;&lt;/code&gt; task, and does not release them.
+The side effect of this is that you will not be able to delete or move
+those files later on in the build.  The workaround is to fork when
+invoking the compiler.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="srcdir" REQUIRED="yes, unless nested &lt;src&gt; elements are present.">
+			<DESCRIPTION>Location of the java files. (See thenote below.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destdir" REQUIRED="no">
+			<DESCRIPTION>Location to store the class files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>Comma- or space-separated list of files (may be specified usingwildcard patterns) that must beincluded; all .java files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>The name of a file that contains a list of files toinclude (may be specified using wildcard patterns)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>Comma- or space-separated list of files (may be specified usingwildcard patterns) that must be excluded; no files (except defaultexcludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>The name of a file that contains a list of files toexclude (may be specified using wildcard patterns)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>The classpath to use</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sourcepath" REQUIRED="no">
+			<DESCRIPTION>The sourcepath to use; defaults to the value of the srcdir attribute (or nested &lt;src&gt; elements).To suppress the sourcepath switch, use sourcepath=&quot;&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bootclasspath" REQUIRED="no">
+			<DESCRIPTION>Location of bootstrap class files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>The classpath to use, given as areference to a path defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sourcepathref" REQUIRED="no">
+			<DESCRIPTION>The sourcepath to use, given as areference to a path defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bootclasspathref" REQUIRED="no">
+			<DESCRIPTION>Location of bootstrap class files, given as areference to a path defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="extdirs" REQUIRED="no">
+			<DESCRIPTION>Location of installed extensions</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>Encoding of source files. (Note: gcj doesn't supportthis option yet.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nowarn" REQUIRED="no">
+			<DESCRIPTION>Indicates whether the -nowarn switchshould be passed to the compiler; defaults to off</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debug" REQUIRED="no">
+			<DESCRIPTION>Indicates whether source should be compiled with debuginformation; defaults to off</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debuglevel" REQUIRED="no">
+			<DESCRIPTION>Keyword list to be appended to the -gcommand-line switch.  This will be ignored by all implementations exceptmodern and classic(ver &gt;= 1.2).Legal values are none or a comma-separated list of thefollowing keywords:lines, vars, and source.If debuglevel is not specified, by default,:none will beappended to -g.  If debug is not turned on,this attribute will be ignored.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="optimize" REQUIRED="no">
+			<DESCRIPTION>Indicates whether source should be compiled withoptimization; defaults to off</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="deprecation" REQUIRED="no">
+			<DESCRIPTION>Indicates whether source should be compiled withdeprecation information; defaults to off</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="target" REQUIRED="no">
+			<DESCRIPTION>Generate class files for specific VM version(e.g., 1.1 or 1.2). Note that thedefault value depends on the JVM that is running Ant.  Inparticular, if you use JDK 1.4 the generated classes will not beusable for a 1.1 Java VM unless you explicitly set this attributeto the value 1.1 (which is the default value for JDK 1.1 to1.3)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>Asks the compiler for verbose output</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="depend" REQUIRED="no">
+			<DESCRIPTION>Enables dependency-trackingfor compilers that support this (jikes andclassic)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includeantruntime" REQUIRED="no">
+			<DESCRIPTION>Whether to include the Ant run-time libraries in theclasspath; defaults to yes</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includejavaruntime" REQUIRED="no">
+			<DESCRIPTION>Whether to include the default run-timelibraries from the executing VM in the classpath;defaults to yes</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="fork" REQUIRED="no">
+			<DESCRIPTION>Whether to execute javac using theJDK compiler externally; defaults to no</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="executable" REQUIRED="no">
+			<DESCRIPTION>Complete path to the javacexecutable to use in case of fork=&quot;yes&quot;.Defaults to the compiler of the Java version that is currentlyrunning Ant.  Ignored if fork=&quot;no</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="memoryinitialsize" REQUIRED="no">
+			<DESCRIPTION>The initial size of the memory for the underlying VM,if javac is run externally; ignored otherwise. Defaultsto the standard VM memory setting.(Examples: 83886080, 81920k, or80m</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="memorymaximumsize" REQUIRED="no">
+			<DESCRIPTION>The maximum size of the memory for the underlying VM,if javac is run externally; ignored otherwise. Defaultsto the standard VM memory setting.(Examples: 83886080, 81920k, or80m</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>Indicates whether the build will continue even if there are compilation errors; defaults to true.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="source" REQUIRED="no">
+			<DESCRIPTION>Value of the -source command-lineswitch; will be ignored by all implementations exceptjavac1.4 (or modern when Ant is notrunning in a 1.3 VM) and jikesIf you use thisattribute together with jikes, you must make surethat your version of jikes supports the -sourceswitchLegal values are 1.3 and 1.4&amp;ndash; by default, no -source argument will be usedat all</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compiler" REQUIRED="no">
+			<DESCRIPTION>The compiler implementation to use.If this attribute is not set, the value of thebuild.compiler property, if set, will be used.Otherwise, the default compiler for the current VM will be used.(See the above list of validcompilers.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="listfiles" REQUIRED="no">
+			<DESCRIPTION>Indicates whether the source files to be compiled willbe listed; defaults to no</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="javadoc">
+		<DESCRIPTION>&lt;p&gt;Generates code documentation using the javadoc tool.&lt;/p&gt;
+&lt;p&gt;The source directory will be recursively scanned for Java source files to process
+but only those matching the inclusion rules, and not matching the exclusions rules
+will be passed to the javadoc tool. This
+allows wildcards to be used to choose between package names, reducing verbosity
+and management costs over time. This task, however, has no notion of
+&amp;quot;changed&amp;quot; files, unlike the &lt;a href=&quot;javac.html&quot;&gt;javac&lt;/a&gt; task. This means
+all packages will be processed each time this task is run. In general, however,
+this task is used much less frequently.&lt;/p&gt;
+&lt;p&gt;This task works seamlessly between different javadoc versions (1.1,
+1.2 and 1.4), with the obvious restriction that the 1.2 attributes
+will be ignored if run in a 1.1 VM.&lt;/p&gt;
+&lt;p&gt;NOTE: since javadoc calls System.exit(), javadoc cannot be run inside the
+same VM as ant without breaking functionality. For this reason, this task 
+always forks the VM. This overhead is not significant since javadoc is normally a heavy
+application and will be called infrequently.&lt;/p&gt;
+&lt;p&gt;NOTE: the packagelist attribute allows you to specify the list of packages to 
+document outside of the Ant file. It's a much better practice to include everything 
+inside the build.xml file. This option was added in order to make it easier to 
+migrate from regular makefiles, where you would use this option of javadoc. 
+The packages listed in packagelist are not checked, so the task performs even 
+if some packages are missing or broken. Use this option if you wish to convert from 
+an existing makefile. Once things are running you should then switch to the regular 
+notation. &lt;/p&gt;
+&lt;p&gt;&lt;i&gt;&lt;b&gt;DEPRECATION:&lt;/b&gt; the javadoc2 task simply points to the javadoc task and it's
+there for back compatibility reasons. Since this task will be removed in future
+versions, you are strongly encouraged to use &lt;a href=&quot;javadoc.html&quot;&gt;javadoc&lt;/a&gt;
+instead.&lt;/i&gt;&lt;/p&gt;
+&lt;p&gt;In the table below, 1.1 means available if your current Java VM is
+a 1.1 VM, 1.2 for either 1.2 or 1.3 and 1.4 for a 1.4 Java VM.  1.2+
+means any VM of at least version 1.2.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="sourcepath" REQUIRED="at least one of the three or nested
+     &lt;sourcepath&gt;, &lt;fileset&gt; or
+     &lt;packageset&gt;">
+			<DESCRIPTION>Specify where to find source file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sourcepathref" REQUIRED="">
+			<DESCRIPTION>Specify where to find source files by reference to a PATH defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sourcefiles" REQUIRED="">
+			<DESCRIPTION>Comma separated list of source file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destdir" REQUIRED="yes, unless a doclet has been specified.">
+			<DESCRIPTION>Destination directory for output file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="maxmemory" REQUIRED="no">
+			<DESCRIPTION>Max amount of memory to allocate to the javadoc V</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="packagenames" REQUIRED="no">
+			<DESCRIPTION>Comma separated list of package files (with terminatingwildcard</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="packagelist" REQUIRED="no">
+			<DESCRIPTION>The name of a file containing the packages to proces</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>Specify where to find user class file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bootclasspath" REQUIRED="no">
+			<DESCRIPTION>Override location of class files loaded by the bootstrapclass loade</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>Specify where to find user class files by reference to a PATH defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bootclasspathref" REQUIRED="no">
+			<DESCRIPTION>Override location of class files loaded by thebootstrap class loader by reference to aPATH defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="extdirs" REQUIRED="no">
+			<DESCRIPTION>Override location of installed extension</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="overview" REQUIRED="no">
+			<DESCRIPTION>Read overview documentation from HTML fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="access" REQUIRED="no (default protected)">
+			<DESCRIPTION>Access mode: one of public, protected,package, or privat</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="public" REQUIRED="no">
+			<DESCRIPTION>Show only public classes and member</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="protected" REQUIRED="no">
+			<DESCRIPTION>Show protected/public classes and members (default</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="package" REQUIRED="no">
+			<DESCRIPTION>Show package/protected/public classes and member</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="private" REQUIRED="no">
+			<DESCRIPTION>Show all classes and member</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="old" REQUIRED="no">
+			<DESCRIPTION>Generate output using JDK 1.1 emulating docle</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>Output messages about what Javadoc is doin</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="locale" REQUIRED="no">
+			<DESCRIPTION>Locale to be used, e.g. en_US or en_US_WI</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>Source file encoding nam</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="version" REQUIRED="no">
+			<DESCRIPTION>Include @version paragraph</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="use" REQUIRED="no">
+			<DESCRIPTION>Create class and package usage page</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="author" REQUIRED="no">
+			<DESCRIPTION>Include @author paragraph</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="splitindex" REQUIRED="no">
+			<DESCRIPTION>Split index into one file per lette</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="windowtitle" REQUIRED="no">
+			<DESCRIPTION>Browser window title for the documentation (text</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="doctitle" REQUIRED="no">
+			<DESCRIPTION>Include title for the package index(first) page (html-code</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="header" REQUIRED="no">
+			<DESCRIPTION>Include header text for each page (html-code</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="footer" REQUIRED="no">
+			<DESCRIPTION>Include footer text for each page (html-code</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bottom" REQUIRED="no">
+			<DESCRIPTION>Include bottom text for each page (html-code</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="link" REQUIRED="no">
+			<DESCRIPTION>Create links to javadoc output at the given UR</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="linkoffline" REQUIRED="no">
+			<DESCRIPTION>Link to docs at &lt;url&gt; using package list at&lt;url2&gt; - separate the URLs by using a space character</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="group" REQUIRED="no">
+			<DESCRIPTION>Group specified packages together in overviewpage.  The format is as described below</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nodeprecated" REQUIRED="no">
+			<DESCRIPTION>Do not include @deprecated informatio</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nodeprecatedlist" REQUIRED="no">
+			<DESCRIPTION>Do not generate deprecated lis</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="notree" REQUIRED="no">
+			<DESCRIPTION>Do not generate class hierarch</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="noindex" REQUIRED="no">
+			<DESCRIPTION>Do not generate inde</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nohelp" REQUIRED="no">
+			<DESCRIPTION>Do not generate help lin</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nonavbar" REQUIRED="no">
+			<DESCRIPTION>Do not generate navigation ba</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="serialwarn" REQUIRED="no">
+			<DESCRIPTION>Generate warning about @serial ta</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="helpfile" REQUIRED="no">
+			<DESCRIPTION>Specifies the HTML help file to us</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="stylesheetfile" REQUIRED="no">
+			<DESCRIPTION>Specifies the CSS stylesheet to us</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="charset" REQUIRED="no">
+			<DESCRIPTION>Charset for cross-platform viewing of generateddocumentatio</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="docencoding" REQUIRED="no">
+			<DESCRIPTION>Output file encoding nam</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="doclet" REQUIRED="no">
+			<DESCRIPTION>Specifies the class file that starts the doclet used in generating the documentation</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="docletpath" REQUIRED="no">
+			<DESCRIPTION>Specifies the path to the doclet class file that is specified with the -doclet option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="docletpathref" REQUIRED="no">
+			<DESCRIPTION>Specifies the path to the doclet class file thatis specified with the -doclet option by reference to a PATH defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="additionalparam" REQUIRED="no">
+			<DESCRIPTION>Lets you add additional parameters to the javadoccommand line. Useful for doclets. Parameters containingspaces need to be quoted using &amp;quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>Stop the buildprocess if the command exits with areturncode other than 0</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludepackagenames" REQUIRED="no">
+			<DESCRIPTION>comma separated list of packages you don't wantdocs for</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used(yes | no); default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="useexternalfile" REQUIRED="no">
+			<DESCRIPTION>indicates whether the sourcefile name specifiedin srcfiles or as nested source elements should be written to atemporary file to make the command line shorter. Also applies tothe package names specified via the packagenames attribute ornested package elements.(yes | no). Default is no</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="source" REQUIRED="no">
+			<DESCRIPTION>Necessary to enable javadoc to handle assertionspresent in J2SE v 1.4 source code. Set this to &quot;1.4&quot; todocuments code that compiles using &quot;javac -source1.4&quot;.  Will be ignored if you use a customdoclet</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="loadfile">
+		<DESCRIPTION>&lt;p&gt;
+Load a text file into a single property. Unless an encoding is specified,
+the encoding of the current locale is used.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="srcfile" REQUIRED="yes">
+			<DESCRIPTION>source fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="property" REQUIRED="yes">
+			<DESCRIPTION>property to save t</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>encoding to use when loading the fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no, default &quot;true&quot;">
+			<DESCRIPTION>Whether to halt the build on failur</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="loadproperties">
+		<DESCRIPTION>&lt;p&gt;
+Load a file's contents as Ant properties.  This is equivalent
+to &amp;lt;property file=&amp;quot;...&amp;quot;/&amp;gt; except that it
+supports nested &amp;lt;filterchain&amp;gt; elements and it cannot be
+specified outside a target.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="srcfile" REQUIRED="yes">
+			<DESCRIPTION>source fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>encoding to use when loading the fil</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="mail">
+		<DESCRIPTION>&lt;p&gt;A task to send SMTP email. This task can send mail using either plain
+text, UU encoding, or MIME format mail, depending on what is available.
+Attachments may be sent using nested
+&lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;fileset&lt;/a&gt; elements.&lt;/p&gt;
+&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This task may depend on external libraries
+that are not included
+in the Ant distribution.  See &lt;a href=&quot;../install.html#librarydependencies&quot;&gt;
+Library Dependencies&lt;/a&gt; for more information.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="from" REQUIRED="either a from attribute, or a &lt;from&gt;
+     element.">
+			<DESCRIPTION>Email address of sender</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tolist" REQUIRED="at least one of these, or the
+        equivalent elements.">
+			<DESCRIPTION>Comma-separated list of recipients</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="cclist" REQUIRED="">
+			<DESCRIPTION>Comma-separated list of recipients to carbon cop</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bcclist" REQUIRED="">
+			<DESCRIPTION>Comma-separated list of recipients to carbon cop</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="message" REQUIRED="one of these or a
+     &lt;message&gt; element.">
+			<DESCRIPTION>Message to send in the body of the email</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="messagefile" REQUIRED="">
+			<DESCRIPTION>File to send as the body of the email. Propertyvalues in the file will be expanded</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="messagemimetype" REQUIRED="no">
+			<DESCRIPTION>The content type of the message.  The default istext/plain</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="files" REQUIRED="no">
+			<DESCRIPTION>Files to send as attachments to the email.  Separate multiplefile names using a comma.  You can also use &lt;fileset&gt;elements to specify files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no.">
+			<DESCRIPTION>flag to indicate whether to halt the build onany error.  The default value is true</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includefilenames" REQUIRED="no">
+			<DESCRIPTION>Include filename(s) before file contents.Valid only when the plain encoding is used.  The defaultvalue is false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="mailhost" REQUIRED="no">
+			<DESCRIPTION>Host name of the SMTP server.  The default value islocalhost</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="mailport" REQUIRED="no">
+			<DESCRIPTION>TCP port of the SMTP server.  The default value is 25</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>Specifies the encoding to use for the content of the email.Values are mime, uu, plain, orauto.  The default value is auto</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="subject" REQUIRED="no">
+			<DESCRIPTION>Email subject line</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="manifest">
+		<DESCRIPTION>&lt;p&gt;Creates a manifest file.&lt;/p&gt;
+&lt;p&gt;This task can be used to write a Manifest file, optionally
+replacing or updating an existing file.&lt;/p&gt;
+&lt;p&gt;Manifests are processed according to the 
+&lt;a href=&quot;http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html&quot;&gt;Jar
+file specification.&lt;/a&gt;. Specifically, a manifest element consists of
+a set of attributes and sections. These sections in turn may contain
+attributes. Note in particular that this may result in manifest lines
+greater than 72 bytes being wrapped and continued on the next
+line.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="yes">
+			<DESCRIPTION>the manifest-file to create/update</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="mode" REQUIRED="no">
+			<DESCRIPTION>One of &quot;update&quot; or &quot;replace&quot;, default is &quot;replace&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="mkdir">
+		<DESCRIPTION>&lt;p&gt;Creates a directory. Also non-existent parent directories are created, when
+necessary.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="dir" REQUIRED="yes">
+			<DESCRIPTION>the directory to create</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="move">
+		<DESCRIPTION>&lt;p&gt;Moves a file to a new file or directory, or sets of files to
+a new directory.  By default, the
+destination file is overwritten if it already exists.  When &lt;var&gt;overwrite&lt;/var&gt; is
+turned off, then files are only moved if the source file is newer than
+the destination file, or when the destination file does not exist.&lt;/p&gt;
+&lt;p&gt;&lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt;s are used to select sets of files
+to move to the &lt;var&gt;todir&lt;/var&gt; directory.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="one of file or
+      at least one nested fileset element">
+			<DESCRIPTION>the file to mov</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tofile" REQUIRED="with the file attribute,
+     either tofile or todir can be used.  with nested filesets,
+     if the fileset size is greater than 1 or if the only entry in the fileset is a
+     directory or if the file attribute is already specified, only
+     todir is allowed">
+			<DESCRIPTION>the file to move t</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="todir" REQUIRED="">
+			<DESCRIPTION>the directory to move t</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="overwrite" REQUIRED="no">
+			<DESCRIPTION>overwrite existing files even if the destinationfiles are newer (default is &quot;true&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filtering" REQUIRED="no">
+			<DESCRIPTION>indicates whether token filtering should take place duringthe move.  See the filter task for a description ofhow filters work</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="flatten" REQUIRED="no">
+			<DESCRIPTION>ignore directory structure of source directory,copy all files into a single directory, specified by the todirattribute (default is &quot;false&quot;).Note that you can achieve thesame effect by using a flatten mappe</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includeemptydirs" REQUIRED="no">
+			<DESCRIPTION>Copy empty directories included with the nested FileSet(s).Defaults to &quot;yes&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="parallel">
+		<DESCRIPTION>&lt;p&gt;Parallel is a container task - it can contain other Ant tasks. Each nested
+task within the parallel task will be executed in its own thread. &lt;/p&gt;
+&lt;p&gt;Parallel tasks have a number of uses in an Ant buildfile including:&lt;/p&gt;
+&lt;ul&gt;
+&lt;li&gt;Taking advantage of available processing resources to reduce build time&lt;/li&gt;
+&lt;li&gt;Testing servers, where the server can be run in one thread and the test
+harness is run in another thread.&lt;/li&gt;
+&lt;/ul&gt;
+&lt;p&gt;Care must be taken when using multithreading to ensure the tasks within the
+threads do not interact. For example, two javac compile tasks which write 
+classes into the same destination directory may interact where one tries to
+read a class for dependency information while the other task is writing the 
+class file. Be sure to avoid these types of interactions within a 
+&amp;lt;parallel&amp;gt; task&lt;/p&gt;
+&lt;p&gt;The parallel task has no attributes and does not support any nested 
+elements apart from Ant tasks. Any valid Ant task may be embedded within a 
+parallel task, including other parallel tasks.&lt;/p&gt;
+&lt;p&gt;Note that while the tasks within the parallel task are being run, the main 
+thread will be blocked waiting for all the child threads to complete.&lt;/p&gt;  
+&lt;p&gt;If any of the tasks within the &amp;lt;parallel&amp;gt; task fails, the remaining 
+tasks in other threads will continue to run until all threads have completed. 
+In this situation, the parallel task will also fail.&lt;/p&gt;
+&lt;p&gt;The parallel task may be combined with the &lt;a href=&quot;sequential.html&quot;&gt;
+sequential&lt;/a&gt; task to define sequences of tasks to be executed on each thread
+within the parallel block&lt;/p&gt;
+&lt;h3&gt;Examples&lt;/h3&gt;
+&lt;pre&gt;
+&amp;lt;parallel&amp;gt;
+&amp;lt;wlrun ... &amp;gt;
+&amp;lt;sequential&amp;gt;
+&amp;lt;sleep seconds=&amp;quot;30&amp;quot;/&amp;gt;
+&amp;lt;junit ... &amp;gt;
+&amp;lt;wlstop/&amp;gt;
+&amp;lt;/sequential&amp;gt;
+&amp;lt;/parallel&amp;gt;
+&lt;/pre&gt;
+&lt;p&gt;This example represents a typical pattern for testing a server application. 
+In one thread the server is started (the wlrun task). The other thread consists 
+of a three tasks which are performed in sequence. The sleep task is used to 
+give the server time to come up. Another task which is capable of validating 
+that the server is available could be used in place of the sleep task. The 
+test harness is then run. Once the tests are complete, the server is stopped 
+(using wlstop in this example), allowing both threads to complete. The 
+parallel task will also complete at this time and the build will then 
+continue.&lt;/p&gt;
+&lt;pre&gt;
+&amp;lt;parallel&amp;gt;
+&amp;lt;javac ...&amp;gt; &amp;lt;!-- compiler servlet code --&amp;gt;
+&amp;lt;wljspc ...&amp;gt; &amp;lt;!-- precompile JSPs --&amp;gt;
+&amp;lt;/parallel&amp;gt;
+&lt;/pre&gt;
+&lt;p&gt;This example shows two independent tasks being run to achieve better 
+resource utilization during the build. In this instance, some servlets are being
+compiled in one thead and a set of JSPs is being precompiled in another. As 
+noted above, you need to be careful that the two tasks are independent, both in 
+terms of their dependencies and in terms of their potential interactions in
+Ant's external environment.&lt;/p&gt;
+&lt;hr&gt;
+&lt;p align=&quot;center&quot;&gt;Copyright &amp;copy; 2001-2002 Apache Software Foundation. All rights
+Reserved.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+</DESCRIPTION>	</TASK>
+	<TASK NAME="patch">
+		<DESCRIPTION>&lt;p&gt;Applies a diff file to originals. ; requires &quot;patch&quot; to be
+on the execution path.  &lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="patchfile" REQUIRED="yes">
+			<DESCRIPTION>the file that includes the diff outpu</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="originalfile" REQUIRED="no, tries to guess it from the diff 
+       file">
+			<DESCRIPTION>the file to patc</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="backups" REQUIRED="no">
+			<DESCRIPTION>Keep backups of the unpatched file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="quiet" REQUIRED="no">
+			<DESCRIPTION>Work silently unless an error occur</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="reverse" REQUIRED="no">
+			<DESCRIPTION>Assume patch was created with old and new files swapped</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="ignorewhitespace" REQUIRED="no">
+			<DESCRIPTION>Ignore whitespace differences</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="strip" REQUIRED="no">
+			<DESCRIPTION>Strip the smallest prefix containing num leading slashes from filenames</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="no, default is the project's basedir.">
+			<DESCRIPTION>The directory in which to run the patch command</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="pathconvert">
+		<DESCRIPTION>&lt;p&gt;Converts a nested &lt;code&gt;&amp;lt;path&amp;gt;&lt;/code&gt; or reference to a Path,
+FileSet, DirSet, or FileList into a path
+form for a particular platform, and stores the result in a given property.
+It can also be used when you need
+to convert a Path, FileSet, or DirSet into a list, separated by a given
+character, such as a comma or space, or, conversely, to convert a list
+of files in a FileList into a path.
+&lt;/p&gt;
+&lt;p&gt;Nested &lt;code&gt;&amp;lt;map&amp;gt;&lt;/code&gt; elements can be specified to map Windows
+drive letters to Unix paths, and vice-versa.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="targetos" REQUIRED="yes, unless pathsep and/or
+        dirsep are specified.
+     ">
+			<DESCRIPTION>The target architecture.  Must be one of 'unix', 'windows', 'netware' or 'os/2'.This is a shorthand mechanism for specifying bothpathsep and dirsepaccording to the specified target architecture.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dirsep" REQUIRED="no, defaults to current jvm file.separator">
+			<DESCRIPTION>The character(s) to use as the directory separator in thegenerated paths.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="pathsep" REQUIRED="no, defaults to current jvm file.pathseparator">
+			<DESCRIPTION>The character(s) to use as the path-element separator in thegenerated paths.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="property" REQUIRED="yes">
+			<DESCRIPTION>The name of the property in which to place the converted path</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="refid" REQUIRED="no; if omitted, a nested
+         &lt;path&gt; element must be supplied.">
+			<DESCRIPTION>What to convert, given as areference to a&lt;path&gt;, &lt;fileset&gt;,&lt;dirset&gt;, or &lt;fileset&gt;defined elsewher</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="setonempty" REQUIRED="no; default is &quot;true&quot;.
+   ">
+			<DESCRIPTION>Should the property be set, even if the resultis the empty string?</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="property">
+		<DESCRIPTION>&lt;p&gt;Sets a property (by name and value), or set of properties (from file or
+resource) in the project.  Properties are case sensitive.&lt;/p&gt;
+Properties are immutable: whoever sets a property first freezes it for the
+rest of the build; they are most definately not variable. 
+&lt;p&gt;There are five ways to set properties:&lt;/p&gt;
+&lt;ul&gt;
+&lt;li&gt;By supplying both the &lt;i&gt;name&lt;/i&gt; and &lt;i&gt;value&lt;/i&gt; attribute.&lt;/li&gt;
+&lt;li&gt;By supplying both the &lt;i&gt;name&lt;/i&gt; and &lt;i&gt;refid&lt;/i&gt; attribute.&lt;/li&gt;
+&lt;li&gt;By setting the &lt;i&gt;file&lt;/i&gt; attribute with the filename of the property
+file to load. This property file has the format as defined by the file used
+in the class java.util.Properties.&lt;/li&gt;
+&lt;li&gt;By setting the &lt;i&gt;resource&lt;/i&gt; attribute with the resource name of the
+property file to load. This property file has the format as defined by the
+file used in the class java.util.Properties.&lt;/li&gt;
+&lt;li&gt;By setting the &lt;i&gt;environment&lt;/i&gt; attribute with a prefix to use.
+Properties will be defined for every environment variable by
+prefixing the supplied name and a period to the name of the variable.&lt;/li&gt;
+&lt;/ul&gt;
+&lt;p&gt;Although combinations of these ways are possible, only one should be used
+at a time. Problems might occur with the order in which properties are set, for
+instance.&lt;/p&gt;
+&lt;p&gt;The value part of the properties being set, might contain references to other
+properties. These references are resolved at the time these properties are set.
+This also holds for properties loaded from a property file.&lt;/p&gt;
+&lt;p&gt;A list of predefined properties can be found &lt;a
+href=&quot;../using.html#built-in-props&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="name" REQUIRED="no">
+			<DESCRIPTION>the name of the property to set</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="value" REQUIRED="one of these, when using the
+        name attribute">
+			<DESCRIPTION>the value of the property</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="location" REQUIRED="">
+			<DESCRIPTION>Sets the property to the absolute filename of thegiven file. If the value of this attribute is an absolute path, itis left unchanged (with / and \ characters converted to thecurrent platforms conventions). Otherwise it is taken as a pathrelative to the project's basedir and expanded</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="refid" REQUIRED="">
+			<DESCRIPTION>Reference to an objectdefined elsewhere. Only yields reasonable results for referencesto PATH like structures or properties</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="resource" REQUIRED="one of these, when
+       not using the name attribute">
+			<DESCRIPTION>the resource name of the property file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="file" REQUIRED="">
+			<DESCRIPTION>the filename of the property file </DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="environment" REQUIRED="">
+			<DESCRIPTION>the prefix to use when retrieving environment variables. Thusif you specify environment=&quot;myenv&quot; you will be able to access OS-specific environment variables via property names &quot;myenv.PATH&quot; or &quot;myenv.TERM&quot;. Note that if you supply a property name with a final &quot;.&quot; it will not be doubled. ie environment=&quot;myenv.&quot; will still allow access of environment variables through &quot;myenv.PATH&quot; and &quot;myenv.TERM&quot;. This functionality is currently only implemented on select platforms. Feel free to send patches to increase the number of platformsthis functionality is supported on ;)Note also that properties are case sensitive, even if theenvironment variables on your operating system are not, e.g. itwill be ${env.Path} not ${env.PATH} on Windows 2000</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>the classpath to use when looking up a resource</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>the classpath to use when looking up a resource,given as reference to a &lt;path&gt; definedelsewhere.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="prefix" REQUIRED="no">
+			<DESCRIPTION>Prefix to apply to properties loaded using fileor resource. A &quot;.&quot; is appended to the prefix if not specified</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="recorder">
+		<DESCRIPTION>&lt;p&gt;A recorder is a listener to the current build process that records the
+output to a file.&lt;/p&gt;
+&lt;p&gt;Several recorders can exist at the same time.  Each recorder is
+associated with a file.  The filename is used as a unique identifier for
+the recorders.  The first call to the recorder task with an unused filename
+will create a recorder (using the parameters provided) and add it to the
+listeners of the build.  All subsequent calls to the recorder task using
+this filename will modify that recorders state (recording or not) or other
+properties (like logging level).&lt;/p&gt;
+&lt;p&gt;Some technical issues: the file's print stream is flushed for &amp;quot;finished&amp;quot;
+events (buildFinished, targetFinished and taskFinished), and is closed on
+a buildFinished event.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="name" REQUIRED="yes">
+			<DESCRIPTION>The name of the file this logger is associated with</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="action" REQUIRED="no">
+			<DESCRIPTION>This tells the logger what to do: should it startrecording or stop?  The first time that the recorder task is called forthis logfile, and if this attribute is not provided, then the defaultfor this attribute is &quot;start&quot;.  If this attribute is not provided onsubsequent calls, then the state remains as previous.[Values = {start|stop}, Default = no state change</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="append" REQUIRED="no">
+			<DESCRIPTION>Should the recorder append to a file, or create a newone? This is only applicable the first time this task is called forthis file.  [Values = {yes|no}, Default=yes</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="emacsmode" REQUIRED="no, default is false">
+			<DESCRIPTION>Removes [task] banners like Ant's-emacs command line switch if set totrue</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="loglevel" REQUIRED="no">
+			<DESCRIPTION>At what logging level should this recorder instancerecord to?  This is not a once only parameter (like appendis) -- you can increase or decrease the logging level as the build processcontinues.  [Values= {error|warn|info|verbose|debug}, Default = no change]</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="rename">
+		<DESCRIPTION>&lt;p&gt;Renames a given file.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="src" REQUIRED="yes">
+			<DESCRIPTION>file to rename</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dest" REQUIRED="yes">
+			<DESCRIPTION>new name of the file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="replace" REQUIRED="no">
+			<DESCRIPTION>Enable replacing of existing file (default: on)</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="replace">
+		<DESCRIPTION>&lt;p&gt;Replace is a directory based task for replacing the occurrence of a given string with another string 
+in selected file.&lt;/p&gt;
+&lt;p&gt;If you want to replace a text that crosses line boundaries, you
+must use a nested &lt;code&gt;&amp;lt;replacetoken&amp;gt;&lt;/code&gt; element.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="exactly one of the two.">
+			<DESCRIPTION>file for which the token should be replaced</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="">
+			<DESCRIPTION>The base directory to use when replacing a token in multiple files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no - defaults to default jvm encoding">
+			<DESCRIPTION>The encoding of the files upon which replace operates</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="token" REQUIRED="yes, unless a nested
+     replacetoken element or the replacefilterfile
+     attribute is used.">
+			<DESCRIPTION>the token which must be replaced</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="value" REQUIRED="no">
+			<DESCRIPTION>the new value for the token. When omitted, an empty string(&quot;&quot;) is used</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="summary" REQUIRED="no, by default no summary is produced">
+			<DESCRIPTION>Indicates whether a summary of the replace operation should be produced, detailing how many token occurrences and files were processed</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="propertyfile" REQUIRED="yes only if property attribute of &lt;replacefilter&gt; is used.">
+			<DESCRIPTION>valid property file from which properties specified using nested &lt;replacefilter&gt; elements are drawn</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="replacefilterfile" REQUIRED="no.">
+			<DESCRIPTION>valid property file.  Each property will betreated as a replacefilter where token is the name ofthe property and value is the properties value.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="rmic">
+		<DESCRIPTION>&lt;p&gt;Runs the rmic compiler for a certain class.&lt;/p&gt;
+&lt;p&gt;Rmic can be run on a single class (as specified with the classname
+attribute) or a number of classes at once (all classes below base that
+are neither _Stub nor _Skel classes).  If you want to rmic a single
+class and this class is a class nested into another class, you have to
+specify the classname in the form &lt;code&gt;Outer$$Inner&lt;/code&gt; instead of
+&lt;code&gt;Outer.Inner&lt;/code&gt;.&lt;/p&gt;
+&lt;p&gt;It is possible to refine the set of files that are being rmiced. This can be
+done with the &lt;i&gt;includes&lt;/i&gt;, &lt;i&gt;includesfile&lt;/i&gt;, &lt;i&gt;excludes&lt;/i&gt;, &lt;i&gt;excludesfile&lt;/i&gt; and &lt;i&gt;defaultexcludes&lt;/i&gt;
+attributes. With the &lt;i&gt;includes&lt;/i&gt; or &lt;i&gt;includesfile&lt;/i&gt; attribute you specify the files you want to
+have included by using patterns. The &lt;i&gt;exclude&lt;/i&gt; or &lt;i&gt;excludesfile&lt;/i&gt; attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the &lt;i&gt;defaultexcludes&lt;/i&gt; attribute, you can specify whether you
+want to use default exclusions or not. See the section on &lt;a
+href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based tasks&lt;/a&gt;, on how the
+inclusion/exclusion of files works, and how to write patterns.&lt;/p&gt;
+&lt;p&gt;This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and
+supports all attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;
+(&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;base&lt;/code&gt;) as well as the nested
+&lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt; and
+&lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+&lt;p&gt;It is possible to use different compilers. This can be selected
+with the &amp;quot;build.rmic&amp;quot; property or the &lt;code&gt;compiler&lt;/code&gt;
+attribute. &lt;a name=&quot;compilervalues&quot;&gt;There are three choices&lt;/a&gt;:&lt;/p&gt;
+&lt;ul&gt;
+&lt;li&gt;sun (the standard compiler of the JDK)&lt;/li&gt;
+&lt;li&gt;kaffe (the standard compiler of &lt;a href=&quot;http://www.kaffe.org&quot; target=&quot;_top&quot;&gt;Kaffe&lt;/a&gt;)&lt;/li&gt;
+&lt;li&gt;weblogic&lt;/li&gt;
+&lt;/ul&gt;
+&lt;p&gt;The &lt;a href=&quot;http://dione.zcu.cz/~toman40/miniRMI/&quot;&gt;miniRMI&lt;/a&gt;
+project contains a compiler implementation for this task as well,
+please consult miniRMI's documentation to learn how to use it.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="base" REQUIRED="yes">
+			<DESCRIPTION>the location to store the compiled files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classname" REQUIRED="no">
+			<DESCRIPTION>the class for which to run rmic</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filtering" REQUIRED="no">
+			<DESCRIPTION>indicates whether token filtering should take plac</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sourcebase" REQUIRED="no">
+			<DESCRIPTION>Pass the &quot;-keepgenerated&quot; flag to rmic andmove the generated source file to the base directory</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="stubversion" REQUIRED="no">
+			<DESCRIPTION>Specify the JDK version for the generated stub code.Specify &quot;1.1&quot; to pass the &quot;-v1.1&quot; option to rmic</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>The classpath to use during compilatio</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>The classpath to use during compilation, given as reference to a PATH defined elsewher</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verify" REQUIRED="no">
+			<DESCRIPTION>check that classes implement Remote before handing them to rmic (default is false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="iiop" REQUIRED="no">
+			<DESCRIPTION>indicates that portable (RMI/IIOP) stubs should be generate</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="iiopopts" REQUIRED="no">
+			<DESCRIPTION>additional arguments for IIOP class generatio</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="idl" REQUIRED="no">
+			<DESCRIPTION>indicates that IDL output files should be generate</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="idlopts" REQUIRED="no">
+			<DESCRIPTION>additional arguments for IDL file generatio</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debug" REQUIRED="no">
+			<DESCRIPTION>generate debug info (passes -g to rmic). Defaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includeantruntime" REQUIRED="no">
+			<DESCRIPTION>whether to include the Ant run-time libraries;defaults to yes</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includejavaruntime" REQUIRED="no">
+			<DESCRIPTION>whether to include the default run-timelibraries from the executing VM; defaults to no</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="extdirs" REQUIRED="no">
+			<DESCRIPTION>location of installed extensions</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compiler" REQUIRED="no">
+			<DESCRIPTION>The compiler implementation to use.If this attribute is not set, the value of thebuild.rmic property, if set, will be used.Otherwise, the default compiler for the current VM will be used.(See the above list of validcompilers.</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="sequential">
+		<DESCRIPTION>&lt;p&gt;Sequential is a container task - it can contain other Ant tasks. The nested 
+tasks are simply executed in sequence. Sequential's primary use is to support 
+the sequential execution of a subset of tasks within the 
+&lt;a href=&quot;parallel.html&quot;&gt;parallel&lt;/a&gt; task&lt;/p&gt;
+&lt;p&gt;The sequential task has no attributes and does not support any nested 
+elements apart from Ant tasks. Any valid Ant task may be embedded within the 
+sequential task.&lt;/p&gt;
+&lt;h3&gt;Example&lt;/h3&gt;
+&lt;pre&gt;
+&amp;lt;parallel&amp;gt;
+&amp;lt;wlrun ... &amp;gt;
+&amp;lt;sequential&amp;gt;
+&amp;lt;sleep seconds=&amp;quot;30&amp;quot;/&amp;gt;
+&amp;lt;junit ... &amp;gt;
+&amp;lt;wlstop/&amp;gt;
+&amp;lt;/sequential&amp;gt;
+&amp;lt;/parallel&amp;gt;
+&lt;/pre&gt;
+&lt;p&gt;This example shows how the sequential task is used to execute three tasks in
+sequence, while another task is being executed in a separate thread. &lt;/p&gt;
+&lt;hr&gt;
+&lt;p align=&quot;center&quot;&gt;Copyright &amp;copy; 2001-2002 Apache Software Foundation. All rights
+Reserved.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+</DESCRIPTION>	</TASK>
+	<TASK NAME="signjar">
+		<DESCRIPTION>&lt;p&gt;Signs jar or zip files with the javasign command line tool. The
+tool detailed dependency checking: files are only signed if they
+are not signed. The &lt;tt&gt;signjar&lt;/tt&gt; attribute can point to the file to
+generate; if this file exists then
+its modification date is used as a cue as to whether to resign any JAR file.
+&lt;br&gt;  
+&lt;strong&gt;Note:&lt;/strong&gt; Requires Java 1.2 or later. &lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="jar" REQUIRED="yes.">
+			<DESCRIPTION>the jar file to sig</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="alias" REQUIRED="yes.">
+			<DESCRIPTION>the alias to sign unde</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="storepass" REQUIRED="yes.">
+			<DESCRIPTION>password for keystore integrity</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="keystore" REQUIRED="no">
+			<DESCRIPTION>keystore locatio</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="storetype" REQUIRED="no">
+			<DESCRIPTION>keystore typ</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="keypass" REQUIRED="no">
+			<DESCRIPTION>password for private key (if different</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sigfile" REQUIRED="no">
+			<DESCRIPTION>name of .SF/.DSA fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="signedjar" REQUIRED="no">
+			<DESCRIPTION>name of signed JAR fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no; default false">
+			<DESCRIPTION>(true | false) verbose output when signin</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="internalsf" REQUIRED="no; default false">
+			<DESCRIPTION>(true | false) include the .SF file inside the signaturebloc</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sectionsonly" REQUIRED="no; default false">
+			<DESCRIPTION>(true | false) don't compute hash of entire manifes</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="lazy" REQUIRED="no; default false">
+			<DESCRIPTION>flag to control whether the presence of a signaturefile means a JAR is signe</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="sleep">
+		<DESCRIPTION>&lt;p&gt; A task for sleeping a short period of time, useful when a build or deployment 
+process requires an interval between tasks.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="hours" REQUIRED="no">
+			<DESCRIPTION>hours to to add to the sleep tim</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="minutes" REQUIRED="no">
+			<DESCRIPTION>minutes to add to the sleep tim</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="seconds" REQUIRED="no">
+			<DESCRIPTION>seconds to add to the sleep tim</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="milliseconds" REQUIRED="no">
+			<DESCRIPTION>milliseconds to add to the sleep tim</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>flag controlling whether to break the build on an error. </DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="sql">
+		<DESCRIPTION>&lt;p&gt;Executes a series of SQL statements via JDBC to a database. Statements can 
+either be read in from a text file using the &lt;i&gt;src&lt;/i&gt; attribute or from 
+between the enclosing SQL tags.&lt;/p&gt;
+&lt;p&gt;Multiple statements can be provided, separated by semicolons (or the 
+defined &lt;i&gt;delimiter&lt;/i&gt;). Individual lines within the statements can be 
+commented using either --, // or REM at the start of the line.&lt;/p&gt;
+&lt;p&gt;The &lt;i&gt;autocommit&lt;/i&gt; attribute specifies whether auto-commit should be 
+turned on or off whilst executing the statements. If auto-commit is turned 
+on each statement will be executed and committed. If it is turned off the 
+statements will all be executed as one transaction.&lt;/p&gt;
+&lt;p&gt;The &lt;i&gt;onerror&lt;/i&gt; attribute specifies how to proceed when an error occurs 
+during the execution of one of the statements. 
+The possible values are: &lt;b&gt;continue&lt;/b&gt; execution, only show the error;
+&lt;b&gt;stop&lt;/b&gt; execution and commit transaction;
+and &lt;b&gt;abort&lt;/b&gt; execution and transaction and fail task.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="driver" REQUIRED="yes">
+			<DESCRIPTION>Class name of the jdbc drive</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="url" REQUIRED="yes">
+			<DESCRIPTION>Database connection ur</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="userid" REQUIRED="yes">
+			<DESCRIPTION>Database user nam</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="password" REQUIRED="yes">
+			<DESCRIPTION>Database passwor</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="src" REQUIRED="yes, unless statements enclosed within tags">
+			<DESCRIPTION>File containing SQL statement</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no - defaults to default jvm encoding">
+			<DESCRIPTION>The encoding of the files containing SQL statement</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="delimiter" REQUIRED="no, default &quot;;&quot;">
+			<DESCRIPTION>String that separates SQL statement</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="autocommit" REQUIRED="no, default &quot;false&quot;">
+			<DESCRIPTION>Auto commit flag for database connection (default false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="print" REQUIRED="no, default &quot;false&quot;">
+			<DESCRIPTION>Print result sets from the statements (default false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="showheaders" REQUIRED="no, default &quot;true&quot;">
+			<DESCRIPTION>Print headers for result sets from the statements (default true</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="output" REQUIRED="no (print to system.out by default)">
+			<DESCRIPTION>Output file for result sets (defaults to System.out</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="append" REQUIRED="no">
+			<DESCRIPTION>whether output should be appended to or overwritean existing file.  Defaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no (use system classpath)">
+			<DESCRIPTION>Classpath used to load drive</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no (use system classpath)">
+			<DESCRIPTION>The classpath to use, given as a reference to a path defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="onerror" REQUIRED="no, default &quot;abort&quot;">
+			<DESCRIPTION>Action to perform when statement fails: continue, stop, abor</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="rdbms" REQUIRED="no (no restriction)">
+			<DESCRIPTION>Execute task only if this rdbm</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="version" REQUIRED="no (no restriction)">
+			<DESCRIPTION>Execute task only if rdbms version matc</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="caching" REQUIRED="no (default=true)">
+			<DESCRIPTION>Should the task cache loaders and the driver</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="tar">
+		<DESCRIPTION>&lt;p&gt;Creates a tar archive.&lt;/p&gt;
+&lt;p&gt;The &lt;i&gt;basedir&lt;/i&gt; attribute is the reference directory from where to tar.&lt;/p&gt;
+&lt;p&gt;This task is a &lt;a href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based task&lt;/a&gt;
+and, as such, forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;Fileset&lt;/a&gt;. This
+defines which files, relative to the &lt;i&gt;basedir&lt;/i&gt;, will be included in the
+archive. The tar task supports all the attributes of Fileset to refine the
+set of files to be included in the implicit fileset.&lt;/p&gt;
+&lt;p&gt;In addition to the implicit fileset, the tar task supports nested filesets. These
+filesets are extended to allow control over the access mode, username and groupname
+to be applied to the tar entries. This is useful, for example, when preparing archives for
+Unix systems where some files need to have execute permission.&lt;/p&gt;
+&lt;p&gt;Early versions of tar did not support path lengths greater than 100
+characters. Modern versions of tar do so, but in incompatible ways.
+The behaviour of the tar task when it encounters such paths is
+controlled by the &lt;i&gt;longfile&lt;/i&gt; attribute.
+If the longfile attribute is set to &lt;code&gt;fail&lt;/code&gt;, any long paths will
+cause the tar task to fail.  If the longfile attribute is set to
+&lt;code&gt;truncate&lt;/code&gt;, any long paths will be truncated to the 100 character
+maximum length prior to adding to the archive. If the value of the longfile
+attribute is set to &lt;code&gt;omit&lt;/code&gt; then files containing long paths will be
+omitted from the archive.  Either option ensures that the archive can be
+untarred by any compliant version of tar. If the loss of path or file
+information is not acceptable, and it rarely is, longfile may be set to the
+value &lt;code&gt;gnu&lt;/code&gt;. The tar task will then produce a GNU tar file which
+can have arbitrary length paths. Note however, that the resulting archive will
+only be able to be untarred with GNU tar.  The default for the longfile
+attribute is &lt;code&gt;warn&lt;/code&gt; which behaves just like the gnu option except
+that it produces a warning for each file path encountered that does not match
+the limit.&lt;/p&gt;
+&lt;p&gt;This task can perform compression by setting the compression attribute to &quot;gzip&quot;
+or &quot;bzip2&quot;.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="destfile" REQUIRED="yes">
+			<DESCRIPTION>the tar-file to create</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="basedir" REQUIRED="no">
+			<DESCRIPTION>the directory from which to tar the files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="longfile" REQUIRED="no">
+			<DESCRIPTION>Determines how long files (&gt;100 chars) are to behandled.  Allowable values are &quot;truncate&quot;, &quot;fail&quot;,&quot;warn&quot;, &quot;omit&quot; and &quot;gnu&quot;.  Default is&quot;warn&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compression" REQUIRED="no">
+			<DESCRIPTION>compression method.  Allowable values are &quot;none&quot;, &quot;gzip&quot; and &quot;bzip2&quot;.  Default is&quot;none&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="taskdef">
+		<DESCRIPTION>&lt;p&gt;Adds a task definition to the current project, such that this new task can be
+used in the current project. Two attributes are needed, the name that identifies
+this task uniquely, and the full name of the class (including the packages) that
+implements this task.&lt;/p&gt;
+&lt;p&gt;You can also define a group of tasks at once using the file or
+resource attributes.  These attributes point to files in the format of
+Java property files.  Each line defines a single task in the
+format:&lt;/p&gt;
+&lt;pre&gt;
+taskname=fully.qualified.java.classname
+&lt;/pre&gt;
+&lt;p&gt;Taskdef should be used to add your own tasks to the system. See also &amp;quot;&lt;a
+href=&quot;../develop.html#writingowntask&quot;&gt;Writing your own task&lt;/a&gt;&amp;quot;.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="name" REQUIRED="yes, unless file or resource have
+     been specified.">
+			<DESCRIPTION>the name of the tas</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classname" REQUIRED="yes, unless file or resource have
+     been specified.">
+			<DESCRIPTION>the full class name implementing the tas</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="file" REQUIRED="no">
+			<DESCRIPTION>Name of the property file to loadtaskname/classname pairs from</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="resource" REQUIRED="no">
+			<DESCRIPTION>Name of the property resource to loadtaskname/classname pairs from</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>the classpath touse when looking up classname orresource</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>Reference to a classpath touse when looking up classname orresource</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="loaderref" REQUIRED="no">
+			<DESCRIPTION>the name of the loader that isused to load the class, constructed from the specified classpath. Use this toallow multiple tasks/types to be loaded with the same loader, so they can calleach other. ( introduced in ant1.5 </DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="touch">
+		<DESCRIPTION>&lt;p&gt;Changes the modification time of a file and possibly creates it at
+the same time. In addition to working with a single file, this Task
+can also work a &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;Fileset&lt;/a&gt; (which
+also includes directories).&lt;/p&gt;
+&lt;p&gt;For JDK 1.1 only the creation of new files with a modification time
+of now works, all other cases will emit a warning.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="unless a nested fileset element
+        has been specified.">
+			<DESCRIPTION>the name of the fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="millis" REQUIRED="no">
+			<DESCRIPTION>specifies the new modification time of the filein milliseconds since midnight Jan 1 197</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="datetime" REQUIRED="no">
+			<DESCRIPTION>specifies the new modification time of the filein the format MM/DD/YYYY HH:MM AM_or_PM</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="tstamp">
+		<DESCRIPTION>&lt;p&gt;Sets the &lt;code&gt;DSTAMP&lt;/code&gt;, &lt;code&gt;TSTAMP&lt;/code&gt;, and &lt;code&gt;TODAY&lt;/code&gt;
+properties in the current project. By default,
+the &lt;code&gt;DSTAMP&lt;/code&gt; property is in the
+format &amp;quot;yyyyMMdd&amp;quot;, &lt;code&gt;TSTAMP&lt;/code&gt; is in the
+format &amp;quot;hhmm&amp;quot;, and &lt;code&gt;TODAY&lt;/code&gt; is in the
+format &amp;quot;MMMM dd yyyy&amp;quot;. Use the nested &amp;lt;format&amp;gt; element
+to specify a different format.&lt;/p&gt;
+&lt;p&gt;These properties can be used in the build-file, for instance, to create
+time-stamped filenames, or used to replace placeholder tags inside documents
+to indicate, for example, the release date. The best place for this task is
+probably in an initialization target.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="prefix" REQUIRED="no">
+			<DESCRIPTION>Prefix used for all properties set. The default is no prefix</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="typedef">
+		<DESCRIPTION>&lt;p&gt;Adds a data type definition to the current project, such that this
+new type can be used in the current project. Two attributes are
+needed, the name that identifies this data type uniquely, and the full
+name of the class (including the packages) that implements this
+type.&lt;/p&gt;
+&lt;p&gt;You can also define a group of data types at once using the file or
+resource attributes.  These attributes point to files in the format of
+Java property files.  Each line defines a single data type in the
+format:&lt;/p&gt;
+&lt;pre&gt;
+typename=fully.qualified.java.classname
+&lt;/pre&gt;
+&lt;p&gt;Typedef should be used to add your own types to the system. Data
+types are things like &lt;a href=&quot;../using.html#path&quot;&gt;paths&lt;/a&gt; or &lt;a
+href=&quot;../CoreTypes/fileset.html&quot;&gt;filesets&lt;/a&gt; that can be defined at
+the project level and referenced via their ID attribute.&lt;/p&gt;
+&lt;p&gt;Custom data types usually need custom tasks to put them to good use.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="name" REQUIRED="yes, unless file or resource have
+     been specified.">
+			<DESCRIPTION>the name of the data typ</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classname" REQUIRED="yes, unless file or resource have
+     been specified.">
+			<DESCRIPTION>the full class name implementing the data typ</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="file" REQUIRED="no">
+			<DESCRIPTION>Name of the property file to loadtypename/classname pairs from</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="resource" REQUIRED="no">
+			<DESCRIPTION>Name of the property resource to loadtypename/classname pairs from</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>the classpath touse when looking up classname</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="loaderref" REQUIRED="no">
+			<DESCRIPTION>the name of the loader that isused to load the class, constructed from the specified classpath. Use this toallow multiple tasks/types to be loaded with the same loader, so they can calleach other. ( introduced in ant1.5 </DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="unzip">
+		<DESCRIPTION>&lt;p&gt;Unzips a zip-, war-, tar- or jarfile.&lt;/p&gt;
+&lt;p&gt;For JDK 1.1 &amp;quot;last modified time&amp;quot; field is set to current time instead of being
+carried from the archive file.&lt;/p&gt;
+&lt;p&gt;&lt;a href=&quot;../CoreTypes/patternset.html&quot;&gt;PatternSet&lt;/a&gt;s are used to select files to extract
+&lt;I&gt;from&lt;/I&gt; the archive.  If no patternset is used, all files are extracted.
+&lt;/p&gt;
+&lt;p&gt;&lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt;s may be used used to select archived files
+to perform unarchival upon.
+&lt;/p&gt;
+&lt;p&gt;File permissions will not be restored on extracted files.&lt;/p&gt;
+&lt;p&gt;The untar task recognizes the long pathname entries used by GNU tar.&lt;p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="src" REQUIRED="yes, if filesets are not used.">
+			<DESCRIPTION>archive file to expand</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dest" REQUIRED="yes">
+			<DESCRIPTION>directory where to store the expanded files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="overwrite" REQUIRED="no">
+			<DESCRIPTION>Overwrite files, even if they are newer than thecorresponding entries in the archive (true or false, default istrue)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compression" REQUIRED="no">
+			<DESCRIPTION>compression method for untar.  Allowable values are&quot;none&quot;, &quot;gzip&quot; and &quot;bzip2&quot;.  Default is&quot;none&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="uptodate">
+		<DESCRIPTION>&lt;p&gt;Sets a property if a target file or set of target files is more up-to-date
+than a source file or set of source files. A single source file is specified
+using the &lt;code&gt;srcfile&lt;/code&gt; attribute. A set of source files is specified
+using the nested &lt;code&gt;&amp;lt;srcfiles&amp;gt;&lt;/code&gt;
+elements. These are &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt;s,
+whereas multiple target files are specified using a nested
+&lt;a href=&quot;../CoreTypes/mapper.html&quot;&gt;&lt;code&gt;&amp;lt;mapper&amp;gt;&lt;/code&gt;&lt;/a&gt; element.&lt;/p&gt;
+&lt;p&gt;By default, the value of the property is set to &lt;code&gt;true&lt;/code&gt; if
+the timestamp of the target file(s) is more recent than the timestamp of
+the corresponding source file(s). You can set the value to something other
+than the default by specifying the &lt;code&gt;value&lt;/code&gt; attribute.&lt;/p&gt;
+&lt;p&gt;If a &lt;code&gt;&amp;lt;srcfiles&amp;gt;&lt;/code&gt; element is used, without also specifying
+a &lt;code&gt;&amp;lt;mapper&amp;gt;&lt;/code&gt; element, the default behavior is to use a
+&lt;a href=&quot;../CoreTypes/mapper.html#merge-mapper&quot;&gt;merge mapper&lt;/a&gt;, with the
+&lt;code&gt;to&lt;/code&gt; attribute set to the value of the
+&lt;code&gt;targetfile&lt;/code&gt; attribute.&lt;/p&gt;
+&lt;p&gt;Normally, this task is used to set properties that are useful to avoid
+target execution depending on the relative age of the specified files.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="property" REQUIRED="yes">
+			<DESCRIPTION>The name of the property to set</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="value" REQUIRED="no; defaults to true.">
+			<DESCRIPTION>The value to set the property to</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="srcfile" REQUIRED="yes, unless a nested
+       &lt;srcfiles&gt; element is present.">
+			<DESCRIPTION>The file to check against the target file(s)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="targetfile" REQUIRED="yes, unless a nested
+       &lt;mapper&gt; element is present.">
+			<DESCRIPTION>The file for which we want to determine the status</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="waitfor">
+		<DESCRIPTION>&lt;p&gt;Blocks execution until a set of specified conditions become true. This is intended
+to be used with the &lt;a href=&quot;parallel.html&quot;&gt;parallel&lt;/a&gt; task to
+synchronize a set of processes.&lt;/p&gt;
+&lt;p&gt;The conditions to wait for are defined in &lt;a href=&quot;waitfor.html#nested&quot;&gt;nested elements&lt;/a&gt;,
+if multiple conditions are specified, then the task will wait until all conditions are true..&lt;/p&gt;
+&lt;p&gt;&lt;/p&gt;
+&lt;p&gt;If both maxwait and maxwaitunit are not specified, the maxwait is 3 minutes (180000 milliseconds).&lt;/p&gt;
+&lt;p&gt;If the &lt;code&gt;timeoutproperty&lt;/code&gt; attribute has been set, a
+property of that name will be created if the condition didn't come
+true within the specified time.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="maxwait" REQUIRED="no">
+			<DESCRIPTION>The maximum amount of time to wait for all the required conditionsto become true before failing the task. Defaults to 180000 maxwaitunits</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="maxwaitunit" REQUIRED="no">
+			<DESCRIPTION>The unit of time that must be used to interpret the value of themaxwait attribute.  Defaults to millisecond.Valid Values aremillisecondsecondminutehourdayweek</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="checkevery" REQUIRED="no">
+			<DESCRIPTION>The amount of time to wait between each test of the conditions.Defaults to 500 checkeveryunits</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="checkeveryunit" REQUIRED="no">
+			<DESCRIPTION>The unit of time that must be used to interpret the value of thecheckevery attribute.  Defaults to millisecond.Valid Values aremillisecondsecondminutehourdayweek</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="timeoutproperty" REQUIRED="no">
+			<DESCRIPTION>the name of the property to set if maxwait hasbeen exceeded</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="war">
+		<DESCRIPTION>&lt;p&gt;An extension of the &lt;a href=&quot;jar.html&quot;&gt;Jar&lt;/a&gt; task with special
+treatment for files that should end up in the
+&lt;code&gt;WEB-INF/lib&lt;/code&gt;, &lt;code&gt;WEB-INF/classes&lt;/code&gt; or
+&lt;code&gt;WEB-INF&lt;/code&gt; directories of the Web Application Archive.&lt;/p&gt;
+&lt;p&gt;(The War task is a shortcut for specifying the particular layout of a WAR file. 
+The same thing can be accomplished by using the &lt;i&gt;prefix&lt;/i&gt; and &lt;i&gt;fullpath&lt;/i&gt;
+attributes of zipfilesets in a Zip or Jar task.)&lt;/p&gt;
+&lt;p&gt;The extended zipfileset element from the zip task (with attributes &lt;i&gt;prefix&lt;/i&gt;, &lt;i&gt;fullpath&lt;/i&gt;, and &lt;i&gt;src&lt;/i&gt;) is available in the War task.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="destfile" REQUIRED="yes">
+			<DESCRIPTION>the WAR file to create</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="warfile" REQUIRED="no">
+			<DESCRIPTION>Deprecated name of the file to create-use destfile instead</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="webxml" REQUIRED="yes, unless update is set to true">
+			<DESCRIPTION>The deployment descriptor to use (WEB-INF/web.xml)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="basedir" REQUIRED="no">
+			<DESCRIPTION>the directory from which to jar the files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compress" REQUIRED="no">
+			<DESCRIPTION>Not only store data but also compress them, defaults to tru</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>The character encoding to use for filenamesinside the archive.  Defaults to UTF8. It is notrecommended to change this value as the created archive will mostlikely be unreadable for Java otherwise</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filesonly" REQUIRED="no">
+			<DESCRIPTION>Store only file entries, defaults to fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="manifest" REQUIRED="no">
+			<DESCRIPTION>the manifest file to use</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="update" REQUIRED="no">
+			<DESCRIPTION>indicates whether to update or overwritethe destination file if it already exists</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="duplicate" REQUIRED="no">
+			<DESCRIPTION>behavior when a duplicate file is found.  Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;.  The default value is &quot;add&quot;. </DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="xmlproperty">
+		<DESCRIPTION>&lt;p&gt;
+Loads property values from a valid xml file.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="yes">
+			<DESCRIPTION>The XML file to parse</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="prefix" REQUIRED="no">
+			<DESCRIPTION>The prefix to prepend to each propert</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="keeproot" REQUIRED="no, default is true.">
+			<DESCRIPTION>If false, it doesn't include the xml root tag as a firstvalue in the property name</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="validate" REQUIRED="no, default is false.">
+			<DESCRIPTION>If true, it enables validation</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="collapseattributes" REQUIRED="no, default is false.">
+			<DESCRIPTION>If true, it treats attributes as nested elements</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="xslt">
+		<DESCRIPTION>&lt;p&gt;Process a set of documents via XSLT.&lt;/p&gt;
+&lt;p&gt;This is useful for building views of XML based documentation,
+or for generating code.&lt;/p&gt;
+&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This task depends on external libraries not included in the Ant distribution.
+See &lt;a href=&quot;../install.html#librarydependencies&quot;&gt;Library Dependencies&lt;/a&gt; for more information.&lt;/p&gt;
+&lt;p&gt;It is possible to refine the set of files that are being processed. This can be
+done with the &lt;i&gt;includes&lt;/i&gt;, &lt;i&gt;includesfile&lt;/i&gt;, &lt;i&gt;excludes&lt;/i&gt;, &lt;i&gt;excludesfile&lt;/i&gt; and &lt;i&gt;defaultexcludes&lt;/i&gt;
+attributes. With the &lt;i&gt;includes&lt;/i&gt; or &lt;i&gt;includesfile&lt;/i&gt; attribute you specify the files you want to
+have included by using patterns. The &lt;i&gt;exclude&lt;/i&gt; or &lt;i&gt;excludesfile&lt;/i&gt; attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the &lt;i&gt;defaultexcludes&lt;/i&gt; attribute, you can specify whether you
+want to use default exclusions or not. See the section on &lt;a
+href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based tasks&lt;/a&gt;, on how the
+inclusion/exclusion of files works, and how to write patterns.&lt;/p&gt;
+&lt;p&gt;This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and supports all
+attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt; (&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;basedir&lt;/code&gt;)
+as well as the nested &lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt;
+and &lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+&lt;p&gt;This task supports the use of a nested &amp;lt;param&amp;gt; element which is used to pass values
+to an &amp;lt;xsl:param&amp;gt; declaration.&lt;/p&gt;
+&lt;p&gt;This task supports the use of a nested &lt;a href=&quot;../CoreTypes/xmlcatalog.html&quot;&gt;xmlcatalog&lt;/a&gt;
+element which is used to perform Entity and URI resolution&lt;/p&gt;
+&lt;p&gt;&lt;i&gt;&amp;lt;style&amp;gt; and &amp;lt;xslt&amp;gt; refer to the same Ant task and can be used interchangeably.&lt;/i&gt;&lt;/p&gt;
+&lt;p&gt;If you want to use Xalan-J 1 or XSL:P, you also need Ant's optional.jar&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="basedir" REQUIRED="no">
+			<DESCRIPTION>where to find the source XML file, default is theproject's basedir</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destdir" REQUIRED="yes, unless in and out have been
+       specified.">
+			<DESCRIPTION>directory in which to store the results</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="extension" REQUIRED="no">
+			<DESCRIPTION>desired file extension to be used for the targets. If notspecified, the default is &quot;.html&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="style" REQUIRED="yes">
+			<DESCRIPTION>name of the stylesheet to use - given either relativeto the project's basedir or as an absolute pathDEPRECATED - can be specified as a path relativeto the basedir attribute of this task as well.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>the classpath to use when looking up the XSLTprocessor</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>the classpath to use, given as reference to a path defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="force" REQUIRED="no; default is false">
+			<DESCRIPTION>Recreate target files, even if they are newerthan their corresponding source files or the stylesheet</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="processor" REQUIRED="no">
+			<DESCRIPTION>name of the XSLT processor to use.  Permissible values are&quot;trax&quot; for a TraX compliant processor (ie JAXP interfaceimplementation such as Xalan 2 or Saxon),&quot;xslp&quot; for the XSL:P processor, &quot;xalan&quot; forthe Apache XML Xalan (version 1) processor the name of anarbitrary XSLTLiaison class. Defaults to trax, followed by xalanand then xslp (in that order). The first one found in your classpath is the one that is used.DEPRECATED - XSL:P and xalan are deprecated and nomore supported..</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must be included.All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file is taken to bean include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must be excluded.No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file is taken to bean exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="in" REQUIRED="no">
+			<DESCRIPTION>specifies a single XML document to be styled. Should be usedwith the out attribute</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="out" REQUIRED="no">
+			<DESCRIPTION>specifies the output name for the styled result from thein attribute</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="scanincludeddirectories" REQUIRED="no">
+			<DESCRIPTION>If any directories are matched by theincludes/excludes patterns, try to transform all files in thesedirectories.  Default is tru</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="zip">
+		<DESCRIPTION>&lt;p&gt;Creates a zipfile.&lt;/p&gt;
+&lt;p&gt;The &lt;i&gt;basedir&lt;/i&gt; attribute is the reference directory from where to zip.&lt;/p&gt;
+&lt;p&gt;Note that file permissions will not be stored in the resulting zipfile.&lt;/p&gt;
+&lt;p&gt;It is possible to refine the set of files that are being zipped. This can be
+done with the &lt;i&gt;includes&lt;/i&gt;, &lt;i&gt;includesfile&lt;/i&gt;, &lt;i&gt;excludes&lt;/i&gt;, &lt;i&gt;excludesfile&lt;/i&gt; and &lt;i&gt;defaultexcludes&lt;/i&gt;
+attributes. With the &lt;i&gt;includes&lt;/i&gt; or &lt;i&gt;includesfile&lt;/i&gt; attribute you specify the files you want to
+have included by using patterns. The &lt;i&gt;exclude&lt;/i&gt; or &lt;i&gt;excludesfile&lt;/i&gt; attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the &lt;i&gt;defaultexcludes&lt;/i&gt; attribute, you can specify whether you
+want to use default exclusions or not. See the section on &lt;a
+href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based tasks&lt;/a&gt;, on how the
+inclusion/exclusion of files works, and how to write patterns. &lt;/p&gt;
+&lt;p&gt;This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and
+supports all attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;
+(&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;basedir&lt;/code&gt;) as well as the nested
+&lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt; and
+&lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+&lt;p&gt;Or, you may place within it nested file sets, or references to file sets.
+In this case &lt;code&gt;basedir&lt;/code&gt; is optional; the implicit file set is &lt;i&gt;only used&lt;/i&gt;
+if &lt;code&gt;basedir&lt;/code&gt; is set. You may use any mixture of the implicit file set
+(with &lt;code&gt;basedir&lt;/code&gt; set, and optional attributes like &lt;code&gt;includes&lt;/code&gt;
+and optional subelements like &lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;); explicit nested
+&lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt; elements so long as at least one fileset total is specified. The ZIP file will
+only reflect the relative paths of files &lt;i&gt;within&lt;/i&gt; each fileset. The Zip task and its derivatives know a special form of a fileset named zipfileset that has additional attributes (described below). &lt;/p&gt;
+&lt;p&gt;The Zip task also supports the merging of multiple zip files into the zip file. 
+This is possible through either the &lt;i&gt;src&lt;/i&gt; attribute of any nested filesets 
+or by using the special nested fileset &lt;i&gt;zipgroupfileset&lt;/i&gt;.&lt;/p&gt;
+&lt;p&gt;The &lt;code&gt;update&lt;/code&gt; parameter controls what happens if the
+ZIP file already exists. When set to &lt;code&gt;yes&lt;/code&gt;, the ZIP file is
+updated with the files specified. (New files are added; old files are
+replaced with the new versions.) When set to &lt;code&gt;no&lt;/code&gt; (the
+default) the ZIP file is overwritten.&lt;/p&gt;
+&lt;p&gt;The &lt;code&gt;whenempty&lt;/code&gt; parameter controls what happens when no files match.
+If &lt;code&gt;skip&lt;/code&gt; (the default), the ZIP is not created and a warning is issued.
+If &lt;code&gt;fail&lt;/code&gt;, the ZIP is not created and the build is halted with an error.
+If &lt;code&gt;create&lt;/code&gt;, an empty ZIP file (explicitly zero entries) is created,
+which should be recognized as such by compliant ZIP manipulation tools.&lt;/p&gt;
+&lt;p&gt;This task will now use the platform's default character encoding
+for filenames - this is consistent with the command line ZIP tools,
+but causes problems if you try to open them from within Java and your
+filenames contain non US-ASCII characters. Use the encoding attribute
+and set it to UTF8 to create zip files that can safely be read by
+Java.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="destfile" REQUIRED="yes">
+			<DESCRIPTION>the zip-file to create</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="zipfile" REQUIRED="yes">
+			<DESCRIPTION>the deprecated old name of destfile</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="basedir" REQUIRED="no">
+			<DESCRIPTION>the directory from which to zip the files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compress" REQUIRED="no">
+			<DESCRIPTION>Not only store data but also compress them, defaults to tru</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>The character encoding to use for filenamesinside the zip file.  For a list of possible values see http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html.Defaults to the platform's default character encoding</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filesonly" REQUIRED="no">
+			<DESCRIPTION>Store only file entries, defaults to fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="update" REQUIRED="no">
+			<DESCRIPTION>indicates whether to update or overwritethe destination file if it already exists</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="whenempty" REQUIRED="no">
+			<DESCRIPTION>behavior when no files match.  Valid values are &quot;fail&quot;, &quot;skip&quot;, and &quot;create&quot;.  Default is &quot;skip&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="duplicate" REQUIRED="no">
+			<DESCRIPTION>behavior when a duplicate file is found.  Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;. The default value is &quot;add&quot;. </DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="antlr">
+		<DESCRIPTION>&lt;p&gt;
+Invokes the &lt;a HREF=&quot;http://www.antlr.org/&quot; target=&quot;_top&quot;&gt;ANTLR&lt;/a&gt; Translator generator
+on a grammar file.
+&lt;/p&gt;
+&lt;p&gt;
+To use the ANTLR task, set the &lt;i&gt;target&lt;/i&gt; attribute to the name of the
+grammar file to process.  Optionally, you can also set the
+&lt;i&gt;outputdirectory&lt;/i&gt; to write the generated file to a specific directory.
+Otherwise ANTLR writes the generated files to the directory containing
+the grammar file.
+&lt;/p&gt;
+&lt;p&gt;
+This task only invokes ANTLR if the grammar file is newer than the generated
+files.
+&lt;/p&gt;
+&lt;p&gt;
+&lt;i&gt;
+To successfully run ANTLR, your best option is probably to build the whole
+jar with the provided script &lt;b&gt;mkalljar&lt;/b&gt; and drop the resulting jar (about 300KB)
+into ${ant.home}/lib. Dropping the default jar (70KB) is probably not enough
+for most needs and your only option will be to add ANTLR home directory
+to your classpath as described in ANTLR &lt;tt&gt;install.html&lt;/tt&gt; document.
+&lt;/i&gt;
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="target" REQUIRED="yes">
+			<DESCRIPTION>The grammar file to process</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="outputdirectory" REQUIRED="no">
+			<DESCRIPTION>The directory to write the generated files to.  If not set, the filesare written to the directory containing the grammar file.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="glib" REQUIRED="no">
+			<DESCRIPTION>An optional super grammar file that the target grammar overrides.  Thisfeature is only needed for advanced vocabularies.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debug" REQUIRED="no">
+			<DESCRIPTION>When set to &quot;yes&quot;, this flag adds code to the generated parser that willlaunch the ParseView debugger upon invocation.  The default is &quot;no&quot;.Note: ParseView is a separate component that needs to be installed or yourgrammar will have compilation errors.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="html" REQUIRED="no">
+			<DESCRIPTION>Emit an html version of the grammar with hyperlinked actions.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="diagnostic" REQUIRED="no">
+			<DESCRIPTION>Generates a text file with debugging infomation based on the target grammar.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="trace" REQUIRED="no">
+			<DESCRIPTION>Forces all rules to call traceIn/traceOut if set to &quot;yes&quot;.The default is &quot;no&quot;.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="traceparser" REQUIRED="no">
+			<DESCRIPTION>Only forces parser rules to call traceIn/traceOut if set to &quot;yes&quot;.The default is &quot;no&quot;.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tracelexer" REQUIRED="no">
+			<DESCRIPTION>Only forces lexer rules to call traceIn/traceOut if set to &quot;yes&quot;.The default is &quot;no&quot;.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tracetreewalker" REQUIRED="no">
+			<DESCRIPTION>Only forces tree walker rules to call traceIn/traceOut if set to&quot;yes&quot;.  The default is &quot;no&quot;.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="no">
+			<DESCRIPTION>The directory to invoke the VM in.</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="borlandgenerateclient">
+		<DESCRIPTION>&lt;p&gt;The BorlandGenerateClient is a task dedicated to Borland Application Server
+v 4.5. It offers to generate the client jar file corresponding to an ejb jar
+file.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="ejbjar" REQUIRED="yes">
+			<DESCRIPTION>ejb jar fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debug" REQUIRED="no">
+			<DESCRIPTION>If true, turn on the debug mode for each borlandtools (java2iiop, iastool ...) default = fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="clientjar" REQUIRED="no">
+			<DESCRIPTION>client jar file name. If missing the client jarfile name is build using the ejbjar file name: ejbjar = hellobean-ejb.jar=&gt; hellobean-ejbclient.ja</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="mode" REQUIRED="no">
+			<DESCRIPTION>choose the command launching mode. Two values:java or fork. default = fork. java is not supported for version=5.Possibility to specify a classpath</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="version" REQUIRED="no, defaults to 4">
+			<DESCRIPTION>set the Borland Application Version.4 means B.A.S (Borland Application Server 4.x)5 means B.E.S (Borland Application Server 5.x)</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="cab">
+		<DESCRIPTION>&lt;p&gt;The cab task creates Microsoft cab archive files.  It is invoked
+similar to the &lt;a href=&quot;../CoreTasks/jar.html&quot;&gt;jar&lt;/a&gt; or &lt;a href=&quot;../CoreTasks/zip.html&quot;&gt;zip&lt;/a&gt; tasks.
+This task will work on Windows using the external cabarc tool (provided by Microsoft)
+which must be located in your executable path.&lt;/p&gt;
+&lt;p&gt;To use this task on other platforms you need to download and compile libcabinet from
+&lt;a href=&quot;http://trill.cis.fordham.edu/~barbacha/cabinet_library/&quot;&gt;
+http://trill.cis.fordham.edu/~barbacha/cabinet_library/&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;See the section on &lt;a href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based
+tasks&lt;/a&gt;, on how the inclusion/exclusion of files works, and how to
+write patterns.&lt;/p&gt;
+&lt;p&gt;This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and
+supports all attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;
+(&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;basedir&lt;/code&gt;) as well as the nested
+&lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt; and
+&lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="cabfile" REQUIRED="yes">
+			<DESCRIPTION>the name of the cab file to create</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="basedir" REQUIRED="yes">
+			<DESCRIPTION>the directory to start archiving files from</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>set to &quot;yes&quot; if you want to see the output fromthe cabarc tool.  defaults to &quot;no&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compress" REQUIRED="no">
+			<DESCRIPTION>set to &quot;no&quot; to store files without compressing.defaults to &quot;yes&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="options" REQUIRED="no">
+			<DESCRIPTION>use to set additional command-line options forthe cabarc tool.  should not normally be necessary</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files thatmust be included. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files thatmust be excluded. No files (except default excludes) are excludedwhen omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be usedor not (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="depend">
+		<DESCRIPTION>&lt;p&gt;
+The depend task works by determining which classes are out of date with
+respect to their source and then removing the class files of any other
+classes which depend on the out-of-date classes.
+&lt;/p&gt;
+&lt;p&gt; To determine the class dependencies, the depend task analyses the class 
+files of all class files passed to it. Depend does not parse your source code in 
+any way but relies upon the class references encoded into the class files by the 
+compiler. This is generally faster than parsing the Java source.&lt;/p&gt;
+&lt;p&gt;
+To learn more about how this information is obtained from the class files, 
+please refer to &lt;a href=&quot;http://java.sun.com/docs/books/vmspec/&quot;&gt;the Java 
+Virtual Machine Specification&lt;/a&gt;
+&lt;/p&gt;
+&lt;p&gt; Since a class' dependencies only change when the class itself changes, the 
+depend task is able to cache dependency information. Only those class files 
+which have changed will have their dependency information re-analysed. Note that 
+if you change a class' dependencies by changing the source, it will be 
+recompiled anyway. You can examine the dependency files created to understand 
+the  dependencies of your classes. Please do not rely, however, on the format of 
+the information, as it may change in a later release. &lt;/p&gt;
+&lt;p&gt; Once depend discovers all of the class dependencies, it &amp;quot;inverts&amp;quot; 
+this relation to determine, for each class, which other classes are dependent 
+upon it. This &amp;quot;affects&amp;quot; list is used to discover which classes are 
+invalidated by the out of date class. The class files of the invalidated 
+classes are removed, triggering the compilation of the affected classes. &lt;/p&gt;
+&lt;p&gt; The depend task supports an attribute, &amp;quot;closure&amp;quot; which controls 
+whether depend will only consider direct class-class relationships or whether it 
+will also consider transitive, indirect relationships. For example, say there 
+are three classes, A, which depends on B, which in-turn depend on C. Now say 
+that class C is out of date. Without closure, only class B would be removed by 
+depend. With closure set, class A would also be removed. Normally direct 
+relationships are sufficient - it is unusual for a class to depend on another 
+without having a direct relationship. With closure set, you will notice that 
+depend typically removes far more class files. &lt;/p&gt;
+&lt;p&gt;The classpath attribute for &lt;code&gt;&amp;lt;depend&amp;gt;&lt;/code&gt; is optional. If it is present, 
+depend will check class dependencies against classes and jars on this classpath.
+Any classes which depend on an element from this classpath and which are older 
+than that element will be deleted. A typical example where you would use this 
+facility would be where you are building a utility jar and want to make sure 
+classes which are out of date with respect to this jar are rebuilt. You should
+&lt;b&gt;not&lt;/b&gt; include jars in this classpath which you do not expect to change, 
+such as the JDK runtime jar or third party jars, since doing so will just slow 
+down the dependency check. This means that if you do use a classpath for the 
+depend task it may be different from the classpath necessary to actually 
+compile your code.&lt;/p&gt;
+&lt;h3&gt;Performance&lt;/h3&gt; 
+&lt;p&gt; The performance of the depend task is dependent on a 
+number of factors such as class relationship complexity and how many class files 
+are out of date. The decision about whether it is cheaper to just recompile all 
+classes or to use the depend task will depend on the size of your project and 
+how interrelated your classes are. &lt;/p&gt;
+&lt;h3&gt;Limitations&lt;/h3&gt;
+&lt;p&gt; There are some source dependencies which depend will not detect. &lt;/p&gt;
+&lt;ul&gt;
+&lt;li&gt;If the Java compiler optimizes away a class relationship, 
+there can be a source dependency without a class dependency. &lt;/li&gt;
+&lt;li&gt;Non public classes cause two problems. Firstly depend cannot relate
+the class file to a source file. In the future this may be addressed
+using the source file attribute in the classfile. Secondly, neither 
+depend nor the compiler tasks can detect when a non public class is
+missing. Inner classes are handled by the depend task.&lt;/li&gt;
+&lt;/ul&gt;
+The most obvious example of these limitations is that the task can't tell
+which classes to recompile when a constant primitive data type exported 
+by other classes is changed. For example, a change in the definition of
+something like
+&lt;pre&gt;
+public final class Constants {
+public final static boolean DEBUG=false;
+}
+&lt;/pre&gt; will not be picked up by other classes.
+</DESCRIPTION>
+		<ATTRIBUTE NAME="srcdir" REQUIRED="yes">
+			<DESCRIPTION>This is the directory where the source exists. dependwill examine this to determine which classes are out of date. If you use multiplesource directories you can pass this attribute a path of source directories</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destdir" REQUIRED="no">
+			<DESCRIPTION>This is the root directory of the class files whichwill be analysed. If this is not present, the srcdir is used</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="cache" REQUIRED="no">
+			<DESCRIPTION>This is a directory in which depend can store andretrieve dependency information. If this is not present, depend will notuse a cache</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="closure" REQUIRED="no">
+			<DESCRIPTION>This attribute controls whether depend only removesclasses which directly depend on out of date classes. If this is set to true,depend will traverse the class dependency graph deleting all affectedclasses. Defaults to fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dump" REQUIRED="no">
+			<DESCRIPTION>If true the dependency information will be written to the debug level log</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>The classpath containg jars and classes for which &lt;depend&gt; should alsocheck dependencie</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="echoproperties">
+		<DESCRIPTION>&lt;p&gt;Displays all the current properties in the project.  The output can be
+sent to a file if desired. You can also specify a subset of properties
+to save by naming a prefix: only properties starting with this
+prefix will be saved. This task can be used as a somewhat contrived
+means of returning data from an &lt;tt&gt;&amp;lt;ant&amp;gt;&lt;/tt&gt; invocation,
+but is really for debugging buildfiles.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="destfile" REQUIRED="no">
+			<DESCRIPTION>If specified, the value indicates the name of thefile to send the output of the statement to.  The generated output fileis compatible for loading by any Java application as a property file.If not specified, then the output will go to the Ant log</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="prefix" REQUIRED="no">
+			<DESCRIPTION>a prefix which is used to filter the propertiesonly those properties starting with this prefix will be echoed.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>By default, the &quot;failonerror&quot; attribute is enabled.If an error occurs while writing the properties to a file, and thisattribute is enabled, then a BuildException will be thrown, causing thebuild to fail.  If disabled, then IO errors will be reported as a logstatement, and the build will continue without failure from this task</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="ftp">
+		<DESCRIPTION>&lt;p&gt;The ftp task implements a basic FTP client that can send, receive,
+list, delete files, and create directories.  See below for descriptions and examples of how
+to perform each task.&lt;/p&gt;
+&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This task depends on external libraries not included in the Ant distribution.
+See &lt;a href=&quot;../install.html#librarydependencies&quot;&gt;Library Dependencies&lt;/a&gt; for more information.&lt;/p&gt;
+&lt;p&gt;The ftp task makes no attempt to determine what file system syntax is
+required by the remote server, and defaults to Unix standards.
+&lt;i&gt;remotedir&lt;/i&gt; must be specified in the exact syntax required by the ftp
+server. If the usual Unix conventions are not supported by the server,
+&lt;i&gt;separator&lt;/i&gt; can be used to set the file separator that should be used
+instead.&lt;/p&gt;
+&lt;p&gt;See the section on &lt;a href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based
+tasks&lt;/a&gt;, on how the inclusion/exclusion of files works, and how to
+write patterns.&lt;/p&gt;
+&lt;p&gt;
+&lt;b&gt;Warning: &lt;/b&gt; for the get and delete actions to work properly 
+with a Windows 2000 ftp server, it needs to be configured to generate
+Unix style listings, and not the default MS-DOS listing. Or someone needs to write
+the code to parse MS-DOS listings -any takers?
+</DESCRIPTION>
+		<ATTRIBUTE NAME="server" REQUIRED="yes">
+			<DESCRIPTION>the address of the remote ftp server</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="port" REQUIRED="no">
+			<DESCRIPTION>the port number of the remote ftp server.Defaults to port 21</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="userid" REQUIRED="yes">
+			<DESCRIPTION>the login id to use on the ftp server</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="password" REQUIRED="yes">
+			<DESCRIPTION>the login password to use on the ftp server</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="remotedir" REQUIRED="no">
+			<DESCRIPTION>the directory to which to upload files on the ftp server</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="action" REQUIRED="no">
+			<DESCRIPTION>the ftp action to perform, defaulting to &quot;send&quot;.  Currently supports &quot;put&quot;, &quot;get&quot;,&quot;del&quot;, &quot;list&quot;, &quot;chmod&quot; and &quot;mkdir&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="binary" REQUIRED="no">
+			<DESCRIPTION>selects binary-mode (&quot;yes&quot;) or text-mode (&quot;no&quot;) transfers.  Defaults to &quot;yes</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="passive" REQUIRED="no">
+			<DESCRIPTION>selects passive-mode (&quot;yes&quot;) transfers.  Defaults to &quot;no</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>displays information on each file transferred if set to &quot;yes&quot;. Defaults to &quot;no&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="depends" REQUIRED="no">
+			<DESCRIPTION>transfers only new or changed files if set to &quot;yes&quot;. Defaults to &quot;no&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="newer" REQUIRED="no">
+			<DESCRIPTION>a synonym for depends</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="separator" REQUIRED="no">
+			<DESCRIPTION>sets the file separator used on the ftp server.Defaults to &quot;/&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="umask" REQUIRED="no">
+			<DESCRIPTION>sets the default file permissions for new files,unix only</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="chmod" REQUIRED="no">
+			<DESCRIPTION>sets or changes file permissions for new or existing files,unix only. If used with a put action, chmod will be issued for each file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="listing" REQUIRED="no">
+			<DESCRIPTION>the file to write results of the &quot;list&quot; action.Required for the &quot;list&quot; action, ignored otherwise</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="ignorenoncriticalerrors" REQUIRED="no">
+			<DESCRIPTION>flag which permits the task to ignore some non-fatal errorcodes sent by some servers during directory creation: wu-ftp in particular.Default: fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="skipfailedtransfers" REQUIRED="no">
+			<DESCRIPTION>flag which enables unsuccessful file put, deleteand get operations to be skipped with a warning and theremainder of the files still transferred. Default: fals</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="icontract">
+		<DESCRIPTION>&lt;P&gt;
+Instruments Java classes with &lt;a href=&quot;http://www.reliable-systems.com/tools/&quot;&gt;iContract&lt;/a&gt;
+DBC preprocessor.&lt;br&gt;
+The task can generate a properties file for &lt;a href=&quot;http://home.sol.no/~hellesoy/icplus.html&quot;&gt;iControl&lt;/a&gt;,
+a graphical user interface that lets you turn on/off assertions. iControl generates a control file that you can refer to
+from this task using the controlfile attribute.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="srcdir" REQUIRED="yes">
+			<DESCRIPTION>Location of the java files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="instrumentdir" REQUIRED="yes">
+			<DESCRIPTION>Indicates where the instrumented source files should go</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="repositorydir" REQUIRED="yes">
+			<DESCRIPTION>Indicates where the repository source files should go</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="builddir" REQUIRED="no">
+			<DESCRIPTION>Indicates where the compiled instrumented classes should go.Defaults to the value of instrumentdir.NOTE: Don't use the same directory for compiled instrumented classesand uninstrumented classes. It will break the dependency checking. (Classes willnot be reinstrumented if you change them)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="repositorybuilddir" REQUIRED="no">
+			<DESCRIPTION>Indicates where the compiled repository classes should go.Defaults to the value of repositorydir</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="pre" REQUIRED="no">
+			<DESCRIPTION>Indicates whether or not to instrument for preconditions.Defaults to true unless controlfile is specified, in which case itdefaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="post" REQUIRED="no">
+			<DESCRIPTION>Indicates whether or not to instrument for postconditions.Defaults to true unless controlfile is specified, in which case itdefaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="invariant" REQUIRED="no">
+			<DESCRIPTION>Indicates whether or not to instrument for invariants.Defaults to true unless controlfile is specified, in which case itdefaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failthrowable" REQUIRED="no">
+			<DESCRIPTION>The full name of the Throwable (Exception) that should bethrown when an assertion is violated. Defaults to java.lang.Erro</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbosity" REQUIRED="no">
+			<DESCRIPTION>Indicates the verbosity level of iContract. Any combinationof error*,warning*,note*,info*,progress*,debug* (comma separated) can beused. Defaults to error</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="quiet" REQUIRED="no">
+			<DESCRIPTION>Indicates if iContract should be quiet. Turn it off if many your classes extend uninstrumented classesand you don't want warnings about this. Defaults to fals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="updateicontrol" REQUIRED="no">
+			<DESCRIPTION>If set to true, it indicates that the properties file foriControl in the current directory should be updated (or created if it doesn't exist).Defaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="controlfile" REQUIRED="only if updateicontrol=true">
+			<DESCRIPTION>The name of the control file to pass to iContract. Consider using iControl to generate the file.Default is not to pass a file.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classdir" REQUIRED="only if updateicontrol=true">
+			<DESCRIPTION>Indicates where compiled (unistrumented) classes are located.This is required in order to properly update the icontrol.properties file, notfor instrumentation</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="targets" REQUIRED="no">
+			<DESCRIPTION>Name of the file that will be generated by this task, which lists all theclasses that iContract will instrument. If specified, the file will not be deleted after execution.If not specified, a file will still be created, but it will be deleted after execution</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="jarlib-available">
+		<DESCRIPTION>&lt;p&gt;Check whether an extension is present in a fileset or an extensionSet.
+If the extension is present then a property is set.&lt;/p&gt;
+&lt;p&gt;Note that this task
+works with extensions as defined by the &quot;Optional Package&quot; specification.
+For more information about optional packages, see the document
+&lt;em&gt;Optional Package Versioning&lt;/em&gt; in the documentation bundle for your
+Java2 Standard Edition package, in file
+&lt;code&gt;guide/extensions/versioning.html&lt;/code&gt; or online at
+&lt;a href=&quot;http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html&quot;&gt;
+http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;See the Extension and ExtensionSet documentation for further details&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="property" REQUIRED="yes">
+			<DESCRIPTION>The name of property to set if extensions is available</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="file" REQUIRED="no, one of file, nested
+     extensionset or nested fileset must be present.">
+			<DESCRIPTION>The file to check for extensio</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="jarlib-display">
+		<DESCRIPTION>&lt;p&gt;Display the &quot;Optional Package&quot; and &quot;Package Specification&quot; information
+contained within the specified jars.&lt;/p&gt;
+&lt;p&gt;Note that this task
+works with extensions as defined by the &quot;Optional Package&quot; specification.
+For more information about optional packages, see the document
+&lt;em&gt;Optional Package Versioning&lt;/em&gt; in the documentation bundle for your
+Java2 Standard Edition package, in file
+&lt;code&gt;guide/extensions/versioning.html&lt;/code&gt; or online at
+&lt;a href=&quot;http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html&quot;&gt;
+http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;See the Extension and ExtensionSet documentation for further details&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="no, but one of file or fileset must be
+     present.">
+			<DESCRIPTION>The file to display extension information about</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="jarlib-manifest">
+		<DESCRIPTION>&lt;p&gt;Task to generate a manifest that declares all the dependencies
+in manifest. The dependencies are determined by looking in the
+specified path and searching for Extension / &quot;Optional Package&quot;
+specifications in the manifests of the jars.&lt;/p&gt;
+&lt;p&gt;Note that this task
+works with extensions as defined by the &quot;Optional Package&quot; specification.
+For more information about optional packages, see the document
+&lt;em&gt;Optional Package Versioning&lt;/em&gt; in the documentation bundle for your
+Java2 Standard Edition package, in file
+&lt;code&gt;guide/extensions/versioning.html&lt;/code&gt; or online at
+&lt;a href=&quot;http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html&quot;&gt;
+http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;See the Extension and ExtensionSet documentation for further details&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="destfile" REQUIRED="yes.">
+			<DESCRIPTION>The file to generate Manifest int</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="jarlib-resolve">
+		<DESCRIPTION>&lt;p&gt;Try to locate a jar to satisfy an extension and place
+location of jar into property. The task allows you to
+add a number of resolvers that are capable of locating a
+library for a specifc extension. Each resolver will be attempted
+in specified order until library is found or no resolvers are left.
+If no resolvers are left and failOnError is true then a BuildException
+will be thrown.&lt;/p&gt;
+&lt;p&gt;Note that this task
+works with extensions as defined by the &quot;Optional Package&quot; specification.
+For more information about optional packages, see the document
+&lt;em&gt;Optional Package Versioning&lt;/em&gt; in the documentation bundle for your
+Java2 Standard Edition package, in file
+&lt;code&gt;guide/extensions/versioning.html&lt;/code&gt; or online at
+&lt;a href=&quot;http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html&quot;&gt;
+http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;See the Extension and ExtensionSet documentation for further details&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="property" REQUIRED="yes">
+			<DESCRIPTION>The name of property to set to library location</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no, defaults to true.">
+			<DESCRIPTION>True if failure to locate library should result in build exception</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="checkextension" REQUIRED="no, defaults to true.">
+			<DESCRIPTION>True if librarys returned by nested resolvers should be checked to see ifthey supply extension</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="javacc">
+		<DESCRIPTION>&lt;p&gt;
+Invokes the &lt;a HREF=&quot;http://www.webgain.com/products/java_cc/&quot; target=&quot;_top&quot;&gt;JavaCC&lt;/a&gt; compiler 
+compiler on a grammar file.
+&lt;/p&gt;
+&lt;p&gt;
+To use the javacc task, set the &lt;i&gt;target&lt;/i&gt; attribute to the name of the 
+grammar file to process.  You also need to specify the directory containing 
+the JavaCC installation using the &lt;i&gt;javacchome&lt;/i&gt; attribute, so that ant 
+can find the JavaCC classes.  Optionally, you can also set the 
+&lt;i&gt;outputdirectory&lt;/i&gt; to write the generated file to a specific directory.
+Otherwise javacc writes the generated files to the directory containing
+the grammar file.
+&lt;/p&gt;
+&lt;p&gt;
+This task only invokes JavaCC if the grammar file is newer than the generated 
+Java files.  javacc assumes that the Java class name of the generated parser
+is the same as the name of the grammar file, ignoring the .jj.
+If this is not the case, the javacc task will still work, but it will always 
+generate the output files.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="target" REQUIRED="yes">
+			<DESCRIPTION>The grammar file to process</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="javacchome" REQUIRED="yes">
+			<DESCRIPTION>The directory containing the JavaCC distribution</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="outputdirectory" REQUIRED="no">
+			<DESCRIPTION>The directory to write the generated files to.  If not set, the filesare written to the directory containing the grammar file.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="buildparser" REQUIRED="no">
+			<DESCRIPTION>Sets the BUILD_PARSER grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="buildtokenmanager" REQUIRED="no">
+			<DESCRIPTION>Sets the BUILD_TOKEN_MANAGER grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="cachetokens" REQUIRED="no">
+			<DESCRIPTION>Sets the CACHE_TOKENS grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="choiceambiguitycheck" REQUIRED="no">
+			<DESCRIPTION>Sets the CHOICE_AMBIGUITY_CHECK grammar option.  This is an integer option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="commontokenaction" REQUIRED="no">
+			<DESCRIPTION>Sets the COMMON_TOKEN_ACTION grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debuglookahead" REQUIRED="no">
+			<DESCRIPTION>Sets the DEBUG_LOOKAHEAD grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debugparser" REQUIRED="no">
+			<DESCRIPTION>Sets the DEBUG_PARSER grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debugtokenmanager" REQUIRED="no">
+			<DESCRIPTION>Sets the DEBUG_TOKEN_MANAGER grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="errorreporting" REQUIRED="no">
+			<DESCRIPTION>Sets the ERROR_REPORTING grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="forcelacheck" REQUIRED="no">
+			<DESCRIPTION>Sets the FORCE_LA_CHECK grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="ignorecase" REQUIRED="no">
+			<DESCRIPTION>Sets the IGNORE_CASE grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="javaunicodeescape" REQUIRED="no">
+			<DESCRIPTION>Sets the JAVA_UNICODE_ESCAPE grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="lookahead" REQUIRED="no">
+			<DESCRIPTION>Sets the LOOKAHEAD grammar option.  This is an integer option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="optimizetokenmanager" REQUIRED="no">
+			<DESCRIPTION>Sets the OPTIMIZE_TOKEN_MANAGER grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="otherambiguitycheck" REQUIRED="no">
+			<DESCRIPTION>Sets the OTHER_AMBIGUITY_CHECK grammar option.  This is an integer option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sanitycheck" REQUIRED="no">
+			<DESCRIPTION>Sets the SANITY_CHECK grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="static" REQUIRED="no">
+			<DESCRIPTION>Sets the STATIC grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="unicodeinput" REQUIRED="no">
+			<DESCRIPTION>Sets the UNICODE_INPUT grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="usercharstream" REQUIRED="no">
+			<DESCRIPTION>Sets the USER_CHAR_STREAM grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="usertokenmanager" REQUIRED="no">
+			<DESCRIPTION>Sets the USER_TOKEN_MANAGER grammar option.  This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="javah">
+		<DESCRIPTION>&lt;p&gt;Generates JNI headers from a Java class.&lt;/p&gt;
+&lt;p&gt; When this task executes, it will generate the C header and source files that
+are needed to implement native methods. JNI operates differently depending on
+whether &lt;a href=&quot;http://java.sun.com/j2se/1.3/docs/tooldocs/win32/javah.html&quot;&gt;JDK1.2&lt;/a&gt;
+(or later) or &lt;a href=&quot;http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/javah.html&quot;&gt;pre-JDK1.2&lt;/a&gt;
+systems are used.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="class" REQUIRED="yes">
+			<DESCRIPTION>the fully-qualified name of the class (or classes,separated by commas</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="outputfile" REQUIRED="yes">
+			<DESCRIPTION>concatenates the resulting header or source files for all the classes listed into this fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destdir" REQUIRED="">
+			<DESCRIPTION>sets the directory where javah saves the header files or thestub files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="force" REQUIRED="no">
+			<DESCRIPTION>specifies that output files should always be written (JDK1.2 only</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="old" REQUIRED="no">
+			<DESCRIPTION>specifies that old JDK1.0-style header files should be generated(otherwise output file contain JNI-style native method      function prototypes) (JDK1.2 only</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="stubs" REQUIRED="no">
+			<DESCRIPTION>generate C declarations from the Java object file (used with old</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>causes Javah to print a message concerning the status     of the generated file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>the classpath to use</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bootclasspath" REQUIRED="no">
+			<DESCRIPTION>location of bootstrap class files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="extdirs" REQUIRED="no">
+			<DESCRIPTION>location of installed extensions</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="jdepend">
+		<DESCRIPTION>&lt;P&gt;Invokes the &lt;a href=&quot;http://www.clarkware.com/software/JDepend.html&quot;&gt;JDepend&lt;/a&gt; parser.&lt;/P&gt;
+&lt;P&gt;This parser &amp;quot;traverses a set of Java source file directories and generates design quality metrics for each Java package&amp;quot;.
+It allows to &amp;quot;automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to
+effectively manage and control package dependencies.&amp;quot;&lt;/P&gt;
+&lt;p&gt;Source file directories are defined by nested &lt;code&gt;&amp;lt;sourcespath&amp;gt;&lt;/code&gt;, see &lt;a href=&quot;#nested&quot;&gt;nested elements&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;Optionally, you can also set the &lt;code&gt;outputfile&lt;/code&gt; name where the output is stored. By default the task writes its report to the standard output.&lt;/P&gt;
+&lt;p&gt; The task requires at least the JDepend 1.2 version. &lt;/p&gt;
+&lt;P&gt;Note: whereas the JDepend tool can be customized to exclude some packages, the current jdepend And Task does not have parameters to allow these exclusions. Read JDepend specific documentation for that purpose.&lt;/P&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="outputfile" REQUIRED="no">
+			<DESCRIPTION>The output file name. If not set, the output is printed on the standard output</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="format" REQUIRED="no">
+			<DESCRIPTION>The format to write the output in. The default is &quot;text&quot;, the alternative is &quot;xml</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="fork" REQUIRED="no, default is &quot;off&quot;">
+			<DESCRIPTION>Run the tests in a separate VM</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="haltonerror" REQUIRED="no, default is &quot;off&quot;">
+			<DESCRIPTION>Stop the build process if an error occurs during the jdepend analysis</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="timeout" REQUIRED="no">
+			<DESCRIPTION>Cancel the operation if it doesn't finish in the given time (measured in milliseconds). (Ignored if fork is disabled.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="jvm" REQUIRED="no, default &quot;java&quot;">
+			<DESCRIPTION>The command used to invoke the Java Virtual Machine, default is 'java'. The command is resolved by java.lang.Runtime.exec(). (Ignored if fork is disabled.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="no">
+			<DESCRIPTION>The directory to invoke the VM in. (Ignored if fork is disabled</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>the classpath to use, given as reference to a PATH defined elsewhere</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="jjtree">
+		<DESCRIPTION>Invokes the &lt;a href=&quot;http://www.webgain.com/products/java_cc/&quot;&gt;JJTree&lt;/a&gt; preprocessor
+for the JavaCC compiler compiler. It inserts parse tree building actions
+at various places in the JavaCC source that it generates. The output of
+JJTree is run through JavaCC to create the parser.
+&lt;p&gt;To use the jjtree task, set the &lt;i&gt;target&lt;/i&gt; attribute to the name
+of the jjtree grammar file to process. You also need to specify the directory
+containing the JavaCC installation using the &lt;i&gt;javacchome&lt;/i&gt; attribute,
+so that ant can find the JavaCC classes. Optionally, you can also set the
+&lt;i&gt;outputdirectory&lt;/i&gt;
+to write the generated file to a specific directory. Otherwise jjtree writes
+the generated JavaCC grammar file to the directory containing the JJTree
+grammar file.&lt;/p&gt;
+&lt;p&gt;This task only invokes JJTree if the grammar file is newer than the
+generated JavaCC file.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="target" REQUIRED="yes">
+			<DESCRIPTION>The jjtree grammar file to process</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="javacchome" REQUIRED="yes">
+			<DESCRIPTION>The directory containing the JavaCC distribution</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="outputdirectory" REQUIRED="no">
+			<DESCRIPTION>The directory to write the generated file to. If not set,the files are written to the directory containing the grammar file.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="buildnodefiles" REQUIRED="no">
+			<DESCRIPTION>Sets the BUILD_NODE_FILES grammar option. This is a booleanoption</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="multi" REQUIRED="no">
+			<DESCRIPTION>Sets the MULTI grammar option. This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nodedefaultvoid" REQUIRED="no">
+			<DESCRIPTION>Sets the NODE_DEFAULT_VOID grammar option. This is a booleanoption</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nodefactory" REQUIRED="no">
+			<DESCRIPTION>Sets the NODE_FACTORY grammar option. This is boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nodescopehook" REQUIRED="no">
+			<DESCRIPTION>Sets the NODE_SCOPE_HOOK grammar option. This is a booleanoption</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nodeusesparser" REQUIRED="no">
+			<DESCRIPTION>Sets the NODE_USES_PARSER grammar option. This is a booleanoption</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="static" REQUIRED="no">
+			<DESCRIPTION>Sets the STATIC grammar option. This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="visitor" REQUIRED="no">
+			<DESCRIPTION>Sets the VISITOR grammar option. This is a boolean option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nodepackage" REQUIRED="no">
+			<DESCRIPTION>Sets the NODE_PACKAGE grammar option. This is a string option</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="visitorexception" REQUIRED="no">
+			<DESCRIPTION>Sets the VISITOR_EXCEPTION grammar option. This is a stringoption</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="nodeprefix" REQUIRED="no">
+			<DESCRIPTION>Sets the NODE_PREFIX grammar option. This is a string option</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="jlink">
+		<DESCRIPTION>&lt;p&gt;Links entries from sub-builds and libraries.&lt;/p&gt;
+&lt;p&gt;The jlink task can be used to build jar and zip files, similar to 
+the &lt;i&gt;jar&lt;/i&gt; task.
+However, jlink provides options for controlling the way entries from 
+input files
+are added to the output file. Specifically, capabilities for merging 
+entries from
+multiple zip or jar files is available.&lt;/p&gt;
+&lt;p&gt;If a mergefile is specified directly (eg. at the top level of a 
+&lt;i&gt;mergefiles&lt;/i&gt;
+pathelement) &lt;i&gt;and&lt;/i&gt; the mergefile ends in &amp;quot;.zip&amp;quot; or 
+&amp;quot;.jar&amp;quot;,
+entries in the mergefile will be merged into the outfile. A file with 
+any other extension
+will be added to the output file, even if it is specified in the 
+mergefiles element.
+Directories specified in either the mergefiles or addfiles element 
+are added to the
+output file as you would expect: all files in subdirectories are 
+recursively added to
+the output file with appropriate prefixes in the output file 
+(without merging).
+&lt;/p&gt;
+&lt;p&gt;
+In the case where duplicate entries and/or files are found among the 
+files to be merged or
+added, jlink merges or adds the first entry and ignores all subsequent entries.
+&lt;/p&gt;
+&lt;p&gt;
+jlink ignores META-INF directories in mergefiles. Users should supply their
+own manifest information for the output file.
+&lt;/p&gt;
+&lt;p&gt;It is possible to refine the set of files that are being jlinked. 
+This can be
+done with the &lt;i&gt;includes&lt;/i&gt;, &lt;i&gt;includesfile&lt;/i&gt;, &lt;i&gt;excludes&lt;/i&gt;, 
+&lt;i&gt;excludesfile&lt;/i&gt;,
+and &lt;i&gt;defaultexcludes&lt;/i&gt; attributes on the &lt;i&gt;addfiles&lt;/i&gt; and 
+&lt;i&gt;mergefiles&lt;/i&gt;
+nested elements. With the &lt;i&gt;includes&lt;/i&gt; or &lt;i&gt;includesfile&lt;/i&gt;
+attribute you specify the files you want to have included by using patterns.
+The &lt;i&gt;exclude&lt;/i&gt; or &lt;i&gt;excludesfile&lt;/i&gt; attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the &lt;i&gt;defaultexcludes&lt;/i&gt; attribute, you can specify whether you
+want to use default exclusions or not. See the section on &lt;a
+href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based tasks&lt;/a&gt;, on how the
+inclusion/exclusion of files works, and how to write patterns. The patterns are
+relative to the &lt;i&gt;base&lt;/i&gt; directory.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="outfile" REQUIRED="yes">
+			<DESCRIPTION>the path of the output file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compress" REQUIRED="no">
+			<DESCRIPTION>whether or not the output should be compressed. true,yes, or on result in compressed output.If omitted, output will be uncompressed (inflated)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="mergefiles" REQUIRED="at least one of 
+ mergefiles or addfiles">
+			<DESCRIPTION>files to be merged into the output, if possible</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="addfiles" REQUIRED="">
+			<DESCRIPTION>files to be added to the output</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="jspc">
+		<DESCRIPTION>&lt;p&gt; Ant task to run the JSP compiler and turn JSP pages into Java source.
+&lt;p&gt;
+It can be used to precompile JSP pages for fast initial invocation
+of JSP pages, deployment on a server without the full JDK installed,
+or simply to syntax check the pages without deploying them.
+In most cases, a javac task is usually the next stage in the build process.
+The task does basic dependency checking to prevent unnecessary recompilation -this
+checking compares source and destination timestamps, and does not factor
+in class or taglib dependencies, or &amp;lt;jsp:include&amp;gt; references.
+&lt;p&gt;
+By default the task uses the Jasper JSP compiler. This
+means the task needs jasper.jar and jasper-runtime.jar, which come with
+builds of Tomcat 4/Catalina from the
+&lt;a href=&quot;http://jakarta.apache.org/tomcat/&quot;&gt;Jakarta Tomcat project&lt;/a&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="destdir" REQUIRED="yes">
+			<DESCRIPTION>Where to place the generated files. They are locatedunder here according to the given package name</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="srcdir" REQUIRED="yes">
+			<DESCRIPTION>Where to look for source jsp files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>The verbosity integer to pass to the compiler. Default=&quot;0</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="package" REQUIRED="no">
+			<DESCRIPTION>Name of the destination package for generated javaclasses</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compiler" REQUIRED="no">
+			<DESCRIPTION>class name of a JSP compiler adapte</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="ieplugin" REQUIRED="no">
+			<DESCRIPTION>Java Plugin classid for Internet Explorer</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="mapped" REQUIRED="no">
+			<DESCRIPTION>(boolean) Generate separate write() calls for each HTMLline in the JSP</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>The classpath to use to run the jsp compiler.This can also be specifiedby the nested element classpathPath)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>A Reference. Asper classpat</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>flag to control action on compile failures: default=ye</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="uribase" REQUIRED="no">
+			<DESCRIPTION>The uri context of relative URIreferences in the JSP pages. If it does notexist then it is derived from the location of the filerelative to the declared or derived value of uriroot.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="uriroot" REQUIRED="no">
+			<DESCRIPTION>The root directory that uri files should be resolvedagainst.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compiler" REQUIRED="no">
+			<DESCRIPTION>Class name of jsp compiler adapter to use.  Defaults tothe standard adapter for Jasper.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compilerclasspath" REQUIRED="no">
+			<DESCRIPTION>The classpath used to find the compiler adapter specifiedby the compiler attribute</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="junit">
+		<DESCRIPTION>&lt;p&gt;This task runs tests from the JUnit testing framework. The latest
+version of the framework can be found at
+&lt;a href=&quot;http://www.junit.org&quot;&gt;http://www.junit.org&lt;/a&gt;.
+This task has been tested with JUnit 3.0 up to JUnit 3.8.1; it won't
+work with versions prior to JUnit 3.0.&lt;/p&gt;
+&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This task depends on external libraries not included
+in the Ant distribution.  See &lt;a href=&quot;../install.html#librarydependencies&quot;&gt;
+Library Dependencies&lt;/a&gt; for more information.
+&lt;/p&gt;
+&lt;p&gt;
+&lt;strong&gt;Note&lt;/strong&gt;:
+You must have &lt;code&gt;junit.jar&lt;/code&gt; and the class files for the
+&lt;code&gt;&amp;lt;junit&amp;gt;&lt;/code&gt; task in the same classpath.
+You can do one of:
+&lt;ol&gt;
+&lt;li&gt;
+Put both &lt;code&gt;junit.jar&lt;/code&gt; and the optional tasks jar file in
+&lt;code&gt;ANT_HOME/lib&lt;/code&gt;.
+&lt;/li&gt;
+&lt;li&gt;
+Do not put either in &lt;code&gt;ANT_HOME/lib&lt;/code&gt;, and instead
+include their locations in your &lt;code&gt;CLASSPATH&lt;/code&gt; environment variable.
+&lt;/li&gt;
+&lt;li&gt;
+Do neither of the above, and instead, specify their locations using
+a &lt;code&gt;&amp;lt;classpath&amp;gt;&lt;/code&gt; element in the buildfile.
+See &lt;a href=&quot;../../faq.html#delegating-classloader&quot; target=&quot;_top&quot;&gt;the
+FAQ&lt;/a&gt; for details.
+&lt;/ol&gt;
+&lt;/p&gt;
+&lt;p&gt;Tests are defined by nested &lt;code&gt;test&lt;/code&gt; or
+&lt;code&gt;batchtest&lt;/code&gt; tags (see &lt;a href=&quot;#nested&quot;&gt;nested
+elements&lt;/a&gt;).&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="printsummary" REQUIRED="no; default is off.">
+			<DESCRIPTION>Print one-line statistics for each testcase. Cantake the values on,off, andwithOutAndErr.withOutAndErr is the sameas on but also includes the output of the testas written to System.out and System.err</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="fork" REQUIRED="no; default is off.">
+			<DESCRIPTION>Run the tests in a separate VM</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="haltonerror" REQUIRED="no; default is off.">
+			<DESCRIPTION>Stop the build process if an error occurs during the testrun</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="errorproperty" REQUIRED="no">
+			<DESCRIPTION>The name of a property to set in the event of an error</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="haltonfailure" REQUIRED="no; default is off.">
+			<DESCRIPTION>Stop the build process if a test fails (errors areconsidered failures as well)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failureproperty" REQUIRED="no.">
+			<DESCRIPTION>The name of a property to set in the event of a failure(errors are considered failures as well)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filtertrace" REQUIRED="no; default is on.">
+			<DESCRIPTION>Filter out Junit and Ant stack frames from error and failure stack traces</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="timeout" REQUIRED="no">
+			<DESCRIPTION>Cancel the individual tests if they don't finishin the given time (measured in milliseconds).  Ignored iffork is disabled</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="maxmemory" REQUIRED="no">
+			<DESCRIPTION>Maximum amount of memory to allocate to the forked VM.Ignored if fork is disabled</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="jvm" REQUIRED="no; default is java.">
+			<DESCRIPTION>The command used to invoke the Java Virtual Machine,default is 'java'.  The command is resolved byjava.lang.Runtime.exec().Ignored if fork is disabled</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dir" REQUIRED="no">
+			<DESCRIPTION>The directory in which to invoke the VM. Ignored iffork is disabled</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="newenvironment" REQUIRED="no; default is false.">
+			<DESCRIPTION>Do not propagate the old environment when newenvironment variables are specified. Ignored if fork isdisabled</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includeantruntime" REQUIRED="no; default is true.">
+			<DESCRIPTION>Implicitly add the Ant classes required to runthe tests and JUnit to the classpath in forked mode</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="showoutput" REQUIRED="no">
+			<DESCRIPTION>Send any output generated by tests to Ant'slogging system as well as to the formatters.  By default only theformatters receive the output</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="maudit">
+		<DESCRIPTION>&lt;p&gt;
+Invokes the Metamata Audit/ Webgain Quality Analyzer on a set of Java files.
+&lt;/p&gt;
+&lt;p&gt;
+&lt;i&gt;maudit&lt;/i&gt; performs static analysis of the Java source code and byte code files to find and report
+errors of style and potential problems related to performance, maintenance and robustness.
+.  As a convenience, a stylesheet is given in &lt;tt&gt;etc&lt;/tt&gt; directory, so that an HTML report can be generated from the XML file.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="tofile" REQUIRED="yes">
+			<DESCRIPTION>The XML file to which the Audit result should be written to</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="metamatahome" REQUIRED="yes">
+			<DESCRIPTION>The home directory containing the Metamata distribution</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="fix" REQUIRED="no.default to false.">
+			<DESCRIPTION>Automatically fix certain errors (those marked as fixable in the manual).</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="list" REQUIRED="no. default to false.">
+			<DESCRIPTION>Creates listing file for each audited file. A .maudit file will be generated in thesame location as the source file.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="unused" REQUIRED="no. default to false.">
+			<DESCRIPTION>Finds declarations unused in search paths. It will look for unused global declarationsin the source code within a use domain specified by the searchpath element.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="maxmemory" REQUIRED="no">
+			<DESCRIPTION>Set the maximum memory for the JVM. this is a convenientway to set the -mx or -Xmx argument</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="mimemail">
+		<DESCRIPTION>&lt;p&gt;Sends SMTP mail with MIME attachments.
+&lt;a href=&quot;http://java.sun.com/products/javamail/index.html&quot;&gt;JavaMail&lt;/a&gt;
+and &lt;a href=&quot;http://java.sun.com/products/javabeans/glasgow/jaf.html&quot;&gt;Java
+Activation Framework&lt;/a&gt; are required for this task.&lt;/p&gt;
+&lt;p&gt;Multiple files can be attached using &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSets.&lt;/a&gt;&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="message" REQUIRED="no, but only one of of 'message' or
+       'messagefile' may be specified. if not specified, a fileset must be
+       provided.">
+			<DESCRIPTION>The message bod</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="messagefile" REQUIRED="">
+			<DESCRIPTION>A filename to read and used as the message bod</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="messagemimetype" REQUIRED="no, defaults to &quot;text/plain&quot;">
+			<DESCRIPTION>MIME type to use for 'message' or 'messageFile' whenattached</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tolist" REQUIRED="yes, at least one of 'tolist', 'cclist',
+       or 'bcclist' must be specified.">
+			<DESCRIPTION>Comma-separated list of To: recipient</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="cclist" REQUIRED="">
+			<DESCRIPTION>Comma-separated list of CC: recipient</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bcclist" REQUIRED="">
+			<DESCRIPTION>Comma-separated list of BCC: recipient</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="mailhost" REQUIRED="no, default to &quot;localhost&quot;">
+			<DESCRIPTION>Host name of the mail server</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="subject" REQUIRED="no">
+			<DESCRIPTION>Email subject line</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="from" REQUIRED="yes">
+			<DESCRIPTION>Email address of sender</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no, default to &quot;true&quot;">
+			<DESCRIPTION>Stop the build process if an error occurs sending thee-mail</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="mmetrics">
+		<DESCRIPTION>&lt;p&gt;
+Invokes the Metamata Metrics / WebGain Quality Analyzer source code 
+analyzer on a set of Java files.
+&lt;/p&gt;
+&lt;p&gt;
+&lt;i&gt;mmetrics&lt;/i&gt; will compute the metrics of a set of Java files and write the results to an XML
+file. As a convenience, a stylesheet is given in &lt;tt&gt;etc&lt;/tt&gt; directory, so that an HTML report can be generated from the XML file.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="metamatahome" REQUIRED="yes">
+			<DESCRIPTION>The home directory containing the Metamata distribution</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="tofile" REQUIRED="yes">
+			<DESCRIPTION>The XML were the resulting metrics will be written to</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="granularity" REQUIRED="yes">
+			<DESCRIPTION>Metrics granularity of the source files. Must be eitherfiles (compilation-units), types (types and compilation-units) or methods(methods, types and compilation-units).</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="maxmemory" REQUIRED="no">
+			<DESCRIPTION>Set the maximum memory for the JVM. this is a convenientway to set the -mx or -Xmx argument</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="mparse">
+		<DESCRIPTION>&lt;p&gt;
+Invokes the Metamata &lt;a HREF=&quot;http://www.metamata.com/parse.html&quot;&gt;MParse&lt;/a&gt; compiler 
+compiler on a grammar file.
+&lt;/p&gt;
+&lt;p&gt;
+To use the &lt;i&gt;mparse&lt;/i&gt; task, set the &lt;i&gt;target&lt;/i&gt; attribute to the name of the 
+grammar file to process.  You also need to specify the directory containing 
+the Metamata installation using the &lt;i&gt;metamatahome&lt;/i&gt; attribute, so that Ant 
+can find the MParse classes.
+&lt;/p&gt;
+&lt;p&gt;
+This task only invokes MParse if the grammar file is newer than the generated 
+Java files. MParse assumes that the Java class name of the generated parser
+is the same as the name of the grammar file, less the .jj extension.
+&lt;/p&gt;
+&lt;p&gt;For additional information about MParse, please consult the online manual available &lt;a href=&quot;http://download.metamata.com/parse.pdf&quot;&gt;here&lt;/a&gt;
+(PDF)
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="target" REQUIRED="yes">
+			<DESCRIPTION>The .jj grammar file to process. It will only be processedif the grammar is newer than the corresponding .java file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="metamatahome" REQUIRED="yes">
+			<DESCRIPTION>The home directory containing the Metamata distribution</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>Enable all messages</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debugparser" REQUIRED="no">
+			<DESCRIPTION>Enables parser debugging</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="debugscanner" REQUIRED="no">
+			<DESCRIPTION>Enables scanner debugging</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="cleanup" REQUIRED="no. default to false">
+			<DESCRIPTION>Remove the intermediate SunJavaCC file created during the transformation of the grammar file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="maxmemory" REQUIRED="no">
+			<DESCRIPTION>Set the maximum memory for the JVM. this is a convenientway to set the -mx or -Xmx argument</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="native2ascii">
+		<DESCRIPTION>&lt;p&gt;
+Converts files from native encodings to ASCII with escaped Unicode.
+A common usage is to convert source files maintained in a native
+operating system encoding, to ASCII prior to compilation.
+&lt;/p&gt;
+&lt;p&gt;
+Files in the directory &lt;em&gt;src&lt;/em&gt;
+are converted from a native encoding to ASCII.
+By default, all files in the directory are converted.
+However, conversion may be limited to selected files using
+&lt;em&gt;includes&lt;/em&gt; and &lt;em&gt;excludes&lt;/em&gt; attributes.
+For more information on file matching patterns,
+see the section on
+&lt;a href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based tasks&lt;/a&gt;.
+If no &lt;em&gt;encoding&lt;/em&gt; is specified,
+the default encoding for the JVM is used.
+If &lt;em&gt;ext&lt;/em&gt; is specified, then output files are renamed
+to use it as a new extension.
+More sophisticated file name translations can be achieved using a nested
+&lt;em&gt;&amp;lt;mapper&amp;gt;&lt;/em&gt; element. By default an
+&lt;a href=&quot;../CoreTypes/mapper.html#identity-mapper&quot;&gt;identity mapper&lt;/a&gt; will be used.
+If &lt;em&gt;dest&lt;/em&gt; and &lt;em&gt;src&lt;/em&gt; point to the same directory,
+the &lt;em&gt;ext&lt;/em&gt; attribute or a nested &lt;em&gt;&amp;lt;mapper&amp;gt;&lt;/em&gt;
+is required.
+&lt;/p&gt;
+&lt;p&gt;
+This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;File Set&lt;/a&gt;,
+and supports all attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;
+(&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;src&lt;/code&gt;) as well as
+nested &lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt;,
+and &lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="reverse" REQUIRED="no">
+			<DESCRIPTION>Reverse the sense of the conversion,i.e. convert from ASCII to nativ</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="encoding" REQUIRED="no">
+			<DESCRIPTION>The native encoding the files are in(default is the default encoding for the JVM</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="src" REQUIRED="no">
+			<DESCRIPTION>The directory to find files in (default is basedir</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dest" REQUIRED="yes">
+			<DESCRIPTION>The directory to output file t</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="ext" REQUIRED="no">
+			<DESCRIPTION>File extension to use in renaming output file</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;).Default excludes are used when omitted.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must be excluded.No files (except default excludes) are excluded when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="netrexxc">
+		<DESCRIPTION>&lt;p&gt;Compiles a &lt;a href=&quot;http://www2.hursley.ibm.com/netrexx&quot; target=&quot;_top&quot;&gt;NetRexx&lt;/a&gt;
+source tree within the running (Ant) VM.&lt;/p&gt;
+&lt;p&gt;The source and destination directory will be recursively scanned for
+NetRexx source files to compile.  Only NetRexx files that have no corresponding
+class file or where the class file is older than the java file will be compiled.&lt;/p&gt;
+&lt;p&gt;Files in the source tree are copied to the destination directory,
+allowing support files to be located properly in the classpath. The source
+files are copied because the NetRexx compiler cannot produce class files in a
+specific directory via parameters&lt;/p&gt;
+&lt;p&gt;The directory structure of the source tree should follow the package
+hierarchy.&lt;/p&gt;
+&lt;p&gt;It is possible to refine the set of files that are being compiled/copied.
+This can be done with the &lt;i&gt;includes&lt;/i&gt;, &lt;i&gt;includesfile&lt;/i&gt;, &lt;i&gt;excludes&lt;/i&gt;, &lt;i&gt;excludesfile&lt;/i&gt; and
+&lt;i&gt;defaultexcludes&lt;/i&gt; attributes. With the &lt;i&gt;includes&lt;/i&gt; or &lt;i&gt;includesfile&lt;/i&gt; attribute you
+specify the files you want to have included by using patterns. The
+&lt;i&gt;exclude&lt;/i&gt; or &lt;i&gt;excludesfile&lt;/i&gt; attribute is used to specify the files you want to have
+excluded.  This is also done with patterns.  And finally with the
+&lt;i&gt;defaultexcludes&lt;/i&gt; attribute, you can specify whether you
+want to use default exclusions or not. See the section on &lt;a
+href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based tasks&lt;/a&gt;, on how the
+inclusion/exclusion of files works, and how to write patterns.&lt;/p&gt;
+&lt;p&gt;This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and
+supports all attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;
+(&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;srcdir&lt;/code&gt;) as well as the nested
+&lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt; and
+&lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+&lt;p&gt;All properties except classpath, srcdir and destDir are also available as properties in the form
+&lt;code&gt;ant.netrexxc.&lt;i&gt;attributename&lt;/i&gt;&lt;/code&gt;, eg.&lt;br&gt;
+&lt;code&gt;&amp;lt;property name=&quot;ant.netrexxc.verbose&quot; value=&quot;noverbose&quot;/&amp;gt;&lt;/code&gt;&lt;br&gt;
+or from the command line as&lt;br&gt;
+&lt;code&gt;ant -Dant.netrexxc.verbose=noverbose ...&lt;/code&gt;
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="binary" REQUIRED="no">
+			<DESCRIPTION>Whether literals are treated as the java binarytype rather than the NetRexx type</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="no">
+			<DESCRIPTION>The classpath to use during compilatio</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="comments" REQUIRED="no">
+			<DESCRIPTION>Whether comments are passed through to thegenerated java sourc</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compact" REQUIRED="no">
+			<DESCRIPTION>Whether error messages come out in compact orverbose format. Default is the compact format</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="compile" REQUIRED="no">
+			<DESCRIPTION>Whether the NetRexx compiler should compile thegenerated java cod</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="console" REQUIRED="no">
+			<DESCRIPTION>Whether or not messages should be displayed on the'console</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="crossref" REQUIRED="no">
+			<DESCRIPTION>Whether variable cross references are generate</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="decimal" REQUIRED="no">
+			<DESCRIPTION>Whether decimal arithmetic should be used for theNetRexx cod</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used whenomitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destdir" REQUIRED="yes">
+			<DESCRIPTION>the destination directory into which the NetRexxsource files should be copied and then compile</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="diag" REQUIRED="no">
+			<DESCRIPTION>Whether diagnostic information about the compile isgenerate</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded whenomitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="explicit" REQUIRED="no">
+			<DESCRIPTION>Whether variables must be declared explicitlybefore us</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="format" REQUIRED="no">
+			<DESCRIPTION>Whether the generated java code is formatted nicelyor left to match NetRexx line numbers for call stack debuggin</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="java" REQUIRED="no">
+			<DESCRIPTION>Whether the generated java code is produce</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="keep" REQUIRED="no">
+			<DESCRIPTION>Sets whether the generated java source file should be keptafter compilation. The generated files will have an extension of.java.keep, not .jav</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="logo" REQUIRED="no">
+			<DESCRIPTION>Whether the compiler text logo is displayed whencompilin</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="replace" REQUIRED="no">
+			<DESCRIPTION>Whether the generated .java file should be replacedwhen compilin</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="savelog" REQUIRED="no">
+			<DESCRIPTION>Whether the compiler messages will be written toNetRexxC.log as well as to the consol</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="sourcedir" REQUIRED="no">
+			<DESCRIPTION>Tells the NetRexx compiler to store the class files in thesame directory as the source files. The alternative is the workingdirector</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="srcdir" REQUIRED="yes">
+			<DESCRIPTION>Set the source dir to find the source NetRexxfile</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="strictargs" REQUIRED="no">
+			<DESCRIPTION>Tells the NetRexx compiler that method calls alwaysneed parentheses, even if no arguments are needed, e.g.aStringVar.getBytes vs.aStringVar.getBytes(</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="strictassign" REQUIRED="no">
+			<DESCRIPTION>Tells the NetRexx compile that assignments mustmatch exactly on typ</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="strictcase" REQUIRED="no">
+			<DESCRIPTION>Specifies whether the NetRexx compiler should becase sensitive or no</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="strictimport" REQUIRED="no">
+			<DESCRIPTION>Whether classes need to be imported explicitly using animport statement.  By default the NetRexx compiler willimport certain packages automaticall</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="strictprops" REQUIRED="no">
+			<DESCRIPTION>Whether local properties need to be qualifiedexplicitly using thi</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="strictsignal" REQUIRED="no">
+			<DESCRIPTION>Whether the compiler should force catching ofexceptions by explicitly named type</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="symbols" REQUIRED="no">
+			<DESCRIPTION>Whether debug symbols should be generated into theclass fil</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="time" REQUIRED="no">
+			<DESCRIPTION>Asks the NetRexx compiler to print compilationtimes to the consol</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="trace" REQUIRED="no">
+			<DESCRIPTION>Turns on or off tracing and directs the resultanttrace outpu</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="utf8" REQUIRED="no">
+			<DESCRIPTION>Tells the NetRexx compiler that the source is in UTF</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="verbose" REQUIRED="no">
+			<DESCRIPTION>Whether lots of warnings and error messages shouldbe generate</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="suppressmethodargumentnotused" REQUIRED="no">
+			<DESCRIPTION>Tells whether we should filter out the&amp;Method argument not used&amp; messages in strictargs mode</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="suppressprivatepropertynotused" REQUIRED="no">
+			<DESCRIPTION>Tells whether we should filter out the&amp;Private Property defined, but not used&amp; messages in strictargs mode</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="suppressvariablenotused" REQUIRED="no">
+			<DESCRIPTION>Tells whether we should filter out the&amp;Variable set but not used&amp; messages in strictargs mode.Please be careful with this one, as you can hide errors behind it</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="suppressexceptionnotsignalled" REQUIRED="no">
+			<DESCRIPTION>Tells whether we should filter out the&amp;Exception is declared, but not signalled within the method&amp;messages in strictsignal mode</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="suppressdeprecation" REQUIRED="no">
+			<DESCRIPTION>Tells wether we should filter out any deprecation-messagesof the compiler out</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="pvcs">
+		<DESCRIPTION>The pvcs task is set to point at a PVCS repository and optionally a project
+within that repository, and can from that specification get the latest
+version of the files contained by the repository.
+</DESCRIPTION>
+		<ATTRIBUTE NAME="repository" REQUIRED="yes">
+			<DESCRIPTION>The location of the repository (see your PVCSmanuals</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="pvcsproject" REQUIRED="no">
+			<DESCRIPTION>The project within the PVCS repository to extractfiles from (&quot;/&quot; is root project and that is default if this attribute isn'tspecified</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="label" REQUIRED="no">
+			<DESCRIPTION>Only files marked with this label are extracted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="promotiongroup" REQUIRED="no">
+			<DESCRIPTION>Only files within this promotion group are extracted. Usingboth the label and the promotiongroup tag will cause the files in thepromotion group and with that label to be extracted.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="force" REQUIRED="no">
+			<DESCRIPTION>If set to yes all files that exists and are writable are overwritten. Default no causes the files that are writable to be ignored. This stops the PVCS command get to stop asking questions</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="workspace" REQUIRED="no">
+			<DESCRIPTION>By specifying a workspace, the files are extracted to that location. A PVCS workspace is aname for a location of the workfiles and isn't as such the location itself. You define the location for a workspaceusing the PVCS GUI clients. If this isn't specified the default workspace for the current user is used</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="pvcsbin" REQUIRED="no">
+			<DESCRIPTION>On some systems the PVCS executables pcliand get are not found in the PATH. In such cases this attributeshould be set to the bin directory of the PVCS installation containingthe executables mentioned before. If this attribute isn't specified thetag expects the executables to be found using the PATH environment variable</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="ignorereturncode" REQUIRED="no">
+			<DESCRIPTION>If set to true the return value from executingthe pvcs commands are ignored</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="updateonly" REQUIRED="no">
+			<DESCRIPTION>If set to true files are gotten only ifnewer than existing local files</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="filenameformat" REQUIRED="no">
+			<DESCRIPTION>The format of your folder names in aformat suitable for java.text.MessageFormat.Defaults to {0}-arc({1}).  Repositories wherethe archive extension is not  -arc should setthis</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="linestart" REQUIRED="no">
+			<DESCRIPTION>Used to parse the output of the pclicommand. It defaults to &quot;P:.  The parser alreadyknows about / and \\, this property is useful in cases where therepository is accessed on a Windows platform via a drive lettermapping</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="renameextensions">
+		<DESCRIPTION>&lt;p&gt;Renames files in the &lt;code&gt;srcDir&lt;/code&gt; directory ending with the
+&lt;code&gt;fromExtension&lt;/code&gt; string so that they end with the
+&lt;code&gt;toExtension&lt;/code&gt; string. Files are only replaced if
+&lt;code&gt;replace&lt;/code&gt; is true
+&lt;/p&gt;
+&lt;p&gt;See the section on
+&lt;a href=&quot;../dirtasks.html#directorybasedtasks&quot;&gt;directory based tasks&lt;/a&gt;, on how the
+inclusion/exclusion of files works, and how to write patterns.
+This task forms an implicit &lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt; and
+supports all attributes of &lt;code&gt;&amp;lt;fileset&amp;gt;&lt;/code&gt;
+(&lt;code&gt;dir&lt;/code&gt; becomes &lt;code&gt;srcDir&lt;/code&gt;) as well as the nested
+&lt;code&gt;&amp;lt;include&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;exclude&amp;gt;&lt;/code&gt; and
+&lt;code&gt;&amp;lt;patternset&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="defaultexcludes" REQUIRED="no">
+			<DESCRIPTION>indicates whether default excludes should be used or not(&quot;yes&quot;/&quot;no&quot;). Default excludes are used whenomitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beexcluded. No files (except default excludes) are excluded whenomitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="excludesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an exclude patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="fromextention" REQUIRED="yes">
+			<DESCRIPTION>The string that files must end in to be rename</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includes" REQUIRED="no">
+			<DESCRIPTION>comma- or space-separated list of patterns of files that must beincluded. All files are included when omitted</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="includesfile" REQUIRED="no">
+			<DESCRIPTION>the name of a file. Each line of this file istaken to be an include patter</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="replace" REQUIRED="no">
+			<DESCRIPTION>Whether the file being renamed to should bereplaced if it already exist</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="srcdir" REQUIRED="yes">
+			<DESCRIPTION>The starting directory for files to search i</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="toextension" REQUIRED="yes">
+			<DESCRIPTION>The string that renamed files will end with oncompletio</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="replaceregeexp">
+		<DESCRIPTION>&lt;p&gt;ReplaceRegExp is a directory based task for replacing the
+occurrence of a given regular expression with a substitution pattern
+in a selected file or set of files.&lt;/p&gt;
+&lt;p&gt;Similar to &lt;a href=&quot;../CoreTypes/mapper.html#regexp-mapper&quot;&gt;regexp
+type mappers&lt;/a&gt; this task needs a supporting regular expression
+library and an implementation of
+&lt;code&gt;org.apache.tools.ant.util.regexp.Regexp&lt;/code&gt;.  Ant comes with
+implementations for
+&lt;a href=&quot;http://java.sun.com/j2se/1.4/docs/api/java/util/regex/package-summary.html&quot; target=&quot;_top&quot;&gt;the java.util.regex package of JDK 1.4&lt;/a&gt;,
+&lt;a href=&quot;http://jakarta.apache.org/regexp/&quot; target=&quot;_top&quot;&gt;jakarta-regexp&lt;/a&gt;
+and &lt;a href=&quot;http://jakarta.apache.org/oro/&quot; target=&quot;_top&quot;&gt;jakarta-ORO&lt;/a&gt;,
+but you will still need the library itself.&lt;/p&gt;
+&lt;p&gt;
+&lt;i&gt;
+There are cross-platform issues for matches related to line terminator.
+For example if you use $ to anchor your regular expression on the end of a line
+the results might be very different depending on both your platform and the regular
+expression library you use. It is 'highly recommended' that you test your pattern on
+both Unix and Windows platforms before you rely on it.
+&lt;ul&gt;
+&lt;li&gt;Jakarta Oro defines a line terminator as '\n' and is consistent with Perl.&lt;/li&gt;
+&lt;li&gt;Jakarta RegExp uses a system-dependant line terminator.&lt;/li&gt;
+&lt;li&gt;JDK 1.4 uses '\n', '\r\n', '\u0085', '\u2028', '\u2029' as a default
+but is configured in the wrapper to use only '\n' (UNIX_LINE)&lt;/li&gt;
+&lt;/ul&gt;
+We &lt;b&gt;strongly&lt;/b&gt; recommend that you use Jakarta Oro.
+&lt;/i&gt;
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="yes if no nested &lt;fileset&gt; is used">
+			<DESCRIPTION>file for which the regular expression should be replaced</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="match" REQUIRED="yes, if no nested &lt;regexp&gt; is used">
+			<DESCRIPTION>The regular expression pattern to match in the file(s</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="replace" REQUIRED="yes, if no nested &lt;substitution&gt; is used">
+			<DESCRIPTION>The substitution pattern to place in the file(s) in placeof the regular expression</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="flags" REQUIRED="no">
+			<DESCRIPTION>The flags to use when matching the regular expression.  For moreinformation, consult the Perl5 syntag : Global replacement.  Replace all occurences founi : Case Insensitive.  Do not consider case in the matcm : Multiline.  Treat the string as multiple lines of input, using &quot;^&quot; and &quot;$&quot; as the start or end of any line, respectively, rather than start or end of strings : Singleline.  Treat the string as a single line of input, using &quot;.&quot; to match any character, including a newline, which normally, it would not match</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="byline" REQUIRED="no">
+			<DESCRIPTION>Process the file(s) one line at a time, executing the replacementon one line at a time (true/false).  This is useful if youwant to only replace the first occurence of a regular expression oneach line, which is not easy to do when processing the file as a whole.Defaults to false</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="rpm">
+		<DESCRIPTION>&lt;p&gt;
+A basic task for invoking the rpm executable to build a Linux installation
+file. The task currently only works on Linux or other Unix platforms
+with rpm support.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="specfile" REQUIRED="yes">
+			<DESCRIPTION>The name of the spec File to be used</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="topdir" REQUIRED="no">
+			<DESCRIPTION>this is the directory which will have the expectedsubdirectories, SPECS, SOURCES, BUILD, SRPMS.  If this isn't specified,the baseDir value is used</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="cleanbuilddir" REQUIRED="no">
+			<DESCRIPTION>This will remove the generated files in the BUILDdirectory</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="removespec" REQUIRED="no">
+			<DESCRIPTION>this will remove the spec file from SPEC</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="removesource" REQUIRED="no">
+			<DESCRIPTION>Flag (optional, default=false) to remove the sources after the build.See the the --rmsource  option of rpmbuild</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="command" REQUIRED="no">
+			<DESCRIPTION>very similar idea to the cvs task.  the default is &quot;-bb</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="output/error" REQUIRED="no">
+			<DESCRIPTION>where standard output and error g</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="script">
+		<DESCRIPTION>&lt;p&gt;Execute a script in a 
+&lt;a href=&quot;http://www-124.ibm.com/developerworks/projects/bsf&quot; target=&quot;_top&quot;&gt;BSF&lt;/a&gt; supported language.&lt;/p&gt;
+&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This task depends on external libraries not included in the Ant distribution.
+See &lt;a href=&quot;../install.html#librarydependencies&quot;&gt;Library Dependencies&lt;/a&gt; for more information.&lt;/p&gt;
+&lt;p&gt;All items (tasks, targets, etc) of the running project are
+accessible from the script, using either their &lt;code&gt;name&lt;/code&gt; or
+&lt;code&gt;id&lt;/code&gt; attributes (as long as their names are considered
+valid Java identifiers, that is). 
+The name &quot;project&quot; is a pre-defined reference to the Project, which can be
+used instead of the project name.&lt;/p&gt;
+&lt;p&gt;&lt;b&gt;BeanShell users:&lt;/b&gt; This task now natively supports the BeanShell
+scripting language, using language=&quot;beanshell&quot;. The BeanShell engine is
+still required.
+&lt;/p&gt;
+&lt;p&gt;Scripts can do almost anything a task written in Java could do.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="language" REQUIRED="yes">
+			<DESCRIPTION>The programming language the script is written in.Must be a supported BSF languag</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="src" REQUIRED="no">
+			<DESCRIPTION>The location of the script as a file, if not inlin</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="serverdeploy">
+		<DESCRIPTION>&lt;p&gt;The &lt;code&gt;serverdeploy&lt;/code&gt; task is used to run a &quot;hot&quot; deployment tool for
+vendor-specific J2EE server. The task requires nested elements which define
+the attributes of the vendor-specific deployment tool being executed.
+Vendor-specific deployment tools elements may enforce rules for which
+attributes are required, depending on the tool.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="action" REQUIRED="yes">
+			<DESCRIPTION>This is the action to be performed.  For most cases thiswill be &quot;deploy&quot;.  Some tools support additional actions, such as &quot;delete&quot;, &quot;list&quot;,&quot;undeploy&quot;, &quot;update&quot;..</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="source" REQUIRED="tool dependant">
+			<DESCRIPTION>A fully qualified path/filename of the component to be deployed.This may be an .ear, .jar, .war, or any other type that is supported by the server.</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="splash">
+		<DESCRIPTION>&lt;p&gt;This task creates a splash screen. The splash screen is displayed
+for the duration of the build and includes a handy progress bar as
+well. Use in conjunction with the sound task to provide interest
+whilst waiting for your builds to complete...&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="imageurl" REQUIRED="no">
+			<DESCRIPTION>A URL pointing to an image to display</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="showduration" REQUIRED="no">
+			<DESCRIPTION>Initial period to pause the build to show thesplash in milliseconds</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="stylebook">
+		<DESCRIPTION>&lt;p&gt;This executes the apache Stylebook documentation generator. 
+Unlike the commandline version of this tool, all three arguments
+are required to run stylebook.&lt;/p&gt;
+&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This task depends on external libraries not included in the Ant distribution.
+See &lt;a href=&quot;../install.html#librarydependencies&quot;&gt;Library Dependencies&lt;/a&gt; for more information.&lt;/p&gt;
+&lt;p&gt;
+Being extended from &amp;lt;Java&amp;gt;, all the parent's attributes
+and options are available. Do not set any apart from the &lt;tt&gt;classpath&lt;/tt&gt;
+as they are not guaranteed to be there in future.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="book" REQUIRED="yes">
+			<DESCRIPTION>the book xml file that the documentation generation starts from</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="skindirectory" REQUIRED="yes">
+			<DESCRIPTION>the directory that contains the stylebook skin</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="targetdirectory" REQUIRED="yes">
+			<DESCRIPTION>the destination directory where the documentation is generated </DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="telnet">
+		<DESCRIPTION>Task to automate a remote telnet session. The task uses 
+nested &lt;tt&gt;&amp;lt;read&amp;gt;&lt;/tt&gt; to indicate strings to wait for, and
+&lt;tt&gt;&amp;lt;write&amp;gt;&lt;/tt&gt; tags to specify text to send.  
+&lt;p&gt;If you do specify a userid and password, the system will 
+assume a common unix prompt to wait on. This behavior can be easily over-ridden.&lt;/p&gt;
+&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; This task depends on external libraries not included in the Ant distribution.
+See &lt;a href=&quot;../install.html#librarydependencies&quot;&gt;Library Dependencies&lt;/a&gt; for more information.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="userid" REQUIRED="only if password is specified">
+			<DESCRIPTION>the login id to use on the telnet server</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="password" REQUIRED="only if userid is specified">
+			<DESCRIPTION>the login password to use on the telnet server</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="server" REQUIRED="yes">
+			<DESCRIPTION>the address of the remote telnet server</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="port" REQUIRED="no">
+			<DESCRIPTION>the port number of the remote telnet server. Defaults to port 23</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="initialcr" REQUIRED="no">
+			<DESCRIPTION>send a cr after connecting (&quot;yes&quot;). Defaults to &quot;no&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="timeout" REQUIRED="no">
+			<DESCRIPTION>set a default timeout to wait for a response. Specified in seconds. Default is no timeout</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="test">
+		<DESCRIPTION>&lt;p&gt;This is a primitive task to execute a unit test in the org.apache.testlet framework.&lt;/p&gt;
+&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This task depends on external libraries not included
+in the Ant distribution.  See &lt;a href=&quot;../install.html#librarydependencies&quot;&gt;
+Library Dependencies&lt;/a&gt; for more information.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="showsuccess" REQUIRED="no">
+			<DESCRIPTION>a boolean value indicating whether tests should display a message on success</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="showbanner" REQUIRED="no">
+			<DESCRIPTION>a boolean value indicating whether a banner should be displayed when starting testlet engine</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="forceshowtrace" REQUIRED="no">
+			<DESCRIPTION>a boolean indicating that a stack trace is displayed on any failure</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="showtrace" REQUIRED="no">
+			<DESCRIPTION>a boolean indicating that a stack trace is displayed on error (but not normal failure)</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="translate">
+		<DESCRIPTION>&lt;p&gt;Identifies keys in files delimited by special tokens
+and translates them with values read from resource bundles.
+&lt;/p&gt;
+&lt;p&gt;
+A resource bundle contains locale-specific key-value pairs.
+A resource bundle is a hierarchical set of property files.
+A bundle name makes up its base family name.  Each file that
+makes up this bundle has this name plus its locale.  For example,
+if the resource bundle name is MyResources, the file that contains
+German text will take the name MyResources_de.  In addition to
+language, country and variant are also used to form the files in
+the bundle.
+&lt;/p&gt;
+&lt;p&gt;
+The resource bundle lookup searches for resource files with various
+suffixes on the basis of (1) the desired locale and (2) the default
+locale (basebundlename), in the following order from lower-level
+(more specific) to parent-level (less specific):
+&lt;/p&gt;
+&lt;pre&gt;
+basebundlename + &amp;quot;_&amp;quot; + language1 + &amp;quot;_&amp;quot; + country1 + &amp;quot;_&amp;quot; + variant1
+basebundlename + &amp;quot;_&amp;quot; + language1 + &amp;quot;_&amp;quot; + country1
+basebundlename + &amp;quot;_&amp;quot; + language1
+basebundlename
+basebundlename + &amp;quot;_&amp;quot; + language2 + &amp;quot;_&amp;quot; + country2 + &amp;quot;_&amp;quot; + variant2
+basebundlename + &amp;quot;_&amp;quot; + language2 + &amp;quot;_&amp;quot; + country2
+basebundlename + &amp;quot;_&amp;quot; + language2
+&lt;/pre&gt;
+&lt;p&gt;
+The file names generated thus are appended with the string &amp;quot;.properties&amp;quot;
+to make up the file names that are to be used.
+&lt;/p&gt;
+&lt;p&gt;
+File encoding is supported.  The encoding scheme of the source files,
+destination files and the bundle files can be specified.
+Destination files can be exlicitly overwritten using the
+&lt;var&gt;forceoverwrite&lt;/var&gt; attribute.  If &lt;var&gt;forceoverwrite&lt;/var&gt;
+is false, the destination file is overwritten only if either the
+source file or any of the files that make up the bundle have been
+modified after the destination file was last modified.
+&lt;/p&gt;
+&lt;p&gt;&lt;a href=&quot;../CoreTypes/fileset.html&quot;&gt;FileSet&lt;/a&gt;s are used to select files to
+translate.
+&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="todir" REQUIRED="yes">
+			<DESCRIPTION>Destination directory where destination files areto be created</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="starttoken" REQUIRED="yes">
+			<DESCRIPTION>The starting token to identify keys</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="endtoken" REQUIRED="yes">
+			<DESCRIPTION>The ending token to identify keys</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bundle" REQUIRED="yes">
+			<DESCRIPTION>Family name of resource bundle</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bundlelanguage" REQUIRED="no">
+			<DESCRIPTION>Locale specific language of resource bundle.  Defaults todefault locale's language.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bundlecountry" REQUIRED="no">
+			<DESCRIPTION>Locale specific country of resource bundle.  Defaults todefault locale's country.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bundlevariant" REQUIRED="no">
+			<DESCRIPTION>Locale specific variant of resource bundle.  Defaults tothe default variant of the country and language being used.</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="srcencoding" REQUIRED="no">
+			<DESCRIPTION>Source file encoding scheme.  Defaults tosystem default file encoding</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="destencoding" REQUIRED="no">
+			<DESCRIPTION>Destination file encoding scheme.  Defaults tosource file encoding</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="bundleencoding" REQUIRED="no">
+			<DESCRIPTION>Resource Bundle file encoding scheme.  Defaults tosource file encoding</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="forceoverwrite" REQUIRED="no">
+			<DESCRIPTION>Overwrite existing files even if the destinationfiles are newer. Defaults to &quot;no&quot;</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="wljspc">
+		<DESCRIPTION>&lt;p&gt;Class to precompile JSP's using weblogic's jsp compiler (weblogic.jspc)&lt;/p&gt;
+Tested only on Weblogic 4.5.1 - NT4.0 and Solaris 5.7,5.8&lt;br&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="src" REQUIRED="yes">
+			<DESCRIPTION>oot of source tree for JSP, ie, the document root for your weblogic serve</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="dest" REQUIRED="yes">
+			<DESCRIPTION>root of destination directory, what you have set as WorkingDir in the weblogic propertie</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="package" REQUIRED="yes">
+			<DESCRIPTION>start package name under which your JSP's would be compile</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpath" REQUIRED="yes">
+			<DESCRIPTION>Class path to use when compiling jsp'</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+	<TASK NAME="xmlvalidate">
+		<DESCRIPTION>&lt;p&gt;This task checks xml files are valid (or only well formed). The
+task uses the SAX2 parser implementation provided by JAXP by default
+(probably the one that is used by Ant itself), but one can specify any
+SAX1/2 parser if needed.&lt;/p&gt;
+&lt;p&gt;This task supports the use of nested &lt;a
+href=&quot;../CoreTypes/xmlcatalog.html&quot;&gt;xmlcatalog&lt;/a&gt; elements and/or nested
+&lt;tt&gt;&amp;lt;dtd&amp;gt;&lt;/tt&gt; elements which are used to resolve DTDs and entities.&lt;/p&gt;
+</DESCRIPTION>
+		<ATTRIBUTE NAME="file" REQUIRED="no">
+			<DESCRIPTION>the file(s) you want to check. (optionally can use an embedded fileset</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="lenient" REQUIRED="no">
+			<DESCRIPTION>if true, only check the xml document is well formed(ignored if the specified parser is as SAX1 parser)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classname" REQUIRED="no">
+			<DESCRIPTION>the parser to use</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="classpathref" REQUIRED="no">
+			<DESCRIPTION>where to find the parser class. Optionally can use an embedded classpath element</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="failonerror" REQUIRED="no">
+			<DESCRIPTION>fails on a error if set to true (defaults to true)</DESCRIPTION>
+		</ATTRIBUTE>
+
+		<ATTRIBUTE NAME="warn" REQUIRED="no">
+			<DESCRIPTION>log parser warn events</DESCRIPTION>
+		</ATTRIBUTE>
+	</TASK>
+</TASKS>
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/AntDTDMessages.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/AntDTDMessages.java
new file mode 100644
index 0000000..d866975
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/AntDTDMessages.java
@@ -0,0 +1,24 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.dtd;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntDTDMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.dtd.AntDTDMessages";//$NON-NLS-1$
+
+	public static String Parser_XML_parser_does_not_support_DeclHandler_1;
+	public static String Parser_Error_parsing_XML_document_or_DTD_2;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntDTDMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/AntDTDMessages.properties b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/AntDTDMessages.properties
new file mode 100644
index 0000000..4aa9c35
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/AntDTDMessages.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# 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
+###############################################################################
+
+Parser_XML_parser_does_not_support_DeclHandler_1=XML parser does not support DeclHandler
+Parser_Error_parsing_XML_document_or_DTD_2=Error parsing XML document or DTD
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IAtom.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IAtom.java
new file mode 100644
index 0000000..f33630a
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IAtom.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd;
+
+/**
+ * Schema atom interface.
+ * @author Bob Foster
+ */
+public interface IAtom {
+
+	public static final int ELEMENT = 0;
+	public static final int ATTRIBUTE = 1;
+	
+	/**
+	 * Return the atom name.
+	 */
+	public String getName();
+	
+	/**
+	 * Return the atom name.
+	 */
+	public String toString();
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IAttribute.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IAttribute.java
new file mode 100644
index 0000000..3ff7943
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IAttribute.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd;
+
+/**
+ * Schema attribute interface.
+ * @author Bob Foster
+ */
+public interface IAttribute extends IAtom {
+
+	public static final String CDATA = "CDATA"; //$NON-NLS-1$
+	public static final String ID = "ID"; //$NON-NLS-1$
+	public static final String IDREF = "IDREF"; //$NON-NLS-1$
+	public static final String IDREFS = "IDREFS"; //$NON-NLS-1$
+	public static final String NMTOKEN = "NMTOKEN"; //$NON-NLS-1$
+	public static final String NMTOKENS = "NMTOKENS"; //$NON-NLS-1$
+	public static final String ENTITY = "ENTITY"; //$NON-NLS-1$
+	public static final String ENTITIES = "ENTITIES"; //$NON-NLS-1$
+	public static final String NOTATION = "NOTATION"; //$NON-NLS-1$
+	public static final String ENUMERATION = "enumeration"; //$NON-NLS-1$
+	
+	/**
+	 * @return the attribute type. This will be one of "CDATA", "ID", "IDREF",
+	 * "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", "NOTATION" or
+	 * "enumeration". The type is interned and may be compared to a constant
+	 * with ==. For "NOTATION" or "enumeration", <code>getEnum()</code> will
+	 * return a list of values.
+	 */
+	public String getType();
+	
+	/**
+	 * 
+	 * @return String[] or null if type is not "NOTATION" or "ENUMERATION".
+	 */
+	public String[] getEnum();
+	
+	/**
+	 * Return the element the attribute is defined in.
+	 */
+	public IElement getElement();
+	
+	/**
+	 * Return the default value or null if none.
+	 */
+	public String getDefault();
+	
+	/**
+	 * Return true if the default value is fixed.
+	 */
+	public boolean isFixed();
+	
+	/**
+	 * Return true if attribute is required, false if it is optional.
+	 */
+	public boolean isRequired();
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IDfm.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IDfm.java
new file mode 100644
index 0000000..f9923df
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IDfm.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd;
+
+/**
+ * A Dfm is an IModel converted to a form more appropriate for
+ * validation. The whole point of a Dfm is to run fast.
+ * @author Bob Foster
+ */
+public interface IDfm {
+
+	/**
+	 * Return true if no further symbols are required.
+	 */
+	boolean isAccepting();
+	
+	/**
+	 * If the symbol represented by name is acceptable,
+	 * return the dfm to apply to the next (child) symbol.
+	 * Otherwise, return null.
+	 */
+	IDfm advance(String name);
+	
+	/**
+	 * If the symbol represented by the namespace,name pair is acceptable,
+	 * return the dfm to apply to the next (child) symbol. Otherwise, return
+	 * null.
+	 */
+	IDfm advance(String namespace, String localname);
+	
+	/**
+	 * If the symbol represented by name is acceptable
+	 * to <code>advance()</code>
+	 * return the corresponding atom.
+	 * Otherwise, return null.
+	 */
+	IAtom getAtom(String name);
+	
+	/**
+	 * Return the symbols for which <code>advance()</code>
+	 * will return a next dfm. If no symbols will
+	 * advance this dfm or if any symbol will, returns
+	 * an empty array. Use <code>isAny()</code> and
+	 * <code>isEmpty()</code> to disambiguate the
+	 * cases.
+	 */
+	String[] getAccepts();
+	
+	/**
+	 * Return the symbols for which <code>advance()</code>
+	 * will return a next dfm. If no symbols will
+	 * advance this dfm or if any symbol will, returns
+	 * null. Use <code>isAny()</code> and
+	 * <code>isEmpty()</code> to disambiguate the
+	 * cases.
+	 */
+	Object[] getKeys();
+	
+	/**
+	 * Return true if dfm will accept any symbol
+	 * and return itself; false otherwise.
+	 * This interface keeps the dfm from needing
+	 * schema knowledge, but a better way to
+	 * process an ANY dfm for elements is use the 
+	 * schema to look up the element and use its 
+	 * dfm instead of this one.
+	 */
+	boolean isAny();
+	
+	/**
+	 * Return true if dfm will reject every symbol
+	 * (<code>advance()</code> returns null);
+	 * false otherwise. Included for completeness,
+	 * so every element can have a dfm, regardless
+	 * of its type.
+	 */
+	boolean isEmpty();
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IElement.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IElement.java
new file mode 100644
index 0000000..db3039f
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IElement.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *		IBM Corporation - fix for Bug 40951
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd;
+
+import java.util.Map;
+
+/**
+ * IElement interface.
+ * @author Bob Foster
+ */
+public interface IElement extends IAtom {
+
+	/**
+	 * @return true if the element has been referenced in a schema but is not
+	 * yet defined.
+	 */
+	public boolean isUndefined();
+	
+	/**
+	 * @return true if element model is <code>"(#PCDATA)"</code>.
+	 */
+	public boolean isText();
+	
+	/**
+	 * @return true if element model is EMPTY.
+	 */
+	public boolean isEmpty();
+	
+	/**
+	 * @return true if element model is ANY.
+	 */
+	public boolean isAny();
+	
+	/**
+	 * @return the element's content model. The content model will be empty
+	 * if <code>isText()</code>, <code>isAny()</code> or <code>isEmpty()</code>.
+	 * Note that the content model deals with child elements only; use
+	 * <code>isMixed()</code> to see if text is also allowed.
+	 */
+	public IModel getContentModel();
+	
+	/**
+	 * @return the DFM corresponding to the content model. Every element
+	 * has a DFM.
+	 */
+	public IDfm getDfm();
+	
+	/**
+	 * @return Map with attribute qname keys and IAttr values.
+	 * If element has no attributes, the map is empty.
+	 * Map must not be modified by caller; for performance reasons,
+	 * it is not a copy.
+	 */
+	public Map getAttributes();
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IModel.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IModel.java
new file mode 100644
index 0000000..85e5a5c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/IModel.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd;
+
+import org.eclipse.ant.internal.ui.dtd.schema.Nfm;
+
+
+/**
+ * Content model.
+ * This is the printable version of the model.
+ * The walkable version is the IDfm.
+ * @author Bob Foster
+ */
+public interface IModel {
+
+	public static final int UNKNOWN = 0;
+	public static final int SEQUENCE = 1;
+	public static final int CHOICE = 2;
+	public static final int LEAF = 4;
+	
+	public static final int UNBOUNDED = Integer.MAX_VALUE;
+	
+	/**
+	 * @return one of SEQUENCE, CHOICE, LEAF
+	 */
+	public int getKind();
+	
+	/**
+	 * @return one of 0 or 1.
+	 */
+	public int getMinOccurs();
+	
+	/**
+	 * @return one of 1 or UNBOUNDED.
+	 */
+	public int getMaxOccurs();
+	
+	/**
+	 * @return if SEQUENCE or CHOICE return array of sub-models; otherwise
+	 * undefined.
+	 */
+	public IModel[] getContents();
+	
+	/**
+	 * @return if LEAF return atom; otherwise undefined.
+	 */
+	public IAtom getLeaf();
+	
+	/**
+	 * @return if SEQUENCE or CHOICE return "," and "|", respectively; otherwise
+	 * undefined. Useful when printing model.
+	 */
+	public String getOperator();
+	
+	/**
+	 * @return one of "", "?", "*" or "+". Useful when printing model.
+	 */
+	public String getQualifier();
+	
+	/**
+	 * Convert content model to string representation.
+	 */
+	public String stringRep();
+	
+	/**
+	 * Convert the model to an Nfm on demand.
+	 * @return Nfm
+	 */
+	public Nfm toNfm();
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/ISchema.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/ISchema.java
new file mode 100644
index 0000000..49ed34d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/ISchema.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd;
+
+public interface ISchema {
+
+	/**
+	 * Find element by name.
+	 * @param qname Element name.
+	 * @return element or null if no such element.
+	 */
+	IElement getElement(String qname);
+	
+	/**
+	 * @return IElement[] of all visible elements.
+	 */
+	IElement[] getElements();
+	
+	/**
+	 * @return Exception thrown by parser when schema was built or <code>null</code> if none.
+	 * Note that the exception does not necessarily mean the schema is
+	 * incomplete.
+	 */
+	Exception getErrorException();
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/ParseError.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/ParseError.java
new file mode 100644
index 0000000..4a5759e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/ParseError.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *		IBM Corporation - serial version id
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd;
+
+/**
+ * @author Bob Foster
+ */
+public class ParseError extends Exception {
+	
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Constructor for ParseError.
+	 * @param msg Message
+	 */
+	public ParseError(String msg) {
+		super(msg);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/Parser.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/Parser.java
new file mode 100644
index 0000000..4874fe6
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/Parser.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.ant.internal.ui.dtd.schema.SchemaFactory;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.DeclHandler;
+
+
+/**
+ * Simple parser for DTDs. Returns ISchema representing the DTD.
+ * 
+ * To parse a DTD, you must parse an XML document. The <code>parseDTD()</code>
+ * method builds a temporary XML document in memory that refers to or includes
+ * the DTD.
+ * 
+ * There is no dependency in this package on any code outside the package except
+ * XMLReader.
+ * 
+ * To hide the underlying parser, XML parser exceptions are wrapped by a
+ * ParseError. Unless debugging, the two string constants are sufficient to
+ * determine the cause of the error.
+ * @author Bob Foster
+ */
+public class Parser {
+	
+	/** ParseError message when system parser doesn't do the job */
+	public static final String NOT_SUPPORTED = AntDTDMessages.Parser_XML_parser_does_not_support_DeclHandler_1;
+	/** ParseError message for a well-formed or validation error in XML or DTD.
+	 *  Currently not returned. */
+	public static final String PARSE_ERROR = AntDTDMessages.Parser_Error_parsing_XML_document_or_DTD_2;
+	
+	private static final String INTERNAL = "internal://usereader.objfac.com"; //$NON-NLS-1$
+	
+	/**
+	 * Parse the XML document at the input source and return a document walker
+	 * that can be used to validate any document with the same DTD (internal and
+	 * external) or provide user assistance for this document.
+	 * @param inputSource Source for XML document to start DTD parse. Must
+	 * contain a DOCTYPE declaration with internal or external subset, or both.
+	 * @param entityResolver EntityResolver or null.
+	 * @return schema for document.
+	 * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
+	 * @throws IOException
+	 */
+	public ISchema parse(InputSource inputSource, EntityResolver entityResolver) throws ParseError, IOException {
+		XMLReader parser = null;
+		SchemaFactory factory = new SchemaFactory();
+		try {
+			parser = getXMLReader();
+			DeclHandler handler = factory;
+			parser.setProperty("http://xml.org/sax/properties/declaration-handler", handler); //$NON-NLS-1$
+			if (entityResolver != null) {
+				parser.setEntityResolver(entityResolver);
+			}
+			parser.parse(inputSource);
+		} catch (SAXNotRecognizedException e) {
+			throw new ParseError(NOT_SUPPORTED);
+		} catch (SAXNotSupportedException e) {
+			throw new ParseError(NOT_SUPPORTED);
+		} catch (SAXException e) {
+			// Don't care about errors in XML, so just fall thru.
+			// If parse failed in DTD, may have incomplete schema,
+			// but this is better than no schema.
+			factory.setErrorException(e);
+		}
+
+		return factory.getSchema();
+	}
+	
+	private XMLReader getXMLReader() throws ParseError {
+		SAXParser parser = null;
+		try {
+			parser = SAXParserFactory.newInstance().newSAXParser();
+			return parser.getXMLReader();
+		} catch (ParserConfigurationException e) {
+			throw new ParseError(e.getMessage());
+		} catch (SAXException e) {
+			throw new ParseError(e.getMessage());
+		}
+	}
+	
+	/**
+	 * Parse the XML document at the argument URL and return a document walker
+	 * that can be used to validate any document with the same DTD (internal
+	 * and external) or provide user assistance for this document.
+	 * @param url Of XML document to start DTD parse. Must contain a DOCTYPE
+	 * declaration with internal or external subset, or both.
+	 * @return IWalker that can be used to traverse document.
+	 * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
+	 * @throws IOException
+	 */
+	public ISchema parse(String url) throws ParseError, IOException {
+		return parse(new InputSource(url), null);
+	}
+	
+	/**
+	 * Parse the XML document using the argument reader and return a document
+	 * walker that can be used to validate any document with the same DTD
+	 * (internal and external) or provide user assistance for this document.
+	 * @param reader Reader for XML document to start DTD parse. Must contain a
+	 * DOCTYPE declaration with internal or external subset, or both.
+	 * @return IWalker that can be used to traverse document.
+	 * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
+	 * @throws IOException
+	 */
+	public ISchema parse(Reader reader) throws ParseError, IOException {
+		return parse(new InputSource(reader), null);
+	}
+	
+	/**
+	 * Parse the DTD with the given public and system ids and return a document
+	 * walker that can be used to validate or provide user assistance for any
+	 * document with the same external DTD and no internal subset.
+	 * @param pub PUBLIC id of DTD.
+	 * @param sys SYSTEM id of DTD.
+	 * @param root Plausible root element qname. Any name will do but a
+	 * name that will not cause a validation error is preferred.
+	 * @return IWalker that can be used to traverse document.
+	 * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
+	 * @throws IOException
+	 */
+	public ISchema parseDTD(String pub, String sys, String root) throws ParseError, IOException {
+		return parse(new InputSource(new DTDReader(pub, sys, root)), null);
+	}
+	
+	/**
+	 * Parse the DTD from the reader and return a document walker that can be
+	 * used to validate or provide user assistance for any document with the
+	 * same external DTD and no internal subset.
+	 * @param reader Reader for external subset DTD
+	 * @param root Plausible root element qname. Any name will do but a
+	 * name that will not cause a validation error is preferred.
+	 * @return ISchema that can be used to traverse document.
+	 * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
+	 * @throws IOException
+	 */
+	public ISchema parseDTD(Reader reader, String root) throws ParseError, IOException {
+		return parse(new InputSource(new DTDReader(INTERNAL, INTERNAL, root)), new DTDEntityResolver(reader));
+	}
+	
+	private static class DTDReader extends Reader {
+		private Reader fDelegate;
+		
+		public DTDReader(String pub, String sys, String root) {
+			String document = "<!DOCTYPE "+root+" PUBLIC '"+pub+"' '"+sys+"'><"+root+"/>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+			fDelegate = new StringReader(document);
+		}
+		
+		/**
+		 * @see java.io.Reader#close()
+		 */
+		public void close() throws IOException {
+			fDelegate.close();
+		}
+
+		/* (non-Javadoc)
+		 * @see java.io.Reader#read(char[], int, int)
+		 */
+		public int read(char[] cbuf, int off, int len) throws IOException {
+			return fDelegate.read(cbuf, off, len);
+		}
+	}
+	
+	private static class DTDEntityResolver implements EntityResolver {
+		private Reader reader;
+		public DTDEntityResolver(Reader reader) {
+			this.reader = reader;
+		}
+		/**
+		 * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)
+		 */
+		public InputSource resolveEntity(String publicId, String systemId) {
+			if (publicId.equals(INTERNAL) && systemId.equals(INTERNAL))
+				return new InputSource(reader);
+			return null;
+		}
+	}	
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/AntDTDSchemaMessages.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/AntDTDSchemaMessages.java
new file mode 100644
index 0000000..b5b87f7
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/AntDTDSchemaMessages.java
@@ -0,0 +1,29 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.dtd.schema;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntDTDSchemaMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.dtd.schema.AntDTDSchemaMessages";//$NON-NLS-1$
+
+	public static String Model_model_may_not_be_changed;
+	public static String Model____UNKNOWN____2;
+	public static String NfmParser_Ambiguous;
+	public static String SchemaFactory_Doubly_defined;
+	public static String SchemaFactory_Start_with_left_parenthesis;
+	public static String SchemaFactory_Expecting_operator_or_right_parenthesis;
+	public static String SchemaFactory_Unexpected_end;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntDTDSchemaMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/AntDTDSchemaMessages.properties b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/AntDTDSchemaMessages.properties
new file mode 100644
index 0000000..d1f0d9c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/AntDTDSchemaMessages.properties
@@ -0,0 +1,18 @@
+###############################################################################
+# 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
+###############################################################################
+
+Model_model_may_not_be_changed=model may not be changed once its contents have been requested
+Model____UNKNOWN____2=<UNKNOWN>
+NfmParser_Ambiguous=Ambiguous content model starting with {0}
+SchemaFactory_Doubly_defined=Element {0} is doubly defined
+SchemaFactory_Start_with_left_parenthesis=Element {0} model does not start with left parenthesis
+SchemaFactory_Expecting_operator_or_right_parenthesis=Expecting operator or right parenthesis in element {0} model {1}
+SchemaFactory_Unexpected_end=Unexpected end of content model for element {0}: {1}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Attribute.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Attribute.java
new file mode 100644
index 0000000..9c9c029
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Attribute.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.schema;
+
+import org.eclipse.ant.internal.ui.dtd.*;
+
+/**
+ * Attr contains information about a single attribute.
+ * @author Bob Foster
+ */
+public class Attribute extends Atom implements IAttribute {
+	private String fType;
+	private String[] fEnum;
+	private IElement fElement;
+	private String fDefault;
+	private boolean fFixed;
+	private boolean fRequired;
+	
+	/**
+	 * Constructor.
+	 * @param name Attribute qname.
+	 * @param element Parent element.
+	 */
+	public Attribute(String name, IElement element) {
+		super(ATTRIBUTE, name);
+		fElement = element;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IAttribute#getType()
+	 */
+	public String getType() {
+		return fType;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IAttribute#getEnum()
+	 */
+	public String[] getEnum() {
+		return fEnum;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IAttribute#getElement()
+	 */
+	public IElement getElement() {
+		return fElement;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IAttribute#getDefault()
+	 */
+	public String getDefault() {
+		return fDefault;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IAttribute#isFixed()
+	 */
+	public boolean isFixed() {
+		return fFixed;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IAttribute#isRequired()
+	 */
+	public boolean isRequired() {
+		return fRequired;
+	}
+	
+	public void setType(String type) {
+		fType = type;
+	}
+	
+	/**
+	 * Sets the default value.
+	 * @param defaultValue Value
+	 */
+	public void setDefault(String defaultValue) {
+		fDefault = defaultValue;
+	}
+
+	/**
+	 * Sets the enumeration.
+	 * @param enumeration The enumeration to set
+	 */
+	public void setEnum(String[] enumeration) {
+		fEnum = enumeration;
+	}
+
+	/**
+	 * Sets the fixed.
+	 * @param fixed The fixed to set
+	 */
+	public void setFixed(boolean fixed) {
+		fFixed = fixed;
+	}
+
+	/**
+	 * Sets the required.
+	 * @param required The required to set
+	 */
+	public void setRequired(boolean required) {
+		fRequired = required;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Dfm.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Dfm.java
new file mode 100644
index 0000000..6eea0ff
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Dfm.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.schema;
+
+import org.eclipse.ant.internal.ui.dtd.IAtom;
+import org.eclipse.ant.internal.ui.dtd.IDfm;
+import org.eclipse.ant.internal.ui.dtd.util.Factory;
+import org.eclipse.ant.internal.ui.dtd.util.FactoryObject;
+import org.eclipse.ant.internal.ui.dtd.util.MapHolder;
+import org.eclipse.ant.internal.ui.dtd.util.SortedMap;
+
+
+/**
+ * Deterministic finite state machine.
+ * Once constructed DFM is immutable and can be used by multiple threads.
+ * A Dfm node is essentially an accepting flag and a hashtable mapping atoms to
+ * Dfm nodes. (Almost of org.eclipse.ant.internal.ui.dtd.util is aimed at reducing the storage
+ * overhead of hundreds of little hashtables.)
+ * @author Bob Foster
+ */
+public class Dfm extends MapHolder implements IDfm, FactoryObject {
+
+	public boolean accepting;
+	public boolean empty, any;
+	public int id;
+	private static int unique = 0;
+	private static Factory factory = new Factory();
+	private Dfm fNext;
+	
+	public static Dfm dfm(boolean accepting) {
+		Dfm dfm = free();
+		dfm.accepting = accepting;
+		return dfm;
+	}
+
+	protected Dfm() {
+	}
+	
+	private static Dfm free() {
+		Dfm dfm = (Dfm) factory.getFree();
+		if (dfm == null)
+			dfm = new Dfm();
+		dfm.accepting = dfm.empty = dfm.any = false;
+		dfm.id = unique++;
+		return dfm;
+	}
+
+	public static Dfm dfm(IAtom accept, Dfm follow) {
+		Dfm dfm = free();
+		dfm.keys = new Object[1];
+		dfm.keys[0] = accept;
+		dfm.values = new Object[1];
+		dfm.values[0] = follow;
+		return dfm;
+	}
+	
+	public static void free(Dfm dfm) {
+		dfm.setKeys(null);
+		dfm.setValues(null);
+		factory.setFree(dfm);
+	}
+	
+	public boolean isAccepting() {
+		return accepting;
+	}
+	
+	public IDfm advance(String name) {
+		if (any)
+			return this;
+		if (empty)
+			return null;
+		if (keys == null)
+			return null;
+		SortedMap map = getIndirectStringMap(this);
+		Dfm dfm = (Dfm) map.get(name);
+		freeMap(map);
+		return dfm;
+	}
+	
+	public String[] getAccepts() {
+		if (keys == null)
+			return new String[0];
+		String[] s = new String[keys.length];
+		for (int i = 0; i < s.length; i++) {
+			s[i] = keys[i].toString();
+		}
+		return s;
+	}
+
+	public Dfm[] getFollows() {
+		if (values == null)
+			return new Dfm[0];
+		Dfm[] s = new Dfm[values.length];
+		System.arraycopy(values,0,s,0,values.length);
+		return s;
+	}
+
+	public void merge(Dfm other) {
+		accepting |= other.accepting;
+		SortedMap map = getIndirectStringMap(this);
+		SortedMap othermap = getIndirectStringMap(other);
+		map.merge(othermap);
+		freeMap(map);
+		freeMap(othermap);
+	}
+	
+	public SortedMap getMap() {
+		return getIndirectStringMap(this);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.FactoryObject#next()
+	 */
+	public FactoryObject next() {
+		return fNext;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.FactoryObject#next(org.eclipse.ant.internal.ui.dtd.util.FactoryObject)
+	 */
+	public void next(FactoryObject obj) {
+		fNext = (Dfm) obj;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IDfm#isAny()
+	 */
+	public boolean isAny() {
+		return any;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IDfm#isEmpty()
+	 */
+	public boolean isEmpty() {
+		return empty;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IDfm#getAtom(java.lang.String)
+	 */
+	public IAtom getAtom(String name) {
+		Object[] allKeys = getKeys();
+		if (empty || allKeys == null){
+			return null;
+		}
+		SortedMap map = getIndirectStringMap(this);
+		int index = map.keyIndex(name);
+		if (index < 0) {
+			return null;
+		}
+		return (IAtom) allKeys[index];
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IDfm#advance(java.lang.String, java.lang.String)
+	 */
+	public IDfm advance(String namespace, String localname) {
+		// no namespace support here
+		return advance(localname);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Element.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Element.java
new file mode 100644
index 0000000..985bbc0
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Element.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *		IBM Corporation - fix for Bug 40951
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.schema;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.ant.internal.ui.dtd.IAttribute;
+import org.eclipse.ant.internal.ui.dtd.IDfm;
+import org.eclipse.ant.internal.ui.dtd.IElement;
+import org.eclipse.ant.internal.ui.dtd.IModel;
+import org.eclipse.ant.internal.ui.dtd.ParseError;
+
+public class Element extends Atom implements IElement {
+	private boolean fUndefined = true;
+	private boolean fText;
+	private IModel fModel;
+	private Map fMap = new HashMap(4); 
+	private Dfm fElementDfm;
+
+	/**
+	 * Constructor
+	 * @param name QName of element.
+	 */
+	public Element(String name) {
+		super(ELEMENT, name);
+	}
+
+	/**
+	 * Set undefined property.
+	 * @param undefined False if defined; otherwise true (default).
+	 */
+	public void setUndefined(boolean undefined) {
+		fUndefined = undefined;
+	}
+	
+	/**
+	 * Set text property.
+	 * @param text True if text only; otherwise false (default).
+	 */
+	public void setText(boolean text) {
+		fText = text;
+	}
+	
+	/**
+	 * Set model property.
+	 * @param model Dfm describing content model.
+	 */
+	public void setContentModel(IModel model) {
+		fModel = model;
+	}
+	
+	/**
+	 * Add an attribute to the attribute map.
+	 * @param attribute Attribute to add.
+	 */
+	public void addAttribute(IAttribute attribute) {
+		fMap.put(attribute.getName(), attribute);
+	}
+	
+	/**
+	 * @see org.eclipse.ant.internal.ui.dtd.IElement#getAttributes()
+	 */
+	public Map getAttributes() {
+		return fMap;
+	}
+
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.IElement#isMixed()
+	 */
+	public IModel getContentModel() {
+		return fModel;
+	}
+
+	/**
+	 * @see org.eclipse.ant.internal.ui.dtd.IElement#isText()
+	 */
+	public boolean isText() {
+		return fText;
+	}
+
+	/**
+	 * @see org.eclipse.ant.internal.ui.dtd.IElement#isUndefined()
+	 */
+	public boolean isUndefined() {
+		return fUndefined;
+	}
+
+	/**
+	 * @see org.eclipse.ant.internal.ui.dtd.IElement#getDfm()
+	 */
+	public IDfm getDfm() {
+		Dfm dfm = fElementDfm;
+		if (dfm == null) {
+			dfm = parseElementDfm();
+			fElementDfm = dfm;
+		}
+		return dfm;
+	}
+	
+	private Dfm parseElementDfm() {
+		Dfm dfm;
+		if (fAny) {
+			dfm = Dfm.dfm(true);
+			dfm.any = true;
+		}
+		else if (fEmpty || fText) {
+			dfm = Dfm.dfm(true);
+			dfm.empty = true;
+		}
+		else {
+			dfm = parseModel(fModel);
+		}
+		return dfm;
+	}
+	
+	private Dfm parseModel(IModel model) {
+		Dfm dfm;
+		Nfm nfm = model.toNfm();
+		if (nfm != null) {
+			try {
+				dfm = fNfmParser.parse(nfm);
+			} catch (ParseError e) {
+				//??? this would be the place to log the error
+				dfm = Dfm.dfm(false);
+			}
+		}
+		else {
+			dfm = Dfm.dfm(false);
+		}
+		return dfm;
+	}
+	
+	private static final NfmParser fNfmParser = new NfmParser();
+	private boolean fAny;
+	private boolean fEmpty;
+
+	/**
+	 * @see org.eclipse.ant.internal.ui.dtd.IElement#isAny()
+	 */
+	public boolean isAny() {
+		return fAny;
+	}
+
+	/**
+	 * @see org.eclipse.ant.internal.ui.dtd.IElement#isEmpty()
+	 */
+	public boolean isEmpty() {
+		return fEmpty;
+	}
+
+	/**
+	 * Sets the any.
+	 * @param any The any to set
+	 */
+	public void setAny(boolean any) {
+		fAny = any;
+	}
+
+	/**
+	 * Sets the empty.
+	 * @param empty The empty to set
+	 */
+	public void setEmpty(boolean empty) {
+		fEmpty = empty;
+	}
+
+}
+
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Nfm.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Nfm.java
new file mode 100644
index 0000000..cc9599c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Nfm.java
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.schema;
+
+import org.eclipse.ant.internal.ui.dtd.IAtom;
+import org.eclipse.ant.internal.ui.dtd.util.Factory;
+import org.eclipse.ant.internal.ui.dtd.util.FactoryObject;
+
+
+/**
+ * Non-deterministic finite state machine.
+ * @author Bob Foster
+ */
+public class Nfm implements FactoryObject {
+	private NfmNode start;
+	private NfmNode stop;
+	
+	public NfmNode getStart() {
+		return start;
+	}
+	
+	public NfmNode getStop() {
+		return stop;
+	}
+	
+	/**
+	 * Construct an nfm such that:
+	 * <pre>
+	 * start  stop
+	 *   |      |
+	 * +---+  +---+
+	 * | s |->|   |
+	 * +---+  +---+
+	 * </pre>
+	 * In all pictures, boxes are NfmNodes.
+	 */
+	private static Nfm nfm(IAtom s) {
+		Nfm nfm = free();
+		nfm.stop = NfmNode.nfmNode();
+		nfm.start = NfmNode.nfmNode(s, nfm.stop);
+		return nfm;
+	}
+	
+	/**
+	 * Construct an nfm that "wraps" an existing nfm x such that:
+	 * <pre>
+	 * start                            stop
+	 *   |                                |
+	 * +---+  +---------+  +---------+  +---+
+	 * |   |->| x start |  | x stop  |->|   |
+	 * +---+  +---------+  +---------+  +---+
+	 * </pre>
+	 */
+	private static Nfm nfm(Nfm x) {
+		Nfm nfm = free();
+		nfm.start = NfmNode.nfmNode(x.start);
+		nfm.stop = NfmNode.nfmNode();
+		x.stop.next1 = nfm.stop;
+		return nfm;
+	}
+	
+	private static Nfm nfm() {
+		Nfm nfm = free();
+		nfm.start = NfmNode.nfmNode();
+		nfm.stop = NfmNode.nfmNode();
+		return nfm;
+	}
+
+	public static Nfm getNfm(IAtom s) {
+		return nfm(s);
+	}
+	
+	/**
+	 * "Star" an existing nfm x.
+	 * <pre>
+	 * start                            stop
+	 *   |                                |
+	 * +---+  +---------+  +---------+  +---+
+	 * |   |->| x start |  | x stop  |->|   |
+	 * +---+  +---------+  +---------+  +---+
+	 *   |         |            |         |
+	 *   |         +-----<------+         |
+	 *   +------>-------------------------+
+	 * </pre>
+	 * Frees x.
+	 */
+	public static Nfm getStar(Nfm x) {
+		// Make the back link
+		x.stop.next2 = x.start;
+		Nfm tmp = nfm(x);
+		// Make the forward link
+		tmp.start.next2 = tmp.stop;
+		free(x);
+		return tmp;
+	}
+	
+	/**
+	 * "Question" an existing nfm x: x => x?
+	 * <pre>
+	 * start                            stop
+	 *   |                                |
+	 * +---+  +---------+  +---------+  +---+
+	 * |   |->| x start |  | x stop  |->|   |
+	 * +---+  +---------+  +---------+  +---+
+	 *   |                                |
+	 *   +---------------->---------------+
+	 * </pre>
+	 * Frees x.
+	 */
+	public static Nfm getQuestion(Nfm x) {
+		Nfm tmp = nfm(x);
+		// Make the forward link
+		tmp.start.next2 = tmp.stop;
+		free(x);
+		return tmp;
+	}
+
+	/**
+	 * "Plus" an existing nfm x -> x+
+	 * <pre>
+	 * start                            stop
+	 *   |                                |
+	 * +---+  +---------+  +---------+  +---+
+	 * |   |->| x start |  | x stop  |->|   |
+	 * +---+  +---------+  +---------+  +---+
+	 *             |            |
+	 *             +-----<------+
+	 * </pre>
+	 * Frees x.
+	 */
+	public static Nfm getPlus(Nfm x) {
+		// Make the back link
+		x.stop.next2 = x.start;
+		Nfm tmp = nfm(x);
+		free(x);
+		return tmp;
+	}
+	
+	/**
+	 * "Or" two existing nfms x,y -> x|y
+	 * <pre>
+	 * start                            stop
+	 *   |                                |
+	 * +---+  +---------+  +---------+  +---+
+	 * |   |->| x start |  | x stop  |->|   |
+	 * +---+  +---------+  +---------+  +---+
+	 *   |                                |
+	 *   |    +---------+  +---------+    |
+	 *   +--->| y start |  | y stop  |-->-+
+	 *        +---------+  +---------+
+	 * </pre>
+	 * Frees x and y.
+	 */
+	public static Nfm getOr(Nfm x, Nfm y) {
+		Nfm tmp = nfm();
+		tmp.start.next1 = x.start;
+		tmp.start.next2 = y.start;
+		x.stop.next1 = tmp.stop;
+		y.stop.next1 = tmp.stop;
+		free(x);
+		free(y);
+		return tmp;
+	}
+	
+	/**
+	 * "Comma" two existing nfms x,y -> x,y
+	 * 
+	 * <p>Re-uses x so that x.stop is first
+	 * transformed to y.start and then
+	 * x.stop is reset to y.stop.
+	 * This is as efficient as possible.
+	 * <pre>
+	 * x start      former x stop   x stop
+	 *     |               |           |
+	 * +---------+  +----------+  +--------+
+	 * | x start |  | y start  |->| y stop |
+	 * +---------+  +----------+  +--------+
+	 * </pre>
+	 * Frees y, returns x modified.
+	 */
+	public static Nfm getComma(Nfm x, Nfm y) {
+		x.stop.next1 = y.start.next1;
+		x.stop.next2 = y.start.next2;
+		x.stop.symbol = y.start.symbol;
+		x.stop = y.stop;
+		free(y);
+		return x;
+	}
+	
+	/**
+	 * "{min,*}" an existing nfm x -> x[0],x[1],...,x[min-1],x[min]*
+	 * Frees x.
+	 */
+	public static Nfm getUnbounded(Nfm x, int min) {
+		if (min == 0)
+			return getStar(x);
+		if (min == 1)
+			return getPlus(x);
+		Nfm last1 = nfm(x), last2 = nfm(x);
+		for (int i = 2; i < min; i++) {
+			last1 = getComma(last1, last2);
+			free(last2);
+			last2 = nfm(x);
+		}
+		free(x);
+		return getComma(last1, getStar(last2));
+	}
+	
+	/**
+	 * "{min,max}" an existing nfm x -> x[0],x[1],...,x[min-1],x[min]?,...,x[max-1]?
+	 * Frees or returns x.
+	 */
+	public static Nfm getMinMax(Nfm x, int min, int max) {
+		if (max == Integer.MAX_VALUE)
+			return getUnbounded(x, min);
+		if (max == 0) {
+			free(x);
+			return nfm((IAtom)null);
+		}
+		if (max == 1) {
+			if (min == 0)
+				return getQuestion(x);
+			return x;
+		}
+		Nfm last = null;
+		int i = 0;
+		for (; i < min; i++) {
+			if (last == null)
+				last = nfm(x);
+			else {
+				Nfm tmp = nfm(x);
+				last = getComma(last, tmp);
+				free(tmp);
+			}
+		}
+		for (; i < max; i++) {
+			if (last == null)
+				last = getQuestion(x);
+			else {
+				Nfm tmp = getQuestion(x);
+				last = getComma(last, tmp);
+				free(tmp);
+				//??? this is inefficient since the first failure
+				//    in a sequence of x?,x?,...,x? can skip to
+				//    the end rather than keep trying to match x
+			}
+		}
+		free(x);
+		return last;
+	}
+	
+	// Below here is factory stuff
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.FactoryObject#next()
+	 */
+	public FactoryObject next() {
+		return fNext;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.FactoryObject#next(org.eclipse.ant.internal.ui.dtd.util.FactoryObject)
+	 */
+	public void next(FactoryObject obj) {
+		fNext = (Nfm) obj;
+	}
+	private Nfm fNext;
+	private static Factory fFactory = new Factory();
+	private static Nfm free() {
+		Nfm nfm = (Nfm) fFactory.getFree();
+		if (nfm == null)
+			return new Nfm();
+		return nfm;
+	}
+	public static void free(Nfm nfm) {
+		nfm.start = nfm.stop = null;
+		fFactory.setFree(nfm);
+	}
+	private Nfm() {
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/NfmNode.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/NfmNode.java
new file mode 100644
index 0000000..e9d0189
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/NfmNode.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.schema;
+
+import org.eclipse.ant.internal.ui.dtd.IAtom;
+import org.eclipse.ant.internal.ui.dtd.util.Factory;
+import org.eclipse.ant.internal.ui.dtd.util.FactoryObject;
+
+/**
+ * Non-deterministic finite state machine node.<p>
+ * 
+ * Following Aho & Ullman, nfm nodes contain two
+ * transition links. The graph is constructed so
+ * that no node requires more than two links.
+ * There are exactly these kinds of nodes:
+ * <pre>
+ *		Symbol	Next1	Next2	Meaning
+ *		  "a"	 fwd	 null	Regexp "a"
+ *		  null	 null	 null	Accepting node
+ *		  null	 fwd1	 fwd2	Start node of ? and * regexp
+ *								fwd2 points to stop node
+ *		  null	 fwd	 bkw	Internal node of + and * regexp
+ *								fwd points to stop node
+ *								bkw points, e.g., in "a*" to start node of "a"
+ *		  null	 fwd1	 fwd2	Start node of | regexp, e.g., "a|b",
+ *								fwd nodes point to start nodes of "a" and "b".
+ *		  null	 fwd	 null	Internal node of |.
+ *								fwd points to stop node.
+ * </pre>
+ * See Nfm for pictures of how nodes are used.
+ * @author Bob Foster
+ */
+public class NfmNode implements FactoryObject {
+
+	public IAtom symbol;
+	public NfmNode next1;
+	public NfmNode next2;
+	public Dfm dfm;
+	public int mark;
+	
+	private NfmNode() {
+	}
+	
+	public static NfmNode nfmNode(IAtom symbol, NfmNode next) {
+		NfmNode nfm = getFree();
+		nfm.symbol = symbol;
+		nfm.next1 = next;
+		return nfm;
+	}
+	
+	public static NfmNode nfmNode(NfmNode next) {
+		NfmNode nfm = getFree();
+		nfm.next1 = next;
+		return nfm;
+	}
+	
+	public static NfmNode nfmNode() {
+		return getFree();
+	}
+	
+	/**
+	 * Free all NfmNodes in use.
+	 */
+	public static void freeAll() {
+		while (fUsed != null) {
+			FactoryObject nfm = fUsed;
+			fUsed = nfm.next();
+			setFree((NfmNode)nfm);
+		}
+	}
+	
+	// Below here is factory stuff
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.FactoryObject#next()
+	 */
+	public FactoryObject next() {
+		return next;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.FactoryObject#next(org.eclipse.ant.internal.ui.dtd.util.FactoryObject)
+	 */
+	public void next(FactoryObject obj) {
+		next = (NfmNode) obj;
+	}
+	private NfmNode next;
+	private static Factory fFactory = new Factory();
+	private static FactoryObject fUsed = null;
+	private static NfmNode getFree() {
+		NfmNode nfm = (NfmNode) fFactory.getFree();
+		if (nfm == null)
+			nfm = new NfmNode();
+		nfm.next(fUsed);
+		fUsed = nfm;
+		return nfm;
+	}
+	private static void setFree(NfmNode nfm) {
+		nfm.symbol = null;
+		nfm.next1 = nfm.next2 = null;
+		nfm.dfm = null;
+		nfm.mark = 0;
+		fFactory.setFree(nfm);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Schema.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Schema.java
new file mode 100644
index 0000000..bf30296
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/schema/Schema.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.schema;
+
+import java.util.HashMap;
+
+import org.eclipse.ant.internal.ui.dtd.IElement;
+import org.eclipse.ant.internal.ui.dtd.ISchema;
+
+/**
+ * This is a very simple schema suitable for DTDs.
+ * Once constructed, a schema is immutable and could be
+ * used by multiple threads. However, since in general
+ * the schema will reflect the internal DTD subset,
+ * re-use for multiple documents is problematic.
+ * @author Bob Foster
+ */
+public class Schema implements ISchema {
+	private HashMap fElementMap = new HashMap();
+	private Exception fErrorException;
+	/**
+	 * @see org.eclipse.ant.internal.ui.dtd.ISchema#getElement(java.lang.String)
+	 */
+	public IElement getElement(String qname) {
+		return (IElement) fElementMap.get(qname);
+	}
+
+	/**
+	 * @see org.eclipse.ant.internal.ui.dtd.ISchema#getElements()
+	 */
+	public IElement[] getElements() {
+		return (IElement[]) fElementMap.entrySet().toArray(new IElement[fElementMap.entrySet().size()]);
+	}
+	
+	/**
+	 * Add a visible element to the schema.
+	 * @param element Element to add.
+	 */
+	public void addElement(IElement element) {
+		fElementMap.put(element.getName(), element);
+	}
+	
+	/**
+	 * Sets the exception thrown by then parser when the schema was built.
+	 * Note that the exception does not necessarily mean the schema is incomplete.
+	 * 
+	 * @param e the Exception
+	 */
+	public void setErrorException(Exception e) {
+		fErrorException = e;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.ISchema#getErrorException()
+	 */
+	public Exception getErrorException() {
+		return fErrorException;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/AntDTDUtilMessages.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/AntDTDUtilMessages.java
new file mode 100644
index 0000000..3be9719
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/AntDTDUtilMessages.java
@@ -0,0 +1,24 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.dtd.util;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntDTDUtilMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.dtd.util.AntDTDUtilMessages";//$NON-NLS-1$
+
+	public static String SortedMap_next___called_for_empty_array_1;
+	public static String SortedMap_remove__0___in_empty_map_2;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntDTDUtilMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/AntDTDUtilMessages.properties b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/AntDTDUtilMessages.properties
new file mode 100644
index 0000000..1c651cf
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/AntDTDUtilMessages.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# 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
+###############################################################################
+
+SortedMap_next___called_for_empty_array_1=next() called for empty array
+SortedMap_remove__0___in_empty_map_2=remove({0}) in empty map
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/Factory.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/Factory.java
new file mode 100644
index 0000000..a6113a6
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/Factory.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.util;
+
+import java.lang.ref.SoftReference;
+
+/**
+ * Factory maintains a free list and, with FactoryObject,
+ * serves as a basis for factories of all types.
+ * Factory should only be subclassed in singleton classes;
+ * for static factories, it may be instantiated as
+ * a static object.
+ * @author Bob Foster
+ */
+public class Factory {
+	
+	/**
+	 * Return the first object on the free list
+	 * or null if none.
+	 */
+	public FactoryObject getFree() {
+		Head head = getHead();
+		FactoryObject obj = head.next;
+		if (obj != null) {
+			head.next = obj.next();
+			obj.next(null);
+		}
+		return obj;
+	}
+	
+	/**
+	 * Add an object to the free list.
+	 */
+	public void setFree(FactoryObject obj) {
+		Head head = getHead();
+		obj.next(head.next);
+		head.next = obj;
+	}
+	
+	private Head getHead() {
+		Head head = (Head) free.get();
+		if (head == null) {
+			// head is needed because you can't change
+			// the referent of a SoftReference.
+			// Without head, we would need to create
+			// a new SoftReference each time we remove
+			// a map from the list. With head, getting
+			// a free object only causes memory allocation
+			// when the list has been previously collected.
+			head = new Head();
+			free = new SoftReference(head);
+		}
+		return head;
+	}
+
+	private static class Head {
+		public FactoryObject next;
+	}
+	private SoftReference free = new SoftReference(new Head());
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/FactoryObject.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/FactoryObject.java
new file mode 100644
index 0000000..6799426
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/FactoryObject.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.util;
+
+/**
+ * A FactoryObject must implement a simple linked list.
+ * @author Bob Foster
+ */
+public interface FactoryObject {
+
+	FactoryObject next();
+	
+	void next(FactoryObject obj);
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/IKeyHolder.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/IKeyHolder.java
new file mode 100644
index 0000000..a214e89
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/IKeyHolder.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.util;
+
+/**
+ * @author Bob Foster
+ */
+public interface IKeyHolder {
+
+	Object[] getKeys();
+	
+	void setKeys(Object[] keys);
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/IMapHolder.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/IMapHolder.java
new file mode 100644
index 0000000..46ab094
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/IMapHolder.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.util;
+
+/**
+ * @author Bob Foster
+ */
+public interface IMapHolder extends IKeyHolder, IValueHolder {
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/IValueHolder.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/IValueHolder.java
new file mode 100644
index 0000000..95f0b26
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/IValueHolder.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.util;
+
+/**
+ * @author Bob Foster
+ */
+public interface IValueHolder {
+
+	Object[] getValues();
+	
+	void setValues(Object[] values);
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/MapHolder.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/MapHolder.java
new file mode 100644
index 0000000..7f86223
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/MapHolder.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.util;
+
+/**
+ * @author Bob Foster
+ */
+public class MapHolder extends SortedMapFactory implements IMapHolder {
+
+	public Object[] keys;
+	public Object[] values;
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.IKeyHolder#getKeys()
+	 */
+	public Object[] getKeys() {
+		return keys;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.IKeyHolder#setKeys(java.lang.Object[])
+	 */
+	public void setKeys(Object[] keys) {
+		this.keys = keys;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.IValueHolder#getValues()
+	 */
+	public Object[] getValues() {
+		return values;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.dtd.util.IValueHolder#setValues(java.lang.Object[])
+	 */
+	public void setValues(Object[] values) {
+		this.values = values;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/SortedMapFactory.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/SortedMapFactory.java
new file mode 100644
index 0000000..e372e97
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/SortedMapFactory.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2006 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *      IBM Corporation - fix for Bug 110636
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.util;
+
+import java.util.Comparator;
+
+/**
+ * Can be inherited or used statically.
+ * @author Bob Foster
+ */
+public class SortedMapFactory {
+
+	private static class IndirectStringComparator implements Comparator {
+		/**
+		 * @see java.util.Comparator#compare(Object, Object)
+		 */
+		public int compare(Object o1, Object o2) {
+			return o1.toString().compareTo(o2.toString());
+		}
+	}
+    
+	private static final IndirectStringComparator fIndirectStringComp = new IndirectStringComparator();
+	private static final Factory fFactory = new Factory();
+
+	public static SortedMap getMap(IMapHolder holder, Comparator comp) {
+		SortedMap map = (SortedMap) fFactory.getFree();
+		if (map == null)
+			map = new SortedMap();
+		map.setMapHolder(holder);
+		map.setComparator(comp);
+		return map;
+	}
+	
+	public static SortedMap getIndirectStringMap(IMapHolder holder) {
+		return getMap(holder, fIndirectStringComp);
+	}
+	
+	public static void freeMap(SortedMap map) {
+		map.setComparator(null);
+		map.setMapHolder(null);
+		fFactory.setFree(map);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/SortedSet.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/SortedSet.java
new file mode 100644
index 0000000..1007fdc
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/dtd/util/SortedSet.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 Object Factory Inc.
+ * 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:
+ *		Object Factory Inc. - Initial implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.dtd.util;
+
+import java.util.Comparator;
+
+/**
+ * SortedSet is a flyweight set implementation that uses
+ * an external array provided by a KeyHolder.
+ * SortedSet provides both equality/comparison operations
+ * and identity operations.
+ * @author Bob Foster
+ */
+public class SortedSet {
+	protected Comparator fComp;
+	protected IKeyHolder fKeyHolder;
+	protected SortedSet fNext;
+	
+	public SortedSet(IKeyHolder holder, Comparator comp) {
+		fComp = comp;
+		fKeyHolder = holder;
+	}
+	/**
+	 * Constructor. A keyholder must be
+	 * supplied by <code>setKeyHolder()</code> prior ot
+	 * <i>any</i> operations.
+	 */
+	public SortedSet(Comparator comp) {
+		fComp = comp;
+	}
+	/**
+	 * Constructor, no comparator. Only identity operations
+	 * may be performed in this set.
+	 */
+	public SortedSet(IKeyHolder holder) {
+		fKeyHolder = holder;
+	}
+	/**
+	 * Constructor, no comparator. Only identity operations
+	 * may be performed in this set. A keyholder must be
+	 * supplied by <code>setKeyHolder()</code> prior ot
+	 * <i>any</i> operations.
+	 */
+	public SortedSet() {
+	}
+	public void setKeyHolder(IKeyHolder holder) {
+		fKeyHolder = holder;
+	}
+	public void setComparator(Comparator comp) {
+		fComp = comp;
+	}
+	/**
+	 * Add to set (no duplicates allowed).
+	 * @param obj Object to add
+	 * @return true if object was added; false
+	 * if object was already in the set.
+	 */
+	public boolean add(Object obj) {
+		return internalAdd(obj, false) >= 0;
+	}
+	protected int internalAdd(Object obj, boolean always) {
+		Object[] array = fKeyHolder.getKeys();
+		if (array == null) {
+			array = new Object[1];
+			fKeyHolder.setKeys(array);
+			array[0] = obj;
+			return 0;
+		}
+		int i = 0;
+		int comp = -1;
+		
+		for (; i < array.length; i++) {
+			if ((comp = fComp.compare(obj, array[i])) <= 0) {
+				break;
+			}
+		}
+		if (comp == 0 && !always)
+			return -1;
+		internalAdd(i, obj);
+		return i;
+	}
+	protected void internalAdd(int i, Object obj) {
+		Object[] array = fKeyHolder.getKeys();
+		if (array == null) {
+			array = new Object[1];
+			array[0] = obj;
+			fKeyHolder.setKeys(array);
+		}
+		else {
+			Object[] tmp = new Object[array.length+1];
+			System.arraycopy(array,0,tmp,0,i);
+			tmp[i] = obj;
+			System.arraycopy(array,i,tmp,i+1,array.length-i);
+			fKeyHolder.setKeys(tmp);
+		}
+	}
+	/**
+	 * Add allowing duplicates.
+	 * @param obj Object to add
+	 * @return index where object was added in sorted order.
+	 */
+	public int addAlways(Object obj) {
+		return internalAdd(obj, true);
+	}
+	/**
+	 * Append, a variant of add allowing duplicates that
+	 * always puts the new member at the end of the set.
+	 * Set can be used with identity operations only.
+	 */
+	public void append(Object obj) {
+		Object[] array = fKeyHolder.getKeys();
+		int len = array != null ? array.length : 0;
+		internalAdd(len, obj);
+	}
+	public boolean contains(Object obj) {
+		return indexOf(obj) >= 0;
+	}
+	public int indexOf(Object obj) {
+		Object[] array = fKeyHolder.getKeys();
+		if (array == null)
+			return -1;
+		for (int i = 0; i < array.length; i++) {
+			int comp = fComp.compare(obj, array[i]);
+			if (comp == 0)
+				return i;
+			if (comp < 0)
+				return -1;
+		}
+		return -1;
+	}
+	public boolean containsIdentity(Object obj) {
+		return indexOf(obj) >= 0;
+	}
+	public int indexOfIdentity(Object obj) {
+		Object[] array = fKeyHolder.getKeys();
+		if (array == null)
+			return -1;
+		for (int i = 0; i < array.length; i++) {
+			if (obj == array[i])
+				return i;
+		}
+		return -1;
+	}
+	public boolean equals(Object o) {
+		if (this == o)
+			return true;
+		if (!(o instanceof SortedSet))
+			return false;
+		SortedSet other = (SortedSet) o;
+		Object[] array = fKeyHolder.getKeys();
+		Object[] otherarray = other.fKeyHolder.getKeys();
+		if ((array == null) != (otherarray == null))
+			return false;
+		if (array == null)
+			return true;
+		if (array.length != otherarray.length)
+			return false;
+		for (int i = 0; i < array.length; i++) {
+			if (array[i] != otherarray[i])
+				return false;
+		}
+		return true;
+	}
+	public boolean equalsIdentify(Object o) {
+		if (this == o)
+			return true;
+		if (!(o instanceof SortedSet))
+			return false;
+		SortedSet other = (SortedSet) o;
+		Object[] array = fKeyHolder.getKeys();
+		Object[] otherarray = other.fKeyHolder.getKeys();
+		if ((array == null) != (otherarray == null))
+			return false;
+		if (array == null)
+			return true;
+		if (array.length != otherarray.length)
+			return false;
+		for (int i = 0; i < array.length; i++) {
+			if (fComp.compare(array[i], otherarray[i]) != 0)
+				return false;
+		}
+		return true;
+	}
+	public void merge(SortedSet other) {
+		Object[] array = fKeyHolder.getKeys();
+		Object[] otherarray = other.fKeyHolder.getKeys();
+		if (otherarray == null)
+			return;
+		if (array == null) {
+			array = otherarray;
+			return;
+		}
+		int ithis = 0, iother = 0, i = 0;
+		int mthis = array.length, mother = otherarray.length;
+		Object[] tmp = new Object[mthis+mother];
+		while (ithis < mthis && iother < mother) {
+			int comp = fComp.compare(array[ithis], otherarray[iother]);
+			if (comp <= 0) {
+				tmp[i++] = array[ithis++];
+			}
+			else {
+				tmp[i++] = otherarray[iother++];
+			}
+		}
+		while (ithis < mthis) {
+			tmp[i++] = array[ithis++];
+		}
+		while (iother < mother) {
+			tmp[i++] = otherarray[iother++];
+		}
+	}
+	public Object[] members() {
+		Object[] array = fKeyHolder.getKeys();
+		if (array == null)
+			return new Object[0];
+		return array;
+	}
+	public int size() {
+		Object[] array = fKeyHolder.getKeys();
+		return array == null ? 0 : array.length;
+	}
+	public void remove(int i) {
+		Object[] array = fKeyHolder.getKeys();
+		Object[] tmp = new Object[array.length-1];
+		System.arraycopy(array,0,tmp,0,i);
+		System.arraycopy(array,i+1,tmp,i,array.length-i-1);
+		fKeyHolder.setKeys(tmp);
+	}
+	public boolean remove(Object obj) {
+		int i = indexOf(obj);
+		if (i >= 0) {
+			remove(i);
+			return true;
+		}
+		return false;
+	}
+	public boolean removeIdentity(Object obj) {
+		int i = indexOfIdentity(obj);
+		if (i >= 0) {
+			remove(i);
+			return true;
+		}
+		return false;
+	}
+	public SortedSet getNextSet() {
+		return fNext;
+	}
+	public void setNextSet(SortedSet next) {
+		fNext = next;
+	}
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntAutoEditStrategy.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntAutoEditStrategy.java
new file mode 100644
index 0000000..3c997e4
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntAutoEditStrategy.java
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+ 
+package org.eclipse.ant.internal.ui.editor;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.editor.formatter.XmlDocumentFormatter;
+import org.eclipse.ant.internal.ui.model.AntElementNode;
+import org.eclipse.ant.internal.ui.model.AntModel;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+
+/**
+ * Auto edit strategy for Ant build files
+ * Current does special indenting.
+ */
+public class AntAutoEditStrategy extends DefaultIndentLineAutoEditStrategy {
+	
+	private AntModel fModel;
+	private int fAccumulatedChange= 0;
+	
+	public AntAutoEditStrategy(AntModel model) {
+		fModel= model;
+	}
+	
+	/**
+	 * Sets the indentation based on the Ant element node that contains the offset
+	 * of the document command.
+	 *
+	 * @param d the document to work on
+	 * @param c the command to deal with
+	 */
+	private synchronized void autoIndentAfterNewLine(IDocument d, DocumentCommand c) {
+		
+		if (c.offset == -1 || d.getLength() == 0 || fModel.getProjectNode(false) == null) {
+			return;
+		}
+		
+		int position= (c.offset == d.getLength() ? c.offset  - 1 : c.offset);
+		AntElementNode node= fModel.getProjectNode(false).getNode(position - fAccumulatedChange);
+		if (node == null) {
+			return;
+		}
+		
+		try {
+			StringBuffer correct= XmlDocumentFormatter.getLeadingWhitespace(node.getOffset(), d);
+			if (!nextNodeIsEndTag(c.offset, d)) {
+				correct.append(XmlDocumentFormatter.createIndent());
+			}
+			StringBuffer buf= new StringBuffer(c.text);
+			buf.append(correct);
+			fAccumulatedChange+= buf.length();
+			
+			int line= d.getLineOfOffset(position);
+			IRegion reg= d.getLineInformation(line);
+			int lineEnd= reg.getOffset() + reg.getLength();
+			int contentStart= findEndOfWhiteSpace(d, c.offset, lineEnd);
+			
+			c.length=  Math.max(contentStart - c.offset, 0);
+			c.caretOffset= c.offset + buf.length();
+			c.shiftsCaret= false;
+			c.text= buf.toString();
+	
+		} catch (BadLocationException e) {
+			AntUIPlugin.log(e);
+		}
+	}
+	
+	private boolean nextNodeIsEndTag(int offset, IDocument document) {
+		if (offset + 1 > document.getLength()) {
+			return false;
+		}
+		try {
+			IRegion lineRegion= document.getLineInformationOfOffset(offset);
+			offset= findEndOfWhiteSpace(document, offset, lineRegion.getOffset() + lineRegion.getLength());
+			String nextChars= document.get(offset, 2).trim();
+			if ("</".equals(nextChars) || "/>".equals(nextChars)) { //$NON-NLS-1$ //$NON-NLS-2$
+				return true;
+			}
+		} catch (BadLocationException e) {
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand)
+	 */
+	public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
+		
+		if (c.length == 0 && c.text != null && isLineDelimiter(d, c.text)) {
+			autoIndentAfterNewLine(d, c);
+		} else if (c.text.length() > 1) {
+			smartPaste(d, c);
+		}
+	}
+	
+	 private boolean isLineDelimiter(IDocument document, String text) {
+		String[] delimiters= document.getLegalLineDelimiters();
+		if (delimiters != null)
+			return TextUtilities.equals(delimiters, text) > -1;
+		return false;
+	}
+	
+	public synchronized void reconciled() {
+		fAccumulatedChange= 0;
+	}
+	
+	private void smartPaste(IDocument document, DocumentCommand command) {
+		try {
+			if (command.offset == -1 || document.getLength() == 0 || fModel.getProjectNode(false) == null) {
+				return;
+			}
+			String origChange= command.text;
+			int position= (command.offset == document.getLength() ? command.offset  - 1 : command.offset);
+			AntElementNode node= fModel.getProjectNode(false).getNode(position - fAccumulatedChange);
+			if (node == null) {
+				return;
+			}
+			
+			// eat any WS before the insertion to the beginning of the line
+			int firstLine= 1; // don't format the first line if it has other content before it
+			IRegion line= document.getLineInformationOfOffset(command.offset);
+			String notSelected= document.get(line.getOffset(), command.offset - line.getOffset());
+			if (notSelected.trim().length() == 0) {
+				command.length += notSelected.length();
+				command.offset= line.getOffset();
+				firstLine= 0;
+			}
+			
+			// handle the indentation computation inside a temporary document
+			Document temp= new Document(command.text);
+			
+			// indent the first and second line
+			// compute the relative indentation difference from the second line
+			// (as the first might be partially selected) and use the value to
+			// indent all other lines.
+			boolean isIndentDetected= false;
+			StringBuffer addition= new StringBuffer();
+			int insertLength= 0;
+			int lines= temp.getNumberOfLines();
+			for (int l= firstLine; l < lines; l++) { // we don't change the number of lines while adding indents
+				
+				IRegion r= temp.getLineInformation(l);
+				int lineOffset= r.getOffset();
+				int lineLength= r.getLength();
+				
+				if (lineLength == 0) { // don't modify empty lines
+					continue;
+				}
+				
+				if (!isIndentDetected){
+					
+					// indent the first pasted line
+					StringBuffer current= XmlDocumentFormatter.getLeadingWhitespace(lineOffset, temp);
+					StringBuffer correct= XmlDocumentFormatter.getLeadingWhitespace(node.getOffset(), document);
+					correct.append(XmlDocumentFormatter.createIndent());
+					
+					insertLength= subtractIndent(correct, current, addition);
+					isIndentDetected= true;
+				}
+				
+				// relatively indent all pasted lines 
+				if (insertLength > 0) {
+					addIndent(temp, l, addition);
+				} else if (insertLength < 0) {
+					cutIndent(temp, l, -insertLength);
+				}	
+			}
+			
+			// modify the command
+			if (!origChange.equals(temp.get())) {
+				fAccumulatedChange+=  temp.getLength();
+				command.text= temp.get();
+			}
+			
+		} catch (BadLocationException e) {
+			AntUIPlugin.log(e);
+		}
+	}
+	
+	/**
+	 * Indents line <code>line</code> in <code>document</code> with <code>indent</code>.
+	 * Leaves leading comment signs alone.
+	 * 
+	 * @param document the document
+	 * @param line the line
+	 * @param indent the indentation to insert
+	 * @throws BadLocationException on concurrent document modification
+	 */
+	private void addIndent(Document document, int line, CharSequence indent) throws BadLocationException {
+		IRegion region= document.getLineInformation(line);
+		int insert= region.getOffset();
+		
+		// insert indent
+		document.replace(insert, 0, indent.toString());
+	}
+	
+	/**
+	 * Cuts the visual equivalent of <code>toDelete</code> characters out of the
+	 * indentation of line <code>line</code> in <code>document</code>.
+	 * 
+	 * @param document the document
+	 * @param line the line
+	 * @param toDelete the number of space equivalents to delete.
+	 * @throws BadLocationException on concurrent document modification
+	 */
+	private void cutIndent(Document document, int line, int toDelete) throws BadLocationException {
+		IRegion region= document.getLineInformation(line);
+		int from= region.getOffset();
+		int endOffset= region.getOffset() + region.getLength();
+		
+		int to= from;
+		while (toDelete > 0 && to < endOffset) {
+			char ch= document.getChar(to);
+			if (!Character.isWhitespace(ch))
+				break;
+			toDelete -= computeVisualLength(ch);
+			if (toDelete >= 0) {
+				to++;
+			} else {
+				break;
+			}
+		}
+		
+		document.replace(from, to - from, null);
+	}
+	
+	/**
+	 * Returns the visual length of a given character taking into
+	 * account the visual tabulator length.
+	 * 
+	 * @param ch the character to measure
+	 * @return the visual length of <code>ch</code>
+	 */
+	private int computeVisualLength(char ch) {
+		if (ch == '\t') {
+			return getVisualTabLengthPreference();
+		} 
+			
+		return 1;
+	}
+	
+	/**
+	 * Returns the visual length of a given <code>CharSequence</code> taking into
+	 * account the visual tabulator length.
+	 * 
+	 * @param seq the string to measure
+	 * @return the visual length of <code>seq</code>
+	 */
+	private int computeVisualLength(CharSequence seq) {
+		int size= 0;
+		int tablen= getVisualTabLengthPreference();
+		
+		for (int i= 0; i < seq.length(); i++) {
+			char ch= seq.charAt(i);
+			if (ch == '\t') {
+				size += tablen - size % tablen;
+			} else {
+				size++;
+			}
+		}
+		return size;
+	}
+	
+	/**
+	 * Computes the difference of two indentations and returns the difference in
+	 * length of current and correct. If the return value is positive, <code>addition</code>
+	 * is initialized with a substring of that length of <code>correct</code>.
+	 * 
+	 * @param correct the correct indentation
+	 * @param current the current indentation (might contain non-whitespace)
+	 * @param difference a string buffer - if the return value is positive, it will be cleared and set to the substring of <code>current</code> of that length
+	 * @return the difference in length of <code>correct</code> and <code>current</code> 
+	 */
+	private int subtractIndent(CharSequence correct, CharSequence current, StringBuffer difference) {
+		int c1= computeVisualLength(correct);
+		int c2= computeVisualLength(current);
+		int diff= c1 - c2;
+		if (diff <= 0) {
+			return diff;
+		}
+		
+		difference.setLength(0);
+		int len= 0, i= 0;
+		while (len < diff) {
+			char c= correct.charAt(i++);
+			difference.append(c);
+			len += computeVisualLength(c);
+		}
+		
+		return diff;
+	}
+	
+	/**
+	 * The preference setting for the visual tabulator display.
+	 *  
+	 * @return the number of spaces displayed for a tabulator in the editor
+	 */
+	private int getVisualTabLengthPreference() {
+		return AntUIPlugin.getDefault().getCombinedPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorActionContributor.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorActionContributor.java
new file mode 100644
index 0000000..731ad88
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorActionContributor.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2008 GEBIT Gesellschaft fuer EDV-Beratung
+ * und Informatik-Technologien mbH,
+ * Berlin, Duesseldorf, Frankfurt (Germany) 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:
+ *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
+ * 	   IBM Corporation - bug fixes
+ *     John-Mason P. Shackelford - bug 40255
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.ant.internal.ui.editor.actions.FoldingActionGroup;
+import org.eclipse.ant.internal.ui.editor.actions.OpenDeclarationAction;
+import org.eclipse.ant.internal.ui.editor.actions.OpenExternalDocAction;
+import org.eclipse.ant.internal.ui.editor.actions.ToggleAutoReconcileAction;
+import org.eclipse.ant.internal.ui.editor.actions.ToggleMarkOccurrencesAction;
+import org.eclipse.ant.internal.ui.editor.actions.TogglePresentationAction;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.Separator;
+
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.RetargetTextEditorAction;
+
+import org.eclipse.ui.editors.text.TextEditorActionContributor;
+
+import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
+
+/**
+ * Contributes interesting Ant Editor actions to the desktop's Edit menu and the toolbar.
+ * 
+ */
+public class AntEditorActionContributor extends TextEditorActionContributor {
+
+	private final static String TOGGLE_MARK_OCCURRENCES_ID= "org.eclipse.ant.ui.toggleMarkOccurrences"; //$NON-NLS-1$
+	protected RetargetTextEditorAction fContentAssistProposal;
+	protected RetargetTextEditorAction fContentFormat;
+	private OpenDeclarationAction fOpenDeclarationAction;
+	private TogglePresentationAction fTogglePresentation;
+	private OpenExternalDocAction fOpenExternalDocAction;
+	private ToggleMarkOccurrencesAction fToggleMarkOccurrencesAction;
+    private ToggleAutoReconcileAction fToggleAutoReconcileAction;
+
+	public AntEditorActionContributor() {
+		super();
+		ResourceBundle bundle = AntEditorMessages.getResourceBundle();
+		fContentAssistProposal = new RetargetTextEditorAction(bundle, "ContentAssistProposal."); //$NON-NLS-1$
+		fContentAssistProposal.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+		fContentFormat = new RetargetTextEditorAction(bundle, "ContentFormat."); //$NON-NLS-1$
+		fContentFormat.setActionDefinitionId(IJavaEditorActionDefinitionIds.FORMAT);
+		fTogglePresentation= new TogglePresentationAction();
+		fToggleMarkOccurrencesAction= new ToggleMarkOccurrencesAction();
+        fToggleAutoReconcileAction= new ToggleAutoReconcileAction();
+		
+	}
+	
+	protected void initializeActions(AntEditor editor) {
+		fOpenDeclarationAction= new OpenDeclarationAction(editor);
+		fOpenExternalDocAction= new OpenExternalDocAction(editor);
+	}
+	
+	private void doSetActiveEditor(IEditorPart part) {
+		super.setActiveEditor(part);
+
+		ITextEditor editor= null;
+		if (part instanceof ITextEditor) {
+			editor= (ITextEditor) part;
+		}
+
+		fContentAssistProposal.setAction(getAction(editor, ITextEditorActionConstants.CONTENT_ASSIST));
+		fContentFormat.setAction(getAction(editor, "ContentFormat")); //$NON-NLS-1$
+		
+		if (editor instanceof AntEditor) {
+		    AntEditor antEditor= (AntEditor) part;
+			if (fOpenDeclarationAction == null) {
+				initializeActions(antEditor);
+				contributeToMenu(getActionBars().getMenuManager());
+			}
+			
+			FoldingActionGroup foldingActions= antEditor.getFoldingActionGroup();
+			if (foldingActions != null) {
+				foldingActions.updateActionBars();
+			}
+			if (fOpenDeclarationAction != null) {
+				fOpenDeclarationAction.setEditor(antEditor);
+			}
+			if (fOpenExternalDocAction != null) {
+				fOpenExternalDocAction.setActiveEditor(null, antEditor);
+			}
+		}
+		
+		if (fTogglePresentation != null) {
+		    fTogglePresentation.setEditor(editor);
+		}
+		if (fToggleMarkOccurrencesAction != null) {
+			fToggleMarkOccurrencesAction.setEditor(editor);
+		}
+        if (fToggleAutoReconcileAction != null) {
+            fToggleAutoReconcileAction.setEditor(editor);
+        }
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToMenu(org.eclipse.jface.action.IMenuManager)
+	 */
+	public void contributeToMenu(IMenuManager menu) {
+		if (fOpenDeclarationAction == null) {
+			return;
+		}
+		super.contributeToMenu(menu);
+		
+		IMenuManager navigateMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_NAVIGATE);
+		if (navigateMenu != null) {
+			navigateMenu.appendToGroup(IWorkbenchActionConstants.OPEN_EXT, fOpenDeclarationAction);
+			navigateMenu.appendToGroup(IWorkbenchActionConstants.OPEN_EXT, fOpenExternalDocAction);
+			navigateMenu.setVisible(true);
+		}
+	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.part.EditorActionBarContributor#init(org.eclipse.ui.IActionBars)
+     */
+    public void init(IActionBars bars) {
+        super.init(bars);
+        
+        IMenuManager menuManager= bars.getMenuManager();
+        IMenuManager editMenu= menuManager.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+        if (editMenu != null) {
+            editMenu.add(new Separator());
+            editMenu.add(fContentAssistProposal);
+            editMenu.add(fContentFormat);
+        }
+    }
+    
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IEditorActionBarContributor#setActiveEditor(org.eclipse.ui.IEditorPart)
+	 */
+	public void setActiveEditor(IEditorPart part) {
+		doSetActiveEditor(part);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IEditorActionBarContributor#dispose()
+	 */
+	public void dispose() {
+		doSetActiveEditor(null);
+		super.dispose();
+	}
+	
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.IEditorActionBarContributor#init(org.eclipse.ui.IActionBars, org.eclipse.ui.IWorkbenchPage)
+     */
+    public void init(IActionBars bars, IWorkbenchPage page) {
+        super.init(bars, page);
+        bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation);
+		bars.setGlobalActionHandler(TOGGLE_MARK_OCCURRENCES_ID, fToggleMarkOccurrencesAction);
+        bars.setGlobalActionHandler("org.eclipse.ant.ui.toggleAutoReconcile", fToggleAutoReconcileAction); //$NON-NLS-1$
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.java
new file mode 100644
index 0000000..7e3acff
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor;
+
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class AntEditorMessages {
+
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.editor.AntEditorMessages"; //$NON-NLS-1$
+
+	private static final ResourceBundle fgResourceBundle = ResourceBundle.getBundle(BUNDLE_NAME);
+
+	private AntEditorMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return fgResourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+
+	protected static ResourceBundle getResourceBundle() {
+		return fgResourceBundle;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.properties b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.properties
new file mode 100644
index 0000000..ef1cd17
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorMessages.properties
@@ -0,0 +1,43 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+#     John-Mason P. Shackelford - bug 40255
+###############################################################################
+
+ContentAssistProposal.label=Content &Assist@Ctrl+Space
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.image=
+ContentAssistProposal.description=Content Assist
+
+ContentFormat.label=&Format
+ContentFormat.tooltip=Format build file source
+ContentFormat.image=
+ContentFormat.description=Format build file source
+
+AntEditorCompletionProcessor.Required___4=Required:
+AntEditorCompletionProcessor.28=No attribute completions available
+AntEditorCompletionProcessor.29=No task completions available
+AntEditorCompletionProcessor.30=No task closing completions available
+AntEditorCompletionProcessor.31=No attribute value completions available
+AntEditorCompletionProcessor.32=No property completions available
+AntEditorCompletionProcessor.33=No completions available
+AntEditorCompletionProcessor.39=Closing tag
+AntEditorCompletionProcessor.59=Default: {0}
+AntEditorCompletionProcessor.60=No Template Proposals
+AntEditorCompletionProcessor.61=Template Proposals
+AntEditorCompletionProcessor.62=No Default Proposals
+AntEditorCompletionProcessor.63=Press ''{0}'' to show {1}
+AntEditorCompletionProcessor.64=Click to show {0}
+AntEditorCompletionProcessor.1=Not required
+AntEditorCompletionProcessor.2=Required
+AntEditorCompletionProcessor.0=Default Proposals
+
+AntAnnotationHover.multipleMarkersAtThisLine=Multiple markers at this line
+
+AntEditor.3=Current text selection does not resolve to an Ant reference
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntElementHyperlink.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntElementHyperlink.java
new file mode 100644
index 0000000..aa5188d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntElementHyperlink.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+
+public class AntElementHyperlink implements IHyperlink {
+
+    private IRegion fRegion= null;
+    private Object fLinkTarget= null;
+    private AntEditor fEditor= null;
+    
+    public AntElementHyperlink(AntEditor editor, IRegion region, Object linkTarget) {
+        
+       fRegion= region;
+       fLinkTarget= linkTarget;
+       fEditor= editor;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.hyperlink.IHyperlink#getHyperlinkRegion()
+     */
+    public IRegion getHyperlinkRegion() {
+        return fRegion;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.hyperlink.IHyperlink#getTypeLabel()
+     */
+    public String getTypeLabel() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.hyperlink.IHyperlink#getHyperlinkText()
+     */
+    public String getHyperlinkText() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.hyperlink.IHyperlink#open()
+     */
+    public void open() {
+        fEditor.openTarget(fLinkTarget);
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntElementHyperlinkDetector.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntElementHyperlinkDetector.java
new file mode 100644
index 0000000..276c1a6
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntElementHyperlinkDetector.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor;
+
+import org.eclipse.ant.internal.ui.editor.text.XMLTextHover;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+
+public class AntElementHyperlinkDetector extends AbstractHyperlinkDetector {
+
+    private AntEditor fEditor;
+    
+    public AntElementHyperlinkDetector() {    
+    }
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion, boolean)
+	 */
+	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
+		 if (region == null) {
+			return null;
+        }
+		fEditor = (AntEditor) getAdapter(AntEditor.class);
+        region= XMLTextHover.getRegion(textViewer, region.getOffset());
+        Object linkTarget= fEditor.findTarget(region);
+		if (linkTarget == null) {
+			return null;
+		}
+        return new IHyperlink[] {new AntElementHyperlink(fEditor, region, linkTarget)};
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntSourceViewerInformationControl.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntSourceViewerInformationControl.java
new file mode 100644
index 0000000..f36c02d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/AntSourceViewerInformationControl.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.ant.internal.ui.AntSourceViewerConfiguration;
+import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant;
+
+import org.eclipse.jface.resource.JFaceResources;
+
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlExtension;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class AntSourceViewerInformationControl implements IInformationControl, IInformationControlExtension, DisposeListener {
+	/** The control's shell */
+	private Shell fShell;
+	
+	/** The control's source viewer */
+	private SourceViewer fViewer;
+	
+	/** The control's text widget */
+	private StyledText fText;
+	
+	public AntSourceViewerInformationControl(Shell parent) {
+		GridLayout layout;
+		GridData gd;
+
+		fShell= new Shell(parent, SWT.ON_TOP | SWT.TOOL);
+		Display display= fShell.getDisplay();
+		fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
+
+		Composite composite= fShell;
+		layout= new GridLayout(1, false);
+		layout.marginHeight= 0;
+		layout.marginWidth= 0;
+		composite.setLayout(layout);
+		gd= new GridData(GridData.FILL_HORIZONTAL);
+		composite.setLayoutData(gd);
+		fViewer= createViewer(composite);
+		
+		fText= fViewer.getTextWidget();
+		gd= new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
+		fText.setLayoutData(gd);
+		fText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+		fText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+			
+		fText.addKeyListener(new KeyListener() {
+				
+			public void keyPressed(KeyEvent e)  {
+				if (e.character == 0x1B) // ESC
+					fShell.dispose();
+			}
+				
+			public void keyReleased(KeyEvent e) {}
+		});
+	}
+	
+	
+    private SourceViewer createViewer(Composite parent) {
+    	SourceViewer viewer = new SourceViewer(parent, null, SWT.NONE);
+          
+		SourceViewerConfiguration configuration = new AntSourceViewerConfiguration();
+		viewer.configure(configuration);
+		viewer.setEditable(false);
+		Font font= JFaceResources.getFont(JFaceResources.TEXT_FONT);
+		viewer.getTextWidget().setFont(font);
+		        
+		return viewer;
+    }
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
+	 */
+	public void setInformation(String content) {
+		if (content == null) {
+			fViewer.setInput(null);
+			return;
+		}
+		IDocument document = new Document(content);
+		new AntDocumentSetupParticipant().setup(document);
+		fViewer.setDocument(document);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int, int)
+	 */
+	public void setSizeConstraints(int maxWidth, int maxHeight) {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#computeSizeHint()
+	 */
+	public Point computeSizeHint() {
+		return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#setVisible(boolean)
+	 */
+	public void setVisible(boolean visible) {
+		fShell.setVisible(visible);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#setSize(int, int)
+	 */
+	public void setSize(int width, int height) {
+		fShell.setSize(width, height);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#setLocation(org.eclipse.swt.graphics.Point)
+	 */
+	public void setLocation(Point location) {
+		Rectangle trim= fShell.computeTrim(0, 0, 0, 0);
+		Point textLocation= fText.getLocation();
+		location.x += trim.x - textLocation.x;
+		location.y += trim.y - textLocation.y;
+		fShell.setLocation(location);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#dispose()
+	 */
+	public void dispose() {
+		if (fShell != null && !fShell.isDisposed()) {
+			fShell.dispose();
+		} else {
+			widgetDisposed(null);
+		}
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#addDisposeListener(org.eclipse.swt.events.DisposeListener)
+	 */
+	public void addDisposeListener(DisposeListener listener) {
+		fShell.addDisposeListener(listener);
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#removeDisposeListener(org.eclipse.swt.events.DisposeListener)
+	 */
+	public void removeDisposeListener(DisposeListener listener) {
+		fShell.removeDisposeListener(listener);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#setForegroundColor(org.eclipse.swt.graphics.Color)
+	 */
+	public void setForegroundColor(Color foreground) {
+		fText.setForeground(foreground);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#setBackgroundColor(org.eclipse.swt.graphics.Color)
+	 */
+	public void setBackgroundColor(Color background) {
+		fText.setBackground(background);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#isFocusControl()
+	 */
+	public boolean isFocusControl() {
+		return fText.isFocusControl();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#setFocus()
+	 */
+	public void setFocus() {
+		fShell.forceFocus();
+		fText.setFocus();
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#addFocusListener(org.eclipse.swt.events.FocusListener)
+	 */
+	public void addFocusListener(FocusListener listener) {
+		fText.addFocusListener(listener);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControl#removeFocusListener(org.eclipse.swt.events.FocusListener)
+	 */
+	public void removeFocusListener(FocusListener listener) {
+		fText.removeFocusListener(listener);
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IInformationControlExtension#hasContents()
+	 */
+	public boolean hasContents() {
+		return fText.getCharCount() > 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
+	 */
+	public void widgetDisposed(DisposeEvent e) {
+		fShell= null;
+		fText= null;
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/DecayCodeCompletionDataStructuresThread.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/DecayCodeCompletionDataStructuresThread.java
new file mode 100644
index 0000000..b5a7dc8
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/DecayCodeCompletionDataStructuresThread.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor;
+
+import org.eclipse.ant.internal.ui.editor.utils.ProjectHelper;
+
+
+public class DecayCodeCompletionDataStructuresThread extends Thread {
+	
+	private static final int fgDelay= 6000 * 5; //5 minutes 
+	
+	private static DecayCodeCompletionDataStructuresThread fgInstance;
+	
+	public static DecayCodeCompletionDataStructuresThread getDefault() {
+		if (fgInstance == null) {
+			fgInstance= new DecayCodeCompletionDataStructuresThread();
+		}
+		return fgInstance;
+	}
+	
+	/**
+	 * Creates a new background thread. The thread 
+	 * runs with minimal priority.
+	 */
+	private DecayCodeCompletionDataStructuresThread() {
+		super("Decay Ant Data Structures"); //$NON-NLS-1$
+		setPriority(Thread.MIN_PRIORITY);
+		setDaemon(true);
+		fgInstance= this;
+        setContextClassLoader(null); //don't hold on to any class loaders
+	}
+	
+	/**
+	 * The background activity that is triggered when the last <code>AntModel</code> is disposed.
+	 * Waits for the required delay and then nulls out the memory expensive Ant code
+	 * completion data structures and reset the ProjectHelper.
+	 * If an <code>AntModel</code> is created during the wait, the thread is
+	 * interrupted and no nulling out occurs.
+	 */
+	public void run() {
+		synchronized (this) {
+			try {
+				wait(fgDelay);
+				AntEditorCompletionProcessor.resetCodeCompletionDataStructures();
+                ProjectHelper.reset();
+			} catch (InterruptedException x) {
+			}
+		}
+	}
+	
+	/**
+	 * Cancels the background thread.
+	 */
+	public static void cancel() {
+		if (fgInstance != null) {
+			synchronized (fgInstance) {
+				fgInstance.interrupt();
+				fgInstance= null;
+			}
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/EditorSynchronizer.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/EditorSynchronizer.java
new file mode 100644
index 0000000..c0baf9d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/EditorSynchronizer.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.link.ILinkedModeListener;
+import org.eclipse.jface.text.link.LinkedModeModel;
+
+/**
+ * Synchronizes the Ant editor with the state of its linked mode
+ * 
+ * @since 3.1
+ */
+public class EditorSynchronizer implements ILinkedModeListener {
+    
+    private final AntEditor fEditor;
+    private final boolean fWasOccurrencesOn;
+    
+    /**
+     * Creates a new synchronizer.
+     * 
+     * @param editor the Ant editor that will be 
+     *        synchonized with the linked mode
+     */
+    public EditorSynchronizer(AntEditor editor) {
+        Assert.isLegal(editor != null);
+        fEditor= editor;
+        fWasOccurrencesOn= fEditor.isMarkingOccurrences();
+        fEditor.setInLinkedMode(true, fWasOccurrencesOn);
+    }
+
+    /*
+     * @see org.eclipse.jface.text.link.ILinkedModeListener#left(org.eclipse.jface.text.link.LinkedModeModel, int)
+     */
+    public void left(LinkedModeModel environment, int flags) {
+    	fEditor.setInLinkedMode(false, fWasOccurrencesOn);
+    }
+
+    /*
+     * @see org.eclipse.jface.text.link.ILinkedModeListener#suspend(org.eclipse.jface.text.link.LinkedModeModel)
+     */
+    public void suspend(LinkedModeModel environment) {
+    }
+
+    /*
+     * @see org.eclipse.jface.text.link.ILinkedModeListener#resume(org.eclipse.jface.text.link.LinkedModeModel, int)
+     */
+    public void resume(LinkedModeModel environment, int flags) {
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/OccurrencesFinder.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/OccurrencesFinder.java
new file mode 100644
index 0000000..899026c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/OccurrencesFinder.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.internal.ui.editor.text.XMLTextHover;
+import org.eclipse.ant.internal.ui.model.AntElementNode;
+import org.eclipse.ant.internal.ui.model.AntModel;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+
+public class OccurrencesFinder {
+    
+	private AntModel fAntModel;
+	private AntEditor fEditor;
+	private int fOffset;
+	private IDocument fDocument;
+	
+	public OccurrencesFinder(AntEditor editor, AntModel model, IDocument document, int offset) {
+		fAntModel= model;
+		fEditor= editor;
+		fDocument= document;
+		fOffset= offset;
+	}
+	
+	public List perform() {
+		if (fOffset == 0 || fAntModel == null) {
+			return null;
+		}
+		
+		AntElementNode container= fAntModel.getNode(fOffset, false);
+		if (container == null) {
+			return null;
+		}
+		IRegion region= XMLTextHover.getRegion(fEditor.getViewer(), fOffset);
+		if (region != null) {
+			if (!container.isRegionPotentialReference(region)) {
+				return null;
+			}
+		}
+		AntElementNode node;
+		if (container.isFromDeclaration(region)) {
+			node= container;
+		} else {
+			Object potentialNode= fEditor.findTarget(region);
+			if (!(potentialNode instanceof AntElementNode)) {
+				return null;
+			} 
+			node= (AntElementNode) potentialNode;
+		}
+		String occurrencesIdentifier= node.getOccurrencesIdentifier();
+		if (occurrencesIdentifier == null) {
+			return null;
+		}
+		List nodes= new ArrayList(1);
+		nodes.add(fAntModel.getProjectNode());
+        List usages= new ArrayList();
+        usages.add(node);
+		scanNodesForOccurrences(nodes, usages, occurrencesIdentifier);
+		String identifier;
+		try {
+			identifier= fDocument.get(region.getOffset(), region.getLength());
+		} catch (BadLocationException e) {
+			return null;
+		}
+        int length= identifier.length();
+        if (length == 0) {
+            return null;
+        }
+		List positions= new ArrayList(usages.size());
+		for (Iterator each= usages.iterator(); each.hasNext();) {
+			AntElementNode currentNode= (AntElementNode)each.next();
+			List offsets= currentNode.computeIdentifierOffsets(identifier);
+			if (offsets != null) {
+				for (int i = 0; i < offsets.size(); i++) {
+					positions.add(new Position(((Integer)offsets.get(i)).intValue(), length));
+				}
+			}
+		}
+	
+		return positions;
+	}
+	
+	private void scanNodesForOccurrences(List nodes, List usages, String identifier) {
+		Iterator iter= nodes.iterator();
+		while (iter.hasNext()) {
+			AntElementNode node = (AntElementNode) iter.next();
+			if (!usages.contains(node) && node.containsOccurrence(identifier)) {
+				usages.add(node);	
+			}
+			if (node.hasChildren()) {
+				scanNodesForOccurrences(node.getChildNodes(), usages, identifier);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/AntEditorActionMessages.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/AntEditorActionMessages.java
new file mode 100644
index 0000000..62a79f0
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/AntEditorActionMessages.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.actions;
+
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class AntEditorActionMessages {
+
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.editor.actions.AntEditorActionMessages"; //$NON-NLS-1$
+
+	private static final ResourceBundle fgResourceBundle = ResourceBundle.getBundle(BUNDLE_NAME);
+
+	private AntEditorActionMessages() {
+	}
+
+	public static ResourceBundle getResourceBundle() {
+		return fgResourceBundle;
+	}
+	public static String getString(String key) {
+		try {
+			return fgResourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/AntEditorActionMessages.properties b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/AntEditorActionMessages.properties
new file mode 100644
index 0000000..31501e5
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/AntEditorActionMessages.properties
@@ -0,0 +1,42 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+#     John-Mason P. Shackelford - bug 40255
+###############################################################################
+
+OpenDeclarationAction.0=&Open Declaration
+OpenDeclarationAction.1=Open an editor on the referenced element
+OpenExternalDocAction.0=Open External Ant Documentation
+OpenExternalDocAction.1=Open E&xternal Documentation
+OpenExternalDocAction.2=Opens an external browser on the referenced Ant element
+
+TogglePresentation.label=Show Source of Selected Element Only
+TogglePresentation.tooltip=Show Source of Selected Element Only
+
+ToggleMarkOccurrencesAction.label= Toggle Ant Mark Occurrences
+ToggleMarkOccurrencesAction.tooltip= Toggle Ant Mark Occurrences
+
+ToggleAutoReconcileAction.label= Toggle Auto Reconcile
+ToggleAutoReconcileAction.tooltip= Toggle Auto reconcile
+
+Projection.Toggle.label= &Enable Folding
+Projection.Toggle.tooltip= Toggles Folding
+Projection.Toggle.description= Toggles folding for the current editor
+
+Projection.ExpandAll.label= Expand &All
+Projection.ExpandAll.tooltip= Expands All Folded Regions
+Projection.ExpandAll.description= Expands any folded regions in the current editor
+
+RunToLineAdapter.0=Empty editor
+RunToLineAdapter.1=Missing document
+RunToLineAdapter.2=No file could be found
+RunToLineAdapter.3=Unable to locate debug target
+RenameInFileAction.0=Re&name In File
+RenameInFileAction.1=Renames all references within the same buildfile
+RenameInFileAction.2=Renames all references
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/FoldingActionGroup.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/FoldingActionGroup.java
new file mode 100644
index 0000000..4a707d9
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/FoldingActionGroup.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.actions;
+
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.source.projection.IProjectionListener;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.editors.text.IFoldingCommandIds;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+
+/**
+ * Groups the Ant folding actions.
+ *  
+ * @since 3.1
+ */
+public class FoldingActionGroup extends ActionGroup {
+	private ProjectionViewer fViewer;
+	
+	private TextOperationAction fToggle;
+	private TextOperationAction fExpand;
+	private TextOperationAction fCollapse;
+	private TextOperationAction fExpandAll;
+
+	private IProjectionListener fProjectionListener;
+	
+	/**
+	 * Creates a new projection action group for <code>editor</code>. If the
+	 * supplied viewer is not an instance of <code>ProjectionViewer</code>, the
+	 * action group is disabled.
+	 * 
+	 * @param editor the text editor to operate on
+	 * @param viewer the viewer of the editor
+	 */
+	public FoldingActionGroup(ITextEditor editor, ITextViewer viewer) {
+		if (viewer instanceof ProjectionViewer) {
+			fViewer= (ProjectionViewer) viewer;
+			
+			fProjectionListener= new IProjectionListener() {
+
+				public void projectionEnabled() {
+					update();
+				}
+
+				public void projectionDisabled() {
+					update();
+				}
+			};
+			
+			fViewer.addProjectionListener(fProjectionListener);
+			
+			fToggle= new TextOperationAction(AntEditorActionMessages.getResourceBundle(), "Projection.Toggle.", editor, ProjectionViewer.TOGGLE, true); //$NON-NLS-1$
+			fToggle.setChecked(true);
+			fToggle.setActionDefinitionId(IFoldingCommandIds.FOLDING_TOGGLE);
+			editor.setAction("FoldingToggle", fToggle); //$NON-NLS-1$
+			
+			fExpandAll= new TextOperationAction(AntEditorActionMessages.getResourceBundle(), "Projection.ExpandAll.", editor, ProjectionViewer.EXPAND_ALL, true); //$NON-NLS-1$
+			fExpandAll.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND_ALL);
+			editor.setAction("FoldingExpandAll", fExpandAll); //$NON-NLS-1$
+			
+			fExpand= new TextOperationAction(AntEditorActionMessages.getResourceBundle(), "Projection.Expand.", editor, ProjectionViewer.EXPAND, true); //$NON-NLS-1$
+			fExpand.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND);
+			editor.setAction("FoldingExpand", fExpand); //$NON-NLS-1$
+			
+			fCollapse= new TextOperationAction(AntEditorActionMessages.getResourceBundle(), "Projection.Collapse.", editor, ProjectionViewer.COLLAPSE, true); //$NON-NLS-1$
+			fCollapse.setActionDefinitionId(IFoldingCommandIds.FOLDING_COLLAPSE);
+			editor.setAction("FoldingCollapse", fCollapse); //$NON-NLS-1$
+		}
+	}
+	
+	/**
+	 * Returns <code>true</code> if the group is enabled. 
+	 * <pre>
+	 * Invariant: isEnabled() <=> fViewer and all actions are != null.
+	 * </pre>
+	 * 
+	 * @return <code>true</code> if the group is enabled
+	 */
+	private boolean isEnabled() {
+		return fViewer != null;
+	}
+	
+	/*
+	 * @see org.eclipse.ui.actions.ActionGroup#dispose()
+	 */
+	public void dispose() {
+		if (isEnabled()) {
+			fViewer.removeProjectionListener(fProjectionListener);
+			fViewer= null;
+		}
+		super.dispose();
+	}
+	
+	/**
+	 * Updates the actions.
+	 */
+	protected void update() {
+		if (isEnabled()) {
+			fToggle.update();
+			fToggle.setChecked(fViewer.getProjectionAnnotationModel() != null);
+			fExpand.update();
+			fExpandAll.update();
+			fCollapse.update();
+		}
+	}
+	
+	/*
+	 * @see org.eclipse.ui.actions.ActionGroup#updateActionBars()
+	 */
+	public void updateActionBars() {
+		update();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/FoldingExpandAllRulerAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/FoldingExpandAllRulerAction.java
new file mode 100644
index 0000000..4ef30cf
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/FoldingExpandAllRulerAction.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.ui.editors.text.IFoldingCommandIds;
+import org.eclipse.ui.texteditor.AbstractRulerActionDelegate;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+public class FoldingExpandAllRulerAction extends AbstractRulerActionDelegate {
+
+	/*
+	 * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#createAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.source.IVerticalRulerInfo)
+	 */
+	protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) {
+		TextOperationAction action= new TextOperationAction(AntEditorActionMessages.getResourceBundle(), "Projection.ExpandAll.", editor, ProjectionViewer.EXPAND_ALL, true); //$NON-NLS-1$
+		action.setActionDefinitionId(IFoldingCommandIds.FOLDING_EXPAND_ALL);
+		return action;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/FoldingToggleRulerAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/FoldingToggleRulerAction.java
new file mode 100644
index 0000000..f438671
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/FoldingToggleRulerAction.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.actions;
+
+import org.eclipse.ant.internal.ui.editor.AntEditor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.editors.text.IFoldingCommandIds;
+import org.eclipse.ui.texteditor.AbstractRulerActionDelegate;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextOperationAction;
+
+public class FoldingToggleRulerAction extends AbstractRulerActionDelegate {
+
+	private IAction fUIAction;
+	private TextOperationAction fAction;
+	private ITextEditor fTextEditor;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate#createAction(org.eclipse.ui.texteditor.ITextEditor, org.eclipse.jface.text.source.IVerticalRulerInfo)
+	 */
+	protected IAction createAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) {
+		fTextEditor= editor;
+		fAction= new TextOperationAction(AntEditorActionMessages.getResourceBundle(), "Projection.Toggle.", editor, ProjectionViewer.TOGGLE, true); //$NON-NLS-1$
+		fAction.setActionDefinitionId(IFoldingCommandIds.FOLDING_TOGGLE);
+		return fAction;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart)
+	 */
+	public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) {
+		fUIAction= callerAction;
+		super.setActiveEditor(callerAction, targetEditor);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
+	 */
+	public void menuAboutToShow(IMenuManager manager) {
+		update();
+		super.menuAboutToShow(manager);
+	}
+	
+	private void update() {
+		if (fTextEditor instanceof AntEditor) {
+			ISourceViewer viewer= ((AntEditor) fTextEditor).getViewer();
+			if (viewer instanceof ProjectionViewer) {
+				boolean enabled= ((ProjectionViewer) viewer).getProjectionAnnotationModel() != null;
+				fUIAction.setChecked(enabled);
+			}
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/OpenDeclarationAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/OpenDeclarationAction.java
new file mode 100644
index 0000000..9522bbe
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/OpenDeclarationAction.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.actions;
+
+import org.eclipse.ant.internal.ui.editor.AntEditor;
+import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
+import org.eclipse.jdt.ui.actions.OpenAction;
+import org.eclipse.jface.commands.ActionHandler;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.ui.handlers.IHandlerService;
+
+public class OpenDeclarationAction extends OpenAction {
+	
+	private AntEditor fEditor;
+	
+	public OpenDeclarationAction(AntEditor antEditor) {
+		super(antEditor.getSite());
+		fEditor= antEditor;
+		setActionDefinitionId(IJavaEditorActionDefinitionIds.OPEN_EDITOR);
+		IHandlerService handlerServer= (IHandlerService) antEditor.getSite().getService(IHandlerService.class);
+        handlerServer.activateHandler(IJavaEditorActionDefinitionIds.OPEN_EDITOR, new ActionHandler(this));
+
+		setText(AntEditorActionMessages.getString("OpenDeclarationAction.0"));  //$NON-NLS-1$
+		setDescription(AntEditorActionMessages.getString("OpenDeclarationAction.1")); //$NON-NLS-1$
+		setToolTipText(AntEditorActionMessages.getString("OpenDeclarationAction.1")); //$NON-NLS-1$
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		if (fEditor == null) {
+			return;
+		}
+		
+		fEditor.openReferenceElement();		
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#selectionChanged(org.eclipse.jface.text.ITextSelection)
+	 */
+	public void selectionChanged(ITextSelection selection) {
+		setEnabled(fEditor != null);
+	}
+	
+	public void setEditor(AntEditor editor) {
+		fEditor= editor;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/RenameInFileAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/RenameInFileAction.java
new file mode 100644
index 0000000..e199c56
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/RenameInFileAction.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.actions;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.editor.AntEditor;
+import org.eclipse.ant.internal.ui.editor.EditorSynchronizer;
+import org.eclipse.ant.internal.ui.editor.OccurrencesFinder;
+import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.link.LinkedModeModel;
+import org.eclipse.jface.text.link.LinkedModeUI;
+import org.eclipse.jface.text.link.LinkedPosition;
+import org.eclipse.jface.text.link.LinkedPositionGroup;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.texteditor.link.EditorLinkedModeUI;
+
+public class RenameInFileAction extends SelectionDispatchAction {
+	
+	private AntEditor fEditor;
+	
+	public RenameInFileAction(AntEditor antEditor) {
+		super(antEditor.getSite());
+		fEditor= antEditor;
+		setText(AntEditorActionMessages.getString("RenameInFileAction.0")); //$NON-NLS-1$
+		setDescription(AntEditorActionMessages.getString("RenameInFileAction.1")); //$NON-NLS-1$
+		setToolTipText(AntEditorActionMessages.getString("RenameInFileAction.2")); //$NON-NLS-1$
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		if (fEditor == null) {
+			return;
+		}
+		
+		ISourceViewer viewer= fEditor.getViewer();
+		IDocument document= viewer.getDocument();
+		int offset= ((ITextSelection)getSelection()).getOffset();
+		LinkedPositionGroup group= new LinkedPositionGroup();
+		OccurrencesFinder finder= new OccurrencesFinder(fEditor, fEditor.getAntModel(), document, offset);
+		List positions= finder.perform();
+		if (positions == null) {
+			return;
+		}
+	
+		addPositionsToGroup(offset, positions, document, group);
+		if (group.isEmpty()) {
+		    return;         
+        }
+		try {
+			LinkedModeModel model= new LinkedModeModel();
+			model.addGroup(group);
+			model.forceInstall();
+            model.addLinkingListener(new EditorSynchronizer(fEditor));
+			LinkedModeUI ui= new EditorLinkedModeUI(model, viewer);
+			ui.setExitPosition(viewer, offset, 0, Integer.MAX_VALUE);
+			ui.enter();
+			viewer.setSelectedRange(offset, 0);
+		} catch (BadLocationException e) {
+			AntUIPlugin.log(e);
+		}
+	}
+	
+    
+    private void addPositionsToGroup(int offset, List positions, IDocument document, LinkedPositionGroup group) {
+        Iterator iter= positions.iterator();
+        int i= 0;
+        int j= 0;
+        int firstPosition= -1;
+        try {
+            while (iter.hasNext()) {
+                Position position = (Position) iter.next();
+                if (firstPosition == -1) {
+                    if (position.overlapsWith(offset, 0)) {
+                        firstPosition= i;
+                        group.addPosition(new LinkedPosition(document, position.getOffset(), position.getLength(), j++));
+                    }
+                } else {
+                    group.addPosition(new LinkedPosition(document, position.getOffset(), position.getLength(), j++));
+                }
+                i++;
+            }
+            
+            for (i = 0; i < firstPosition; i++) {
+                Position position= (Position) positions.get(i);
+                group.addPosition(new LinkedPosition(document, position.getOffset(), position.getLength(), j++));
+            }
+        } catch (BadLocationException be) {
+            AntUIPlugin.log(be);
+        }
+    }
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#selectionChanged(org.eclipse.jface.text.ITextSelection)
+	 */
+	public void selectionChanged(ITextSelection selection) {
+		setEnabled(fEditor != null);
+	}
+
+	/**
+	 * Set the Ant editor associated with the action
+	 * @param editor the ant editor to do the renames
+	 */
+	public void setEditor(AntEditor editor) {
+		fEditor= editor;
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/RunToLineAdapter.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/RunToLineAdapter.java
new file mode 100644
index 0000000..ad90610
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/RunToLineAdapter.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.actions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.ant.internal.launching.debug.IAntDebugConstants;
+import org.eclipse.ant.internal.launching.debug.model.AntDebugElement;
+import org.eclipse.ant.internal.launching.debug.model.AntLineBreakpoint;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.ISuspendResume;
+import org.eclipse.debug.ui.actions.IRunToLineTarget;
+import org.eclipse.debug.ui.actions.RunToLineHandler;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Run to line target for the Ant debugger
+ */
+public class RunToLineAdapter implements IRunToLineTarget {
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.actions.IRunToLineTarget#runToLine(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.debug.core.model.ISuspendResume)
+	 */
+	public void runToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) throws CoreException {
+		IEditorPart editorPart = (IEditorPart)part;
+		IEditorInput input = editorPart.getEditorInput();
+		String errorMessage = null;
+		if (input == null) {
+			errorMessage = AntEditorActionMessages.getString("RunToLineAdapter.0"); //$NON-NLS-1$
+		} else {
+			ITextEditor textEditor = (ITextEditor)editorPart;
+			IDocumentProvider provider= textEditor.getDocumentProvider();
+			IDocument document= provider.getDocument(input);
+			
+			if (document == null) {
+				errorMessage = AntEditorActionMessages.getString("RunToLineAdapter.1"); //$NON-NLS-1$
+			} else {
+				
+				ITextSelection textSelection = (ITextSelection) selection;
+				int lineNumber = textSelection.getStartLine() + 1;
+				
+				IBreakpoint breakpoint= null;
+				Map attributes = getRunToLineAttributes();
+				IFile file = (IFile)input.getAdapter(IFile.class);
+				if (file == null) {
+				    errorMessage= AntEditorActionMessages.getString("RunToLineAdapter.2"); //$NON-NLS-1$
+				} else {
+				    breakpoint= new AntLineBreakpoint(file, lineNumber, attributes, false);
+                    breakpoint.setPersisted(false);
+				    errorMessage = AntEditorActionMessages.getString("RunToLineAdapter.3"); //$NON-NLS-1$
+				    if (target instanceof IAdaptable) {
+				        IDebugTarget debugTarget = (IDebugTarget) ((IAdaptable)target).getAdapter(IDebugTarget.class);
+				        if (debugTarget != null) {
+				            RunToLineHandler handler = new RunToLineHandler(debugTarget, target, breakpoint);
+                            handler.run(new NullProgressMonitor());
+				            return;
+				        }
+				    }
+				}
+			}
+		}
+		throw new CoreException(new Status(IStatus.ERROR, AntUIPlugin.getUniqueIdentifier(), AntUIPlugin.INTERNAL_ERROR,
+				errorMessage, null));
+	}
+
+    private Map getRunToLineAttributes() {
+        Map attributes = new HashMap();
+        attributes.put(IMarker.TRANSIENT, Boolean.TRUE);
+        attributes.put(IAntDebugConstants.ANT_RUN_TO_LINE, Boolean.TRUE);
+        return attributes;
+    }
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.actions.IRunToLineTarget#canRunToLine(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.debug.core.model.ISuspendResume)
+	 */
+	public boolean canRunToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) {
+	    return target instanceof AntDebugElement;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/ToggleAutoReconcileAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/ToggleAutoReconcileAction.java
new file mode 100644
index 0000000..c99aa15
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/ToggleAutoReconcileAction.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.actions;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.editor.AntEditor;
+import org.eclipse.ant.internal.ui.model.AntModel;
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * A toolbar action which toggles the {@linkplain org.eclipse.ant.internal.ui.preferences#EDITOR_RECONCILE preference}.
+ * 
+ * @since 3.1
+ */
+public class ToggleAutoReconcileAction extends TextEditorAction implements IPropertyChangeListener {
+		
+	private IPreferenceStore fStore;
+
+	/**
+	 * Constructs and updates the action.
+	 */
+	public ToggleAutoReconcileAction() {
+		super(AntEditorActionMessages.getResourceBundle(), "ToggleAutoReconcileAction.", null, IAction.AS_CHECK_BOX); //$NON-NLS-1$
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_REFRESH));
+		setToolTipText(AntEditorActionMessages.getString("ToggleAutoReconcileAction.tooltip"));		 //$NON-NLS-1$
+		update();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		ITextEditor editor= getTextEditor();
+        if (editor instanceof AntEditor) {
+            AntModel model= ((AntEditor) editor).getAntModel();
+            model.setShouldReconcile(isChecked());
+            fStore.setValue(AntEditorPreferenceConstants.EDITOR_RECONCILE, isChecked());
+        }
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.texteditor.IUpdate#update()
+	 */
+	public void update() {
+		ITextEditor editor= getTextEditor();
+		
+		boolean checked= false;
+		boolean enabled= false;
+		if (editor instanceof AntEditor) {
+            AntModel model= ((AntEditor)editor).getAntModel();
+            enabled=  model != null;
+			checked= enabled && fStore.getBoolean(AntEditorPreferenceConstants.EDITOR_RECONCILE);
+            if (model != null) {
+                model.setShouldReconcile(checked);
+            }
+		}
+			
+		setChecked(checked);
+		setEnabled(enabled);
+	}
+	
+	/*
+	 * @see TextEditorAction#setEditor(ITextEditor)
+	 */
+	public void setEditor(ITextEditor editor) {
+		
+		super.setEditor(editor);
+		
+		if (editor != null) {
+			if (fStore == null) {
+				fStore= AntUIPlugin.getDefault().getPreferenceStore();
+				fStore.addPropertyChangeListener(this);
+			}
+		} else if (fStore != null) {
+			fStore.removePropertyChangeListener(this);
+			fStore= null;
+		}
+		
+		update();
+	}
+	
+	/*
+	 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+	 */
+	public void propertyChange(PropertyChangeEvent event) {
+		if (event.getProperty().equals(AntEditorPreferenceConstants.EDITOR_RECONCILE)) {
+			setChecked(Boolean.valueOf(event.getNewValue().toString()).booleanValue());
+        }
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/ToggleMarkOccurrencesAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/ToggleMarkOccurrencesAction.java
new file mode 100644
index 0000000..6579f0d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/ToggleMarkOccurrencesAction.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.actions;
+
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.editor.AntEditor;
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+
+/**
+ * A toolbar action which toggles the {@linkplain org.eclipse.ant.internal.ui.preferences#EDITOR_MARK_OCCURRENCES mark occurrences preference}.
+ * 
+ * @since 3.1
+ */
+public class ToggleMarkOccurrencesAction extends TextEditorAction implements IPropertyChangeListener {
+		
+	private IPreferenceStore fStore;
+
+	/**
+	 * Constructs and updates the action.
+	 */
+	public ToggleMarkOccurrencesAction() {
+		super(AntEditorActionMessages.getResourceBundle(), "ToggleMarkOccurrencesAction.", null, IAction.AS_CHECK_BOX); //$NON-NLS-1$
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_MARK_OCCURRENCES));
+		setToolTipText(AntEditorActionMessages.getString("ToggleMarkOccurrencesAction.tooltip"));		 //$NON-NLS-1$
+		update();
+	}
+	
+	/*
+	 * @see IAction#actionPerformed
+	 */
+	public void run() {
+		fStore.setValue(AntEditorPreferenceConstants.EDITOR_MARK_OCCURRENCES, isChecked());
+	}
+	
+	/*
+	 * @see TextEditorAction#update
+	 */
+	public void update() {
+		ITextEditor editor= getTextEditor();
+		
+		boolean checked= false;
+		boolean enabled= false;
+		if (editor instanceof AntEditor) {
+			checked= ((AntEditor)editor).isMarkingOccurrences();
+			enabled= ((AntEditor)editor).getAntModel() != null;
+		}
+			
+		setChecked(checked);
+		setEnabled(enabled);
+	}
+	
+	/*
+	 * @see TextEditorAction#setEditor(ITextEditor)
+	 */
+	public void setEditor(ITextEditor editor) {
+		
+		super.setEditor(editor);
+		
+		if (editor != null) {
+			
+			if (fStore == null) {
+				fStore= AntUIPlugin.getDefault().getPreferenceStore();
+				fStore.addPropertyChangeListener(this);
+			}
+			
+		} else if (fStore != null) {
+			fStore.removePropertyChangeListener(this);
+			fStore= null;
+		}
+		
+		update();
+	}
+	
+	/*
+	 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+	 */
+	public void propertyChange(PropertyChangeEvent event) {
+		if (event.getProperty().equals(AntEditorPreferenceConstants.EDITOR_MARK_OCCURRENCES))
+			setChecked(Boolean.valueOf(event.getNewValue().toString()).booleanValue());
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/TogglePresentationAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/TogglePresentationAction.java
new file mode 100644
index 0000000..54666ee
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/actions/TogglePresentationAction.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.actions;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * A tool bar action which toggles the presentation model of the
+ * connected text editor. The editor shows either the highlight range
+ * only or always the whole document.
+ */
+public class TogglePresentationAction extends TextEditorAction implements IPropertyChangeListener {
+		
+	private IPreferenceStore fStore;
+
+	/**
+	 * Constructs and updates the action.
+	 */
+	public TogglePresentationAction() {
+		super(AntEditorActionMessages.getResourceBundle(), "TogglePresentation.", null, IAction.AS_CHECK_BOX); //$NON-NLS-1$
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_SEGMENT_EDIT));
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		
+		ITextEditor editor= getTextEditor();
+		if (editor == null) {
+            return;
+        }
+		
+		IRegion remembered= editor.getHighlightRange();
+		editor.resetHighlightRange();
+		
+		boolean showAll= !editor.showsHighlightRangeOnly();
+		setChecked(showAll);
+		
+		editor.showHighlightRangeOnly(showAll);
+		if (remembered != null) {
+            editor.setHighlightRange(remembered.getOffset(), remembered.getLength(), true);
+        }
+		
+		fStore.removePropertyChangeListener(this);
+		fStore.setValue(AntEditorPreferenceConstants.EDITOR_SHOW_SEGMENTS, showAll);
+		fStore.addPropertyChangeListener(this);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.texteditor.IUpdate#update()
+	 */
+	public void update() {
+		ITextEditor editor= getTextEditor();
+		boolean checked= (editor != null && editor.showsHighlightRangeOnly());
+		setChecked(checked);
+		setEnabled(editor != null);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.texteditor.TextEditorAction#setEditor(org.eclipse.ui.texteditor.ITextEditor)
+	 */
+	public void setEditor(ITextEditor editor) {
+		
+		super.setEditor(editor);
+		
+		if (editor != null) {
+			
+			if (fStore == null) {
+				fStore= AntUIPlugin.getDefault().getPreferenceStore();
+				fStore.addPropertyChangeListener(this);
+			}
+			synchronizeWithPreference(editor);
+			
+		} else if (fStore != null) {
+			fStore.removePropertyChangeListener(this);
+			fStore= null;
+		}
+		
+		update();
+	}
+	
+	/**
+	 * Synchronizes the appearance of the editor with what the preference store indicates
+	 * 
+	 * @param editor the text editor
+	 */
+	private void synchronizeWithPreference(ITextEditor editor) {
+		
+		if (editor == null) {
+			return;
+		}
+		
+		boolean showSegments= fStore.getBoolean(AntEditorPreferenceConstants.EDITOR_SHOW_SEGMENTS);			
+		setChecked(showSegments);
+		
+		if (editor.showsHighlightRangeOnly() != showSegments) {
+			IRegion remembered= editor.getHighlightRange();
+			editor.resetHighlightRange();
+			editor.showHighlightRangeOnly(showSegments);
+			if (remembered != null) {
+				editor.setHighlightRange(remembered.getOffset(), remembered.getLength(), true);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+	 */
+	public void propertyChange(PropertyChangeEvent event) {
+		if (event.getProperty().equals(AntEditorPreferenceConstants.EDITOR_SHOW_SEGMENTS)) {
+            synchronizeWithPreference(getTextEditor());
+        }
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlDocumentFormattingStrategy.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlDocumentFormattingStrategy.java
new file mode 100644
index 0000000..c4cdd69
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlDocumentFormattingStrategy.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 John-Mason P. Shackelford 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:
+ *     John-Mason P. Shackelford - initial API and implementation
+ * 	   IBM Corporation - bug 52076
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.formatter;
+
+import java.util.LinkedList;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy;
+import org.eclipse.jface.text.formatter.FormattingContextProperties;
+import org.eclipse.jface.text.formatter.IFormattingContext;
+
+public class XmlDocumentFormattingStrategy extends ContextBasedFormattingStrategy {
+ 
+	/** Documents to be formatted by this strategy */
+	private final LinkedList fDocuments= new LinkedList();
+    
+	/** access to the preferences store * */
+	private FormattingPreferences prefs; 
+	
+	private int indent= -1;
+	
+	public XmlDocumentFormattingStrategy() {
+	    this.prefs = new FormattingPreferences();
+    }
+ 
+	public XmlDocumentFormattingStrategy(FormattingPreferences prefs, int indent) {
+	    Assert.isNotNull(prefs);
+	    this.prefs = prefs;
+	    this.indent= indent;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.formatter.IFormattingStrategyExtension#format()
+	 */
+	public void format() {
+ 
+        super.format();
+     	final IDocument document= (IDocument)fDocuments.removeFirst();
+		if (document != null) {
+	        // TODO allow formatting of regions, not just the entire document; bug 75611
+	        String documentText = document.get();
+	        XmlDocumentFormatter formatter = new XmlDocumentFormatter();
+	        if (indent != -1) {
+	        	formatter.setInitialIndent(indent);
+	        }
+            formatter.setDefaultLineDelimiter(TextUtilities.getDefaultLineDelimiter(document));
+	        String formattedText = formatter.format(documentText, this.prefs);
+	        if (formattedText != null && !formattedText.equals(documentText)) {
+	        	document.set(formattedText);
+	        }
+		}
+     }
+     
+     /*
+ 	 * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStarts(org.eclipse.jface.text.formatter.IFormattingContext)
+ 	 */
+ 	public void formatterStarts(final IFormattingContext context) {
+ 		super.formatterStarts(context);
+ 		
+ 		fDocuments.addLast(context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM));
+ 	}
+
+ 	/*
+ 	 * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStops()
+ 	 */
+ 	public void formatterStops() {
+ 		super.formatterStops();
+
+ 		fDocuments.clear();
+ 	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlElementFormattingStrategy.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlElementFormattingStrategy.java
new file mode 100644
index 0000000..a0c5341
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlElementFormattingStrategy.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 John-Mason P. Shackelford 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:
+ *     John-Mason P. Shackelford - initial API and implementation
+ * 	   IBM Corporation - bug 52076, bug 84342
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.formatter;
+
+import java.util.LinkedList;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.TypedPosition;
+import org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy;
+import org.eclipse.jface.text.formatter.FormattingContextProperties;
+import org.eclipse.jface.text.formatter.IFormattingContext;
+
+public class XmlElementFormattingStrategy extends ContextBasedFormattingStrategy {
+
+    /** access to the preferences store * */
+    private final FormattingPreferences prefs;
+    
+    /** Documents to be formatted by this strategy */
+	private final LinkedList fDocuments= new LinkedList();
+	/** Partitions to be formatted by this strategy */
+	private final LinkedList fPartitions= new LinkedList();
+
+    public XmlElementFormattingStrategy() {
+        this.prefs = new FormattingPreferences();
+    }
+
+    public XmlElementFormattingStrategy(FormattingPreferences prefs) {
+        Assert.isNotNull(prefs);
+        this.prefs=prefs;
+    }
+    
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.text.formatter.IFormattingStrategyExtension#format()
+     */
+    public void format() {
+
+        super.format();
+                
+    	final IDocument document= (IDocument)fDocuments.removeFirst();
+		final TypedPosition partition= (TypedPosition)fPartitions.removeFirst();
+		
+		if (document == null || partition == null) {
+			return;
+		}
+
+        try {
+            String formatted = formatElement(document, partition);
+            String partitionText = document.get(partition.getOffset(),
+                    partition.getLength());
+
+            if (formatted != null && !formatted.equals(partitionText)) {
+                document.replace(partition.getOffset(), partition.getLength(),
+                        formatted);
+            }
+
+        } catch (BadLocationException e) {
+        }
+    }
+
+    private String formatElement(IDocument document, TypedPosition partition)
+            throws BadLocationException {
+
+        String partitionText = document.get(partition.getOffset(), partition.getLength());
+
+        IRegion line = document.getLineInformationOfOffset(partition.getOffset());
+
+        int indentLength = partition.getOffset() - line.getOffset();
+        String lineDelimiter= document.getLineDelimiter(document.getLineOfOffset(line.getOffset()));
+        if (lineDelimiter == null) {
+            lineDelimiter= TextUtilities.getDefaultLineDelimiter(document);
+        }
+        return XmlTagFormatter.format(partitionText, prefs, document.get(line.getOffset(), indentLength), lineDelimiter);
+
+    }
+
+    /*
+ 	 * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStarts(org.eclipse.jface.text.formatter.IFormattingContext)
+ 	 */
+ 	public void formatterStarts(final IFormattingContext context) {
+ 		super.formatterStarts(context);
+ 		
+ 		fPartitions.addLast(context.getProperty(FormattingContextProperties.CONTEXT_PARTITION));
+ 		fDocuments.addLast(context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM));
+ 	}
+
+ 	/*
+ 	 * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStops()
+ 	 */
+ 	public void formatterStops() {
+ 		super.formatterStops();
+
+ 		fPartitions.clear();
+ 		fDocuments.clear();
+ 	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlTagFormatter.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlTagFormatter.java
new file mode 100644
index 0000000..4ef4a69
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlTagFormatter.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 John-Mason P. Shackelford 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:
+ *     John-Mason P. Shackelford - initial API and implementation
+ *     IBM Corporation - Bug 73411, 84342
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.formatter;
+
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class XmlTagFormatter {
+
+    protected static class AttributePair {
+
+        private String fAttribute;
+        private String fValue;
+        private char fQuote;
+
+        public AttributePair(String attribute, String value, char attributeQuote) {
+            fAttribute = attribute;
+            fValue = value;
+            fQuote= attributeQuote;
+        }
+
+        public String getAttribute() {
+            return fAttribute;
+        }
+
+        public String getValue() {
+            return fValue;
+        }
+        
+        public char getQuote() {
+            return fQuote;
+        }
+    }
+
+    protected static class ParseException extends Exception {
+    	
+		private static final long serialVersionUID = 1L;
+
+		public ParseException(String message) {
+            super(message);
+        }
+    }
+
+    protected static class Tag {
+
+        private List fAttributes = new ArrayList();
+
+        private boolean fClosed;
+
+        private String fElementName;
+
+        public void addAttribute(String attribute, String value, char quote) {
+            fAttributes.add(new AttributePair(attribute, value, quote));
+        }
+
+        public int attributeCount() {
+            return fAttributes.size();
+        }
+
+        public AttributePair getAttributePair(int i) {
+            return (AttributePair) fAttributes.get(i);
+        }
+
+        public String getElementName() {
+            return this.fElementName;
+        }
+
+        public boolean isClosed() {
+            return fClosed;
+        }
+
+        public int minimumLength() {
+            int length = 2; // for the < >
+            if (this.isClosed()) length++; // if we need to add an />
+            length += this.getElementName().length();
+            if (this.attributeCount() > 0 || this.isClosed()) length++;
+            for (int i = 0; i < this.attributeCount(); i++) {
+                AttributePair attributePair = this.getAttributePair(i);
+                length += attributePair.getAttribute().length();
+                length += attributePair.getValue().length();
+                length += 4; // equals sign, quote characters & trailing space
+            }
+            if (this.attributeCount() > 0 && !this.isClosed()) length--;
+            return length;
+        }
+
+        public void setAttributes(List attributePair) {
+            fAttributes.clear();
+            fAttributes.addAll(attributePair);
+        }
+
+        public void setClosed(boolean closed) {
+            fClosed = closed;
+        }
+
+        public void setElementName(String elementName) {
+            fElementName = elementName;
+        }
+
+        public String toString() {
+            StringBuffer sb = new StringBuffer(500);
+            sb.append('<');
+            sb.append(this.getElementName());
+            if (this.attributeCount() > 0 || this.isClosed()) sb.append(' ');
+
+            for (int i = 0; i < this.attributeCount(); i++) {
+                AttributePair attributePair = this.getAttributePair(i);
+                sb.append(attributePair.getAttribute());
+                sb.append('=');
+                sb.append(attributePair.getQuote());
+                sb.append(attributePair.getValue());
+                sb.append(attributePair.getQuote());
+                if (this.isClosed() || i != this.attributeCount() - 1)
+                        sb.append(' ');
+            }
+            if (this.isClosed()) sb.append('/');
+            sb.append('>');
+            return sb.toString();
+        }
+    }
+
+    protected static class TagFormatter {
+
+        private int countChar(char searchChar, String inTargetString) {
+            StringCharacterIterator iter = new StringCharacterIterator(
+                    inTargetString);
+            int i = 0;
+            if (iter.first() == searchChar) i++;
+            while (iter.getIndex() < iter.getEndIndex()) {
+                if (iter.next() == searchChar) {
+                    i++;
+                }
+            }
+            return i;
+        }
+
+        public String format(Tag tag, FormattingPreferences prefs, String indent, String lineDelimiter) {
+            if (prefs.wrapLongTags()
+                    && lineRequiresWrap(indent + tag.toString(), prefs
+                            .getMaximumLineWidth(), prefs.getTabWidth())) {
+                return wrapTag(tag, prefs, indent, lineDelimiter);
+            }
+            return tag.toString();
+        }
+
+        protected boolean lineRequiresWrap(String line, int lineWidth, int tabWidth) {
+            return tabExpandedLineWidth(line, tabWidth) > lineWidth;
+        }
+
+        /**
+         * @param line
+         *            the line in which spaces are to be expanded
+         * @param tabWidth
+         *            number of spaces to substitute for a tab
+         * @return length of the line with tabs expanded to spaces
+         */
+        protected int tabExpandedLineWidth(String line, int tabWidth) {
+            int tabCount = countChar('\t', line);
+            return (line.length() - tabCount) + (tabCount * tabWidth);
+        }
+
+        protected String wrapTag(Tag tag, FormattingPreferences prefs, String indent, String lineDelimiter) {
+            StringBuffer sb = new StringBuffer(1024);
+            sb.append('<');
+            sb.append(tag.getElementName());
+            sb.append(' ');
+
+            if (tag.attributeCount() > 0) {
+                AttributePair pair= tag.getAttributePair(0);
+                sb.append(pair.getAttribute());
+                sb.append('=');
+                sb.append(pair.getQuote());
+                sb.append(tag.getAttributePair(0).getValue());
+                sb.append(pair.getQuote());
+            }
+
+            if (tag.attributeCount() > 1) {
+                char[] extraIndent = new char[tag.getElementName().length() + 2];
+                Arrays.fill(extraIndent, ' ');
+                for (int i = 1; i < tag.attributeCount(); i++) {
+                    AttributePair pair= tag.getAttributePair(i);
+                    sb.append(lineDelimiter);
+                    sb.append(indent);
+                    sb.append(extraIndent);
+                    sb.append(pair.getAttribute());
+                    sb.append('=');
+                    sb.append(pair.getQuote());
+                    sb.append(pair.getValue());
+                    sb.append(pair.getQuote());
+                }
+            }
+
+            if (prefs.alignElementCloseChar()) {
+                sb.append(lineDelimiter);
+                sb.append(indent);
+            } else if (tag.isClosed()) {
+                sb.append(' ');
+            }
+
+            if (tag.isClosed()) sb.append('/');
+            sb.append('>');
+            return sb.toString();
+        }
+    }
+
+    // if object creation is an issue, use static methods or a flyweight
+    // pattern
+    protected static class TagParser {
+
+        private String fElementName;
+
+        private String fParseText;
+
+        protected List getAttibutes(String elementText)
+                throws ParseException {
+
+            class Mode {
+                private int mode;
+                public void setAttributeNameSearching() {mode = 0;}
+                public void setAttributeNameFound() {mode = 1;}
+                public void setAttributeValueSearching() {mode = 2;}
+                public void setAttributeValueFound() {mode = 3;}
+                public void setFinished() {mode = 4;}
+                public boolean isAttributeNameSearching() {return mode == 0;}
+                public boolean isAttributeNameFound() {return mode == 1;}
+                public boolean isAttributeValueSearching() {return mode == 2;}
+                public boolean isAttributeValueFound() {return mode == 3;}
+                public boolean isFinished() {return mode == 4;}
+            }
+
+            List attributePairs = new ArrayList();
+
+            CharacterIterator iter = new StringCharacterIterator(elementText
+                    .substring(getElementName(elementText).length() + 2));
+
+            // state for finding attributes
+            Mode mode = new Mode();
+            mode.setAttributeNameSearching();
+            char attributeQuote = '"';
+            StringBuffer currentAttributeName = null;
+            StringBuffer currentAttributeValue = null;
+
+            char c = iter.first();
+            while (iter.getIndex() < iter.getEndIndex()) {
+                
+                switch (c) {                
+                
+                case '"':
+                case '\'':
+
+                    if (mode.isAttributeValueSearching()) {
+
+                        // start of an attribute value
+                        attributeQuote = c;
+                        mode.setAttributeValueFound();
+                        currentAttributeValue = new StringBuffer(1024);
+
+                    } else if (mode.isAttributeValueFound()
+                            && attributeQuote == c) {
+
+                        // we've completed a pair!
+                        AttributePair pair = new AttributePair(
+                                currentAttributeName.toString(),
+                                currentAttributeValue.toString(), attributeQuote);
+
+                        attributePairs.add(pair);
+
+                        // start looking for another attribute
+                        mode.setAttributeNameSearching();
+
+                    } else if (mode.isAttributeValueFound()
+                            && attributeQuote != c) {
+
+                        // this quote character is part of the attribute value
+                        currentAttributeValue.append(c);
+
+                    } else {
+                        // this is no place for a quote!
+                        throw new ParseException("Unexpected '" + c //$NON-NLS-1$
+                                + "' when parsing:\n\t" + elementText); //$NON-NLS-1$
+                    }
+                    break;
+
+                case '=':
+                    
+                    if (mode.isAttributeValueFound()) {
+
+                        // this character is part of the attribute value
+                        currentAttributeValue.append(c);
+
+                    } else if (mode.isAttributeNameFound()) {
+
+                        // end of the name, now start looking for the value
+                        mode.setAttributeValueSearching();
+                        
+                    } else {
+                        // this is no place for an equals sign!
+                        throw new ParseException("Unexpected '" + c //$NON-NLS-1$
+                                + "' when parsing:\n\t" + elementText); //$NON-NLS-1$
+                    }
+                    break;
+
+                case '/':
+                case '>':
+                    if (mode.isAttributeValueFound()) {
+                        // attribute values are CDATA, add it all
+                        currentAttributeValue.append(c);
+                    } else if (mode.isAttributeNameSearching()) {
+                        mode.setFinished();
+					} else if (mode.isFinished()){
+						// consume the remaining characters
+                    } else {
+                        // we aren't ready to be done!
+                        throw new ParseException("Unexpected '" + c //$NON-NLS-1$
+                                + "' when parsing:\n\t" + elementText); //$NON-NLS-1$
+                    }
+                    break;
+
+                default:
+
+                    if (mode.isAttributeValueFound()) {
+                        // attribute values are CDATA, add it all
+                        currentAttributeValue.append(c);
+
+					} else if (mode.isFinished()) {
+						if (!Character.isWhitespace(c)) {
+								throw new ParseException("Unexpected '" + c //$NON-NLS-1$
+										+ "' when parsing:\n\t" + elementText); //$NON-NLS-1$
+						}
+                    } else {
+                        if (!Character.isWhitespace(c)) {
+                            if (mode.isAttributeNameSearching()) {
+                                // we found the start of an attribute name
+                                mode.setAttributeNameFound();
+                                currentAttributeName = new StringBuffer(255);
+                                currentAttributeName.append(c);
+                            } else if (mode.isAttributeNameFound()) {
+                                currentAttributeName.append(c);                            
+                            }
+                        }
+                    }
+                    break;
+                }
+                
+                c = iter.next();
+            }
+			if (!mode.isFinished()) {
+				throw new ParseException("Element did not complete normally."); //$NON-NLS-1$
+			}
+            return attributePairs;
+        }
+
+        /**
+         * @param tagText
+         *            text of an XML tag
+         * @return extracted XML element name
+         */
+        protected String getElementName(String tagText) throws ParseException {
+            if (!tagText.equals(this.fParseText) || this.fElementName == null) {
+                int endOfTag = tagEnd(tagText);
+                if ((tagText.length() > 2) && (endOfTag > 1)) {
+                    this.fParseText = tagText;
+                    this.fElementName = tagText.substring(1, endOfTag);
+                } else {
+                    throw new ParseException("No element name for the tag:\n\t" //$NON-NLS-1$
+                            + tagText);
+                }
+            }
+            return fElementName;
+        }
+
+        protected boolean isClosed(String tagText) {
+            return tagText.charAt(tagText.lastIndexOf('>') - 1) == '/';
+        }
+
+        /**
+         * @param tagText
+         * @return a fully populated tag
+         */
+        public Tag parse(String tagText) throws ParseException {
+            Tag tag = new Tag();
+            tag.setElementName(getElementName(tagText));
+            tag.setAttributes(getAttibutes(tagText));
+            tag.setClosed(isClosed(tagText));
+            return tag;
+        }
+
+        private int tagEnd(String text) {
+            // This is admittedly a little loose, but we don't want the
+            // formatter to be too strict...
+            // http://www.w3.org/TR/2000/REC-xml-20001006#NT-Name
+            for (int i = 1; i < text.length(); i++) {
+                char c = text.charAt(i);
+                if (!Character.isLetterOrDigit(c) && c != ':' && c != '.'
+                        && c != '-' && c != '_') { return i; }
+            }
+            return -1;
+        }
+    }
+
+    public static String format(String tagText, FormattingPreferences prefs, String indent, String lineDelimiter) {
+
+        Tag tag;
+        if (tagText.startsWith("</") || tagText.startsWith("<%") //$NON-NLS-1$ //$NON-NLS-2$
+                || tagText.startsWith("<?") || tagText.startsWith("<[")) { //$NON-NLS-1$ //$NON-NLS-2$
+            return tagText;
+        } 
+    	try {
+            tag = new TagParser().parse(tagText);
+        } catch (ParseException e) {
+            // if we can't parse the tag, give up and leave the text as is.
+            return tagText;
+        }
+        return new TagFormatter().format(tag, prefs, indent, lineDelimiter);
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/AntOutlineMessages.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/AntOutlineMessages.java
new file mode 100644
index 0000000..89b5968
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/AntOutlineMessages.java
@@ -0,0 +1,36 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ * John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 53547
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.editor.outline;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntOutlineMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.editor.outline.AntOutlineMessages";//$NON-NLS-1$
+	
+	public static String AntEditorContentOutlinePage_Open_With_1;
+
+	public static String FilterInternalTargetsAction_0;
+	public static String FilterImportedElementsAction_0;
+	public static String FilterPropertiesAction_0;
+
+	public static String FilterTopLevelAction_0;
+
+	public static String ToggleSortAntOutlineAction_0;
+
+	public static String ToggleLinkWithEditorAction_0;
+	public static String ToggleLinkWithEditorAction_1;
+	public static String ToggleLinkWithEditorAction_2;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntOutlineMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/AntOutlineMessages.properties b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/AntOutlineMessages.properties
new file mode 100644
index 0000000..403b1cd
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/AntOutlineMessages.properties
@@ -0,0 +1,25 @@
+###############################################################################
+# Copyright (c) 2000, 2008 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
+#     John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 53547
+###############################################################################
+
+AntEditorContentOutlinePage_Open_With_1=Open With
+
+FilterInternalTargetsAction_0=Hide Internal Targets
+FilterImportedElementsAction_0=Hide Imported Elements
+FilterPropertiesAction_0=Hide Properties
+
+FilterTopLevelAction_0=Hide Top Level Elements
+
+ToggleSortAntOutlineAction_0=Sort
+
+ToggleLinkWithEditorAction_0=Lin&k with Editor
+ToggleLinkWithEditorAction_1=Link with Editor
+ToggleLinkWithEditorAction_2=Link with active editor
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterImportedElementsAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterImportedElementsAction.java
new file mode 100644
index 0000000..ed37bb9
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterImportedElementsAction.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 John-Mason P. Shackelford 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:
+ *     John-Mason P. Shackelford - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.outline;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.custom.BusyIndicator;
+
+/** 
+ * An action which toggles filtering of imported elements from the Ant outline.
+ */
+public class FilterImportedElementsAction extends Action {
+    
+	private AntEditorContentOutlinePage fPage;
+	
+	public FilterImportedElementsAction(AntEditorContentOutlinePage page) {
+		super(AntOutlineMessages.FilterImportedElementsAction_0);
+		fPage = page;
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_FILTER_IMPORTED_ELEMENTS));
+		setToolTipText(AntOutlineMessages.FilterImportedElementsAction_0);
+		setChecked(fPage.filterImportedElements());
+	}
+
+    /**
+	 * Toggles the filtering of imported elements from the Ant outline
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		BusyIndicator.showWhile(fPage.getControl().getDisplay(), new Runnable() {
+			public void run() {
+				fPage.setFilterImportedElements(isChecked());
+			}
+		});
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterInternalTargetsAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterInternalTargetsAction.java
new file mode 100644
index 0000000..84b8c3d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterInternalTargetsAction.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.outline;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.custom.BusyIndicator;
+
+/** 
+ * An action which toggles filtering of internal targets from the Ant outline.
+ */
+public class FilterInternalTargetsAction extends Action {
+	
+	private AntEditorContentOutlinePage fPage;
+	
+	public FilterInternalTargetsAction(AntEditorContentOutlinePage page) {
+		super(AntOutlineMessages.FilterInternalTargetsAction_0);
+		fPage = page;
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_FILTER_INTERNAL_TARGETS));
+		setToolTipText(AntOutlineMessages.FilterInternalTargetsAction_0);
+		setChecked(fPage.filterInternalTargets());
+	}
+	
+	/**
+	 * Toggles the filtering of internal targets from the Ant outline
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		BusyIndicator.showWhile(fPage.getControl().getDisplay(), new Runnable() {
+			public void run() {
+				fPage.setFilterInternalTargets(isChecked());
+			}
+		});
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterPropertiesAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterPropertiesAction.java
new file mode 100644
index 0000000..f36aef2
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterPropertiesAction.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.outline;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.custom.BusyIndicator;
+
+/** 
+ * An action which toggles filtering of properties from the Ant outline.
+ */
+public class FilterPropertiesAction extends Action {
+	
+	private AntEditorContentOutlinePage fPage;
+	
+	public FilterPropertiesAction(AntEditorContentOutlinePage page) {
+		super(AntOutlineMessages.FilterPropertiesAction_0);
+		fPage = page;
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_FILTER_PROPERTIES));
+		setToolTipText(AntOutlineMessages.FilterPropertiesAction_0);
+		setChecked(fPage.filterProperties());
+	}
+	
+	/**
+	 * Toggles the filtering of properties from the Ant outline
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		BusyIndicator.showWhile(fPage.getControl().getDisplay(), new Runnable() {
+			public void run() {
+				fPage.setFilterProperties(isChecked());
+			}
+		});
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterTopLevelAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterTopLevelAction.java
new file mode 100644
index 0000000..398ea89
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/FilterTopLevelAction.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.outline;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.custom.BusyIndicator;
+
+/** 
+ * An action which toggles filtering of properties from the Ant outline.
+ */
+public class FilterTopLevelAction extends Action {
+	
+	private AntEditorContentOutlinePage fPage;
+	
+	public FilterTopLevelAction(AntEditorContentOutlinePage page) {
+		super(AntOutlineMessages.FilterTopLevelAction_0);
+		fPage = page;
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_FILTER_TOP_LEVEL));
+		setToolTipText(AntOutlineMessages.FilterTopLevelAction_0);
+		setChecked(fPage.filterTopLevel());
+	}
+	
+	/**
+	 * Toggles the filtering of top level tasks and types from the Ant outline
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		BusyIndicator.showWhile(fPage.getControl().getDisplay(), new Runnable() {
+			public void run() {
+				fPage.setFilterTopLevel(isChecked());
+			}
+		});
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/ToggleLinkWithEditorAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/ToggleLinkWithEditorAction.java
new file mode 100644
index 0000000..e08ce64
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/ToggleLinkWithEditorAction.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.outline;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
+import org.eclipse.ant.internal.ui.editor.AntEditor;
+import org.eclipse.jface.action.Action;
+
+/**
+ * This action toggles whether the Ant Outline page links its selection to the
+ * active editor.
+ * 
+ * @since 3.0
+ */
+public class ToggleLinkWithEditorAction extends Action {
+	
+	AntEditor fEditor;
+	
+	public ToggleLinkWithEditorAction(AntEditor editor) {
+		super(AntOutlineMessages.ToggleLinkWithEditorAction_0);
+		boolean isLinkingEnabled = AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.OUTLINE_LINK_WITH_EDITOR);
+		setChecked(isLinkingEnabled);
+		fEditor = editor;
+		setToolTipText(AntOutlineMessages.ToggleLinkWithEditorAction_1);
+		setDescription(AntOutlineMessages.ToggleLinkWithEditorAction_2);
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_LINK_WITH_EDITOR));
+	}
+	
+	public void run() {
+		AntUIPlugin.getDefault().getPreferenceStore().setValue(IAntUIPreferenceConstants.OUTLINE_LINK_WITH_EDITOR, isChecked());
+		if (isChecked())
+			fEditor.synchronizeOutlinePage(false);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/ToggleSortAntOutlineAction.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/ToggleSortAntOutlineAction.java
new file mode 100644
index 0000000..033b30b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/outline/ToggleSortAntOutlineAction.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.outline;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.jface.action.Action;
+
+/**
+ * An action which toggles sorting in the Ant outline page.
+ */
+public class ToggleSortAntOutlineAction extends Action {
+
+	private AntEditorContentOutlinePage fPage;
+	
+	public ToggleSortAntOutlineAction(AntEditorContentOutlinePage page) {
+		super(AntOutlineMessages.ToggleSortAntOutlineAction_0);
+		fPage = page;
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_SORT_OUTLINE));
+		setToolTipText(AntOutlineMessages.ToggleSortAntOutlineAction_0);
+		setChecked(fPage.isSort());
+	}
+	
+	/**
+	 * Toggles the sorting of targets in the Ant outline
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		fPage.setSort(isChecked());
+	}
+	
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateAccess.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateAccess.java
new file mode 100644
index 0000000..db97e70
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateAccess.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.templates;
+
+import java.io.IOException;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.jface.text.templates.ContextTypeRegistry;
+import org.eclipse.jface.text.templates.persistence.TemplateStore;
+import org.eclipse.ui.editors.text.templates.ContributionContextTypeRegistry;
+import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
+
+
+public class AntTemplateAccess {
+	/** Key to store custom templates. */
+	private static final String CUSTOM_TEMPLATES_KEY= "org.eclipse.ant.ui.customtemplates"; //$NON-NLS-1$
+	
+	/** The shared instance. */
+	private static AntTemplateAccess fgInstance;
+	
+	/** The template store. */
+	private TemplateStore fStore;
+	
+	/** The context type registry. */
+	private ContributionContextTypeRegistry fRegistry;
+	
+	private AntTemplateAccess() {
+	}
+
+	/**
+	 * Returns the shared instance.
+	 * 
+	 * @return the shared instance
+	 */
+	public static AntTemplateAccess getDefault() {
+		if (fgInstance == null) {
+			fgInstance= new AntTemplateAccess();
+		}
+		return fgInstance;
+	}
+
+	/**
+	 * Returns this plug-in's template store.
+	 * 
+	 * @return the template store of this plug-in instance
+	 */
+	public TemplateStore getTemplateStore() {
+		if (fStore == null) {
+			fStore= new ContributionTemplateStore(getContextTypeRegistry(),AntUIPlugin.getDefault().getPreferenceStore(), CUSTOM_TEMPLATES_KEY);
+			try {
+				fStore.load();
+			} catch (IOException e) {
+				AntUIPlugin.log(e);
+			}
+		}
+		return fStore;
+	}
+
+	/**
+	 * Returns this plug-in's context type registry.
+	 * 
+	 * @return the context type registry for this plug-in instance
+	 */
+	public ContextTypeRegistry getContextTypeRegistry() {
+		if (fRegistry == null) {
+			// create and configure the contexts available in the template editor
+			fRegistry= new ContributionContextTypeRegistry();
+			fRegistry.addContextType(BuildFileContextType.BUILDFILE_CONTEXT_TYPE);
+			fRegistry.addContextType(TargetContextType.TARGET_CONTEXT_TYPE);
+			fRegistry.addContextType(TaskContextType.TASK_CONTEXT_TYPE);
+		}
+		return fRegistry;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateInformationControlCreator.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateInformationControlCreator.java
new file mode 100644
index 0000000..5a061c9
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateInformationControlCreator.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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 implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.templates;
+
+import org.eclipse.ant.internal.ui.editor.AntSourceViewerInformationControl;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IInformationControlCreatorExtension;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class AntTemplateInformationControlCreator implements IInformationControlCreator, IInformationControlCreatorExtension {
+	
+	private AntSourceViewerInformationControl fControl;
+	
+	public AntTemplateInformationControlCreator()  {
+	}
+	
+	/*
+	 * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell)
+	 */
+	public IInformationControl createInformationControl(Shell parent) {
+		fControl= new AntSourceViewerInformationControl(parent);
+		fControl.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				fControl= null;
+			}
+		});
+		return fControl;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReuse(org.eclipse.jface.text.IInformationControl)
+	 */
+	public boolean canReuse(IInformationControl control) {
+		return fControl == control && fControl != null;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReplace(org.eclipse.jface.text.IInformationControlCreator)
+	 */
+	public boolean canReplace(IInformationControlCreator creator) {
+		return (creator != null && getClass() == creator.getClass());
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateProposal.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateProposal.java
new file mode 100644
index 0000000..b2894b3
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateProposal.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.templates;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateProposal;
+import org.eclipse.swt.graphics.Image;
+
+public class AntTemplateProposal extends TemplateProposal {
+	
+	public AntTemplateProposal(Template template, TemplateContext context, IRegion region, Image image, int relevance) {
+		super(template, context, region, image, relevance);
+	}
+	
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument, int, org.eclipse.jface.text.DocumentEvent)
+     */
+    public boolean validate(IDocument document, int offset, DocumentEvent event) {
+        try {
+			int replaceOffset= getReplaceOffset();
+			if (offset >= replaceOffset) {
+				String content= document.get(replaceOffset, offset - replaceOffset);
+                if (content.length() == 0) {
+                    return true;
+                }
+				if (content.charAt(0) == '<') {
+				    content= content.substring(1);
+				}
+				return getTemplate().getName().toLowerCase().startsWith(content.toLowerCase());
+			}
+		} catch (BadLocationException e) {
+			// concurrent modification - ignore
+		}
+		return false;
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateVariableTextHover.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateVariableTextHover.java
new file mode 100644
index 0000000..5444c6a
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateVariableTextHover.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+ 
+package org.eclipse.ant.internal.ui.editor.templates;
+
+import java.util.Iterator;
+import org.eclipse.ant.internal.ui.editor.text.XMLTextHover;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+
+public class AntTemplateVariableTextHover implements ITextHover {
+
+	public AntTemplateVariableTextHover() {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
+	 */
+	public String getHoverInfo(ITextViewer textViewer, IRegion subject) {
+		try {
+			IDocument doc= textViewer.getDocument();
+			int offset= subject.getOffset();
+			if (offset >= 2 && "${".equals(doc.get(offset-2, 2))) { //$NON-NLS-1$
+				String varName= doc.get(offset, subject.getLength());
+				TemplateContextType contextType= AntTemplateAccess.getDefault().getContextTypeRegistry().getContextType(TaskContextType.TASK_CONTEXT_TYPE);
+				if (contextType != null) {
+					Iterator iter= contextType.resolvers();
+					while (iter.hasNext()) {
+						TemplateVariableResolver var= (TemplateVariableResolver) iter.next();
+						if (varName.equals(var.getType())) {
+							return var.getDescription();
+						}
+					}
+				}
+			}				
+		} catch (BadLocationException e) {
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
+	 */
+	public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+		if (textViewer != null) {
+			return XMLTextHover.getRegion(textViewer, offset);
+		}
+		return null;	
+	}
+} 
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateViewerConfiguration.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateViewerConfiguration.java
new file mode 100644
index 0000000..27e4b59
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntTemplateViewerConfiguration.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.templates;
+
+import org.eclipse.ant.internal.ui.AntSourceViewerConfiguration;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+public class AntTemplateViewerConfiguration extends AntSourceViewerConfiguration {
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTextHover(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
+	 */
+	public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+		return new AntTemplateVariableTextHover();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntVariableResolver.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntVariableResolver.java
new file mode 100644
index 0000000..15e067b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/AntVariableResolver.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.templates;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+
+/**
+ * Looks up existing ant variables and proposes them. The proposals are sorted by 
+ * their prefix-likeness with the variable type.
+ */
+public class AntVariableResolver extends TemplateVariableResolver {
+	/*
+	 * @see org.eclipse.jface.text.templates.TemplateVariableResolver#resolveAll(org.eclipse.jface.text.templates.TemplateContext)
+	 */
+	protected String[] resolveAll(TemplateContext context) {
+		String[] proposals= new String[] { "${srcDir}", "${dstDir}" }; //$NON-NLS-1$ //$NON-NLS-2$
+		
+		Arrays.sort(proposals, new Comparator() {
+
+			public int compare(Object o1, Object o2) {
+				return getCommonPrefixLength(getType(), (String) o2) - getCommonPrefixLength(getType(), (String) o1);
+			}
+
+			private int getCommonPrefixLength(String type, String var) {
+				int i= 0;
+				CharSequence vSeq= var.subSequence(2, var.length() - 1); // strip away ${}
+				while (i < type.length() && i < vSeq.length())
+					if (Character.toLowerCase(type.charAt(i)) == Character.toLowerCase(vSeq.charAt(i)))
+						i++;
+					else
+						break;
+				return i;
+			}
+		});
+		
+		return proposals;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/BuildFileContextType.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/BuildFileContextType.java
new file mode 100644
index 0000000..76bddf7
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/BuildFileContextType.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.templates;
+
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+
+
+/**
+ * A very simple context type.
+ */
+public class BuildFileContextType extends TemplateContextType {
+
+	/** This context's id */
+	public static final String BUILDFILE_CONTEXT_TYPE= "org.eclipse.ant.ui.templateContextType.buildFile"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new XML context type. 
+	 */
+	public BuildFileContextType() {
+		addGlobalResolvers();
+	}
+
+	private void addGlobalResolvers() {
+		addResolver(new GlobalTemplateVariables.Cursor());
+		addResolver(new GlobalTemplateVariables.WordSelection());
+		addResolver(new GlobalTemplateVariables.LineSelection());
+		addResolver(new GlobalTemplateVariables.Dollar());
+		addResolver(new GlobalTemplateVariables.Date());
+		addResolver(new GlobalTemplateVariables.Year());
+		addResolver(new GlobalTemplateVariables.Time());
+		addResolver(new GlobalTemplateVariables.User());
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/TargetContextType.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/TargetContextType.java
new file mode 100644
index 0000000..8dfa2b0
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/TargetContextType.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.templates;
+
+public class TargetContextType extends BuildFileContextType {
+	public static final String TARGET_CONTEXT_TYPE= "org.eclipse.ant.ui.templateContextType.target"; //$NON-NLS-1$
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/TaskContextType.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/TaskContextType.java
new file mode 100644
index 0000000..56d8f9a
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/templates/TaskContextType.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.templates;
+
+public class TaskContextType extends BuildFileContextType {
+	public static final String TASK_CONTEXT_TYPE= "org.eclipse.ant.ui.templateContextType.task"; //$NON-NLS-1$
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AbstractAntEditorScanner.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AbstractAntEditorScanner.java
new file mode 100644
index 0000000..63e5b02
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AbstractAntEditorScanner.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * 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 implementation
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.ColorManager;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+
+public abstract class AbstractAntEditorScanner extends RuleBasedScanner {
+
+	protected void adaptToColorChange(PropertyChangeEvent event, Token token) {
+		RGB rgb= null;
+		
+		Object value= event.getNewValue();
+		if (value instanceof RGB) {
+			rgb= (RGB) value;
+		} else if (value instanceof String) {
+			rgb= StringConverter.asRGB((String) value);
+		}
+			
+		if (rgb != null) {
+			TextAttribute attr= (TextAttribute) token.getData();
+			token.setData(new TextAttribute(ColorManager.getDefault().getColor(rgb), attr.getBackground(), attr.getStyle()));
+		}
+	}
+
+	protected void adaptToStyleChange(PropertyChangeEvent event, Token token, int styleAttribute) {
+	 	if (token == null) {
+			return;
+		}
+		boolean eventValue= false;
+		Object value= event.getNewValue();
+		if (value instanceof Boolean) {
+			eventValue= ((Boolean) value).booleanValue();
+		} else if (IPreferenceStore.TRUE.equals(value)) {
+			eventValue= true;
+		}
+		
+		TextAttribute attr= (TextAttribute) token.getData();
+		boolean activeValue= (attr.getStyle() & styleAttribute) == styleAttribute;
+		if (activeValue != eventValue) { 
+			token.setData(new TextAttribute(attr.getForeground(), attr.getBackground(), eventValue ? attr.getStyle() | styleAttribute : attr.getStyle() & ~styleAttribute));
+		}
+	}
+
+	protected TextAttribute createTextAttribute(String colorID, String boldKey, String italicKey) {
+		Color color= null;
+		if (colorID != null) {
+			color= AntUIPlugin.getPreferenceColor(colorID);
+		}
+		IPreferenceStore store= AntUIPlugin.getDefault().getPreferenceStore();
+		int style= store.getBoolean(boldKey) ? SWT.BOLD : SWT.NORMAL;
+		if (store.getBoolean(italicKey)) {
+			style |= SWT.ITALIC;
+		}
+		
+		return new TextAttribute(color, null, style);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AnnotationModelFactory.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AnnotationModelFactory.java
new file mode 100644
index 0000000..4cbb25f
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AnnotationModelFactory.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.IAnnotationModelFactory;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+public class AnnotationModelFactory implements IAnnotationModelFactory {
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.filebuffers.IAnnotationModelFactory#createAnnotationModel(org.eclipse.core.runtime.IPath)
+     */
+    public IAnnotationModel createAnnotationModel(IPath location) {
+        IFile file = FileBuffers.getWorkspaceFileAtLocation(location);
+        if (file == null) {
+            return new AntExternalAnnotationModel();
+        }
+        return new AntAnnotationModel(file);
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntAnnotationModel.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntAnnotationModel.java
new file mode 100644
index 0000000..e055a50
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntAnnotationModel.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.internal.launching.debug.IAntDebugConstants;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.editor.outline.AntEditorMarkerUpdater;
+import org.eclipse.ant.internal.ui.model.IProblem;
+import org.eclipse.ant.internal.ui.model.IProblemRequestor;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.AnnotationModelEvent;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.MarkerUtilities;
+import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
+
+public class AntAnnotationModel extends ResourceMarkerAnnotationModel implements IProblemRequestor {
+	
+	private List fGeneratedAnnotations= new ArrayList();
+	private List fCollectedProblems= new ArrayList();
+	
+	public AntAnnotationModel(IFile file) {
+		super(file);
+	}
+
+	/*
+	 * @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#createMarkerAnnotation(org.eclipse.core.resources.IMarker)
+	 */
+	protected MarkerAnnotation createMarkerAnnotation(IMarker marker) {
+		String markerType= MarkerUtilities.getMarkerType(marker);
+		if (AntEditorMarkerUpdater.BUILDFILE_PROBLEM_MARKER.equals(markerType)) {
+		    //we currently do not show Ant buildfile problem markers in the Ant editor as we have no notion of 
+		    //annotation overlays
+		    //bug 
+			return null;
+		}
+		return new MarkerAnnotation(EditorsUI.getAnnotationTypeLookup().getAnnotationType(marker), marker);
+	}
+
+	protected Position createPositionFromProblem(IProblem problem) {
+		int start= problem.getOffset();
+		if (start >= 0) {
+			int length= problem.getLength();
+				
+			if (length >= 0)
+				return new Position(start, length);
+		}
+
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblemRequestor#acceptProblem(org.eclipse.ant.internal.ui.editor.outline.IProblem)
+	 */
+	public void acceptProblem(IProblem problem) {
+		fCollectedProblems.add(problem);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblemRequestor#acceptProblem(org.eclipse.ant.internal.ui.editor.outline.IProblem)
+	 */
+	public void beginReporting() {
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblemRequestor#acceptProblem(org.eclipse.ant.internal.ui.editor.outline.IProblem)
+	 */
+	public void endReporting() {
+		boolean temporaryProblemsChanged= false;
+			
+		synchronized (getAnnotationMap()) {
+				
+			if (fGeneratedAnnotations.size() > 0) {
+				temporaryProblemsChanged= true;	
+				removeAnnotations(fGeneratedAnnotations, false, true);
+				fGeneratedAnnotations.clear();
+			}
+				
+			if (fCollectedProblems != null && fCollectedProblems.size() > 0) {
+				Iterator e= fCollectedProblems.iterator();
+				while (e.hasNext()) {
+						
+					IProblem problem= (IProblem) e.next();
+						
+					Position position= createPositionFromProblem(problem);
+					if (position != null) {
+							
+						XMLProblemAnnotation annotation= new XMLProblemAnnotation(problem);
+						fGeneratedAnnotations.add(annotation);
+						try {
+							addAnnotation(annotation, position, false);
+						} catch (BadLocationException ex) {
+							AntUIPlugin.log(ex);
+						}
+							
+						temporaryProblemsChanged= true;
+					}
+				}
+					
+				fCollectedProblems.clear();
+			}
+		}
+				
+		if (temporaryProblemsChanged)
+			fireModelChanged(new AnnotationModelEvent(this));
+	}
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#isAcceptable(org.eclipse.core.resources.IMarker)
+     */
+    protected boolean isAcceptable(IMarker marker) {
+        if (super.isAcceptable(marker)) {
+          return !marker.getAttribute(IAntDebugConstants.ANT_RUN_TO_LINE, false);  
+        }
+        return false;
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntDocumentSetupParticipant.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntDocumentSetupParticipant.java
new file mode 100644
index 0000000..124bf94
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntDocumentSetupParticipant.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * 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 implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+
+/**
+ * The document setup participant for Ant.
+ */
+public class AntDocumentSetupParticipant  implements IDocumentSetupParticipant {
+
+	/**
+	 * The name of the Ant partitioning.
+	 * @since 3.0
+	 */
+	public final static String ANT_PARTITIONING= "org.eclipse.ant.ui.antPartitioning";  //$NON-NLS-1$
+	
+	public AntDocumentSetupParticipant() {
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.filebuffers.IDocumentSetupParticipant#setup(org.eclipse.jface.text.IDocument)
+	 */
+	public void setup(IDocument document) {
+		if (document instanceof IDocumentExtension3) {
+			IDocumentExtension3 extension3= (IDocumentExtension3) document;
+			IDocumentPartitioner partitioner = createDocumentPartitioner();
+			extension3.setDocumentPartitioner(ANT_PARTITIONING, partitioner);
+			partitioner.connect(document);
+		} 
+	}
+	
+	private IDocumentPartitioner createDocumentPartitioner() {
+		return new FastPartitioner(
+				new AntEditorPartitionScanner(), new String[]{
+						AntEditorPartitionScanner.XML_TAG,
+						AntEditorPartitionScanner.XML_COMMENT, 
+						AntEditorPartitionScanner.XML_CDATA,
+						AntEditorPartitionScanner.XML_DTD});
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorPartitionScanner.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorPartitionScanner.java
new file mode 100644
index 0000000..a1bcdcb
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorPartitionScanner.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2006 GEBIT Gesellschaft fuer EDV-Beratung
+ * und Informatik-Technologien mbH, 
+ * Berlin, Duesseldorf, Frankfurt (Germany) 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:
+ *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
+ * 	   IBM Corporation - bug 32890, bug 24108, bug 111740
+ *     John-Mason P. Shackelford - bug 57379
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+/*
+ * This file originates from an internal package of Eclipse's 
+ * Manifest Editor. It has been copied by GEBIT to here in order to
+ * permanently use those features. It has been renamed and edited by GEBIT 
+ * after copying.
+ */
+
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * Scanner that scans the document and partitions the document into the four 
+ * supported content types:
+ * <ul>
+ * <li>XML_COMMENT</li>
+ * <li>XML_TAG</li>
+ * <li>XML_CDATA</li>
+ * <li>XML_DTD</li>
+ * </ul>
+ */
+public class AntEditorPartitionScanner extends RuleBasedPartitionScanner {
+
+	public final static String XML_COMMENT = "__xml_comment"; //$NON-NLS-1$
+	public final static String XML_TAG = "__xml_tag"; //$NON-NLS-1$
+	public final static String XML_CDATA = "__xml_cdata"; //$NON-NLS-1$
+	public final static String XML_DTD = "__xml_dtd"; //$NON-NLS-1$
+	
+    /**
+     * Creates an instance.
+     */
+	public AntEditorPartitionScanner() {
+
+		IPredicateRule[] rules =new IPredicateRule[4];
+
+        IToken xmlCDATA = new Token(XML_CDATA);
+		rules[0]= new MultiLineRule("<![CDATA[", "]]>", xmlCDATA); //$NON-NLS-1$ //$NON-NLS-2$
+		
+        IToken xmlComment = new Token(XML_COMMENT);
+		rules[1]= new MultiLineRule("<!--", "-->", xmlComment, '\\', true); //$NON-NLS-1$ //$NON-NLS-2$
+
+        IToken tag = new Token(XML_TAG);
+		rules[2]= new TagRule(tag);
+	
+		IToken xmlDTD = new Token(XML_DTD);
+		rules[3]= new DocTypeRule(xmlDTD);
+		
+		setPredicateRules(rules);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorProcInstrScanner.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorProcInstrScanner.java
new file mode 100644
index 0000000..ee5ccdf
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorProcInstrScanner.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 GEBIT Gesellschaft fuer EDV-Beratung
+ * und Informatik-Technologien mbH, 
+ * Berlin, Duesseldorf, Frankfurt (Germany) 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:
+ *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
+ * 	   IBM Corporation - bug fixes
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+
+/**
+ * The scanner to tokenize for XML processing instructions and text
+ */
+public class AntEditorProcInstrScanner extends AbstractAntEditorScanner {
+
+	Token fProcInstructionToken= null;
+	
+    public AntEditorProcInstrScanner() {
+		IRule[] rules =new IRule[2];
+        fProcInstructionToken =
+            new Token(createTextAttribute(IAntEditorColorConstants.PROCESSING_INSTRUCTIONS_COLOR, 
+					IAntEditorColorConstants.PROCESSING_INSTRUCTIONS_COLOR + AntEditorPreferenceConstants.EDITOR_BOLD_SUFFIX,
+					IAntEditorColorConstants.PROCESSING_INSTRUCTIONS_COLOR + AntEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX));
+
+        //Add rule for processing instructions
+        rules[0]= new MultiLineRule("<?", "?>", fProcInstructionToken); //$NON-NLS-1$ //$NON-NLS-2$
+
+        // Add generic whitespace rule.
+        rules[1]= new WhitespaceRule(new AntEditorWhitespaceDetector());
+
+        setRules(rules);
+        
+        setDefaultReturnToken(new Token(createTextAttribute(IAntEditorColorConstants.TEXT_COLOR, 
+    							IAntEditorColorConstants.TEXT_COLOR + AntEditorPreferenceConstants.EDITOR_BOLD_SUFFIX,
+								IAntEditorColorConstants.TEXT_COLOR + AntEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX)));
+    }
+
+	private Token getTokenAffected(PropertyChangeEvent event) {
+    	if (event.getProperty().startsWith(IAntEditorColorConstants.PROCESSING_INSTRUCTIONS_COLOR)) {
+    		return fProcInstructionToken;
+    	}
+    	return (Token)fDefaultReturnToken;
+    }
+    
+    public void adaptToPreferenceChange(PropertyChangeEvent event) {
+    	String property= event.getProperty();
+    	if (property.startsWith(IAntEditorColorConstants.TEXT_COLOR) || property.startsWith(IAntEditorColorConstants.PROCESSING_INSTRUCTIONS_COLOR)) {    		
+    		if (property.endsWith(AntEditorPreferenceConstants.EDITOR_BOLD_SUFFIX)) {
+	    		adaptToStyleChange(event, getTokenAffected(event), SWT.BOLD);
+	    	} else if (property.endsWith(AntEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX)) {
+	    		adaptToStyleChange(event, getTokenAffected(event), SWT.ITALIC);
+	    	} else {
+	    		adaptToColorChange(event, getTokenAffected(event));
+	    	}
+    	}
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorTagScanner.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorTagScanner.java
new file mode 100644
index 0000000..f7b50b2
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorTagScanner.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 GEBIT Gesellschaft fuer EDV-Beratung
+ * und Informatik-Technologien mbH, 
+ * Berlin, Duesseldorf, Frankfurt (Germany) 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:
+ *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
+ * 	   IBM Corporation - bug 31796, bug 24108, bug 47139
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+
+/**
+ * The scanner to tokenize for strings and tags
+ */
+public class AntEditorTagScanner extends AbstractAntEditorScanner {
+
+	private Token fStringToken;
+	
+    public AntEditorTagScanner() {
+    	fStringToken= new Token(
+    			createTextAttribute(IAntEditorColorConstants.STRING_COLOR, 
+    					IAntEditorColorConstants.STRING_COLOR + AntEditorPreferenceConstants.EDITOR_BOLD_SUFFIX,
+						IAntEditorColorConstants.STRING_COLOR + AntEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX));
+                    
+		IRule[] rules= new IRule[3];
+
+        // Add rule for single and double quotes
+        rules[0]= new MultiLineRule("\"", "\"", fStringToken, '\\'); //$NON-NLS-1$ //$NON-NLS-2$
+        rules[1]= new SingleLineRule("'", "'", fStringToken, '\\'); //$NON-NLS-1$ //$NON-NLS-2$
+
+        // Add generic whitespace rule.
+        rules[2]= new WhitespaceRule(new AntEditorWhitespaceDetector());
+
+        setRules(rules);
+        
+        setDefaultReturnToken(
+        		new Token(createTextAttribute(IAntEditorColorConstants.TAG_COLOR, 
+    					IAntEditorColorConstants.TAG_COLOR + AntEditorPreferenceConstants.EDITOR_BOLD_SUFFIX,
+						IAntEditorColorConstants.TAG_COLOR + AntEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX)));
+    }
+    
+    public void adaptToPreferenceChange(PropertyChangeEvent event) {
+    	String property= event.getProperty();
+    	if (property.startsWith(IAntEditorColorConstants.TAG_COLOR) || property.startsWith(IAntEditorColorConstants.STRING_COLOR)) {
+    		if (property.endsWith(AntEditorPreferenceConstants.EDITOR_BOLD_SUFFIX)) {
+    			adaptToStyleChange(event, getTokenAffected(event), SWT.BOLD);
+    		} else if (property.endsWith(AntEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX)) {
+    			adaptToStyleChange(event, getTokenAffected(event), SWT.ITALIC);
+    		} else {
+    			adaptToColorChange(event, getTokenAffected(event));
+    		}
+    	}
+    }
+    
+    private Token getTokenAffected(PropertyChangeEvent event) {
+    	String property= event.getProperty();
+    	if (property.startsWith(IAntEditorColorConstants.STRING_COLOR)) {
+    		return fStringToken;
+    	}// else if (property.startsWith(IAntEditorColorConstants.TAG_COLOR)) {
+    		return (Token)fDefaultReturnToken;
+    	//}
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorTextMessages.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorTextMessages.java
new file mode 100644
index 0000000..f72a558
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorTextMessages.java
@@ -0,0 +1,25 @@
+/**********************************************************************
+ * Copyright (c) 2004, 2007 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntEditorTextMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.editor.text.AntEditorTextMessages";//$NON-NLS-1$
+
+	public static String XMLTextHover_4;
+	public static String XMLTextHover_5;
+	public static String XMLTextHover_6;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntEditorTextMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorTextMessages.properties b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorTextMessages.properties
new file mode 100644
index 0000000..9e7f72b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorTextMessages.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2004, 2007 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
+###############################################################################
+
+XMLTextHover_4=Path Elements:
+XMLTextHover_5=Includes:
+XMLTextHover_6=Excludes:
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorWhitespaceDetector.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorWhitespaceDetector.java
new file mode 100644
index 0000000..e65ff58
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntEditorWhitespaceDetector.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 GEBIT Gesellschaft fuer EDV-Beratung
+ * und Informatik-Technologien mbH, 
+ * Berlin, Duesseldorf, Frankfurt (Germany) 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:
+ *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
+ * 	   IBM Corporation - bug 29148
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+/*
+ * This file originates from an internal package of Eclipse's 
+ * Manifest Editor. It has been copied by GEBIT to here in order to
+ * permanently use those features. It has been renamed by GEBIT 
+ * after copying.
+ */
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+public class AntEditorWhitespaceDetector implements IWhitespaceDetector {
+
+	public boolean isWhitespace(char c) {
+		return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntExternalAnnotationModel.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntExternalAnnotationModel.java
new file mode 100644
index 0000000..69174f9
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntExternalAnnotationModel.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.model.IProblem;
+import org.eclipse.ant.internal.ui.model.IProblemRequestor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.eclipse.jface.text.source.AnnotationModelEvent;
+
+public class AntExternalAnnotationModel extends AnnotationModel implements IProblemRequestor {
+
+    private List fGeneratedAnnotations= new ArrayList();
+	private List fCollectedProblems= new ArrayList();
+
+    /* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblemRequestor#acceptProblem(org.eclipse.ant.internal.ui.editor.outline.IProblem)
+	 */
+	public void acceptProblem(IProblem problem) {
+		fCollectedProblems.add(problem);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblemRequestor#acceptProblem(org.eclipse.ant.internal.ui.editor.outline.IProblem)
+	 */
+	public void endReporting() {
+		boolean temporaryProblemsChanged= false;
+			
+		synchronized (getAnnotationMap()) {
+				
+			if (fGeneratedAnnotations.size() > 0) {
+				temporaryProblemsChanged= true;	
+				removeAnnotations(fGeneratedAnnotations, false, true);
+				fGeneratedAnnotations.clear();
+			}
+				
+			if (fCollectedProblems != null && fCollectedProblems.size() > 0) {
+				Iterator e= fCollectedProblems.iterator();
+				while (e.hasNext()) {
+						
+					IProblem problem= (IProblem) e.next();
+						
+					Position position= createPositionFromProblem(problem);
+					if (position != null) {
+							
+						XMLProblemAnnotation annotation= new XMLProblemAnnotation(problem);
+						fGeneratedAnnotations.add(annotation);
+						try {
+							addAnnotation(annotation, position, false);
+						} catch (BadLocationException ex) {
+							AntUIPlugin.log(ex);
+						}
+							
+						temporaryProblemsChanged= true;
+					}
+				}
+					
+				fCollectedProblems.clear();
+			}
+		}
+				
+		if (temporaryProblemsChanged)
+			fireModelChanged(new AnnotationModelEvent(this));
+	}
+					
+	protected Position createPositionFromProblem(IProblem problem) {
+		int start= problem.getOffset();
+		if (start >= 0) {
+			int length= problem.getLength();
+				
+			if (length >= 0)
+				return new Position(start, length);
+		}
+
+		return null;
+	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ant.internal.ui.model.IProblemRequestor#beginReporting()
+     */
+    public void beginReporting() {
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntInformationProvider.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntInformationProvider.java
new file mode 100644
index 0000000..de57b95
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntInformationProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+ 
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.information.IInformationProvider;
+
+public class AntInformationProvider implements IInformationProvider {
+
+	XMLTextHover fTextHover;
+	
+	public AntInformationProvider(XMLTextHover hover) {
+		fTextHover= hover;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer, int)
+	 */
+	public IRegion getSubject(ITextViewer textViewer, int offset) {
+		return fTextHover.getHoverRegion(textViewer, offset);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.information.IInformationProvider#getInformation(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
+	 */
+	public String getInformation(ITextViewer textViewer, IRegion subject) {
+		return fTextHover.getHoverInfo(textViewer, subject);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntStorageDocumentProvider.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntStorageDocumentProvider.java
new file mode 100644
index 0000000..93b9286
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/AntStorageDocumentProvider.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * 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 implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.ui.editors.text.StorageDocumentProvider;
+
+/**
+ * @since 3.0
+ */
+public class AntStorageDocumentProvider extends StorageDocumentProvider {
+	
+	/*
+	 * @see org.eclipse.ui.editors.text.StorageDocumentProvider#setupDocument(java.lang.Object,
+	 *      org.eclipse.jface.text.IDocument)
+	 */
+	protected void setupDocument(Object element, IDocument document) {
+		if (document != null) {
+			IDocumentPartitioner partitioner= createDocumentPartitioner();
+			if (document instanceof IDocumentExtension3) {
+				IDocumentExtension3 extension3= (IDocumentExtension3) document;
+				extension3.setDocumentPartitioner(AntDocumentSetupParticipant.ANT_PARTITIONING, partitioner);
+			} else {
+				document.setDocumentPartitioner(partitioner);
+			}
+			partitioner.connect(document);
+		}
+	}
+	
+	private IDocumentPartitioner createDocumentPartitioner() {
+		return new FastPartitioner(
+				new AntEditorPartitionScanner(), new String[]{
+						AntEditorPartitionScanner.XML_TAG,
+						AntEditorPartitionScanner.XML_COMMENT,
+						AntEditorPartitionScanner.XML_CDATA,
+						AntEditorPartitionScanner.XML_DTD});
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/DocTypeRule.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/DocTypeRule.java
new file mode 100644
index 0000000..86a9e80
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/DocTypeRule.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+
+public class DocTypeRule extends MultiLineRule {
+
+    private int fEmbeddedStart= 0;
+
+	public DocTypeRule(IToken token) {
+        super("<!DOCTYPE", ">", token); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.text.rules.PatternRule#endSequenceDetected(org.eclipse.jface.text.rules.ICharacterScanner)
+     */
+    protected boolean endSequenceDetected(ICharacterScanner scanner) {
+        int c;
+        while ((c = scanner.read()) != ICharacterScanner.EOF) {
+            if (c == fEscapeCharacter) {
+                // Skip the escaped character.
+                scanner.read();
+            } else if (c == '<') {
+            	fEmbeddedStart++;
+            } else if (c == '>') {
+            	if (fEmbeddedStart == 0) {
+            		return true;
+            	}
+            	fEmbeddedStart--;
+            }
+        }
+        
+        scanner.unread();
+        return false;
+    }    
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/FileScanner.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/FileScanner.java
new file mode 100644
index 0000000..5d817a5
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/FileScanner.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+ 
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.apache.tools.ant.DirectoryScanner;
+
+
+public class FileScanner extends DirectoryScanner {
+	
+	public String[] getExcludesPatterns() {
+		return excludes;
+	}
+	
+	public String[] getIncludePatterns() {
+		return includes;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/IAntEditorColorConstants.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/IAntEditorColorConstants.java
new file mode 100644
index 0000000..5f87320
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/IAntEditorColorConstants.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2005 GEBIT Gesellschaft fuer EDV-Beratung
+ * und Informatik-Technologien mbH, 
+ * Berlin, Duesseldorf, Frankfurt (Germany) 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:
+ *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
+ * 	   IBM Corporation - bug fixes
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * The color constants used by the Ant Editor.
+ */
+public interface IAntEditorColorConstants {
+	RGB XML_COMMENT =       new RGB(128,   0,   0);
+	RGB PROC_INSTR =        new RGB(128, 128, 128);
+	RGB STRING=             new RGB(  0, 128,   0);
+	RGB DEFAULT=            new RGB(  0,   0,   0);
+	RGB TAG=                new RGB(  0,   0, 128);
+	RGB XML_DTD =       	new RGB(128,   0,   0);
+	
+	/**
+	 * The symbolic names for colors used for the various text tokens in the Ant editor
+	 */
+	public static final String XML_COMMENT_COLOR = "org.eclipse.ant.ui.commentsColor"; //$NON-NLS-1$
+	public static final String PROCESSING_INSTRUCTIONS_COLOR = "org.eclipse.ant.ui.processingInstructionsColor"; //$NON-NLS-1$
+	public static final String STRING_COLOR = "org.eclipse.ant.ui.constantStringsColor"; //$NON-NLS-1$
+	public static final String TEXT_COLOR = "org.eclipse.ant.ui.textColor"; //$NON-NLS-1$
+	public static final String TAG_COLOR = "org.eclipse.ant.ui.tagsColor"; //$NON-NLS-1$
+	public static final String XML_DTD_COLOR = "org.eclipse.ant.ui.dtdColor"; //$NON-NLS-1$
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/IReconcilingParticipant.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/IReconcilingParticipant.java
new file mode 100644
index 0000000..130c949
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/IReconcilingParticipant.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+
+
+/**
+ * Interface of an object participating in reconciling.
+ */
+public interface IReconcilingParticipant {
+	
+	/**
+	 * Called after reconciling has been finished.
+	 */
+	void reconciled();
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/MultilineDamagerRepairer.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/MultilineDamagerRepairer.java
new file mode 100644
index 0000000..b1c3427
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/MultilineDamagerRepairer.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.ITokenScanner;
+
+/**
+ * Considers multilines as damage regions even if the document partitioning has not changed.
+ *
+ * @see org.eclipse.jface.text.rules.DefaultDamagerRepairer
+ */
+public class MultilineDamagerRepairer extends DefaultDamagerRepairer {
+
+	public MultilineDamagerRepairer(ITokenScanner scanner, TextAttribute defaultTextAttribute) {
+		super(scanner, defaultTextAttribute);
+	}
+	
+	public MultilineDamagerRepairer(ITokenScanner scanner) {
+		super(scanner);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.presentation.IPresentationDamager#getDamageRegion(org.eclipse.jface.text.ITypedRegion, org.eclipse.jface.text.DocumentEvent, boolean)
+	 */
+	public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, boolean documentPartitioningChanged) {
+		return partition;
+	}
+
+	/**
+	 * Configures the scanner's default return token. This is the text attribute
+	 * which is returned when none is returned by the current token.
+	 */
+	public void setDefaultTextAttribute(TextAttribute defaultTextAttribute) {
+		fDefaultTextAttribute= defaultTextAttribute;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/NotifyingReconciler.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/NotifyingReconciler.java
new file mode 100644
index 0000000..8ccb840
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/NotifyingReconciler.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.MonoReconciler;
+
+
+public class NotifyingReconciler extends MonoReconciler {
+
+	private ArrayList fReconcilingParticipants= new ArrayList();
+	
+	/**
+	 * Constructor for NotifyingReconciler.
+	 * @param strategy
+	 */
+	public NotifyingReconciler(IReconcilingStrategy strategy) {
+		super(strategy, false);
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.reconciler.AbstractReconciler#process(org.eclipse.jface.text.reconciler.DirtyRegion)
+	 */
+	protected void process(DirtyRegion dirtyRegion) {
+		super.process(dirtyRegion);
+		notifyReconcilingParticipants();
+	}
+
+	public void addReconcilingParticipant(IReconcilingParticipant participant) {
+		fReconcilingParticipants.add(participant);
+	}
+
+	public void removeReconcilingParticipant(IReconcilingParticipant participant) {
+		fReconcilingParticipants.remove(participant);
+	}
+
+	protected void notifyReconcilingParticipants() {
+		Iterator i= new ArrayList(fReconcilingParticipants).iterator();
+		while (i.hasNext()) {
+			((IReconcilingParticipant) i.next()).reconciled();
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.reconciler.AbstractReconciler#initialProcess()
+	 */
+	protected void initialProcess() {
+		super.initialProcess();
+		notifyReconcilingParticipants();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/TagRule.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/TagRule.java
new file mode 100644
index 0000000..c67e99d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/TagRule.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2006 GEBIT Gesellschaft fuer EDV-Beratung
+ * und Informatik-Technologien mbH, 
+ * Berlin, Duesseldorf, Frankfurt (Germany) 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:
+ *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
+ * 	   IBM Corporation - bug 24108, bug 111740
+ *     John-Mason P. Shackelford - bug 51215
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+/*
+ * This file originates from an internal package of Eclipse's 
+ * Manifest Editor. It has been copied by GEBIT to here in order to
+ * permanently use those features. It has been renamed and edited by GEBIT 
+ * after copying.
+ */
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+
+public class TagRule extends MultiLineRule {
+
+    public TagRule(IToken token) {
+        super("<", ">", token); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) {
+        int c = scanner.read();
+        if (sequence[0] == '<') {
+            if (c == '?') {
+                // processing instruction - abort
+                scanner.unread();
+                return false;
+            }
+            if (c == '!') {
+                scanner.unread();
+                // comment - abort
+                return false;
+            }
+        } else if (sequence[0] == '>') {
+            scanner.unread();
+        }
+
+        return super.sequenceDetected(scanner, sequence, eofAllowed);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.text.rules.PatternRule#endSequenceDetected(org.eclipse.jface.text.rules.ICharacterScanner)
+     */
+    protected boolean endSequenceDetected(ICharacterScanner scanner) {
+        int c;
+        while ((c = scanner.read()) != ICharacterScanner.EOF) {
+            if (c == fEscapeCharacter) {
+                // Skip the escaped character.
+                scanner.read();
+            } else if (c == '>') {
+                endOfTagDetected(scanner);
+                return true;
+            } 
+        }
+        
+        scanner.unread();
+        return false;
+    }
+
+    private void endOfTagDetected(ICharacterScanner scanner) {
+        int c;
+        int scanAhead = 0;
+        int endOfTagOffset = 0;
+        while ((c = scanner.read()) != ICharacterScanner.EOF && c != '<') {
+            scanAhead++;
+            if (c == '>') {
+            	endOfTagOffset = scanAhead;
+            }
+        }
+
+        if (c == '<') {
+            int rewind = (scanAhead - endOfTagOffset) + 1;
+            for (int i = 0; i < rewind; i++) {
+                scanner.unread();
+            }
+        }
+    }    
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/XMLAnnotationHover.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/XMLAnnotationHover.java
new file mode 100644
index 0000000..d3ed445
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/XMLAnnotationHover.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.ant.internal.ui.editor.AntEditorMessages;
+import org.eclipse.jface.internal.text.html.HTMLPrinter;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+
+/**
+ * Determines all markers for the given line and collects, concatenates, and formulates
+ * their messages.
+ */
+public class XMLAnnotationHover implements IAnnotationHover {
+	
+	/**
+	 * Returns the distance to the ruler line. 
+	 */
+	private int compareRulerLine(Position position, IDocument document, int line) {
+		
+		if (position.getOffset() > -1 && position.getLength() > -1) {
+			try {
+				int xmlAnnotationLine= document.getLineOfOffset(position.getOffset());
+				if (line == xmlAnnotationLine)
+					return 1;
+				if (xmlAnnotationLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength()))
+					return 2;
+			} catch (BadLocationException x) {
+			}
+		}
+		
+		return 0;
+	}
+	
+	/**
+	 * Returns one marker which includes the ruler's line of activity.
+	 */
+	private List getXMLAnnotationsForLine(ISourceViewer viewer, int line) {
+		
+		IDocument document= viewer.getDocument();
+		IAnnotationModel model= viewer.getAnnotationModel();
+		
+		if (model == null)
+			return null;
+			
+		List exact= new ArrayList();
+		
+		Iterator e= model.getAnnotationIterator();
+		Map messagesAtPosition= new HashMap();
+		while (e.hasNext()) {
+			Object o= e.next();
+			if (o instanceof Annotation) {
+				Annotation a= (Annotation)o;
+				Position position= model.getPosition(a);
+				if (position == null)
+					continue;
+
+				if (isDuplicateXMLAnnotation(messagesAtPosition, position, a.getText()))
+					continue;
+
+				switch (compareRulerLine(position, document, line)) {
+					case 1:
+						exact.add(a);
+						break;
+				}
+			}
+		}
+		
+		return exact;
+	}
+
+	private boolean isDuplicateXMLAnnotation(Map messagesAtPosition, Position position, String message) {
+		if (messagesAtPosition.containsKey(position)) {
+			Object value= messagesAtPosition.get(position);
+			if (message.equals(value))
+				return true;
+
+			if (value instanceof List) {
+				List messages= (List)value;
+				if  (messages.contains(message)) {
+					return true;
+				}
+				messages.add(message);
+			} else {
+				ArrayList messages= new ArrayList();
+				messages.add(value);
+				messages.add(message);
+				messagesAtPosition.put(position, messages);
+			}
+		} else
+			messagesAtPosition.put(position, message);
+		return false;
+	}
+		
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, int)
+	 */
+	public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+		List xmlAnnotations= getXMLAnnotationsForLine(sourceViewer, lineNumber);
+		if (xmlAnnotations != null) {
+			
+			if (xmlAnnotations.size() == 1) {
+				
+				// optimization
+				Annotation xmlAnnotation= (Annotation)xmlAnnotations.get(0);
+				String message= xmlAnnotation.getText();
+				if (message != null && message.trim().length() > 0) {
+					return formatSingleMessage(message);
+				}
+					
+			} else {
+					
+				List messages= new ArrayList(xmlAnnotations.size());
+				Iterator e= xmlAnnotations.iterator();
+				while (e.hasNext()) {
+					Annotation xmlAnnotation= (Annotation)e.next();
+					String message= xmlAnnotation.getText();
+					if (message != null && message.trim().length() > 0) {
+						messages.add(message.trim());
+					}
+				}
+				
+				if (messages.size() == 1) {
+					return formatSingleMessage((String) messages.get(0));
+				}
+					
+				if (messages.size() > 1) {
+					return formatMultipleMessages(messages);
+				}
+			}
+		}
+		
+		return null;
+	}
+	
+	/*
+	 * Formats a message as HTML text.
+	 */
+	private String formatSingleMessage(String message) {
+		StringBuffer buffer= new StringBuffer();
+		HTMLPrinter.addPageProlog(buffer);
+		HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(message));
+		HTMLPrinter.addPageEpilog(buffer);
+		return buffer.toString();
+	}
+	
+	/*
+	 * Formats several message as HTML text.
+	 */
+	private String formatMultipleMessages(List messages) {
+		StringBuffer buffer= new StringBuffer();
+		HTMLPrinter.addPageProlog(buffer);
+		HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(AntEditorMessages.getString("AntAnnotationHover.multipleMarkersAtThisLine"))); //$NON-NLS-1$
+		
+		HTMLPrinter.startBulletList(buffer);
+		Iterator e= messages.iterator();
+		while (e.hasNext())
+			HTMLPrinter.addBullet(buffer, HTMLPrinter.convertToHTMLContent((String) e.next()));
+		HTMLPrinter.endBulletList(buffer);	
+		
+		HTMLPrinter.addPageEpilog(buffer);
+		return buffer.toString();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/XMLProblemAnnotation.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/XMLProblemAnnotation.java
new file mode 100644
index 0000000..200123c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/XMLProblemAnnotation.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.ant.internal.ui.model.IProblem;
+import org.eclipse.jface.text.source.Annotation;
+
+/**
+ * Annotation representing an <code>IProblem</code>.
+ */
+public class XMLProblemAnnotation extends Annotation {
+	
+	public static final String ERROR_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.error"; //$NON-NLS-1$
+	public static final String WARNING_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.warning"; //$NON-NLS-1$
+	public static final String INFO_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.info"; //$NON-NLS-1$
+	
+	private IProblem fProblem;
+	
+	public XMLProblemAnnotation(IProblem problem) {
+		
+		fProblem= problem;
+		
+		if (fProblem.isError()) {
+			setType(ERROR_ANNOTATION_TYPE);
+		} else if (fProblem.isWarning()) {
+			setType(WARNING_ANNOTATION_TYPE);
+		} else {
+			setType(INFO_ANNOTATION_TYPE);
+		}	
+		
+		setText(fProblem.getMessage());
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/XMLReconcilingStrategy.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/XMLReconcilingStrategy.java
new file mode 100644
index 0000000..f0c0f51
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/text/XMLReconcilingStrategy.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.editor.text;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.editor.AntEditor;
+import org.eclipse.ant.internal.ui.model.AntModel;
+import org.eclipse.ant.internal.ui.model.IAntModel;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
+
+public class XMLReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension {
+
+	/**
+	 * How long the reconciler will wait for further text changes before
+	 * reconciling
+	 */
+	public static final int DELAY= 500;
+
+	private AntEditor fEditor;
+
+	public XMLReconcilingStrategy(AntEditor editor) {
+		fEditor= editor;
+	}
+
+	private void internalReconcile() {
+		try {
+            IAntModel model= fEditor.getAntModel();
+			if (model instanceof AntModel) {
+				((AntModel)model).reconcile();
+			}
+		} catch (Exception e) {
+			AntUIPlugin.log(e);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
+	 */
+	public void reconcile(IRegion partition) {
+		internalReconcile();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion,
+	 *      org.eclipse.jface.text.IRegion)
+	 */
+	public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+		internalReconcile();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
+	 */
+	public void setDocument(IDocument document) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public void setProgressMonitor(IProgressMonitor monitor) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
+	 */
+	public void initialReconcile() {
+		internalReconcile();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/utils/ProjectHelperMessages.java b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/utils/ProjectHelperMessages.java
new file mode 100644
index 0000000..63771c7
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/utils/ProjectHelperMessages.java
@@ -0,0 +1,23 @@
+/**********************************************************************
+ * Copyright (c) 2004, 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.editor.utils;
+
+import org.eclipse.osgi.util.NLS;
+
+public class ProjectHelperMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.editor.utils.ProjectHelperMessages";//$NON-NLS-1$
+	
+	public static String ProjectHelper_0;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, ProjectHelperMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/utils/ProjectHelperMessages.properties b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/utils/ProjectHelperMessages.properties
new file mode 100644
index 0000000..9354dcc
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/utils/ProjectHelperMessages.properties
@@ -0,0 +1,11 @@
+###############################################################################
+# Copyright (c) 2004, 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
+###############################################################################
+ProjectHelper_0=XML Parser could not be created
diff --git a/ant/org.eclipse.ant.ui/Ant Runner Support/META-INF/eclipse.inf b/ant/org.eclipse.ant.ui/Ant Runner Support/META-INF/eclipse.inf
new file mode 100644
index 0000000..b4df3ab
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Runner Support/META-INF/eclipse.inf
@@ -0,0 +1 @@
+jarprocessor.exclude.sign=true
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Runner Support/org/eclipse/ant/internal/ui/antsupport/AntSupportMessages.java b/ant/org.eclipse.ant.ui/Ant Runner Support/org/eclipse/ant/internal/ui/antsupport/AntSupportMessages.java
new file mode 100644
index 0000000..8679430
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Runner Support/org/eclipse/ant/internal/ui/antsupport/AntSupportMessages.java
@@ -0,0 +1,26 @@
+/**********************************************************************
+ * Copyright (c) 2000, 2009 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.antsupport;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntSupportMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.antsupport.AntSupportMessages";//$NON-NLS-1$
+
+	public static String AntInputHandler_Ant_Input_Request_1;
+	public static String AntInputHandler_Invalid_input_2;
+	public static String AntInputHandler_Unable_to_respond_to__input__request_4;
+	public static String AntInputHandler_5;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntSupportMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Runner Support/org/eclipse/ant/internal/ui/antsupport/AntSupportMessages.properties b/ant/org.eclipse.ant.ui/Ant Runner Support/org/eclipse/ant/internal/ui/antsupport/AntSupportMessages.properties
new file mode 100644
index 0000000..ae3bff0
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Runner Support/org/eclipse/ant/internal/ui/antsupport/AntSupportMessages.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+###############################################################################
+
+AntInputHandler_Ant_Input_Request_1=Ant Input Request
+AntInputHandler_Invalid_input_2=Input does not match validargs attribute
+AntInputHandler_Unable_to_respond_to__input__request_4=Unable to respond to <input> request
+AntInputHandler_5=Unable to respond to input request as a result of the user specified -noinput command
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntDoubleClickStrategy.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntDoubleClickStrategy.java
new file mode 100644
index 0000000..f4554cf
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntDoubleClickStrategy.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui;
+
+import org.eclipse.ant.internal.ui.editor.text.XMLTextHover;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextViewer;
+
+public class AntDoubleClickStrategy implements ITextDoubleClickStrategy {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.ITextDoubleClickStrategy#doubleClicked(org.eclipse.jface.text.ITextViewer)
+	 */
+	public void doubleClicked(ITextViewer textViewer) {
+		int offset= textViewer.getSelectedRange().x;
+
+		if (offset < 0) {
+			return;
+		}
+		IRegion region= XMLTextHover.getRegion(textViewer, offset);
+		if (region != null) {
+			textViewer.setSelectedRange(region.getOffset(), region.getLength());
+		}
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntImageDescriptor.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntImageDescriptor.java
new file mode 100644
index 0000000..aaa2d92
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntImageDescriptor.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * 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
+ *     John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49445
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * A image descriptor consisting of a main icon and several adornments. The adornments
+ * are computed according to flags set on creation of the descriptor.
+ */
+public class AntImageDescriptor extends CompositeImageDescriptor {
+	
+	/** Flag to render an error adornment */
+	public final static int HAS_ERRORS= 0x0001;
+
+	/** Flag to render an imported adornment */
+	public final static int IMPORTED= 0x0002;
+	
+	/** Flag to render an warning adornment */
+	public final static int HAS_WARNINGS= 0x0004;
+	
+	private ImageDescriptor fBaseImage;
+	private int fFlags;
+	private Point fSize;
+
+	/**
+	 * Create a new AntImageDescriptor.
+	 * 
+	 * @param baseImage an image descriptor used as the base image
+	 * @param flags flags indicating which adornments are to be rendered
+	 * 
+	 */
+	public AntImageDescriptor(ImageDescriptor baseImage, int flags) {
+		setBaseImage(baseImage);
+		setFlags(flags);
+	}
+	
+	/**
+	 * @see CompositeImageDescriptor#getSize()
+	 */
+	protected Point getSize() {
+		if (fSize == null) {
+			ImageData data= getBaseImage().getImageData();
+			setSize(new Point(data.width, data.height));
+		}
+		return fSize;
+	}
+	
+	/**
+	 * @see Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object object) {
+		if (!(object instanceof AntImageDescriptor)){
+			return false;
+		}
+			
+		AntImageDescriptor other= (AntImageDescriptor)object;
+		return (getBaseImage().equals(other.getBaseImage()) && getFlags() == other.getFlags());
+	}
+	
+	/**
+	 * @see Object#hashCode()
+	 */
+	public int hashCode() {
+		return getBaseImage().hashCode() | getFlags();
+	}
+	
+	/**
+	 * @see CompositeImageDescriptor#drawCompositeImage(int, int)
+	 */
+	protected void drawCompositeImage(int width, int height) {
+		ImageData bg= getBaseImage().getImageData();
+		if (bg == null) {
+			bg= DEFAULT_IMAGE_DATA;
+		}
+		drawImage(bg, 0, 0);
+		drawOverlays();
+	}
+
+	/**
+	 * Add any overlays to the image as specified in the flags.
+	 */
+	protected void drawOverlays() {
+		int flags= getFlags();
+		int y= 0;
+		ImageData data= null;
+		if ((flags & IMPORTED) != 0) {
+			data= AntUIImages.getImageDescriptor(IAntUIConstants.IMG_OVR_IMPORT).getImageData();
+			drawImage(data, 0, 0);
+		}
+		if ((flags & HAS_ERRORS) != 0) {
+			y= getSize().y;
+			data= AntUIImages.getImageDescriptor(IAntUIConstants.IMG_OVR_ERROR).getImageData();
+			y -= data.height;
+			drawImage(data, 0, y);
+		} else if ((flags & HAS_WARNINGS) != 0) {
+			y= getSize().y;
+			data= AntUIImages.getImageDescriptor(IAntUIConstants.IMG_OVR_WARNING).getImageData();
+			y -= data.height;
+			drawImage(data, 0, y);
+		}
+	}
+	
+	protected ImageDescriptor getBaseImage() {
+		return fBaseImage;
+	}
+
+	protected void setBaseImage(ImageDescriptor baseImage) {
+		fBaseImage = baseImage;
+	}
+
+	protected int getFlags() {
+		return fFlags;
+	}
+
+	protected void setFlags(int flags) {
+		fFlags = flags;
+	}
+
+	protected void setSize(Point size) {
+		fSize = size;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntPropertyValueProvider.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntPropertyValueProvider.java
new file mode 100644
index 0000000..a725bcc
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntPropertyValueProvider.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui;
+
+import org.eclipse.ant.core.IAntPropertyValueProvider;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.JavaCore;
+
+/**
+ * Dynamic provider for Ant properties.
+ * 
+ * Provides the dynamic values for the following Ant properties:
+ * 
+ * <ul>
+ * <li><code>eclipse.target</code> - set to the Eclipse target platform location</li>
+ * </ul>
+ * 
+ * @since 3.1
+ */
+public class AntPropertyValueProvider implements IAntPropertyValueProvider {
+	/**
+	 * Returns the dynamic property values for Ant properties.
+	 * 
+	 * @param propertyName The name of the property to resolve the value for
+	 * @return The resolved value for the property
+	 * @see org.eclipse.ant.core.IAntPropertyValueProvider#getAntPropertyValue(String)
+	 */
+	public String getAntPropertyValue(String propertyName) {
+		String value = null;
+		if ("eclipse.target".equals(propertyName)) { //$NON-NLS-1$
+			try {
+			    IPath home= JavaCore.getClasspathVariable("ECLIPSE_HOME"); //$NON-NLS-1$
+			    if (home != null) {
+			    	value = home.toFile().getAbsolutePath();
+			    	if (value.endsWith("/")) { //$NON-NLS-1$
+			    		value = value.substring(0, value.length() - 1);
+			    	}
+			    }
+			} catch (Exception e) {
+				AntUIPlugin.log(e);
+			}
+		}
+		return value;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntRunnerWorkbenchAdvisor.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntRunnerWorkbenchAdvisor.java
new file mode 100644
index 0000000..3b6fc55
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntRunnerWorkbenchAdvisor.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+import org.eclipse.ant.core.AntRunner;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+
+/**
+ * Workbench advisor to run an ant script after starting the workbench and
+ * then exit the workbench. Used with {@link WorkbenchAntRunner}.
+ * 
+ * @since 3.4
+ */
+public class AntRunnerWorkbenchAdvisor extends WorkbenchAdvisor {
+	
+	private Object fContext;
+
+	protected AntRunnerWorkbenchAdvisor(Object context) {
+		fContext = context;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.application.WorkbenchAdvisor#getInitialWindowPerspectiveId()
+	 */
+	public String getInitialWindowPerspectiveId() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.application.WorkbenchAdvisor#preStartup()
+	 */
+	public void preStartup() {
+		try {
+			new AntRunner().run(fContext);
+		} catch (Exception e) {
+			AntUIPlugin.log(e);
+		}
+		try {
+			ResourcesPlugin.getWorkspace().save(true, null);
+		} catch (CoreException e) {
+			AntUIPlugin.log(e.getStatus());
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.application.WorkbenchAdvisor#openWindows()
+	 */
+	public boolean openWindows() {
+		return false;
+	}	
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntSourceViewerConfiguration.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntSourceViewerConfiguration.java
new file mode 100644
index 0000000..77391a3
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntSourceViewerConfiguration.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui;
+
+import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant;
+import org.eclipse.ant.internal.ui.editor.text.AntEditorPartitionScanner;
+import org.eclipse.ant.internal.ui.editor.text.AntEditorProcInstrScanner;
+import org.eclipse.ant.internal.ui.editor.text.AntEditorTagScanner;
+import org.eclipse.ant.internal.ui.editor.text.IAntEditorColorConstants;
+import org.eclipse.ant.internal.ui.editor.text.MultilineDamagerRepairer;
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
+
+public class AntSourceViewerConfiguration extends TextSourceViewerConfiguration {
+
+	private AntEditorTagScanner tagScanner;
+    private AntEditorProcInstrScanner instructionScanner;
+	private MultilineDamagerRepairer damageRepairer;
+	private MultilineDamagerRepairer dtdDamageRepairer;
+	private TextAttribute xmlCommentAttribute;
+	private TextAttribute xmlDtdAttribute;
+	
+    public AntSourceViewerConfiguration() {
+        super(AntUIPlugin.getDefault().getCombinedPreferenceStore());
+    }
+
+    private AntEditorProcInstrScanner getDefaultScanner() {
+	    if (instructionScanner == null) {
+	        instructionScanner = new AntEditorProcInstrScanner();
+	    }
+	    return instructionScanner;
+	}
+
+	private AntEditorTagScanner getTagScanner() {
+	    if (tagScanner == null) {
+	        tagScanner = new AntEditorTagScanner();
+	    }
+	    return tagScanner;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer)
+	 */
+	public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+	    PresentationReconciler reconciler = new PresentationReconciler();
+	    reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+	    
+		MultilineDamagerRepairer dr = new MultilineDamagerRepairer(getDefaultScanner());
+	    reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+	    reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+	
+	    dr = new MultilineDamagerRepairer(getTagScanner());
+	    reconciler.setDamager(dr, AntEditorPartitionScanner.XML_TAG);
+	    reconciler.setRepairer(dr, AntEditorPartitionScanner.XML_TAG);
+	
+	    int style= getStyle(IAntEditorColorConstants.XML_COMMENT_COLOR);
+	    xmlCommentAttribute=  new TextAttribute(AntUIPlugin.getPreferenceColor(IAntEditorColorConstants.XML_COMMENT_COLOR), null, style);
+		damageRepairer= new MultilineDamagerRepairer(null, xmlCommentAttribute);
+	    reconciler.setDamager(damageRepairer, AntEditorPartitionScanner.XML_COMMENT);
+	    reconciler.setRepairer(damageRepairer, AntEditorPartitionScanner.XML_COMMENT);
+	    
+	    style= getStyle(IAntEditorColorConstants.XML_DTD_COLOR);
+	    xmlDtdAttribute=  new TextAttribute(AntUIPlugin.getPreferenceColor(IAntEditorColorConstants.XML_DTD_COLOR), null, style);
+		dtdDamageRepairer= new MultilineDamagerRepairer(null, xmlDtdAttribute);
+	    reconciler.setDamager(dtdDamageRepairer, AntEditorPartitionScanner.XML_DTD);
+	    reconciler.setRepairer(dtdDamageRepairer, AntEditorPartitionScanner.XML_DTD);
+	
+	    return reconciler;
+	}
+
+	private int getStyle(String pref) {
+		int style= SWT.NORMAL;
+	    if (fPreferenceStore.getBoolean(pref + AntEditorPreferenceConstants.EDITOR_BOLD_SUFFIX)) {
+	    	style |= SWT.BOLD;
+	    }
+	    if (fPreferenceStore.getBoolean(pref + AntEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX)) {
+	    	style |= SWT.ITALIC;
+	    }
+		return style;
+	}
+
+	/**
+	 * Preference colors have changed.  
+	 * Update the default tokens of the scanners.
+	 */
+	public void adaptToPreferenceChange(PropertyChangeEvent event) {
+		if (tagScanner == null) {
+			return; //property change before the editor is fully created
+		}
+		tagScanner.adaptToPreferenceChange(event);
+		instructionScanner.adaptToPreferenceChange(event);
+		String property= event.getProperty();
+		if (property.startsWith(IAntEditorColorConstants.XML_COMMENT_COLOR)) {
+			xmlCommentAttribute= adaptTextAttribute(event, property, xmlCommentAttribute, damageRepairer);
+		} else if (property.startsWith(IAntEditorColorConstants.XML_DTD_COLOR)) {
+			xmlDtdAttribute= adaptTextAttribute(event, property, xmlDtdAttribute, dtdDamageRepairer);
+		} 
+	}
+	
+	private TextAttribute adaptTextAttribute(PropertyChangeEvent event, String property, TextAttribute textAttribute, MultilineDamagerRepairer repairer) {
+		if (property.endsWith(AntEditorPreferenceConstants.EDITOR_BOLD_SUFFIX)) {
+			textAttribute= adaptToStyleChange(event, SWT.BOLD, textAttribute);
+		} else if (property.endsWith(AntEditorPreferenceConstants.EDITOR_ITALIC_SUFFIX)) {
+			textAttribute= adaptToStyleChange(event, SWT.ITALIC, textAttribute);
+		} else {
+			textAttribute= adaptToColorChange(event, textAttribute);
+		}
+		repairer.setDefaultTextAttribute(textAttribute);
+		return textAttribute;
+	}
+
+	private TextAttribute adaptToStyleChange(PropertyChangeEvent event, int styleAttribute, TextAttribute textAttribute) {
+		boolean eventValue= false;
+		Object value= event.getNewValue();
+		if (value instanceof Boolean) {
+			eventValue= ((Boolean) value).booleanValue();
+		} else if (IPreferenceStore.TRUE.equals(value)) {
+			eventValue= true;
+		}
+		
+		boolean activeValue= (textAttribute.getStyle() & styleAttribute) == styleAttribute;
+		if (activeValue != eventValue) { 
+			textAttribute= new TextAttribute(textAttribute.getForeground(), textAttribute.getBackground(), eventValue ? textAttribute.getStyle() | styleAttribute : textAttribute.getStyle() & ~styleAttribute);
+		}	
+		return textAttribute;
+	}
+	
+	 /**
+     * Update the text attributes associated with the tokens of this scanner as a color preference has been changed. 
+     */
+    private TextAttribute adaptToColorChange(PropertyChangeEvent event, TextAttribute textAttribute) {
+    	RGB rgb= null;
+		
+		Object value= event.getNewValue();
+		if (value instanceof RGB) {
+			rgb= (RGB) value;
+		} else if (value instanceof String) {
+			rgb= StringConverter.asRGB((String) value);
+		}
+			
+		if (rgb != null) {
+			textAttribute= new TextAttribute(ColorManager.getDefault().getColor(rgb), textAttribute.getBackground(), textAttribute.getStyle());
+		}
+		return textAttribute;
+    }
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredContentTypes(org.eclipse.jface.text.source.ISourceViewer)
+	 */
+	public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+	    return new String[] {
+	        IDocument.DEFAULT_CONTENT_TYPE,
+	        AntEditorPartitionScanner.XML_COMMENT,
+	        AntEditorPartitionScanner.XML_TAG,
+			AntEditorPartitionScanner.XML_CDATA,
+			AntEditorPartitionScanner.XML_DTD};
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTabWidth(org.eclipse.jface.text.source.ISourceViewer)
+	 */
+	public int getTabWidth(ISourceViewer sourceViewer) {
+		return fPreferenceStore.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
+	}
+	
+	public boolean affectsTextPresentation(PropertyChangeEvent event) {
+		String property= event.getProperty();
+		return property.startsWith(IAntEditorColorConstants.TEXT_COLOR) ||
+			property.startsWith(IAntEditorColorConstants.PROCESSING_INSTRUCTIONS_COLOR) ||
+			property.startsWith(IAntEditorColorConstants.STRING_COLOR) ||
+			property.startsWith(IAntEditorColorConstants.TAG_COLOR) ||
+			property.startsWith(IAntEditorColorConstants.XML_COMMENT_COLOR) || 
+			property.startsWith(IAntEditorColorConstants.XML_DTD_COLOR);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredDocumentPartitioning(org.eclipse.jface.text.source.ISourceViewer)
+	 */
+	public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+		return AntDocumentSetupParticipant.ANT_PARTITIONING;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getDoubleClickStrategy(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
+	 */
+	public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) {
+		if (AntEditorPartitionScanner.XML_TAG.equals(contentType)) {
+			return new AntDoubleClickStrategy();
+		}
+		return super.getDoubleClickStrategy(sourceViewer, contentType);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUIImages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUIImages.java
new file mode 100644
index 0000000..f5f295b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUIImages.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *     John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49380, 49445, 53547
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.osgi.framework.Bundle;
+
+/**
+ * The images provided by the external tools plugin.
+ */
+public class AntUIImages {
+
+	/** 
+	 * The image registry containing <code>Image</code>s.
+	 */
+	private static ImageRegistry imageRegistry;
+	
+	/**
+	 * The registry for composite images
+	 */
+	private static ImageDescriptorRegistry imageDescriptorRegistry;
+
+    private static String ICONS_PATH = "$nl$/icons/full/"; //$NON-NLS-1$
+
+	// Use IPath and toOSString to build the names to ensure they have the slashes correct
+	private final static String LOCALTOOL= ICONS_PATH + "elcl16/"; //basic colors - size 16x16 //$NON-NLS-1$
+	private final static String OBJECT= ICONS_PATH + "obj16/"; //basic colors - size 16x16 //$NON-NLS-1$
+	private final static String OVR= ICONS_PATH + "ovr16/"; //basic colors - size 7x8 //$NON-NLS-1$
+	private final static String WIZ= ICONS_PATH + "wizban/"; //$NON-NLS-1$
+	private static final String T_ETOOL= ICONS_PATH + "etool16"; 	//$NON-NLS-1$
+	
+	/**
+	 * Declare all images
+	 */
+	private static void declareImages() {
+		// Ant Editor images
+		declareRegistryImage(IAntUIConstants.IMG_PROPERTY, OBJECT + "property_obj.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_TASK_PROPOSAL, OBJECT + "task_obj.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_TEMPLATE_PROPOSAL, OBJECT + "template_obj.gif"); //$NON-NLS-1$
+		
+		declareRegistryImage(IAntUIConstants.IMG_SEGMENT_EDIT, T_ETOOL + "segment_edit.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_MARK_OCCURRENCES, T_ETOOL + "mark_occurrences.gif"); //$NON-NLS-1$
+		
+		// Ant View Actions
+		declareRegistryImage(IAntUIConstants.IMG_ANT, OBJECT + "ant.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_REMOVE, LOCALTOOL + "remove_co.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_REMOVE_ALL, LOCALTOOL + "removeall_co.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_ADD, LOCALTOOL + "add_co.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_RUN, LOCALTOOL + "run_tool.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_SEARCH, LOCALTOOL + "search.gif"); //$NON-NLS-1$
+		
+		declareRegistryImage(IAntUIConstants.IMG_FILTER_INTERNAL_TARGETS, LOCALTOOL + "filter_internal_targets.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_FILTER_IMPORTED_ELEMENTS, LOCALTOOL + "filter_imported_elements.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_FILTER_PROPERTIES, LOCALTOOL + "filter_properties.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_FILTER_TOP_LEVEL, LOCALTOOL + "filter_top_level.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_LINK_WITH_EDITOR, LOCALTOOL + "synced.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_SORT_OUTLINE, LOCALTOOL + "alpha_mode.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_REFRESH, LOCALTOOL + "refresh.gif"); //$NON-NLS-1$
+		
+		// Ant View Labels
+		declareRegistryImage(IAntUIConstants.IMG_ANT_PROJECT, OBJECT + "ant_buildfile.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_ANT_TARGET, OBJECT + "targetpublic_obj.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_ANT_TARGET_INTERNAL, OBJECT + "targetinternal_obj.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_ANT_DEFAULT_TARGET, OBJECT + "defaulttarget_obj.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_ANT_TARGET_ERROR, OBJECT + "ant_target_err.gif"); //$NON-NLS-1$
+
+		//ANT objects
+		declareRegistryImage(IAntUIConstants.IMG_TAB_CLASSPATH, OBJECT + "classpath.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_ANT_TYPE, OBJECT + "type.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_ANT_TASKDEF, OBJECT + "taskdef_obj.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_ANT_MACRODEF, OBJECT + "macrodef_obj.gif"); //$NON-NLS-1$
+        declareRegistryImage(IAntUIConstants.IMG_ANT_IMPORT, OBJECT + "import_obj.gif"); //$NON-NLS-1$
+        declareRegistryImage(IAntUIConstants.IMG_ANT_ECLIPSE_RUNTIME_OBJECT, OBJECT + "eclipse_obj.gif"); //$NON-NLS-1$
+        
+		declareRegistryImage(IAntUIConstants.IMG_WIZARD_BANNER, WIZ + "ant_wiz.png"); //$NON-NLS-1$
+        declareRegistryImage(IAntUIConstants.IMG_EXPORT_WIZARD_BANNER, WIZ + "export_ant_wiz.png"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_TAB_ANT_TARGETS, LOCALTOOL + "ant_targets.gif"); //$NON-NLS-1$
+		
+		// Overlays
+		declareRegistryImage(IAntUIConstants.IMG_OVR_ERROR, OVR + "error_co.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_OVR_WARNING, OVR + "warning_co.gif"); //$NON-NLS-1$
+		declareRegistryImage(IAntUIConstants.IMG_OVR_IMPORT, OVR + "import_co.gif"); //$NON-NLS-1$
+	}
+
+	/**
+	 * Declare an Image in the registry table.
+	 * @param key 	The key to use when registering the image
+	 * @param path	The path where the image can be found. This path is relative to where
+	 *				this plugin class is found (i.e. typically the packages directory)
+	 */
+	private final static void declareRegistryImage(String key, String path) {
+        ImageDescriptor desc = ImageDescriptor.getMissingImageDescriptor();
+        Bundle bundle = Platform.getBundle(AntUIPlugin.getUniqueIdentifier());
+        URL url = null;
+        if (bundle != null) {
+            url = FileLocator.find(bundle, new Path(path), null);
+            desc = ImageDescriptor.createFromURL(url);
+        }
+        imageRegistry.put(key, desc);
+    }
+	
+	/**
+	 * Returns the ImageRegistry.
+	 */
+	public static ImageRegistry getImageRegistry() {
+		if (imageRegistry == null) {
+			initializeImageRegistry();
+		}
+		return imageRegistry;
+	}
+
+	/**
+	 *	Initialize the image registry by declaring all of the required
+	 *	graphics. This involves creating JFace image descriptors describing
+	 *	how to create/find the image should it be needed.
+	 *	The image is not actually allocated until requested.
+	 *
+	 * 	Prefix conventions
+	 *		Wizard Banners			WIZBAN_
+	 *		Preference Banners		PREF_BAN_
+	 *		Property Page Banners	PROPBAN_
+	 *		Color toolbar			CTOOL_
+	 *		Enable toolbar			ETOOL_
+	 *		Disable toolbar			DTOOL_
+	 *		Local enabled toolbar	ELCL_
+	 *		Local Disable toolbar	DLCL_
+	 *		Object large			OBJL_
+	 *		Object small			OBJS_
+	 *		View 					VIEW_
+	 *		Product images			PROD_
+	 *		Misc images				MISC_
+	 *
+	 *	Where are the images?
+	 *		The images (typically gifs) are found in the same location as this plugin class.
+	 *		This may mean the same package directory as the package holding this class.
+	 *		The images are declared using this.getClass() to ensure they are looked up via
+	 *		this plugin class.
+	 * @see org.eclipse.jface.resource.ImageRegistry
+	 */
+	public static ImageRegistry initializeImageRegistry() {
+		imageRegistry= new ImageRegistry(AntUIPlugin.getStandardDisplay());
+		declareImages();
+		return imageRegistry;
+	}
+
+	/**
+	 * Returns the <code>Image<code> identified by the given key,
+	 * or <code>null</code> if it does not exist.
+	 */
+	public static Image getImage(String key) {
+		return getImageRegistry().get(key);
+	}
+	
+	/**
+	 * Returns the <code>ImageDescriptor<code> identified by the given key,
+	 * or <code>null</code> if it does not exist.
+	 */
+	public static ImageDescriptor getImageDescriptor(String key) {
+		return getImageRegistry().getDescriptor(key);
+	}
+	
+	/** 
+	 * Returns the image for the given composite descriptor. 
+	 */
+	public static Image getImage(CompositeImageDescriptor imageDescriptor) {
+		if (imageDescriptorRegistry == null) {
+			imageDescriptorRegistry = new ImageDescriptorRegistry();	
+		}
+		return imageDescriptorRegistry.get(imageDescriptor);
+	}
+	
+	public static void disposeImageDescriptorRegistry() {
+		if (imageDescriptorRegistry != null) {
+			imageDescriptorRegistry.dispose(); 
+		}
+	}
+	
+	/**
+	 * Returns whether the images have been initialized.
+	 * 
+	 * @return whether the images have been initialized
+	 */
+	public synchronized static boolean isInitialized() {
+		return imageDescriptorRegistry != null;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUIModelMessages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUIModelMessages.java
new file mode 100644
index 0000000..4c7d596
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUIModelMessages.java
@@ -0,0 +1,29 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntUIModelMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.AntUIModelMessages";//$NON-NLS-1$
+	
+	public static String ImageDescriptorRegistry_Allocating_image_for_wrong_display_1;
+
+	public static String AntUtil_6;
+	public static String AntUtil_7;
+	public static String AntUtil_0;
+	public static String AntUtil_1;
+	public static String AntUtil_2;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntUIModelMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUIModelMessages.properties b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUIModelMessages.properties
new file mode 100644
index 0000000..2bafd38
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUIModelMessages.properties
@@ -0,0 +1,18 @@
+###############################################################################
+# 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
+###############################################################################
+
+ImageDescriptorRegistry_Allocating_image_for_wrong_display_1=Allocating image for wrong display
+
+AntUtil_6=Invalid property file entry: {0}
+AntUtil_7=Unable to generate Ant classpath
+AntUtil_0=Editor failed to open for {0}
+AntUtil_1=Browser could not be opened
+AntUtil_2=Error reading launch configuration
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ColorManager.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ColorManager.java
new file mode 100644
index 0000000..7cabe67
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ColorManager.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jface.text.source.ISharedTextColors;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Generic color manager.
+ */
+public class ColorManager implements ISharedTextColors {	
+	
+	private static ColorManager fgColorManager;
+	
+	private ColorManager() {
+	}
+	
+	public static ColorManager getDefault() {
+		if (fgColorManager == null) {
+			fgColorManager= new ColorManager();
+		}
+		return fgColorManager;
+	}
+	
+	protected Map fColorTable= new HashMap(10);
+	
+	public Color getColor(RGB rgb) {
+		Color color= (Color) fColorTable.get(rgb);
+		if (color == null) {
+			color= new Color(Display.getCurrent(), rgb);
+			fColorTable.put(rgb, color);
+		}
+		return color;
+	}
+	
+	public void dispose() {
+		Iterator e= fColorTable.values().iterator();
+		while (e.hasNext()) {
+			((Color) e.next()).dispose();
+		}
+	}
+}
+
+
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ExternalHyperlink.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ExternalHyperlink.java
new file mode 100644
index 0000000..511976e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ExternalHyperlink.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+import java.io.File;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.console.IHyperlink;
+import org.eclipse.ui.ide.FileStoreEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class ExternalHyperlink implements IHyperlink {
+
+    private File fFile;
+    private int fLineNumber;
+
+    public ExternalHyperlink(File file, int lineNumber) {
+        super();
+        fFile = file;
+        fLineNumber= lineNumber;
+    }
+
+    public void linkEntered() {
+    }
+
+    public void linkExited() {
+    }
+
+    public void linkActivated() {
+    	IEditorInput input;
+    	IFileStore fileStore;
+		try {
+			fileStore= EFS.getStore(fFile.toURI());
+			input = new FileStoreEditorInput(fileStore);
+		} catch (CoreException e) {
+			// unable to link
+			AntUIPlugin.log(e);
+			return;
+		}
+    	
+        IWorkbenchPage activePage = AntUIPlugin.getActiveWorkbenchWindow().getActivePage();
+        try {
+            IEditorPart editorPart= activePage.openEditor(input, "org.eclipse.ant.ui.internal.editor.AntEditor", true); //$NON-NLS-1$
+            if (fLineNumber > 0 && editorPart instanceof ITextEditor) {
+                ITextEditor textEditor = (ITextEditor)editorPart;
+                
+                    IDocumentProvider provider = textEditor.getDocumentProvider();
+                    try {
+                        provider.connect(input);
+                    } catch (CoreException e) {
+                        // unable to link
+                        AntUIPlugin.log(e);
+                        return;
+                    }
+                    IDocument document = provider.getDocument(input);
+                    try {
+                        IRegion lineRegion= document.getLineInformation(fLineNumber);
+                        textEditor.selectAndReveal(lineRegion.getOffset(), lineRegion.getLength());
+                    } catch (BadLocationException e) {
+                        // unable to link
+                        AntUIPlugin.log(e);
+                    }
+                    provider.disconnect(input);
+                }
+            
+        } catch (PartInitException e) {
+        }
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/IAntUIConstants.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/IAntUIConstants.java
new file mode 100644
index 0000000..0c166b2
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/IAntUIConstants.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *     John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49380, 49445, bug 53547
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+
+/**
+ * Defines the constants available for client use.
+ * <p>
+ * This interface is not intended to be extended or implemented by clients.
+ * </p>
+ */
+public interface IAntUIConstants {
+	/**
+	 * Plugin identifier for Ant ui(value <code>org.eclipse.ant.ui</code>).
+	 */
+	public static final String PLUGIN_ID = "org.eclipse.ant.ui"; //$NON-NLS-1$;
+	
+
+	// ------- Views -------
+
+	/**
+	 * Ant View identifier (value <code>org.eclipse.ant.ui.AntView</code>).
+	 */
+	public static final String ANT_VIEW_ID = PLUGIN_ID + ".AntView"; //$NON-NLS-1$
+
+	// ------- Images -------
+	/**
+	 * Main tab image.
+	 */
+	public static final String IMG_TAB_MAIN = PLUGIN_ID + ".IMG_TAB_MAIN"; //$NON-NLS-1$
+
+	public static final String IMG_PROPERTY = PLUGIN_ID + ".IMG_PROPERTY"; //$NON-NLS-1$
+	
+	public static final String IMG_TAB_ANT_TARGETS = PLUGIN_ID + ".IMG_TAB_ANT_TARGETS"; //$NON-NLS-1$
+	public static final String IMG_TAB_CLASSPATH = PLUGIN_ID + ".IMG_TAB_CLASSPATH"; //$NON-NLS-1$;
+	
+	//	Label images
+	 public static final String IMG_ANT= PLUGIN_ID + ".ant"; //$NON-NLS-1$
+	 public static final String IMG_ANT_PROJECT= PLUGIN_ID + ".antProject"; //$NON-NLS-1$
+	 public static final String IMG_ANT_TARGET= PLUGIN_ID + ".antTarget"; //$NON-NLS-1$
+	 public static final String IMG_ANT_TARGET_INTERNAL = PLUGIN_ID + ".antPrivateTarget"; //$NON-NLS-1$
+	 public static final String IMG_ANT_DEFAULT_TARGET= PLUGIN_ID + ".antDefaultTarget"; //$NON-NLS-1$
+	 public static final String IMG_ANT_TARGET_ERROR = PLUGIN_ID + ".antTargetError"; //$NON-NLS-1$
+	 public static final String IMG_ANT_MACRODEF = PLUGIN_ID + ".antMacrodef"; //$NON-NLS-1$
+     public static final String IMG_ANT_IMPORT = PLUGIN_ID + ".antImport"; //$NON-NLS-1$
+     public static final String IMG_ANT_TASKDEF = PLUGIN_ID + ".antTaskdef"; //$NON-NLS-1$
+     public static final String IMG_ANT_ECLIPSE_RUNTIME_OBJECT = PLUGIN_ID + ".antEclipse"; //$NON-NLS-1$
+     
+     //editor toolbar
+     public static final String IMG_SEGMENT_EDIT = PLUGIN_ID + ".segmentEdit"; //$NON-NLS-1$
+	 public static final String IMG_MARK_OCCURRENCES = PLUGIN_ID + ".markOccurrences"; //$NON-NLS-1$
+     
+	/**
+	 * Icon for task proposal.
+	 */
+	public static final String IMG_TASK_PROPOSAL = PLUGIN_ID + ".html_tab_obj"; //$NON-NLS-1$
+	public static final String IMG_TEMPLATE_PROPOSAL= PLUGIN_ID + ".template_obj"; //$NON-NLS-1$
+	
+	// Action images
+	public static final String IMG_REMOVE= PLUGIN_ID + ".remove"; //$NON-NLS-1$
+	public static final String IMG_REMOVE_ALL= PLUGIN_ID + ".removeAll"; //$NON-NLS-1$
+	public static final String IMG_ADD= PLUGIN_ID + ".add"; //$NON-NLS-1$
+	public static final String IMG_RUN= PLUGIN_ID + ".run"; //$NON-NLS-1$
+	public static final String IMG_SEARCH= PLUGIN_ID + ".search"; //$NON-NLS-1$
+	public static final String IMG_FILTER_INTERNAL_TARGETS= PLUGIN_ID + ".filterInternalTargets"; //$NON-NLS-1$
+	public static final String IMG_FILTER_IMPORTED_ELEMENTS= PLUGIN_ID + ".filterImportedElements"; //$NON-NLS-1$
+	public static final String IMG_FILTER_PROPERTIES= PLUGIN_ID + ".filterProperties"; //$NON-NLS-1$
+	public static final String IMG_FILTER_TOP_LEVEL= PLUGIN_ID + ".filterTopLevel"; //$NON-NLS-1$
+	public static final String IMG_SORT_OUTLINE= PLUGIN_ID + ".sortOutline"; //$NON-NLS-1$
+	public static final String IMG_LINK_WITH_EDITOR= PLUGIN_ID + ".linkWithEditor"; //$NON-NLS-1$
+	public static final String IMG_REFRESH = PLUGIN_ID + ".IMG_REFRESH"; //$NON-NLS-1$
+	
+	public static final String IMG_WIZARD_BANNER = PLUGIN_ID + ".IMG_WIZARD_BANNER"; //$NON-NLS-1$
+    public static final String IMG_EXPORT_WIZARD_BANNER = PLUGIN_ID + ".IMG_EXPORT_WIZARD_BANNER"; //$NON-NLS-1$
+	 
+	//	Overlays
+	public static final String IMG_OVR_ERROR = PLUGIN_ID + ".ovrError";  //$NON-NLS-1$
+	public static final String IMG_OVR_WARNING = PLUGIN_ID + ".ovrWarning";  //$NON-NLS-1$
+	public static final String IMG_OVR_IMPORT = PLUGIN_ID + ".ovrImport"; //$NON-NLS-1$
+	
+	public static final String IMG_ANT_TYPE= PLUGIN_ID + ".type"; //$NON-NLS-1$
+
+	// -------- Status Codes -------------
+	
+	/**
+	 * Status code used by the 'Run Ant' status handler which is invoked when
+	 * the launch dialog is opened by the 'Run Ant' action.
+	 */
+	public static final int STATUS_INIT_RUN_ANT = 1000;
+	
+	public static final String DIALOGSTORE_LASTEXTJAR= PLUGIN_ID + ".lastextjar"; //$NON-NLS-1$
+	public static final String DIALOGSTORE_LASTEXTFILE= PLUGIN_ID + ".lastextfile"; //$NON-NLS-1$
+	public static final String DIALOGSTORE_LASTFOLDER= PLUGIN_ID + ".lastfolder"; //$NON-NLS-1$
+	public static final String DIALOGSTORE_LASTANTHOME= PLUGIN_ID + ".lastanthome"; //$NON-NLS-1$
+	
+	/**
+	 * Size of left-hand column for right-justified task name.
+	 * Used for Ant Build logging.
+	 * @see org.eclipse.ant.internal.launching.runtime.logger.AntProcessBuildLogger
+     * @see org.eclipse.ant.internal.launching.launchConfigurations.RemoteAntBuildListener
+	  */
+	public static final int LEFT_COLUMN_SIZE = 15;
+	
+	/**
+	 * Id of the IProcessFactory to use when creating processes for remote Ant builds.
+	 */
+	public static final String REMOTE_ANT_PROCESS_FACTORY_ID= "org.eclipse.ant.ui.remoteAntProcessFactory"; //$NON-NLS-1$
+	
+	/**
+	 * Boolean attribute indicating if an input handler should be supplied for the build
+	 * Default value is <code>true</code>.
+	 */
+	public static final String SET_INPUTHANDLER= PLUGIN_ID + "SET_INPUTHANDLER"; //$NON-NLS-1$	
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ImageDescriptorRegistry.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ImageDescriptorRegistry.java
new file mode 100644
index 0000000..0453032
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ImageDescriptorRegistry.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+ 
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A registry that maps <code>ImageDescriptors</code> to <code>Image</code>.
+ */
+public class ImageDescriptorRegistry {
+
+	private HashMap fRegistry= new HashMap(10);
+	private Display fDisplay;
+	
+	/**
+	 * Creates a new image descriptor registry for the current or default display,
+	 * respectively.
+	 */
+	public ImageDescriptorRegistry() {
+		this(AntUIPlugin.getStandardDisplay());
+	}
+	
+	/**
+	 * Creates a new image descriptor registry for the given display. All images
+	 * managed by this registry will be disposed when the display gets disposed.
+	 * 
+	 * @param display the display the images managed by this registry are allocated for 
+	 */
+	public ImageDescriptorRegistry(Display display) {
+		fDisplay= display;
+		Assert.isNotNull(fDisplay);
+		hookDisplay();
+	}
+	
+	/**
+	 * Returns the image associated with the given image descriptor.
+	 * 
+	 * @param descriptor the image descriptor for which the registry manages an image
+	 * @return the image associated with the image descriptor or <code>null</code>
+	 *  if the image descriptor can't create the requested image.
+	 */
+	public Image get(ImageDescriptor descriptor) {
+		if (descriptor == null)
+			descriptor= ImageDescriptor.getMissingImageDescriptor();
+			
+		Image result= (Image)fRegistry.get(descriptor);
+		if (result != null)
+			return result;
+	
+		Assert.isTrue(fDisplay == AntUIPlugin.getStandardDisplay(), AntUIModelMessages.ImageDescriptorRegistry_Allocating_image_for_wrong_display_1);
+		result= descriptor.createImage();
+		if (result != null)
+			fRegistry.put(descriptor, result);
+		return result;
+	}
+
+	/**
+	 * Disposes all images managed by this registry.
+	 */	
+	public void dispose() {
+		for (Iterator iter= fRegistry.values().iterator(); iter.hasNext(); ) {
+			Image image= (Image)iter.next();
+			image.dispose();
+		}
+		fRegistry.clear();
+	}
+	
+	private void hookDisplay() {
+		fDisplay.disposeExec(new Runnable() {
+			public void run() {
+				dispose();
+			}	
+		});
+	}
+}
+
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/WorkbenchAntRunner.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/WorkbenchAntRunner.java
new file mode 100644
index 0000000..9457da3
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/WorkbenchAntRunner.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Application to run an Ant script after starting the workbench. Shuts down the
+ * workbench after the script runs.
+ * 
+ * @since 3.4
+ */
+public class WorkbenchAntRunner implements IApplication {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
+	 */
+	public Object start(IApplicationContext context) throws Exception {
+		Display display = PlatformUI.createDisplay();
+        try {
+            Shell shell = new Shell(display, SWT.ON_TOP);
+			shell.dispose();
+            // create the workbench with this advisor and run it until it exits
+            // N.B. createWorkbench remembers the advisor, and also registers
+            // the workbench globally so that all UI plug-ins can find it using
+            // PlatformUI.getWorkbench() or AbstractUIPlugin.getWorkbench()
+            PlatformUI.createAndRunWorkbench(display,
+                    new AntRunnerWorkbenchAdvisor(
+                    		context.getArguments().get(IApplicationContext.APPLICATION_ARGS)));
+            return EXIT_OK;
+        } finally {
+            if (display != null) {
+				display.dispose();
+			}
+        }
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.equinox.app.IApplication#stop()
+	 */
+	public void stop() {
+	}
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/AbstractJavacPatternMatcher.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/AbstractJavacPatternMatcher.java
new file mode 100644
index 0000000..7c04aec
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/AbstractJavacPatternMatcher.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.console;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.ui.console.FileLink;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.ui.console.IPatternMatchListenerDelegate;
+import org.eclipse.ui.console.PatternMatchEvent;
+import org.eclipse.ui.console.TextConsole;
+
+public abstract class AbstractJavacPatternMatcher implements IPatternMatchListenerDelegate {
+
+    protected TextConsole fConsole;
+    private static Pattern fgLineNumberPattern = Pattern.compile("\\d+"); //$NON-NLS-1$
+	private static List fgPatternMatchers= new ArrayList();
+    private Map fFileNameToIFile= new HashMap();
+    
+	private JavacMarkerCreator fMarkerCreator;
+	protected static final Integer fgWarningType= new Integer(IMarker.SEVERITY_WARNING);
+	protected static final Integer fgErrorType= new Integer(IMarker.SEVERITY_ERROR);
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.console.IPatternMatchListenerDelegate#connect(org.eclipse.ui.console.TextConsole)
+     */
+    public void connect(TextConsole console) {
+        fConsole= console;
+        IPreferenceStore store= AntUIPlugin.getDefault().getPreferenceStore();
+		if (store.getBoolean(IAntUIPreferenceConstants.ANT_CREATE_MARKERS)) {
+        	fMarkerCreator= new JavacMarkerCreator(fConsole, this instanceof EclipseJavacPatternMatcher);
+        	fgPatternMatchers.add(this);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.console.IPatternMatchListenerDelegate#disconnect()
+     */
+    public void disconnect() {
+        fConsole = null;
+        fFileNameToIFile.clear();
+    }
+    
+    protected IFile getIFile(String filePath) {
+        if (filePath == null) {
+            return null; 
+        }
+        IFile file= (IFile) fFileNameToIFile.get(filePath);
+        if (file == null) {
+            IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(filePath));
+            if (files.length > 0) {
+                file = files[0];
+                fFileNameToIFile.put(filePath, file);
+            }
+        }
+        return file;
+    }
+    
+    protected String getMatchedText(PatternMatchEvent event) {
+        int eventOffset= event.getOffset();
+        int eventLength= event.getLength();
+        IDocument document= fConsole.getDocument();
+        String matchedText= null;
+        try {
+            matchedText= document.get(eventOffset, eventLength);
+        } catch (BadLocationException e) {
+            AntUIPlugin.log(e);
+        }
+        return matchedText;
+    }
+    
+    protected int getLineNumber(int eventOffset, boolean sameLine) {
+        IDocument document= fConsole.getDocument();
+        try {
+            int fileLine = document.getLineOfOffset(eventOffset);
+            if (!sameLine) {
+            	fileLine += 1;
+            }
+            IRegion region = document.getLineInformation(fileLine);
+            int regionLength = region.getLength();
+            if (region.getOffset() != eventOffset) {
+            	 regionLength = regionLength - (eventOffset - region.getOffset());
+            }
+            
+			String lineLine = document.get(eventOffset, regionLength);
+            Matcher matcher = null;
+            synchronized (fgLineNumberPattern) {
+                matcher = fgLineNumberPattern.matcher(lineLine);
+            }
+            if (matcher.find()) {
+                String lineString = matcher.group();
+                return Integer.parseInt(lineString);
+            }
+            
+        } catch (BadLocationException e) {
+            AntUIPlugin.log(e);
+        } catch (NumberFormatException e) {
+            AntUIPlugin.log(e);
+        }
+        return -1;
+    }
+    
+    protected void addLink(String filePath, int lineNumber, int offset, int length, Integer type) {
+        IFile file= getIFile(filePath);
+        if (file == null) {
+            return;
+        }
+        
+        if (fMarkerCreator != null) {
+        	if (type == null) { //match for listfiles
+        		fMarkerCreator.addFileToBeCleaned(file);
+        	} else { //match for error or warning
+        		fMarkerCreator.addMarker(file, lineNumber, offset, type);
+        	}
+        }
+        
+        FileLink link = new FileLink(file, null, -1, -1, lineNumber);
+        try {
+            fConsole.addHyperlink(link, offset, length);
+        } catch (BadLocationException e) {
+            AntUIPlugin.log(e);
+        }
+    }
+
+	public static void consoleClosed(IProcess process) {
+		Iterator iter= new ArrayList(fgPatternMatchers).iterator();
+		while (iter.hasNext()) {
+			AbstractJavacPatternMatcher matcher = (AbstractJavacPatternMatcher) iter.next();
+			matcher.finished(process);
+		}
+	}
+
+	protected void finished(IProcess process) {
+		if (fMarkerCreator != null) {
+			fMarkerCreator.finished(process);
+			fgPatternMatchers.remove(this);
+		}
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/AntConsoleColorProvider.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/AntConsoleColorProvider.java
new file mode 100644
index 0000000..2576bd4
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/AntConsoleColorProvider.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.console;
+
+import org.eclipse.ant.internal.launching.launchConfigurations.AntStreamsProxy;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.console.ConsoleColorProvider;
+import org.eclipse.debug.ui.console.IConsole;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.ui.console.IOConsoleOutputStream;
+
+
+public class AntConsoleColorProvider extends ConsoleColorProvider implements IPropertyChangeListener {
+
+    
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.console.IConsoleColorProvider#getColor(java.lang.String)
+	 */
+	public Color getColor(String streamIdentifer) {
+		if (streamIdentifer.equals(IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM)) {
+			return AntUIPlugin.getPreferenceColor(IAntUIPreferenceConstants.CONSOLE_INFO_COLOR);
+		}
+		if (streamIdentifer.equals(IDebugUIConstants.ID_STANDARD_ERROR_STREAM)) {
+			return AntUIPlugin.getPreferenceColor(IAntUIPreferenceConstants.CONSOLE_ERROR_COLOR);
+		}				
+		if (streamIdentifer.equals(AntStreamsProxy.ANT_DEBUG_STREAM)) {
+			return AntUIPlugin.getPreferenceColor(IAntUIPreferenceConstants.CONSOLE_DEBUG_COLOR);
+		}
+		if (streamIdentifer.equals(AntStreamsProxy.ANT_VERBOSE_STREAM)) {
+			return AntUIPlugin.getPreferenceColor(IAntUIPreferenceConstants.CONSOLE_VERBOSE_COLOR);
+		}
+		if (streamIdentifer.equals(AntStreamsProxy.ANT_WARNING_STREAM)) {
+			return AntUIPlugin.getPreferenceColor(IAntUIPreferenceConstants.CONSOLE_WARNING_COLOR);
+		}
+		return super.getColor(streamIdentifer);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.console.IConsoleColorProvider#connect(org.eclipse.debug.core.model.IProcess, org.eclipse.debug.ui.console.IConsole)
+	 */
+	public void connect(IProcess process, IConsole console) {
+		//Both remote and local Ant builds are guaranteed to have
+		//an AntStreamsProxy. The remote Ant builds make use of the
+		// org.eclipse.debug.core.processFactories extension point
+		AntStreamsProxy proxy = (AntStreamsProxy)process.getStreamsProxy();
+		if (proxy != null) {
+			console.connect(proxy.getDebugStreamMonitor(), AntStreamsProxy.ANT_DEBUG_STREAM);
+			console.connect(proxy.getWarningStreamMonitor(), AntStreamsProxy.ANT_WARNING_STREAM);
+			console.connect(proxy.getVerboseStreamMonitor(), AntStreamsProxy.ANT_VERBOSE_STREAM);
+		}
+		
+		AntUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
+		super.connect(process, console);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.console.IConsoleColorProvider#isReadOnly()
+	 */
+	public boolean isReadOnly() {
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+	 */
+	public void propertyChange(PropertyChangeEvent event) {
+	    final String streamId = getStreamId(event.getProperty());
+		if (streamId != null) {
+			AntUIPlugin.getStandardDisplay().asyncExec(new Runnable() {
+				public void run() {
+				    IOConsoleOutputStream stream = getConsole().getStream(streamId);
+				    if (stream != null) {
+				        stream.setColor(getColor(streamId));
+				    }
+				}
+			});
+		}
+	}
+
+	private String getStreamId(String colorId) {
+		if (IAntUIPreferenceConstants.CONSOLE_DEBUG_COLOR.equals(colorId)) {
+			return AntStreamsProxy.ANT_DEBUG_STREAM;
+		} else if (IAntUIPreferenceConstants.CONSOLE_ERROR_COLOR.equals(colorId)) {
+			return IDebugUIConstants.ID_STANDARD_ERROR_STREAM;
+		} else if (IAntUIPreferenceConstants.CONSOLE_INFO_COLOR.equals(colorId)) {
+			return IDebugUIConstants.ID_STANDARD_OUTPUT_STREAM;
+		} else if (IAntUIPreferenceConstants.CONSOLE_VERBOSE_COLOR.equals(colorId)) {
+			return AntStreamsProxy.ANT_VERBOSE_STREAM;
+		} else if (IAntUIPreferenceConstants.CONSOLE_WARNING_COLOR.equals(colorId)) {
+			return AntStreamsProxy.ANT_WARNING_STREAM;
+		}
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.console.IConsoleColorProvider#disconnect()
+	 */
+	public void disconnect() {
+		AntUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
+		super.disconnect();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/ConsoleMessages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/ConsoleMessages.java
new file mode 100644
index 0000000..e49da3d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/ConsoleMessages.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.console;
+
+import org.eclipse.osgi.util.NLS;
+
+public class ConsoleMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.console.ConsoleMessages";//$NON-NLS-1$
+	
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, ConsoleMessages.class);
+	}
+
+	public static String JavacMarkerCreator_0;
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/EclipseJavacPatternMatcher.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/EclipseJavacPatternMatcher.java
new file mode 100644
index 0000000..27ca7e4
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/EclipseJavacPatternMatcher.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.console;
+
+import org.eclipse.ui.console.PatternMatchEvent;
+
+public class EclipseJavacPatternMatcher extends AbstractJavacPatternMatcher {
+
+    private static final String fgError= "ERROR in"; //$NON-NLS-1$
+    private static final String fgWarning= "WARNING in"; //$NON-NLS-1$
+    private static final String fgStartOfLineNumber= " ("; //$NON-NLS-1$
+    
+    /* [javac] 1. ERROR in /Users/kevinbarnes/Eclipse/runtime-workspace/org.eclipse.ant.core/src_ant/org/eclipse/ant/internal/core/ant/InternalAntRunner.java (at line 66)
+     */
+    public void matchFound(PatternMatchEvent event) {
+        String matchedText= getMatchedText(event);
+        if (matchedText == null) {
+            return;
+        }
+        int index = matchedText.indexOf(fgError);
+        String filePath;
+        Integer type= fgErrorType;
+        if (index == -1) {
+            index = matchedText.indexOf(fgWarning);
+            filePath= matchedText.substring(index + 10).trim();
+            type= fgWarningType;
+        } else {
+            filePath= matchedText.substring(index + 8).trim();
+        }
+
+        int lineNumberStart = filePath.lastIndexOf(fgStartOfLineNumber);
+        if (lineNumberStart != -1) {
+        	filePath = filePath.substring(0, lineNumberStart);
+        }
+        
+        int fileStart = matchedText.indexOf(filePath);
+        int eventOffset= event.getOffset() + fileStart;
+        int eventLength = filePath.length();
+        
+        int lineNumber = getLineNumber(lineNumberStart + eventOffset, true);
+        addLink(filePath, lineNumber, eventOffset, eventLength, type);
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacMarkerCreator.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacMarkerCreator.java
new file mode 100644
index 0000000..1776a5d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacMarkerCreator.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.console;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceRuleFactory;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
+import org.eclipse.jdt.core.IJavaModelMarker;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.FindReplaceDocumentAdapter;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.ui.console.TextConsole;
+
+public class JavacMarkerCreator {
+
+	private final TextConsole fConsole;
+	private IProcess fProcess;
+	private static List fgFilesToBeCleaned= new ArrayList();
+	private Map fFileToMarkerInfo= new HashMap();
+	private final boolean fUseCustomMessage;
+
+	private class MarkerInfo {
+		
+		public int fLineNumber;
+		public int fOffset;
+		public Integer fType;
+
+		public void setLineNumber(int lineNumber) {
+			fLineNumber= lineNumber;
+		}
+		public void setOffset(int offset) {
+			fOffset = offset;
+		}
+		public void setType(Integer type) {
+			fType= type;
+			
+		}
+	}
+	public JavacMarkerCreator(TextConsole console, boolean useCustomMessage) {
+		fConsole = console;
+		fUseCustomMessage = useCustomMessage;
+		if (fConsole instanceof ProcessConsole) {
+			fProcess= ((ProcessConsole) fConsole).getProcess();
+		}
+	}
+
+	protected ISchedulingRule getMarkerRule(IResource resource) {
+	    ISchedulingRule rule = null;
+	    if (resource != null) {
+	        IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
+	        rule = ruleFactory.markerRule(resource);
+	    }
+	    return rule;
+	}
+
+	protected void run(ISchedulingRule rule, IWorkspaceRunnable wr) {
+		try {
+			ResourcesPlugin.getWorkspace().run(wr, rule, 0, null);
+		} catch (CoreException e) {
+			AntUIPlugin.log(e.getStatus());
+		}			
+	}
+
+	protected void addFileToBeCleaned(IFile file) {
+		fgFilesToBeCleaned.add(file);
+	}
+	
+	protected void addMarker(IFile file, int lineNumber, int offset, Integer type) {
+		MarkerInfo info= new MarkerInfo();
+		info.setLineNumber(lineNumber);
+		info.setOffset(offset);
+		info.setType(type);
+		List infos= (List) fFileToMarkerInfo.get(file);
+		if (infos == null) {
+			infos= new ArrayList();
+			fFileToMarkerInfo.put(file, infos);
+		}
+		infos.add(info);
+	}
+	
+	private void createMarkers(final IFile file, final List infos) {
+		IWorkspaceRunnable wr= new IWorkspaceRunnable() {
+			public void run(IProgressMonitor monitor) throws CoreException {
+				
+				try {
+					for (Iterator iter = infos.iterator(); iter.hasNext();) {
+						MarkerInfo info = (MarkerInfo) iter.next();
+						IMarker marker= file.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+						Map attributes= new HashMap(3);
+						attributes.put(IMarker.LINE_NUMBER, new Integer(info.fLineNumber));
+						String message= getMessage(info);
+						attributes.put(IMarker.MESSAGE, message);
+						attributes.put(IMarker.SEVERITY, info.fType);
+						marker.setAttributes(attributes);
+					}
+				} catch (CoreException e) {
+					AntUIPlugin.log(e.getStatus());
+				}	
+			}
+		};
+		run(getMarkerRule(file), wr);
+	}
+
+	protected String getMessage(MarkerInfo info) {
+		IDocument doc= fConsole.getDocument();
+		String message= ConsoleMessages.JavacMarkerCreator_0;
+		if (fUseCustomMessage) {
+			FindReplaceDocumentAdapter adapter= new FindReplaceDocumentAdapter(doc);
+			try {
+				IRegion match=adapter.find(info.fOffset, "[javac] ----------", true, false, false, false); //$NON-NLS-1$
+				if (match != null) {
+					match= adapter.find(match.getOffset(), "[javac]", false, false, false, false); //$NON-NLS-1$
+					if (match != null) {
+						int start= match.getOffset() + match.getLength() + 1;
+						IRegion lineInfo= doc.getLineInformationOfOffset(start);
+						message= doc.get(start, lineInfo.getOffset() - start + lineInfo.getLength());
+					}
+				}
+			} catch (BadLocationException e) {
+				AntUIPlugin.log(e);
+			}
+		}
+		
+		return message;
+	}
+
+	protected void finished(IProcess process) {
+		if (process.equals(fProcess)) {
+			if (!fgFilesToBeCleaned.isEmpty()) {
+				Iterator itr= fgFilesToBeCleaned.iterator();
+				while (itr.hasNext()) {
+					IFile file = (IFile) itr.next();
+					try {
+						file.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
+					} catch (CoreException e) {
+						AntUIPlugin.log(e.getStatus());
+					}					
+				}
+			}
+			if (!fFileToMarkerInfo.isEmpty()) {
+				//generate markers for all the warnings and errors
+				Iterator files= fFileToMarkerInfo.keySet().iterator();
+				while (files.hasNext()) {
+					IFile file = (IFile) files.next();
+					List infos= (List) fFileToMarkerInfo.get(file);
+					createMarkers(file, infos);	
+				}	
+			}
+			
+			fFileToMarkerInfo.clear();
+			fgFilesToBeCleaned.clear();
+		}
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacPatternMatcher.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacPatternMatcher.java
new file mode 100644
index 0000000..3e4ea10
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacPatternMatcher.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.console;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ui.console.PatternMatchEvent;
+
+public class JavacPatternMatcher extends AbstractJavacPatternMatcher {
+
+    /*
+     *     [javac] /Users/kevinbarnes/Eclipse/runtime-workspace/Foo/src/CarriageReturn.java:4: ';' expected
+     */
+    public void matchFound(PatternMatchEvent event) {
+        String matchedText= getMatchedText(event);
+        if (matchedText == null) {
+            return;
+        }
+
+        int numEnd= matchedText.lastIndexOf(':');
+        while (numEnd > 1 && !Character.isDigit(matchedText.charAt(numEnd - 1))) {
+            numEnd= matchedText.lastIndexOf(':', numEnd - 1);
+        }
+        int numStart= matchedText.lastIndexOf(':', numEnd - 1);
+        
+        int index = matchedText.indexOf("]"); //$NON-NLS-1$
+        
+        String filePath;
+        if (numStart == -1) {
+        	//file path from listfiles
+        	filePath= matchedText.substring(index + 1);
+        	filePath = filePath.trim();
+        	int fileStart = matchedText.indexOf(filePath);
+        	int eventOffset= event.getOffset() + fileStart;
+            int eventLength = filePath.length();
+        	addLink(filePath, -1, eventOffset, eventLength, null);
+        } else {
+        	filePath= matchedText.substring(index + 1, numStart);
+        	filePath = filePath.trim();
+
+        	int fileStart = matchedText.indexOf(filePath);
+        	int eventOffset= event.getOffset() + fileStart;
+        	int eventLength = filePath.length();
+
+        	String lineNumberString = matchedText.substring(numStart + 1, numEnd);
+        	int lineNumber= -1; 
+        	try {
+        		lineNumber= Integer.parseInt(lineNumberString);
+        	} catch (NumberFormatException e) {
+        		AntUIPlugin.log(e);
+        	}
+
+        	Integer type= fgErrorType;
+        	if (-1 != matchedText.indexOf("warning", numEnd)) { //$NON-NLS-1$
+        		type= fgWarningType;
+        	}
+        	addLink(filePath, lineNumber, eventOffset, eventLength, type);
+        }
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JikesJavacPatternMatcher.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JikesJavacPatternMatcher.java
new file mode 100644
index 0000000..829fbdc
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JikesJavacPatternMatcher.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.console;
+
+import org.eclipse.ui.console.PatternMatchEvent;
+
+public class JikesJavacPatternMatcher extends AbstractJavacPatternMatcher {
+
+    /*
+     *     [javac] Found 1 semantic error compiling "/Users/kevinbarnes/Eclipse/runtime-workspace/Foo/src/CarriageReturn.java":
+     *     [javac] 3.         System.out.printer("\r");
+     */
+    public void matchFound(PatternMatchEvent event) {
+        String matchedText= getMatchedText(event);
+        if (matchedText == null) {
+            return;
+        }
+        int start = matchedText.indexOf('\"')+1;
+        int end = matchedText.indexOf('\"', start);        
+        String filePath = matchedText.substring(start, end);
+        int eventOffset= event.getOffset();
+        int fileStart = matchedText.indexOf(filePath) + eventOffset;
+        int fileLength = filePath.length();
+        
+        int lineNumber = getLineNumber(eventOffset, false);
+        //TODO determine if error or warning
+        addLink(filePath, lineNumber, fileStart, fileLength, fgErrorType);
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/TaskLineTracker.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/TaskLineTracker.java
new file mode 100644
index 0000000..cfc5964
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/TaskLineTracker.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.console;
+ 
+import org.eclipse.ant.internal.ui.launchConfigurations.TaskLinkManager;
+import org.eclipse.debug.ui.console.IConsole;
+import org.eclipse.debug.ui.console.IConsoleLineTrackerExtension;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * Processes task hyperlinks as lines are appended to the console
+ */
+public class TaskLineTracker implements IConsoleLineTrackerExtension {
+	
+	private IConsole fConsole;
+
+	/**
+	 * Constructor for TaskLineTracker.
+	 */
+	public TaskLineTracker() {
+		super();
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#init(org.eclipse.debug.ui.console.IConsole)
+	 */
+	public void init(IConsole console) {
+		fConsole = console;
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#lineAppended(org.eclipse.jface.text.IRegion)
+	 */
+	public void lineAppended(IRegion line) {
+		TaskLinkManager.processNewLine(fConsole, line);
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.console.IConsoleLineTracker#dispose()
+	 */
+	public void dispose() {
+		fConsole = null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.console.IConsoleLineTrackerExtension#consoleClosed()
+	 */
+	public void consoleClosed() {
+		TaskLinkManager.dispose(fConsole.getProcess());
+		AbstractJavacPatternMatcher.consoleClosed(fConsole.getProcess());
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntBuildfileExportWizard.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntBuildfileExportWizard.java
new file mode 100644
index 0000000..9079a9e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntBuildfileExportWizard.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.datatransfer;
+
+import java.util.List;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.IExportWizard;
+import org.eclipse.ui.IWorkbench;
+
+/**
+ * Exports currently selected Eclipse Java project as an Ant buildfile.
+ */
+public class AntBuildfileExportWizard extends Wizard implements IExportWizard
+{
+    private IStructuredSelection fSelection;
+    private AntBuildfileExportPage fMainPage;
+    
+    /**
+     * Creates buildfile.
+     */
+    public boolean performFinish()
+    {
+        return fMainPage.generateBuildfiles();
+    }
+ 
+    public void addPages()
+    {
+        fMainPage = new AntBuildfileExportPage();
+        List projects = fSelection.toList();
+        fMainPage.setSelectedProjects(projects);
+        addPage(fMainPage);
+    }
+
+    public void init(IWorkbench workbench, IStructuredSelection selection)
+    {
+        setWindowTitle(DataTransferMessages.AntBuildfileExportWizard_0);
+    	setDefaultPageImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_EXPORT_WIZARD_BANNER));
+    	setNeedsProgressMonitor(true);
+        fSelection= selection;
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectWizard.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectWizard.java
new file mode 100644
index 0000000..4214ae5
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectWizard.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.datatransfer;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+
+public class AntNewJavaProjectWizard extends Wizard implements INewWizard {
+
+	private AntNewJavaProjectPage fMainPage;
+
+	public AntNewJavaProjectWizard() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.wizard.IWizard#addPages()
+	 */
+	public void addPages() {
+		super.addPages();
+		fMainPage = new AntNewJavaProjectPage();
+		addPage(fMainPage);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection)
+	 */
+	public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
+		setWindowTitle(DataTransferMessages.AntNewJavaProjectWizard_0);
+		setDefaultPageImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_WIZARD_BANNER));
+		
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.wizard.IWizard#performCancel()
+	 */
+	public boolean performCancel() {
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.wizard.IWizard#performFinish()
+	 */
+	public boolean performFinish() {
+		return (fMainPage.createProject() != null);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/DataTransferMessages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/DataTransferMessages.java
new file mode 100644
index 0000000..14fd7b3
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/DataTransferMessages.java
@@ -0,0 +1,75 @@
+/**********************************************************************
+ * Copyright (c) 2004, 2009 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.datatransfer;
+
+import org.eclipse.osgi.util.NLS;
+
+public class DataTransferMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.datatransfer.DataTransferMessages";//$NON-NLS-1$
+    
+	public static String AntNewJavaProjectPage_23;
+
+	public static String AntNewJavaProjectPage_24;
+
+	public static String AntNewJavaProjectWizard_0;
+	public static String AntBuildfileExportWizard_0;
+	public static String AntBuildfileExportPage_0;
+    public static String AntBuildfileExportPage_10;
+    public static String AntBuildfileExportPage_11;
+    public static String AntBuildfileExportPage_12;
+    public static String AntBuildfileExportPage_13;
+    public static String AntBuildfileExportPage_14;
+    public static String AntBuildfileExportPage_15;
+    public static String AntBuildfileExportPage_16;
+    public static String AntBuildfileExportPage_17;
+    public static String AntBuildfileExportPage_1;
+	public static String AntBuildfileExportPage_2;
+	public static String AntBuildfileExportPage_3;
+	public static String AntBuildfileExportPage_4;
+	public static String AntBuildfileExportPage_6;
+	public static String AntNewJavaProjectPage_9;
+	public static String AntNewJavaProjectPage_0;
+	public static String AntNewJavaProjectPage_10;
+	public static String AntNewJavaProjectPage_11;
+	public static String AntNewJavaProjectPage_12;
+	public static String AntNewJavaProjectPage_13;
+	public static String AntNewJavaProjectPage_14;
+	public static String AntNewJavaProjectPage_15;
+	public static String AntNewJavaProjectPage_16;
+	public static String AntNewJavaProjectPage_17;
+	public static String AntNewJavaProjectPage_18;
+	public static String AntNewJavaProjectPage_19;
+	public static String AntNewJavaProjectPage_1;
+	public static String AntNewJavaProjectPage_21;
+	public static String AntNewJavaProjectPage_22;
+	public static String AntNewJavaProjectPage_2;
+    public static String AntNewJavaProjectPage_3;
+	public static String ProjectCreator_0;
+    public static String JavacTableLabelProvider_0;
+    public static String SourceAnalyzer_0;
+    public static String SourceAnalyzer_1;
+    public static String SourceAnalyzer_2;
+    public static String SourceAnalyzer_3;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, DataTransferMessages.class);
+	}
+
+	public static String AntBuildfileExportPage_18;
+
+	public static String AntBuildfileExportPage_19;
+
+	public static String AntBuildfileExportPage_20;
+
+	public static String AntBuildfileExportPage_creating_build_files;
+
+	public static String BuildFileCreator_generating_buildfile_for;
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/ProjectCreator.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/ProjectCreator.java
new file mode 100644
index 0000000..e8c94cf
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/ProjectCreator.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.datatransfer;
+
+import java.io.File;
+import com.ibm.icu.text.MessageFormat;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Javac;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.launching.JavaRuntime;
+
+public class ProjectCreator {
+		
+	public IJavaProject createJavaProjectFromJavacNode(String projectName, Javac javacTask, IProgressMonitor monitor) throws CoreException {
+		try {
+			IJavaProject javaProject = createJavaProject(projectName, monitor);
+			
+			File destDir= javacTask.getDestdir();
+			String destDirName= destDir == null ? null : destDir.getName();
+			org.apache.tools.ant.types.Path sourceDirs= javacTask.getSrcdir();
+			createSourceDirectories(destDir, destDirName, sourceDirs, javaProject, monitor);
+			
+			// add rt.jar
+			addVariableEntry(javaProject, new Path(JavaRuntime.JRELIB_VARIABLE), new Path(JavaRuntime.JRESRC_VARIABLE), new Path(JavaRuntime.JRESRCROOT_VARIABLE), monitor);
+			
+			setClasspath(javacTask, javaProject, monitor);
+			
+			javaProject.getProject().refreshLocal(IResource.DEPTH_INFINITE, monitor);
+			return javaProject;
+		} catch (BuildException be) {
+			IStatus status= new Status(IStatus.ERROR, AntUIPlugin.PI_ANTUI, IStatus.OK, be.getLocalizedMessage(), be);
+			throw new CoreException(status);
+		}
+	}
+	
+	private void setClasspath(Javac javacTask, IJavaProject javaProject, IProgressMonitor monitor) throws CoreException {
+		try {
+			org.apache.tools.ant.types.Path classpath= javacTask.getClasspath();
+			if (classpath == null) {
+				return;
+			}
+			String[] classpaths= classpath.list();
+			for (int i = 0; i < classpaths.length; i++) {
+				String cp = classpaths[i];
+				File classpathEntry= new File(cp);
+				if (classpathEntry.isFile()) {
+					addLibrary(javaProject, new Path(classpathEntry.getAbsolutePath()), monitor);
+				} else {
+					addContainer(javaProject, new Path(classpathEntry.getAbsolutePath()), monitor);
+				}
+			}
+		} catch (BuildException be) {
+			IStatus status= new Status(IStatus.ERROR, AntUIPlugin.PI_ANTUI, IStatus.OK, MessageFormat.format(DataTransferMessages.ProjectCreator_0, new String[]{be.getLocalizedMessage()}), null);
+			throw new CoreException(status);
+		}
+	}
+
+	private void createSourceDirectories(File destDir, String destDirName, org.apache.tools.ant.types.Path sourceDirs, IJavaProject javaProject, IProgressMonitor monitor) throws CoreException {
+		String[] sourceDirectories= sourceDirs.list();
+		for (int i = 0; i < sourceDirectories.length; i++) {
+			String srcDir = sourceDirectories[i];
+			File srcDirectory= new File(srcDir);
+			String srcDirectoryName= srcDirectory.getName();
+			String destDirPath= destDir == null ? srcDir : destDir.getAbsolutePath();
+			if (destDirName == null) {
+			    destDirName= srcDirectoryName;
+			}
+			addSourceContainer(javaProject, srcDirectoryName, srcDir, destDirName, destDirPath, monitor);
+		}
+	}
+
+	private IJavaProject createJavaProject(String projectName, IProgressMonitor monitor) throws CoreException {
+		IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
+		IProject project= root.getProject(projectName);
+		if (!project.exists()) {
+			project.create(monitor);
+		} else {
+			project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+		}
+		
+		if (!project.isOpen()) {
+			project.open(monitor);
+		}
+		
+		if (!project.hasNature(JavaCore.NATURE_ID)) {
+			addNatureToProject(project, JavaCore.NATURE_ID, monitor);
+		}
+		
+		IJavaProject jproject= JavaCore.create(project);
+		
+		jproject.setRawClasspath(new IClasspathEntry[0], monitor);
+		
+		return jproject;	
+	}
+	
+	private void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException {
+		IProjectDescription description = proj.getDescription();
+		String[] prevNatures= description.getNatureIds();
+		String[] newNatures= new String[prevNatures.length + 1];
+		System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
+		newNatures[prevNatures.length]= natureId;
+		description.setNatureIds(newNatures);
+		proj.setDescription(description, monitor);
+	}
+	
+	/**
+	 * Adds a source container to a IJavaProject.
+	 */		
+	private void addSourceContainer(IJavaProject jproject, String srcName, String srcPath, String outputName, String outputPath, IProgressMonitor monitor) throws CoreException {
+		IProject project= jproject.getProject();
+		IContainer container= null;
+		if (srcName == null || srcName.length() == 0) {
+			container= project;
+		} else {
+			IFolder folder= project.getFolder(srcName);
+			if (!folder.exists()) {
+				folder.createLink(new Path(srcPath), IResource.ALLOW_MISSING_LOCAL, monitor);
+			}
+			container= folder;
+		}
+		IPackageFragmentRoot root= jproject.getPackageFragmentRoot(container);
+
+		IPath output= null;
+		if (outputName!= null) {
+			IFolder outputFolder = project.getFolder(outputName);
+			if (!outputFolder.exists()) {
+			    outputFolder.createLink(new Path(outputPath), IResource.ALLOW_MISSING_LOCAL, monitor);
+			}
+			output= outputFolder.getFullPath();
+		}
+				
+		IClasspathEntry cpe= JavaCore.newSourceEntry(root.getPath(), new IPath[0], output);
+		
+		addToClasspath(jproject, cpe, monitor);		
+	}	
+	
+	private void addToClasspath(IJavaProject jproject, IClasspathEntry cpe, IProgressMonitor monitor) throws JavaModelException {
+		IClasspathEntry[] oldEntries= jproject.getRawClasspath();
+		for (int i= 0; i < oldEntries.length; i++) {
+			if (oldEntries[i].equals(cpe)) {
+				return;
+			}
+		}
+		int nEntries= oldEntries.length;
+		IClasspathEntry[] newEntries= new IClasspathEntry[nEntries + 1];
+		System.arraycopy(oldEntries, 0, newEntries, 0, nEntries);
+		newEntries[nEntries]= cpe;
+		jproject.setRawClasspath(newEntries, monitor);
+	}
+	
+	/**
+	 * Adds a variable entry with source attachment to a IJavaProject if the path can be resolved.
+	 */			
+	private void addVariableEntry(IJavaProject jproject, IPath path, IPath sourceAttachPath, IPath sourceAttachRoot, IProgressMonitor monitor) throws JavaModelException {
+		IClasspathEntry cpe= JavaCore.newVariableEntry(path, sourceAttachPath, sourceAttachRoot);
+		addToClasspath(jproject, cpe, monitor);
+	}
+	
+	/**
+	 * Adds a library entry to an IJavaProject.
+	 */			
+	private void addLibrary(IJavaProject jproject, IPath path, IProgressMonitor monitor) throws JavaModelException {
+		IClasspathEntry cpe= JavaCore.newLibraryEntry(path, null, null);
+		addToClasspath(jproject, cpe, monitor);
+	}
+	
+	/**
+	 * Adds a container entry to an IJavaProject.
+	 */			
+	private void addContainer(IJavaProject jproject, IPath path, IProgressMonitor monitor) throws CoreException {
+		IClasspathEntry cpe= JavaCore.newContainerEntry(path);
+		addToClasspath(jproject, cpe, monitor);
+		IProject project= jproject.getProject();
+		IFolder folder= project.getFolder(path.lastSegment());
+		if (!folder.exists()) {
+			folder.createLink(path, IResource.ALLOW_MISSING_LOCAL, monitor);
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/debug/model/DebugModelMessages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/debug/model/DebugModelMessages.java
new file mode 100644
index 0000000..2452a1d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/debug/model/DebugModelMessages.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.debug.model;
+
+import org.eclipse.osgi.util.NLS;
+
+public class DebugModelMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.debug.model.DebugModelMessages";//$NON-NLS-1$
+
+	public static String AntDebugModelPresentation_0;
+	public static String AntDebugModelPresentation_1;
+	public static String AntDebugModelPresentation_2;
+	public static String AntDebugModelPresentation_3;
+	public static String AntDebugModelPresentation_4;
+	public static String AntDebugModelPresentation_5;
+
+    
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, DebugModelMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/debug/model/DebugModelMessages.properties b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/debug/model/DebugModelMessages.properties
new file mode 100644
index 0000000..373fbc1
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/debug/model/DebugModelMessages.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2004, 2009 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
+###############################################################################
+
+AntDebugModelPresentation_0=<not available>
+AntDebugModelPresentation_1=\ line: {0}
+AntDebugModelPresentation_2=(breakpoint at line {0} in {1})
+AntDebugModelPresentation_3=\ (Suspended {0})
+AntDebugModelPresentation_4=\ (Suspended)
+AntDebugModelPresentation_5=(run to line {0} in {1})
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java
new file mode 100644
index 0000000..b47439e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+import org.eclipse.jdt.internal.debug.ui.actions.RuntimeClasspathAction;
+import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
+import org.eclipse.jdt.launching.JavaRuntime;
+
+public class AddVariableStringAction extends RuntimeClasspathAction {
+	
+	public AddVariableStringAction(IClasspathViewer viewer) {
+		super(AntLaunchConfigurationMessages.AddVariableStringAction_1, viewer);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.debug.ui.actions.RuntimeClasspathAction#getActionType()
+	 */
+	protected int getActionType() {
+		return ADD;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		VariableInputDialog inputDialog = new VariableInputDialog(getShell());
+		inputDialog.open();
+		String variableString= inputDialog.getVariableString();
+		if (variableString != null && variableString.trim().length() > 0) {
+			IRuntimeClasspathEntry newEntry = JavaRuntime.newStringVariableClasspathEntry(variableString);
+			getViewer().addEntries(new IRuntimeClasspathEntry[] {newEntry});
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java
new file mode 100644
index 0000000..1248e65
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+import org.eclipse.ant.internal.ui.AntUtil;
+import org.eclipse.ant.internal.launching.launchConfigurations.AntHomeClasspathEntry;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab;
+import org.eclipse.jdt.internal.debug.ui.actions.AddExternalJarAction;
+import org.eclipse.jdt.internal.debug.ui.actions.AddFolderAction;
+import org.eclipse.jdt.internal.debug.ui.actions.AddJarAction;
+import org.eclipse.jdt.internal.debug.ui.actions.MoveDownAction;
+import org.eclipse.jdt.internal.debug.ui.actions.MoveUpAction;
+import org.eclipse.jdt.internal.debug.ui.actions.RemoveAction;
+import org.eclipse.jdt.internal.debug.ui.actions.RestoreDefaultEntriesAction;
+import org.eclipse.jdt.internal.debug.ui.actions.RuntimeClasspathAction;
+import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathEntry;
+import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathModel;
+import org.eclipse.jdt.internal.debug.ui.classpath.IClasspathEntry;
+import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * The Ant classpath tab
+ */
+public class AntClasspathTab extends JavaClasspathTab {
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab#isShowBootpath()
+	 */
+	public boolean isShowBootpath() {
+		return false;
+	}
+	
+	/**
+	 * Creates actions to manipulate the classpath.
+	 * 
+	 * @param pathButtonComp composite buttons are contained in
+	 * @since 3.0
+	 */
+	protected void createPathButtons(Composite pathButtonComp) {		
+		createButton(pathButtonComp, new MoveUpAction(fClasspathViewer));
+		createButton(pathButtonComp, new MoveDownAction(fClasspathViewer));
+		createButton(pathButtonComp, new RemoveAction(fClasspathViewer));
+		createButton(pathButtonComp, new AddJarAction(fClasspathViewer));
+		createButton(pathButtonComp, new AddExternalJarAction(fClasspathViewer, DIALOG_SETTINGS_PREFIX));
+		Button button = createButton(pathButtonComp, new AddFolderAction(fClasspathViewer));
+		button.setText(AntLaunchConfigurationMessages.AntClasspathTab_0);
+		createButton(pathButtonComp, new AddVariableStringAction(fClasspathViewer));
+		RuntimeClasspathAction action= new RestoreDefaultEntriesAction(fClasspathViewer, this);
+		createButton(pathButtonComp, action);
+		action.setEnabled(true);
+		
+		action= new EditAntHomeEntryAction(fClasspathViewer, this);
+		createButton(pathButtonComp, action);
+		action.setEnabled(true);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#setDirty(boolean)
+	 */
+	public void setDirty(boolean dirty) {
+		super.setDirty(dirty);
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public void initializeFrom(ILaunchConfiguration configuration) {
+		try {
+			AntUtil.migrateToNewClasspathFormat(configuration);
+		} catch (CoreException e) {
+		}
+		super.initializeFrom(configuration);
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.debug.ui.launcher.IEntriesChangedListener#entriesChanged(org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer)
+	 */
+	public void entriesChanged(IClasspathViewer viewer) {
+		super.entriesChanged(viewer);
+		ILaunchConfigurationTab[] tabs = getLaunchConfigurationDialog().getTabs();
+		for (int i = 0; i < tabs.length; i++) {
+			ILaunchConfigurationTab tab = tabs[i];
+			if (tab instanceof AntTargetsTab) {
+				((AntTargetsTab)tab).setDirty(true);
+			}
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public boolean isValid(ILaunchConfiguration launchConfig) {
+		
+		boolean valid= super.isValid(launchConfig);
+		if (!valid) {
+			return false;
+		}
+		
+		return validateAntHome();
+	}
+	
+	private boolean validateAntHome() {
+		ClasspathModel model= getModel();
+		IClasspathEntry userEntry= model.getUserEntry();
+		IClasspathEntry[] entries= userEntry.getEntries();
+		for (int i = 0; i < entries.length; i++) {
+			ClasspathEntry entry = (ClasspathEntry) entries[i];
+			IRuntimeClasspathEntry runtimeEntry= entry.getDelegate();
+			if (runtimeEntry instanceof AntHomeClasspathEntry) {
+				try {
+					((AntHomeClasspathEntry)runtimeEntry).resolveAntHome();
+				} catch (CoreException ce) {
+					setErrorMessage(ce.getStatus().getMessage());
+					return false;
+				}
+				break;
+			}
+		}
+		return true;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntEnvironmentTab.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntEnvironmentTab.java
new file mode 100644
index 0000000..838b6f2
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntEnvironmentTab.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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 implementation
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+import org.eclipse.ant.internal.ui.AntUtil;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.EnvironmentTab;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * An environment tab for Ant launch configurations.
+ * Environment variables are only supported when Ant is
+ * run in a separate VM, so this tab adds a warning message
+ * at the top and disables the widgets if the config isn't
+ * set to run in a separate VM.
+ */
+public class AntEnvironmentTab extends EnvironmentTab {
+	
+	protected Composite wrappingComposite;
+	protected Label warningLabel;
+	
+	public void createControl(Composite parent) {
+		wrappingComposite= new Composite(parent, SWT.NONE);
+		wrappingComposite.setLayout(new GridLayout());
+		wrappingComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		wrappingComposite.setFont(parent.getFont());
+		
+		warningLabel= new Label(wrappingComposite, SWT.NONE);
+		warningLabel.setText(AntLaunchConfigurationMessages.AntEnvironmentTab_0);
+		
+		super.createControl(wrappingComposite);
+		setControl(wrappingComposite); // Overwrite setting in super method
+		Dialog.applyDialogFont(parent);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
+		updateWidgetsEnabled(workingCopy);
+	}
+	
+	protected void updateWidgetsEnabled(ILaunchConfigurationWorkingCopy workingCopy) {
+		if (wrappingComposite == null) {
+			return;
+		}
+		boolean isSeparateJREBuild= AntUtil.isSeparateJREAntBuild(workingCopy);
+		
+		Color tableColor= isSeparateJREBuild ? null : Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
+		Color labelColor= isSeparateJREBuild ? null : Display.getDefault().getSystemColor(SWT.COLOR_RED);
+		Table table = environmentTable.getTable();
+		table.setEnabled(isSeparateJREBuild);
+		table.setBackground(tableColor);
+		warningLabel.setForeground(labelColor);
+		envAddButton.setEnabled(isSeparateJREBuild);
+		envSelectButton.setEnabled(isSeparateJREBuild);
+		updateAppendReplace();
+		//update the enabled state of the edit and remove buttons
+		environmentTable.setSelection(environmentTable.getSelection());
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchConfigurationMessages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchConfigurationMessages.java
new file mode 100644
index 0000000..5546837
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchConfigurationMessages.java
@@ -0,0 +1,93 @@
+/**********************************************************************
+ * Copyright (c) 2000, 2009 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 - Initial API and implementation
+ * dakshinamurthy.karra@gmail.com - bug 165371
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntLaunchConfigurationMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.launchConfigurations.AntLaunchConfigurationMessages";//$NON-NLS-1$
+
+    public static String AddVariableStringAction_1;
+	public static String AddVariableStringAction_2;
+	public static String AddVariableStringAction_3;
+	public static String AddVariableStringAction_4;
+
+	public static String AntLaunchShortcut_Unable;
+	public static String AntLaunchShortcut_2;
+	public static String AntLaunchShortcut_3;
+	public static String AntLaunchShortcut_4;
+	public static String AntLaunchShortcut_5;
+	public static String AntLaunchShortcut_Error_7;
+	public static String AntLaunchShortcut_Build_Failed_2;
+	public static String AntLaunchShortcut_Exception_launching;
+
+	public static String AntPropertiesTab__Properties__6;
+	public static String AntPropertiesTab_Property_f_iles__7;
+	public static String AntPropertiesTab_P_roperties_8;
+	public static String AntPropertiesTab_Error_reading_configuration_9;
+	public static String AntPropertiesTab_6;
+
+	public static String AntJRETab_2;
+	public static String AntJRETab_3;
+	
+	public static String AntBuilderTargetsTab_0;
+	public static String AntBuilderTargetsTab_1;
+	public static String AntBuilderTargetsTab_2;
+	public static String AntBuilderTargetsTab_3;
+	public static String AntBuilderTargetsTab_4;
+	public static String AntBuilderTargetsTab_5;
+	public static String AntBuilderTargetsTab_6;
+	public static String AntBuilderTargetsTab_7;
+	public static String AntBuilderTargetsTab_8;
+	public static String AntBuilderTargetsTab_10;
+
+	public static String AntMainTab__Select_a_build_file__1;
+	public static String AntMainTab_3;
+	public static String AntMainTab_6;
+	public static String AntMainTab_0;
+	public static String AntMainTab_1;
+
+	public static String AntTargetsTab_Check_targets_to_e_xecute__1;
+	public static String AntTargetsTab_0_out_of_0_selected_2;
+	public static String AntTargetsTab_Target_execution_order__3;
+	public static String AntTargetsTab__Order____4;
+	public static String AntTargetsTab_Name_5;
+	public static String AntTargetsTab_Description_6;
+	public static String AntTargetsTab__0__out_of__1__selected_7;
+	public static String AntTargetsTab_Tar_gets_14;
+	public static String AntTargetsTab_Error_reading_configuration_12;
+	public static String AntTargetsTab_12;
+	public static String AntTargetsTab_13;
+	public static String AntTargetsTab_14;
+	public static String AntTargetsTab_15;
+	public static String AntTargetsTab_16;
+	public static String AntTargetsTab_17;
+	public static String AntTargetsTab_0;
+	public static String AntTargetsTab_1;
+	public static String AntClasspathTab_0;
+
+	public static String EditAntHomeEntryAction_1;
+
+	public static String TargetOrderDialog_Order_Targets_1;
+	public static String TargetOrderDialog__Specify_target_execution_order__2;
+	public static String TargetOrderDialog__Up_3;
+	public static String TargetOrderDialog__Down_4;
+
+	public static String AntEnvironmentTab_0;
+	public static String SetTargetsDialog_0;
+    
+    public static String AntWorkingDirectoryBlock_0;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntLaunchConfigurationMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchConfigurationMessages.properties b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchConfigurationMessages.properties
new file mode 100644
index 0000000..5a62681
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchConfigurationMessages.properties
@@ -0,0 +1,82 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+#     dakshinamurthy.karra@gmail.com - bug 165371
+###############################################################################
+
+AddVariableStringAction_1=Add Varia&ble...
+AddVariableStringAction_2=&Classpath Entry Value:
+AddVariableStringAction_3=&Variables...
+AddVariableStringAction_4=Add Variable Classpath Entry
+
+AntLaunchShortcut_Unable=Unable to find an Ant file to run.
+AntLaunchShortcut_2=An exception occurred while creating a default Ant launch configuration for {0}
+AntLaunchShortcut_3=An exception occurred while retrieving Ant launch configurations.
+AntLaunchShortcut_4=Ant Configuration Selection
+AntLaunchShortcut_5=&Choose an Ant configuration to run:
+AntLaunchShortcut_Error_7=Error
+AntLaunchShortcut_Build_Failed_2=Build Failed
+AntLaunchShortcut_Exception_launching=An exception occurred while launching {0}
+
+AntPropertiesTab__Properties__6=&Properties:
+AntPropertiesTab_Property_f_iles__7=P&roperty files:
+AntPropertiesTab_P_roperties_8=Properties
+AntPropertiesTab_Error_reading_configuration_9=Error reading configuration
+AntPropertiesTab_6=Use &global properties as specified in the Ant runtime preferences
+
+AntJRETab_2=Run in the same &JRE as the workspace
+AntJRETab_3=Se&parate JRE:
+
+AntBuilderTargetsTab_0=<Builder is not set to run for this build kind>
+AntBuilderTargetsTab_1=After a "Clean":
+AntBuilderTargetsTab_2=&Set Targets...
+AntBuilderTargetsTab_3=Manual Build:
+AntBuilderTargetsTab_4=Set &Targets...
+AntBuilderTargetsTab_5=Auto Build:
+AntBuilderTargetsTab_6=Set T&argets...
+AntBuilderTargetsTab_7=During a "Clean":
+AntBuilderTargetsTab_8=Set Tar&gets...
+AntBuilderTargetsTab_10=<default target selected>
+
+AntMainTab__Select_a_build_file__1=&Select a buildfile:
+AntMainTab_3=Base Direct&ory:
+AntMainTab_6=Buildfi&le:
+AntMainTab_0=Set an Input &handler
+AntMainTab_1=Error reading configuration
+
+AntTargetsTab_Check_targets_to_e_xecute__1=Check targets to e&xecute:
+AntTargetsTab_0_out_of_0_selected_2=0 out of 0 selected
+AntTargetsTab_Target_execution_order__3=Target execution order:
+AntTargetsTab__Order____4=&Order...
+AntTargetsTab_Name_5=Name
+AntTargetsTab_Description_6=Description
+AntTargetsTab__0__out_of__1__selected_7={0} out of {1} selected
+AntTargetsTab_Tar_gets_14=Targets
+AntTargetsTab_Error_reading_configuration_12=Error reading configuration
+AntTargetsTab_12=&Hide internal targets not selected for execution
+AntTargetsTab_13={0} out of {1} selected ({2} internal target(s) hidden)
+AntTargetsTab_14=&Sort targets
+AntTargetsTab_15=Buildfile does not exist
+AntTargetsTab_16=Buildfile specified is not a file
+AntTargetsTab_17=Target selection is not possible as buildfile location contains variable(s) that cannot be resolved until runtime.
+AntTargetsTab_0=Buildfile contains errors/problems. Check syntax and classpath
+AntTargetsTab_1=No targets could be determined for the buildfile
+AntClasspathTab_0=Add F&olders...
+
+EditAntHomeEntryAction_1=Ant &Home...
+
+TargetOrderDialog_Order_Targets_1=Order Targets
+TargetOrderDialog__Specify_target_execution_order__2=&Specify target execution order:
+TargetOrderDialog__Up_3=&Up
+TargetOrderDialog__Down_4=&Down
+
+AntEnvironmentTab_0=An environment can only be used when running in a separate JRE.\nThis setting can be configured on the JRE tab.
+SetTargetsDialog_0=Set Targets
+
+AntWorkingDirectoryBlock_0=Exception occurred reading configuration: {0}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchDelegate.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchDelegate.java
new file mode 100644
index 0000000..3995213
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchDelegate.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *     Juan A. Hernandez - bug 89926
+ *     dakshinamurthy.karra@gmail.com - bug 165371
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+
+/**
+ * <b>This class should no longer be used.</b>
+ * <p>
+ * Old launch delegate for Ant builds
+ * </p>
+ * @deprecated this class has been replaced with {@link org.eclipse.ant.internal.launching.launchConfigurations.AntLaunchDelegate}
+ *  and is only present for backwards compatibility
+ */
+public class AntLaunchDelegate extends org.eclipse.ant.internal.launching.launchConfigurations.AntLaunchDelegate  {
+	
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchShortcutWithDialog.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchShortcutWithDialog.java
new file mode 100644
index 0000000..ef1df31
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntLaunchShortcutWithDialog.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+public class AntLaunchShortcutWithDialog extends AntLaunchShortcut {
+	
+	/**
+	 * Creates a new Ant launch shortcut that will open the
+	 * launch configuration dialog.
+	 */
+	public AntLaunchShortcutWithDialog() {
+		super();
+		setShowDialog(true);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntPropertiesTab.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntPropertiesTab.java
new file mode 100644
index 0000000..5e50fbe
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntPropertiesTab.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.Property;
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.AntUtil;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.ant.internal.ui.preferences.AntPropertiesBlock;
+import org.eclipse.ant.internal.ui.preferences.IAntBlockContainer;
+import org.eclipse.ant.launching.IAntLaunchConstants;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Tab for setting Ant user properties per launch configuration. All properties
+ * specified here will be set as user properties on the project for the
+ * specified Ant build
+ */
+public class AntPropertiesTab extends AbstractLaunchConfigurationTab implements IAntBlockContainer {
+	
+	private Button fUseDefaultButton;
+	private AntPropertiesBlock fAntPropertiesBlock= new AntPropertiesBlock(this);
+    private boolean fSeparateJRE= true;
+	
+	public void createControl(Composite parent) {
+		Composite top = new Composite(parent, SWT.NONE);
+		top.setFont(parent.getFont());
+		setControl(top);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IAntUIHelpContextIds.ANT_PROPERTIES_TAB);
+
+		top.setLayout(new GridLayout());
+		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+		top.setLayoutData(gridData);
+		
+		createChangeProperties(top);
+		
+		Composite propertiesBlockComposite= new Composite(top, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns= 2;
+		propertiesBlockComposite.setLayout(layout);
+		propertiesBlockComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		fAntPropertiesBlock.createControl(propertiesBlockComposite, AntLaunchConfigurationMessages.AntPropertiesTab__Properties__6, AntLaunchConfigurationMessages.AntPropertiesTab_Property_f_iles__7);
+		
+		Dialog.applyDialogFont(top);
+	}
+	
+	private void createChangeProperties(Composite top) {
+		fUseDefaultButton= createCheckButton(top, AntLaunchConfigurationMessages.AntPropertiesTab_6);
+		fUseDefaultButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				toggleUseDefaultProperties();
+				updateLaunchConfigurationDialog();
+			}
+		});
+	}		
+		
+	private void toggleUseDefaultProperties() {
+		boolean enable= !fUseDefaultButton.getSelection();
+		fAntPropertiesBlock.setEnabled(enable);
+        if (!enable) {
+            initializeAsGlobal(fSeparateJRE);
+        }
+	}
+	
+	/**
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
+	 */
+	public Image getImage() {
+		return AntUIImages.getImage(IAntUIConstants.IMG_PROPERTY);
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
+	 */
+	public String getName() {
+		return AntLaunchConfigurationMessages.AntPropertiesTab_P_roperties_8;
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public void initializeFrom(ILaunchConfiguration configuration) {
+        fSeparateJRE= AntUtil.isSeparateJREAntBuild(configuration);
+		setErrorMessage(null);
+		setMessage(null);
+		Map properties= null;
+		try {
+			properties= configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTIES, (Map)null);
+		} catch (CoreException ce) {
+			AntUIPlugin.log(AntLaunchConfigurationMessages.AntPropertiesTab_Error_reading_configuration_9, ce);
+		}
+		
+		String propertyFiles= null;
+		try {
+			propertyFiles= configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTY_FILES, (String)null);
+		} catch (CoreException ce) {
+			AntUIPlugin.log(AntLaunchConfigurationMessages.AntPropertiesTab_Error_reading_configuration_9, ce);
+		}
+		
+		if (properties == null && propertyFiles == null) {
+		    initializeAsGlobal(fSeparateJRE);
+		} else {
+			fUseDefaultButton.setSelection(false);
+			fAntPropertiesBlock.populatePropertyViewer(properties);
+		
+			String[] files= AntUtil.parseString(propertyFiles, ","); //$NON-NLS-1$
+			fAntPropertiesBlock.setPropertyFilesInput(files);
+		}
+		
+		toggleUseDefaultProperties();
+	}
+
+    private void initializeAsGlobal(boolean separateVM) {
+        AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
+        List prefProperties;
+        if (separateVM) {
+            prefProperties= prefs.getRemoteAntProperties();
+        } else {
+            prefProperties= prefs.getProperties();
+        }
+        fAntPropertiesBlock.setPropertiesInput((Property[]) prefProperties.toArray(new Property[prefProperties.size()]));
+        fAntPropertiesBlock.setPropertyFilesInput(AntCorePlugin.getPlugin().getPreferences().getCustomPropertyFiles(false));
+        fAntPropertiesBlock.setTablesEnabled(false);
+        fUseDefaultButton.setSelection(true);
+    }
+	
+	/**
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+		if (fUseDefaultButton.getSelection()) {
+			configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTIES, (Map)null);
+			configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTY_FILES, (String)null);
+			return;
+		}
+				
+		Object[] items= fAntPropertiesBlock.getProperties();
+		Map properties= null;
+		if (items.length > 0) {
+			properties= new HashMap(items.length);
+			for (int i = 0; i < items.length; i++) {
+				Property property = (Property)items[i];
+				properties.put(property.getName(), property.getValue(false));
+			}
+		}
+		
+		configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTIES, properties);
+		
+		items= fAntPropertiesBlock.getPropertyFiles();
+		String files= null;
+		if (items.length > 0) {
+			StringBuffer buff= new StringBuffer();
+			for (int i = 0; i < items.length; i++) {
+				String path = (String)items[i];
+				buff.append(path);
+				buff.append(',');
+			}
+			files= buff.toString();
+		}
+		
+		configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTY_FILES, files);
+		
+		fAntPropertiesBlock.saveSettings();
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#createPushButton(org.eclipse.swt.widgets.Composite, java.lang.String)
+	 */
+	public void setMessage(String message) {
+		super.setMessage(message);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#createPushButton(org.eclipse.swt.widgets.Composite, java.lang.String)
+	 */
+	public void setErrorMessage(String message) {
+		super.setErrorMessage(message);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#createPushButton(org.eclipse.swt.widgets.Composite, java.lang.String)
+	 */
+	public Button createPushButton(Composite parent, String buttonText) {
+		return super.createPushButton(parent, buttonText, null);
+	}
+	
+	/**
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#update()
+	 */
+	public void update() {
+		updateTargetsTab();
+		updateLaunchConfigurationDialog();
+	}
+	
+	private void updateTargetsTab() {
+		//the properties have changed...set the targets tab to 
+		//need to be recomputed
+		ILaunchConfigurationTab[] tabs=  getLaunchConfigurationDialog().getTabs();
+		for (int i = 0; i < tabs.length; i++) {
+			ILaunchConfigurationTab tab = tabs[i];
+			if (tab instanceof AntTargetsTab) {
+				((AntTargetsTab)tab).setDirty(true);
+				break;
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
+        if (fSeparateJRE != AntUtil.isSeparateJREAntBuild(workingCopy)) {
+            //update the properties if changed whether build is in separate JRE
+            initializeFrom(workingCopy);
+        }
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#deactivated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) {
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntTargetsTab.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntTargetsTab.java
new file mode 100644
index 0000000..10d8ba5
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntTargetsTab.java
@@ -0,0 +1,845 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *     Martin Karpisek (martin.karpisek@gmail.com) - bug 229474
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.AntUtil;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.ant.internal.ui.model.AntElementNode;
+import org.eclipse.ant.internal.ui.model.AntModelContentProvider;
+import org.eclipse.ant.internal.ui.model.AntProjectNode;
+import org.eclipse.ant.internal.ui.model.AntTargetNode;
+import org.eclipse.ant.internal.ui.model.InternalTargetFilter;
+import org.eclipse.ant.launching.IAntLaunchConstants;
+import org.eclipse.core.externaltools.internal.IExternalToolConstants;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.variables.IStringVariableManager;
+import org.eclipse.core.variables.VariablesPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+import com.ibm.icu.text.MessageFormat;
+
+/**
+ * Launch configuration tab which allows the user to choose the targets
+ * from an Ant buildfile that will be executed when the configuration is
+ * launched.
+ */
+public class AntTargetsTab extends AbstractLaunchConfigurationTab {
+	
+	private AntTargetNode fDefaultTarget = null;
+	private AntTargetNode[] fAllTargets= null;
+	private List fOrderedTargets = null;
+	
+	private CheckboxTableViewer fTableViewer = null;
+	private Label fSelectionCountLabel = null;
+	private Text fTargetOrderText = null;
+	private Button fOrderButton = null;
+	private Button fFilterInternalTargets;
+	private InternalTargetFilter fInternalTargetFilter= null;
+	private Button fSortButton;
+	
+	private ILaunchConfiguration fLaunchConfiguration;
+	private int fSortDirection= 0;
+	private boolean fInitializing= false;
+	
+	/**
+	 * Sort direction constants.
+	 */
+	public final static int SORT_NONE= 0;
+	public final static int SORT_NAME= 1;
+	public final static int SORT_NAME_REVERSE= -1;
+	public final static int SORT_DESCRIPTION= 2;
+	public final static int SORT_DESCRIPTION_REVERSE= -2;
+	
+	/**
+	 * A comparator which can sort targets by name or description, in
+	 * forward or reverse order.
+	 */
+	private class AntTargetsComparator extends ViewerComparator {
+		/* (non-Javadoc)
+		 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+		 */
+		public int compare(Viewer viewer, Object e1, Object e2) {
+			if (!(e1 instanceof AntTargetNode && e2 instanceof AntTargetNode)) {
+				return super.compare(viewer, e1, e2);
+			}
+			if (fSortDirection == SORT_NONE) {
+				return 0;
+			}
+			String string1, string2;
+			int result= 0;
+			if (fSortDirection == SORT_NAME || fSortDirection == SORT_NAME_REVERSE) {
+				string1= ((AntTargetNode) e1).getLabel();
+				string2= ((AntTargetNode) e2).getLabel();
+			} else {
+				string1= ((AntTargetNode) e1).getTarget().getDescription();
+				string2= ((AntTargetNode) e2).getTarget().getDescription();
+			}
+			if (string1 != null && string2 != null) {
+				result= getComparator().compare(string1, string2);
+			} else if (string1 == null) {
+				result= 1;
+			} else if (string2 == null) {
+				result= -1;
+			}
+			if (fSortDirection < 0) { // reverse sort
+				if (result == 0) {
+					result= -1;
+				} else {
+					result= -result;
+				}
+			}
+			return result;
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
+	 */
+	public void createControl(Composite parent) {
+		Font font = parent.getFont();
+		
+		Composite comp = new Composite(parent, SWT.NONE);
+		setControl(comp);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IAntUIHelpContextIds.ANT_TARGETS_TAB);
+		GridLayout topLayout = new GridLayout();
+		comp.setLayout(topLayout);		
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		comp.setLayoutData(gd);
+		comp.setFont(font);
+		
+		createTargetsTable(comp);
+		createSelectionCount(comp);
+		
+		Composite buttonComposite= new Composite(comp, SWT.NONE);
+		GridLayout layout= new GridLayout();
+		layout.verticalSpacing = 0;
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		buttonComposite.setLayout(layout);
+		buttonComposite.setFont(font);
+		
+		createSortTargets(buttonComposite);
+		createFilterInternalTargets(buttonComposite);
+		
+		createVerticalSpacer(comp, 1);
+		createTargetOrder(comp);
+		Dialog.applyDialogFont(parent);
+	}
+	
+	/**
+	 * Creates the selection count widget
+	 * @param parent the parent composite
+	 */
+	private void createSelectionCount(Composite parent) {
+		fSelectionCountLabel = new Label(parent, SWT.NONE);
+		fSelectionCountLabel.setFont(parent.getFont());
+		fSelectionCountLabel.setText(AntLaunchConfigurationMessages.AntTargetsTab_0_out_of_0_selected_2);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		fSelectionCountLabel.setLayoutData(gd);
+	}
+
+	/**
+	 * Creates the widgets that display the target order
+	 * @param parent the parent composite
+	 */
+	private void createTargetOrder(Composite parent) {
+		Font font= parent.getFont();
+		
+		Label label = new Label(parent, SWT.NONE);
+		label.setText(AntLaunchConfigurationMessages.AntTargetsTab_Target_execution_order__3);
+		label.setFont(font);
+		
+		Composite orderComposite = new Composite(parent, SWT.NONE);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		orderComposite.setLayoutData(gd);
+		GridLayout layout = new GridLayout(2, false);
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		orderComposite.setLayout(layout);
+		orderComposite.setFont(font);
+				
+		fTargetOrderText = new Text(orderComposite, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY);
+		fTargetOrderText.setFont(font);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.heightHint = 40;
+		gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		fTargetOrderText.setLayoutData(gd);
+
+		fOrderButton = createPushButton(orderComposite, AntLaunchConfigurationMessages.AntTargetsTab__Order____4, null);
+		gd = (GridData)fOrderButton.getLayoutData();
+		gd.verticalAlignment = GridData.BEGINNING;
+		fOrderButton.setFont(font);
+		fOrderButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleOrderPressed();
+			}
+		});
+	}
+
+	/**
+	 * Creates the toggle to filter internal targets from the table
+	 * @param parent the parent composite
+	 */
+	private void createFilterInternalTargets(Composite parent) {
+		fFilterInternalTargets= createCheckButton(parent, AntLaunchConfigurationMessages.AntTargetsTab_12);
+		fFilterInternalTargets.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleFilterTargetsSelected();
+			}
+		});
+	}
+	
+	/**
+	 * Creates the toggle to sort targets in the table
+	 * @param parent the parent composite
+	 */
+	private void createSortTargets(Composite parent) {
+		fSortButton= createCheckButton(parent, AntLaunchConfigurationMessages.AntTargetsTab_14);
+		fSortButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleSortTargetsSelected();
+			}
+		});
+	}
+	
+	/**
+	 * The filter targets button has been toggled. If it's been
+	 * turned on, filter out internal targets. Else, restore internal
+	 * targets to the table.
+	 */
+	private void handleFilterTargetsSelected() {
+		boolean filter= fFilterInternalTargets.getSelection();
+		if (filter) {
+			fTableViewer.addFilter(getInternalTargetsFilter());
+		} else {
+			fTableViewer.removeFilter(getInternalTargetsFilter());
+		}
+		
+		// Must refresh before updating selection count because the selection
+		// count's "hidden" reporting needs the content provider to be queried
+		// first to count how many targets are hidden.
+		updateSelectionCount();
+		if (!fInitializing) {
+		    updateLaunchConfigurationDialog();
+		}
+	}
+	
+	private ViewerFilter getInternalTargetsFilter() {
+		if (fInternalTargetFilter == null) {
+			fInternalTargetFilter= new InternalTargetFilter();
+		}
+		return fInternalTargetFilter;
+	}
+	
+	/**
+	 * The button to sort targets has been toggled.
+	 * Set the tab's sorting as appropriate.
+	 */
+	private void handleSortTargetsSelected() {
+		setSort(fSortButton.getSelection() ? SORT_NAME : SORT_NONE);
+	}
+	
+	/**
+	 * Sets the sorting of targets in this tab. See the sort constants defined
+	 * above.
+	 * 
+	 * @param column the column which should be sorted on
+	 */
+	private void setSort(int column) {
+		fSortDirection= column;
+		fTableViewer.refresh();
+		if (!fInitializing) {
+			updateLaunchConfigurationDialog();
+		}
+	}
+
+	/**
+	 * The target order button has been pressed. Prompt the
+	 * user to reorder the selected targets. 
+	 */
+	private void handleOrderPressed() {
+		TargetOrderDialog dialog = new TargetOrderDialog(getShell(), fOrderedTargets.toArray());
+		int ok = dialog.open();
+		if (ok == Window.OK) {
+			fOrderedTargets.clear();
+			Object[] targets = dialog.getTargets();
+			for (int i = 0; i < targets.length; i++) {
+				fOrderedTargets.add(targets[i]);
+				updateSelectionCount();
+				updateLaunchConfigurationDialog();
+			}
+		}
+	}
+	
+	/**
+	 * Creates the table which displays the available targets
+	 * @param parent the parent composite
+	 */
+	private void createTargetsTable(Composite parent) {
+		Font font= parent.getFont();
+		Label label = new Label(parent, SWT.NONE);
+		label.setFont(font);
+		label.setText(AntLaunchConfigurationMessages.AntTargetsTab_Check_targets_to_e_xecute__1);
+				
+		final Table table= new Table(parent, SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION );
+		
+		GridData data= new GridData(GridData.FILL_BOTH);
+		int availableRows= availableRows(parent);
+		data.heightHint = table.getItemHeight() * (availableRows / 20);
+		data.widthHint= 250;
+		table.setLayoutData(data);
+		table.setFont(font);
+				
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);		
+
+		TableLayout tableLayout= new TableLayout();
+		ColumnWeightData weightData = new ColumnWeightData(30, true);
+		tableLayout.addColumnData(weightData);
+		weightData = new ColumnWeightData(70, true);
+		tableLayout.addColumnData(weightData);		
+		table.setLayout(tableLayout);
+
+		final TableColumn column1= new TableColumn(table, SWT.NULL);
+		column1.setText(AntLaunchConfigurationMessages.AntTargetsTab_Name_5);
+			
+		final TableColumn column2= new TableColumn(table, SWT.NULL);
+		column2.setText(AntLaunchConfigurationMessages.AntTargetsTab_Description_6);
+		
+
+		//TableLayout only sizes columns once. If showing the targets
+		//tab as the initial tab, the dialog isn't open when the layout
+		//occurs and the column size isn't computed correctly. Need to
+		//recompute the size of the columns once all the parent controls 
+		//have been created/sized.
+		//HACK Bug 139190 
+		getShell().addShellListener(new ShellAdapter() {
+			public void shellActivated(ShellEvent e) {
+				if(!table.isDisposed()) {
+					int tableWidth = table.getSize().x;
+					if (tableWidth > 0) {
+						int c1 = tableWidth / 3;
+						column1.setWidth(c1);
+						column2.setWidth(tableWidth - c1);
+					}
+					getShell().removeShellListener(this);
+				}
+			}
+		});
+		
+		fTableViewer = new CheckboxTableViewer(table);
+		fTableViewer.setLabelProvider(new TargetTableLabelProvider());
+		fTableViewer.setContentProvider(new AntModelContentProvider());
+		fTableViewer.setComparator(new AntTargetsComparator());
+		
+		fTableViewer.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+				ISelection selection= event.getSelection();
+				if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
+					IStructuredSelection ss= (IStructuredSelection)selection;
+					Object element= ss.getFirstElement();
+					boolean checked= !fTableViewer.getChecked(element);
+					fTableViewer.setChecked(element, checked);
+					updateOrderedTargets(element, checked);
+				}
+			}
+		});
+		
+		fTableViewer.addCheckStateListener(new ICheckStateListener() {
+			public void checkStateChanged(CheckStateChangedEvent event) {
+				updateOrderedTargets(event.getElement(), event.getChecked());
+			}
+		});
+		
+		TableColumn[] columns= fTableViewer.getTable().getColumns();
+		for (int i = 0; i < columns.length; i++) {
+			final int index= i;
+			columns[index].addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					if (fSortButton.getSelection()) {
+						// index 0 => sort_name (1)
+						// index 1 => sort_description (2)
+						int column= index + 1;
+						if (column == fSortDirection) {
+							column= -column; // invert the sort when the same column is selected twice in a row
+						}
+						setSort(column);
+					}
+				}
+			});
+		}
+	}
+	
+	/**
+	 * Return the number of rows available in the current display using the
+	 * current font.
+	 * @param parent The Composite whose Font will be queried.
+	 * @return int The result of the display size divided by the font size.
+	 */
+	private int availableRows(Composite parent) {
+
+		int fontHeight = (parent.getFont().getFontData())[0].getHeight();
+		int displayHeight = parent.getDisplay().getClientArea().height;
+
+		return displayHeight / fontHeight;
+	}
+	
+	/**
+	 * Updates the ordered targets list in response to an element being checked
+	 * or unchecked. When the element is checked, it's added to the list. When
+	 * unchecked, it's removed.
+	 * 
+	 * @param element the element in question
+	 * @param checked whether the element has been checked or unchecked
+	 */
+	private void updateOrderedTargets(Object element , boolean checked) {
+		if (checked) {
+			 fOrderedTargets.add(element);
+		} else {
+			fOrderedTargets.remove(element);
+		}	 
+		updateSelectionCount();
+		updateLaunchConfigurationDialog();	
+	}
+	
+	/**
+	 * Updates the selection count widget to display how many targets are
+	 * selected (example, "1 out of 6 selected") and filtered.
+	 */
+	private void updateSelectionCount() {
+		Object[] checked = fTableViewer.getCheckedElements();
+		String numSelected = Integer.toString(checked.length);
+	
+		int all= fAllTargets == null ? 0 : fAllTargets.length;
+		int visible= fTableViewer.getTable().getItemCount();
+		String total = Integer.toString(visible);
+		int numHidden= all - visible;
+		if (numHidden > 0) {
+			fSelectionCountLabel.setText(MessageFormat.format(AntLaunchConfigurationMessages.AntTargetsTab_13, new String[]{numSelected, String.valueOf(all), String.valueOf(numHidden)}));
+		} else {
+			fSelectionCountLabel.setText(MessageFormat.format(AntLaunchConfigurationMessages.AntTargetsTab__0__out_of__1__selected_7, new String[]{numSelected, total}));
+		}
+		
+		fOrderButton.setEnabled(checked.length > 1);
+		
+		StringBuffer buffer = new StringBuffer();
+		Iterator iter = fOrderedTargets.iterator();
+		while (iter.hasNext()) {
+			buffer.append(((AntTargetNode)iter.next()).getTargetName());
+			buffer.append(", "); //$NON-NLS-1$
+		}
+		if (buffer.length() > 2) {
+			// remove trailing comma
+			buffer.setLength(buffer.length() - 2);
+		}
+		fTargetOrderText.setText(buffer.toString());
+	}
+	
+	/**
+	 * Returns all targets in the buildfile.
+	 * @return all targets in the buildfile
+	 */
+	private AntTargetNode[] getTargets() {
+		if (fAllTargets == null || isDirty()) {
+			fAllTargets= null;
+			fDefaultTarget= null;
+			setDirty(false);
+			setErrorMessage(null);
+			setMessage(null);
+			
+			final String expandedLocation= validateLocation();
+			if (expandedLocation == null) {
+				return fAllTargets;
+			}
+			final CoreException[] exceptions= new CoreException[1];
+			try {
+				IRunnableWithProgress operation= new IRunnableWithProgress() {
+					/* (non-Javadoc)
+					 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
+					 */
+					public void run(IProgressMonitor monitor) {
+						try {
+							fAllTargets = AntUtil.getTargets(expandedLocation, fLaunchConfiguration);
+						} catch (CoreException ce) {
+							exceptions[0]= ce;
+						}
+					}
+				};
+				
+				IRunnableContext context= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+				if (context == null) {
+				    context= getLaunchConfigurationDialog();
+				}
+
+				ISchedulingRule rule= null;
+				if (!ResourcesPlugin.getWorkspace().isTreeLocked()) {
+					//only set a scheduling rule if not in a resource change callback
+					rule= AntUtil.getFileForLocation(expandedLocation, null);
+				}
+				PlatformUI.getWorkbench().getProgressService().runInUI(context, operation, rule);
+			} catch (InvocationTargetException e) {
+			    AntUIPlugin.log("Internal error occurred retrieving targets", e.getTargetException()); //$NON-NLS-1$
+			    setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_1);
+			    fAllTargets= null;
+			    return null;
+			} catch (InterruptedException e) {
+			    AntUIPlugin.log("Internal error occurred retrieving targets", e); //$NON-NLS-1$
+			    setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_1);
+			    fAllTargets= null;
+			    return null;
+			}
+			
+			if (exceptions[0] != null) {
+				IStatus exceptionStatus= exceptions[0].getStatus();
+				IStatus[] children= exceptionStatus.getChildren();
+				StringBuffer message= new StringBuffer(exceptions[0].getMessage());
+				for (int i = 0; i < children.length; i++) {
+					message.append(' ');
+					IStatus childStatus = children[i];
+					message.append(childStatus.getMessage());
+				}
+				setErrorMessage(message.toString());
+				fAllTargets= null;
+				return fAllTargets;
+			}
+			
+			if (fAllTargets == null) {
+			    //if an error was not thrown during parsing then having no targets is valid (Ant 1.6.*)
+			    return fAllTargets;
+			}
+			
+			AntTargetNode target= fAllTargets[0];
+			AntProjectNode projectNode= target.getProjectNode();
+			setErrorMessageFromNode(projectNode);
+			for (int i=0; i < fAllTargets.length; i++) {
+			    target= fAllTargets[i];
+				if (target.isDefaultTarget()) {
+					fDefaultTarget= target;
+				}
+				setErrorMessageFromNode(target);
+			}
+		}
+		
+		return fAllTargets;
+	}
+	
+	private void setErrorMessageFromNode(AntElementNode node) {
+		if (getErrorMessage() != null) {
+			return;
+		}
+		if (node.isErrorNode() || node.isWarningNode()) {
+			String message= node.getProblemMessage();
+		    if (message != null) {
+		        setErrorMessage(message);
+		    } else {
+		        setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_0);
+		    }
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public void initializeFrom(ILaunchConfiguration configuration) {
+		fInitializing= true;
+		fLaunchConfiguration= configuration;
+		fOrderedTargets = new ArrayList();
+		setErrorMessage(null);
+		setMessage(null);
+		setDirty(true);
+		boolean hideInternal= false;
+		try {
+			hideInternal = fLaunchConfiguration.getAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, false);
+		} catch (CoreException e) {
+			AntUIPlugin.log(e);
+		}
+		fFilterInternalTargets.setSelection(hideInternal);
+		handleFilterTargetsSelected();
+		int sort= SORT_NONE;
+		try {
+			sort = fLaunchConfiguration.getAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, sort);
+		} catch (CoreException e) {
+			AntUIPlugin.log(e);
+		}
+		fSortButton.setSelection(sort != SORT_NONE);
+		setSort(sort);
+		String configTargets= null;
+		String newLocation= null;
+		
+		try {
+			configTargets= configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String)null);
+			newLocation= configuration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String)null);
+		} catch (CoreException ce) {
+			AntUIPlugin.log(AntLaunchConfigurationMessages.AntTargetsTab_Error_reading_configuration_12, ce);
+		}
+		
+		if (newLocation == null) {
+			fAllTargets= null;
+			initializeForNoTargets();
+			return; 
+		}
+		
+		AntTargetNode[] allTargetNodes= getTargets();
+		if (allTargetNodes == null) {
+			initializeForNoTargets();
+			return; 
+		}
+		
+		String[] targetNames= AntUtil.parseRunTargets(configTargets);
+		if (targetNames.length == 0) {
+			fTableViewer.setAllChecked(false);
+			setExecuteInput(allTargetNodes);
+			if (fDefaultTarget != null) {
+				fOrderedTargets.add(fDefaultTarget);
+				fTableViewer.setChecked(fDefaultTarget, true);
+				updateSelectionCount();
+				updateLaunchConfigurationDialog();
+			}
+			fInitializing= false;
+			return;
+		}
+		
+		setExecuteInput(allTargetNodes);
+		fTableViewer.setAllChecked(false);
+		for (int i = 0; i < targetNames.length; i++) {
+			for (int j = 0; j < fAllTargets.length; j++) {
+				if (targetNames[i].equals(fAllTargets[j].getTargetName())) {
+					fOrderedTargets.add(fAllTargets[j]);
+					fTableViewer.setChecked(fAllTargets[j], true);
+				}
+			}
+		}
+		updateSelectionCount();
+		fInitializing= false;
+	}
+	
+	private void initializeForNoTargets() {
+		setExecuteInput(new AntTargetNode[0]);
+		fTableViewer.setInput(new AntTargetNode[0]);
+		fInitializing= false;
+	}
+
+	/**
+	 * Sets the execute table's input to the given input.
+	 */
+	private void setExecuteInput(Object input) {
+		fTableViewer.setInput(input);
+		updateSelectionCount();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+		//	attribute added in 3.0, so null must be used instead of false for backwards compatibility
+		if (fFilterInternalTargets.getSelection()) {
+			configuration.setAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, true);
+		} else {
+			configuration.setAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, (String)null);
+		}
+		//attribute added in 3.0, so null must be used instead of 0 for backwards compatibility
+		if (fSortDirection != SORT_NONE) {
+			configuration.setAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, fSortDirection);
+		} else {
+			configuration.setAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, (String)null);
+		}
+		
+		if (fOrderedTargets.size() == 1) {
+			AntTargetNode item = (AntTargetNode)fOrderedTargets.get(0);
+			if (item.isDefaultTarget()) {
+				configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String)null);
+				return;
+			}
+		} else if (fOrderedTargets.size() == 0) {
+			configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String)null);
+			return;
+		}
+		
+		StringBuffer buff= new StringBuffer();
+		Iterator iter = fOrderedTargets.iterator();
+		String targets = null;
+		while (iter.hasNext()) {
+			AntTargetNode item = (AntTargetNode)iter.next();
+			buff.append(item.getTargetName());
+			buff.append(',');
+		}
+		if (buff.length() > 0) {
+			targets= buff.toString();
+		}  
+
+		configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, targets);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
+	 */
+	public String getName() {
+		return AntLaunchConfigurationMessages.AntTargetsTab_Tar_gets_14;
+	}
+		
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
+	 */
+	public Image getImage() {
+		return AntUIImages.getImage(IAntUIConstants.IMG_TAB_ANT_TARGETS);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public boolean isValid(ILaunchConfiguration launchConfig) {
+		if (fAllTargets == null || isDirty()) {
+			if (getErrorMessage() != null && !isDirty()) {
+				//error in parsing;
+				return false;
+			} 
+			//targets not up to date and no error message...we have not parsed recently
+			initializeFrom(launchConfig);
+			if (getErrorMessage() != null) {
+				//error in parsing;
+				return false;
+			}
+		}
+		
+		setErrorMessage(null);
+		return super.isValid(launchConfig);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#setDirty(boolean)
+	 */
+	protected void setDirty(boolean dirty) {
+		//provide package visibility
+		super.setDirty(dirty);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
+		if (isDirty()) {
+			super.activated(workingCopy);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#deactivated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) {
+		if (fOrderedTargets.size() == 0) {
+			//set the dirty flag so that the state will be reinitialized on activation
+			setDirty(true);
+		}
+	}
+	
+	private String validateLocation() {
+		String expandedLocation= null;
+		String location= null;
+		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
+		try {
+			location= fLaunchConfiguration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String)null);
+			if (location == null) {
+				return null;
+			}
+			
+			expandedLocation= manager.performStringSubstitution(location);
+			if (expandedLocation == null) {
+				return null;
+			}
+			File file = new File(expandedLocation);
+			if (!file.exists()) {
+				setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_15);
+				return null;
+			}
+			if (!file.isFile()) {
+				setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_16);
+				return null;
+			}
+			
+			return expandedLocation;
+			
+		} catch (CoreException e1) {
+			if (location != null) {
+				try {
+					manager.validateStringVariables(location);
+					setMessage(AntLaunchConfigurationMessages.AntTargetsTab_17);
+					return null;
+				} catch (CoreException e2) {//invalid variable
+					setErrorMessage(e2.getStatus().getMessage());
+					return null;
+				}
+			}
+			
+			setErrorMessage(e1.getStatus().getMessage());
+			return null;
+		}
+	}
+	
+	protected boolean isTargetSelected() {
+		return !fOrderedTargets.isEmpty();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java
new file mode 100644
index 0000000..8473b91
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *     Remy Chi Jian Suen <remy.suen@gmail.com> - Bug 214696 Expose WorkingDirectoryBlock as API
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.jdt.internal.debug.ui.launcher.JavaWorkingDirectoryBlock;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.ui.externaltools.internal.launchConfigurations.ExternalToolsUtil;
+
+import com.ibm.icu.text.MessageFormat;
+
+
+public class AntWorkingDirectoryBlock extends JavaWorkingDirectoryBlock {
+	
+	private String fDefaultWorkingDirPath;
+
+	/**
+	 * Returns the default working directory path
+	 * @return the default working directory path
+	 */
+	public String getDefaultWorkingDirPath() {
+		return fDefaultWorkingDirPath;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.debug.ui.launcher.WorkingDirectoryBlock#setDefaultWorkingDir()
+	 */
+	protected void setDefaultWorkingDir() {
+		if (fDefaultWorkingDirPath == null) {
+			super.setDefaultWorkingDir();
+			return;
+		}
+		setDefaultWorkingDirectoryText(fDefaultWorkingDirPath);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public void initializeFrom(ILaunchConfiguration configuration) {
+		setLaunchConfiguration(configuration);
+		try {
+			try {
+				fDefaultWorkingDirPath= ExternalToolsUtil.getLocation(configuration).removeLastSegments(1).toOSString();
+			}
+			catch(CoreException ce){}
+			String wd = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, (String)null);
+			setDefaultWorkingDir();
+			if (wd != null || !isSameAsDefault(wd)) {
+				setOtherWorkingDirectoryText(wd);
+			}
+		} catch (CoreException e) {
+			setErrorMessage(MessageFormat.format(AntLaunchConfigurationMessages.AntWorkingDirectoryBlock_0, new String[] {e.getStatus().getMessage()}));
+			AntUIPlugin.log(e);
+		}
+	}
+	
+	private boolean isSameAsDefault(String workingDir) {
+		return workingDir == null || (workingDir.equals(fDefaultWorkingDirPath) || workingDir.equals(System.getProperty("user.dir"))); //$NON-NLS-1$
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java
new file mode 100644
index 0000000..9b8673d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.internal.launching.launchConfigurations.AntHomeClasspathEntry;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.preferences.AntPreferencesMessages;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jdt.internal.debug.ui.actions.RuntimeClasspathAction;
+import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathEntry;
+import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry2;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.DirectoryDialog;
+
+/**
+ * Edits the Ant Home classpath entry.
+ * 
+ * @since 3.0
+ */
+public class EditAntHomeEntryAction extends RuntimeClasspathAction {
+	
+	private AntClasspathTab fTab;
+	/**
+	 * Constructs an action to edit the Ant Home setting for a launch config.
+	 * 
+	 * @param viewer classpath viewer
+	 */
+	public EditAntHomeEntryAction(IClasspathViewer viewer, AntClasspathTab tab) {
+		super(AntLaunchConfigurationMessages.EditAntHomeEntryAction_1, viewer);
+		fTab = tab;
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		IDialogSettings dialogSettings = AntUIPlugin.getDefault().getDialogSettings();
+		String lastUsedPath= dialogSettings.get(IAntUIConstants.DIALOGSTORE_LASTANTHOME);
+		if (lastUsedPath == null) {
+			lastUsedPath= ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString();
+		}
+		DirectoryDialog dialog = new DirectoryDialog(getShell());
+		dialog.setMessage(AntPreferencesMessages.AntClasspathBlock_3);
+		dialog.setFilterPath(lastUsedPath);
+		String path = dialog.open();
+		if (path == null) {
+			return;
+		}
+		dialogSettings.put(IAntUIConstants.DIALOGSTORE_LASTANTHOME, path);
+		AntCorePreferences preferences = AntCorePlugin.getPlugin().getPreferences();
+		String defaultHome = preferences.getAntHome();
+		if (path.equalsIgnoreCase(defaultHome)) {
+			path = null;
+		}
+		fTab.setDirty(true);
+		// update existing entry or add a new one
+		IRuntimeClasspathEntry[] entries = getViewer().getEntries();
+		for (int i = 0; i < entries.length; i++) {
+			IRuntimeClasspathEntry entry = entries[i];
+			if (entry.getType() == IRuntimeClasspathEntry.OTHER) {
+				IRuntimeClasspathEntry2 entry2 = (IRuntimeClasspathEntry2)((ClasspathEntry)entry).getDelegate();
+				if (entry2.getTypeId().equals(AntHomeClasspathEntry.TYPE_ID)) {
+					((AntHomeClasspathEntry)entry2).setAntHome(path);
+					getViewer().refresh(entry);
+					getViewer().notifyChanged();
+					return;
+				}
+			}
+		}				
+		// no entry found - add a new one
+		getViewer().addEntries(new IRuntimeClasspathEntry[]{new AntHomeClasspathEntry(path)});		
+	}
+	
+	/**
+	 * @see SelectionListenerAction#updateSelection(IStructuredSelection)
+	 */
+	protected boolean updateSelection(IStructuredSelection selection) {
+		return true;
+	}	
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/IAntLaunchConfigurationConstants.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/IAntLaunchConfigurationConstants.java
new file mode 100644
index 0000000..869b9eb
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/IAntLaunchConfigurationConstants.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+import org.eclipse.ant.launching.IAntLaunchConstants;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.ui.externaltools.internal.model.IExternalToolConstants;
+
+/**
+ * Constant definitions for Ant launch configurations.
+ * <p>
+ * Constant definitions only; not to be implemented.
+ * </p>
+ * @since 3.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @deprecated This interface has been replaced with {@link IAntLaunchConstants}
+ */
+public interface IAntLaunchConfigurationConstants {
+
+	/**
+	* String attribute indicating the custom runtime classpath to use for an Ant
+	* build. Default value is <code>null</code> which indicates that the global
+	* classpath is to be used. Format is a comma separated listing of URLs.
+	* @deprecated no longer supported: use {@link IJavaLaunchConfigurationConstants#ATTR_CLASSPATH_PROVIDER}
+	* @see IJavaLaunchConfigurationConstants#ATTR_DEFAULT_CLASSPATH
+	*/
+	public static final String ATTR_ANT_CUSTOM_CLASSPATH = IExternalToolConstants.PLUGIN_ID + ".ATTR_ANT_CUSTOM_CLASSPATH"; //$NON-NLS-1$
+	/**
+	 * String attribute indicating the custom Ant home to use for an Ant build.
+	 * Default value is <code>null</code> which indicates that no Ant home is to
+	 * be set 
+	 * @deprecated no longer supported: use {@link IJavaLaunchConfigurationConstants#ATTR_CLASSPATH_PROVIDER}
+	 * @see IJavaLaunchConfigurationConstants#ATTR_DEFAULT_CLASSPATH
+	 */
+	public static final String ATTR_ANT_HOME = IExternalToolConstants.PLUGIN_ID + ".ATTR_ANT_HOME"; //$NON-NLS-1$
+	
+	
+	/**
+	 * String attribute indicating the Ant targets to execute. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants}
+	 */
+	public static final String ATTR_ANT_TARGETS = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_ANT_TARGETS;
+	/**
+	 * String attribute indicating the Ant targets to execute after a clean (full build) for an Ant builder. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * @since 3.1
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants}
+	 */
+	public static final String ATTR_ANT_AFTER_CLEAN_TARGETS = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_ANT_AFTER_CLEAN_TARGETS;
+	/**
+	 * String attribute indicating the Ant targets to execute during a manual build for an Ant builder. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * @since 3.1
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants} 
+	 */
+	public static final String ATTR_ANT_MANUAL_TARGETS = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_ANT_MANUAL_TARGETS;
+	/**
+	 * String attribute indicating the Ant targets to execute during an auto build for an Ant builder. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * @since 3.1
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants} 
+	 */
+	public static final String ATTR_ANT_AUTO_TARGETS = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_ANT_AUTO_TARGETS;
+	/**
+	 * String attribute indicating the Ant targets to execute during a clean for an Ant builder. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * @since 3.1
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants} 
+	 */
+	public static final String ATTR_ANT_CLEAN_TARGETS = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_ANT_CLEAN_TARGETS;
+	/**
+	 * Boolean attribute indicating whether or not target specification for an Ant builder has been updated for
+	 * 3.1 
+	 * 
+	 * @since 3.1
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants}
+	 */
+	public static final String ATTR_TARGETS_UPDATED = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_TARGETS_UPDATED;
+	/**
+	 * Map attribute indicating the Ant properties to be defined during the
+	 * build. Default value is <code>null</code> which indicates no additional
+	 * properties will be defined.
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants}
+	 */
+	public static final String ATTR_ANT_PROPERTIES = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTIES;				
+	/**
+	 * String attribute indicating the Ant targets to execute. Default value is
+	 * <code>null</code> which indicates that no additional property files
+	 * will be defined. Format is a comma separated listing of property files.
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants} 
+	 */
+	public static final String ATTR_ANT_PROPERTY_FILES = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTY_FILES;
+	/**
+	 * Boolean attribute indicating whether or not internal targets (targets with no
+	 * description) should be hidden from the user in the launch configuration dialog.
+	 * Default value is <code>false</code> which indicates that all targets will be
+	 * displayed.
+	 * 
+	 * @since 3.0
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants}
+	 */
+	public static final String ATTR_HIDE_INTERNAL_TARGETS = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_HIDE_INTERNAL_TARGETS;
+	/**
+	 * Integer attribute indicating which column targets should be sorted on. A
+	 * value of 0 indicates target name, 1 indicates target description, and -1
+	 * indicates no sort. Default value is -1.
+	 * 
+	 * @since 3.0
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants}
+	 */
+	public static final String ATTR_SORT_TARGETS = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ATTR_SORT_TARGETS;
+	/**
+	 * Ant launch configuration type identifier.
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants} 
+	 */
+	public static final String ID_ANT_LAUNCH_CONFIGURATION_TYPE = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE;
+	/**
+	 * Ant builder launch configuration type identifier. Ant project builders
+	 * are of this type.
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants} 
+	 */
+	public static final String ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE;
+	/**
+	 * Identifier for Ant processes (value <code>org.eclipse.ant.ui.antProcess</code>). This identifier is
+	 * set as the value for the <code>IProcess.ATTR_PROCESS_TYPE</code>
+	 * attribute in processes created by the Ant launch delegate.
+	 * 
+	 * @deprecated This constant has been migrated to {@link org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants} 
+	 */
+	public static final String ID_ANT_PROCESS_TYPE = org.eclipse.ant.ui.launching.IAntLaunchConfigurationConstants.ID_ANT_PROCESS_TYPE;
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/RunAntStatusHandler.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/RunAntStatusHandler.java
new file mode 100644
index 0000000..b52ddfa
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/RunAntStatusHandler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.debug.core.IStatusHandler;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+
+/**
+ * Status handler called when the launch dialog is opened via the "Run Ant..."
+ * action. This allows us to set the initial tab.
+ */
+public class RunAntStatusHandler implements IStatusHandler {
+
+	/**
+	 * @see org.eclipse.debug.core.IStatusHandler#handleStatus(org.eclipse.core.runtime.IStatus, java.lang.Object)
+	 */
+	public Object handleStatus(IStatus status, Object source) {
+		ILaunchConfigurationDialog dialog = (ILaunchConfigurationDialog)source;
+		dialog.setActiveTab(3);
+		return null;
+	}
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/TargetOrderDialog.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/TargetOrderDialog.java
new file mode 100644
index 0000000..f0a7d81
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/TargetOrderDialog.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.ant.internal.ui.model.AntModelContentProvider;
+import org.eclipse.ant.internal.ui.model.AntModelLabelProvider;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Dialog to specify target execution order
+ */
+public class TargetOrderDialog extends Dialog implements ISelectionChangedListener {
+	
+	private Button fUp;
+	private Button fDown;
+	private TableViewer fViewer;
+	private Object[] fTargets;
+
+	/**
+	 * Constructs the dialog.
+	 * 
+	 * @param parentShell
+	 */
+	public TargetOrderDialog(Shell parentShell, Object[] targets) {
+		super(parentShell);
+		fTargets = targets;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createDialogArea(Composite parent) {
+		getShell().setText(AntLaunchConfigurationMessages.TargetOrderDialog_Order_Targets_1);
+		
+		Composite comp = (Composite)super.createDialogArea(parent);
+		((GridLayout)comp.getLayout()).numColumns= 2;
+		Label label = new Label(comp, SWT.NONE);
+		label.setText(AntLaunchConfigurationMessages.TargetOrderDialog__Specify_target_execution_order__2);
+		label.setFont(comp.getFont());
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 2;
+		label.setLayoutData(gd);		
+		
+		createTargetList(comp);
+		
+		createButtons(comp);
+		
+		updateButtons();
+		
+		return comp;
+	}
+
+	/**
+	 * Create button area & buttons
+	 * 
+	 * @param comp
+	 */
+	private void createButtons(Composite parent) {
+		Composite comp = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight= 0;
+		layout.marginWidth= 0;
+		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.verticalAlignment = GridData.BEGINNING;
+		comp.setLayout(layout);
+		comp.setLayoutData(gd);
+		
+		fUp = new Button(comp, SWT.PUSH);
+		fUp.setFont(parent.getFont());
+		fUp.setText(AntLaunchConfigurationMessages.TargetOrderDialog__Up_3);
+		setButtonLayoutData(fUp);
+		fUp.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleUpPressed();
+			}
+		});
+		
+		fDown = new Button(comp, SWT.PUSH);
+		fDown.setFont(parent.getFont());
+		fDown.setText(AntLaunchConfigurationMessages.TargetOrderDialog__Down_4);
+		setButtonLayoutData(fDown);
+		fDown.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleDownPressed();
+			}
+		});
+	}
+
+	private void handleDownPressed() {
+		List targets = getOrderedSelection();
+		if (targets.isEmpty()) {
+			return;
+		}
+		List list= new ArrayList(Arrays.asList(fTargets));
+		int bottom = list.size() - 1;
+		int index = 0;
+		for (int i = targets.size() - 1; i >= 0; i--) {
+			Object target = targets.get(i);
+			index = list.indexOf(target);
+			if (index < bottom) {
+				bottom = index + 1;
+				Object temp = list.get(bottom);
+				list.set(bottom, target);
+				list.set(index, temp);
+			}
+			bottom = index;
+		} 
+		setEntries(list);
+	}
+
+	private void handleUpPressed() {
+		List targets = getOrderedSelection();
+		if (targets.isEmpty()) {
+			return;
+		}
+		int top = 0;
+		int index = 0;
+		List list= new ArrayList(Arrays.asList(fTargets));
+		Iterator entries = targets.iterator();
+		while (entries.hasNext()) {
+			Object target = entries.next();
+			index = list.indexOf(target);
+			if (index > top) {
+				top = index - 1;
+				Object temp = list.get(top);
+				list.set(top, target);
+				list.set(index, temp);
+			}
+			top = index;
+		} 
+		setEntries(list);
+	}
+	
+	/**
+	 * Updates the entries to the entries in the given list
+	 */
+	private void setEntries(List list) {
+		fTargets= list.toArray();
+		fViewer.setInput(fTargets);
+		// update all selection listeners
+		fViewer.setSelection(fViewer.getSelection());
+	}
+	
+	/**
+	 * Returns the selected items in the list, in the order they are
+	 * displayed (not in the order they were selected).
+	 * 
+	 * @return targets for an action
+	 */
+	private List getOrderedSelection() {
+		List targets = new ArrayList();
+		List selection = ((IStructuredSelection)fViewer.getSelection()).toList();
+		Object[] entries = fTargets;
+		for (int i = 0; i < entries.length; i++) {
+			Object target = entries[i];
+			if (selection.contains(target)) {
+				targets.add(target);
+			}
+		}
+		return targets;		
+	}
+
+	/**
+	 * Creates a list viewer for the targets
+	 * 
+	 * @param comp
+	 */
+	private void createTargetList(Composite comp) {
+		fViewer = new TableViewer(comp, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
+		fViewer.setLabelProvider(new AntModelLabelProvider());
+	
+		fViewer.setContentProvider(new AntModelContentProvider());
+		fViewer.setInput(fTargets);
+		fViewer.addSelectionChangedListener(this);
+		Table table = fViewer.getTable();
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.heightHint = 200;
+		gd.widthHint = 250;		
+		table.setLayoutData(gd);
+		table.setFont(comp.getFont());
+	}
+	
+	/**
+	 * Returns the ordered targets
+	 */
+	public Object[] getTargets() {
+		return fTargets;
+	}
+	
+	/**
+	 * Update button enablement
+	 * 
+	 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+	 */
+	public void selectionChanged(SelectionChangedEvent event) {
+		updateButtons();
+	}
+	
+	private void updateButtons() {
+		int[] selections = fViewer.getTable().getSelectionIndices();
+		int last = fTargets.length - 1;
+		boolean up = true && selections.length > 0;
+		boolean down = true && selections.length > 0;
+		for (int i = 0; i < selections.length; i++) {
+			if (selections[i] == 0) {
+				up = false;
+			}
+			if (selections[i] == last) {
+				down = false;
+			}
+		}
+		fUp.setEnabled(up);
+		fDown.setEnabled(down);		
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+	 */
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IAntUIHelpContextIds.TARGET_ORDER_DIALOG);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/VariableInputDialog.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/VariableInputDialog.java
new file mode 100644
index 0000000..11bf4de
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/VariableInputDialog.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.launchConfigurations;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.debug.ui.StringVariableSelectionDialog;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+
+public class VariableInputDialog extends Dialog {
+	
+	private static String DIALOG_SETTINGS_SECTION = "RuntimeClasspathAction.VariableInputDialog"; //$NON-NLS-1$
+	private Text fText;
+	private String fVariableString;
+	
+	public VariableInputDialog(Shell shell) {
+		super(shell);
+		setShellStyle(SWT.RESIZE | getShellStyle());
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createDialogArea(Composite parent) {
+        Composite inner= (Composite) super.createDialogArea(parent);
+		((GridLayout)inner.getLayout()).numColumns= 2;
+		
+		Label label = new Label(inner, SWT.NONE);
+		label.setText(AntLaunchConfigurationMessages.AddVariableStringAction_2);
+		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+        gd.horizontalSpan= 2;
+		label.setLayoutData(gd);
+		
+		fText = new Text(inner, SWT.SINGLE | SWT.BORDER);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.grabExcessHorizontalSpace = true;
+		gd.widthHint = 200;
+		fText.setLayoutData(gd);
+		
+		Button button = new Button(inner, SWT.PUSH); 
+		button.setText(AntLaunchConfigurationMessages.AddVariableStringAction_3);		
+		button.addSelectionListener(new SelectionAdapter() {
+			public  void widgetSelected(SelectionEvent se) {
+				getVariable();
+			}
+		});
+		
+		applyDialogFont(parent);
+		return inner;
+	}
+	
+	protected void createButtonsForButtonBar(Composite parent) {
+		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+	}
+    
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+	 */
+	protected void configureShell(Shell newShell) {
+		super.configureShell(newShell);
+		newShell.setText(AntLaunchConfigurationMessages.AddVariableStringAction_4);
+	}
+	
+	private void getVariable() {
+		StringVariableSelectionDialog variableDialog = new StringVariableSelectionDialog(getShell());
+		int returnCode = variableDialog.open();
+		if (returnCode == IDialogConstants.OK_ID) {
+			String variable = variableDialog.getVariableExpression();
+			if (variable != null) {
+				fText.insert(variable);
+			}
+		}			
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+	 */
+	protected void okPressed() {
+		String variableString = fText.getText();
+		if (variableString != null && variableString.trim().length() > 0) {
+			fVariableString= variableString;
+		} else {
+			fVariableString= null;
+		}
+		super.okPressed();
+	}
+	
+	public String getVariableString() {
+		return fVariableString;
+	}
+
+	 /* (non-Javadoc)
+     * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
+     */
+    protected IDialogSettings getDialogBoundsSettings() {
+    	 IDialogSettings settings = AntUIPlugin.getDefault().getDialogSettings();
+         IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION);
+         if (section == null) {
+             section = settings.addNewSection(DIALOG_SETTINGS_SECTION);
+         } 
+         return section;
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntCommentNode.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntCommentNode.java
new file mode 100644
index 0000000..fbc7a08
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntCommentNode.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.model;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+public class AntCommentNode extends AntElementNode {
+	public AntCommentNode() {
+		super("AntComment"); //$NON-NLS-1$
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.model.AntElementNode#isStructuralNode()
+	 */
+	public boolean isStructuralNode() {
+		return false;
+	}
+	
+	public boolean collapseProjection() {
+		IPreferenceStore store= AntUIPlugin.getDefault().getPreferenceStore();		
+		if (store.getBoolean(AntEditorPreferenceConstants.EDITOR_FOLDING_COMMENTS)) {
+			return true;
+		}
+		return false;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntDTDNode.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntDTDNode.java
new file mode 100644
index 0000000..4ff29ef
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntDTDNode.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.model;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+public class AntDTDNode extends AntElementNode {
+	public AntDTDNode(String name) {
+		super(name);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.model.AntElementNode#isStructuralNode()
+	 */
+	public boolean isStructuralNode() {
+		return false;
+	}
+	
+	public boolean collapseProjection() {
+		IPreferenceStore store= AntUIPlugin.getDefault().getPreferenceStore();		
+		if (store.getBoolean(AntEditorPreferenceConstants.EDITOR_FOLDING_DTD)) {
+			return true;
+		}
+		return false;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntElementAdapterFactory.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntElementAdapterFactory.java
new file mode 100644
index 0000000..80117f7
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntElementAdapterFactory.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.model;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdapterFactory;
+
+/**
+ * Adapter factory for Ant elements in editor outline
+ */
+public class AntElementAdapterFactory implements IAdapterFactory {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+	 */
+	public Object getAdapter(Object adaptableObject, Class adapterType) {
+		if (adaptableObject instanceof AntElementNode) {
+			AntElementNode node = (AntElementNode) adaptableObject;
+			if (IResource.class.equals(adapterType)) {
+				return node.getIFile();
+			}
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+	 */
+	public Class[] getAdapterList() {
+		return new Class[] {IResource.class};
+	}
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelChangeEvent.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelChangeEvent.java
new file mode 100644
index 0000000..777ea26
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelChangeEvent.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.model;
+
+
+public class AntModelChangeEvent {
+	
+	private IAntModel fModel;
+	private boolean fPreferenceChange= false;
+	
+	public AntModelChangeEvent(IAntModel model) {
+		fModel= model;
+	}
+	
+	public AntModelChangeEvent(IAntModel model, boolean preferenceChange) {
+		fModel= model;
+		fPreferenceChange= preferenceChange;
+	}
+	
+	public IAntModel getModel() {
+		return fModel;
+	}
+	
+	/**
+	 * Returns whether the Ant model has changed as a result of a preference change.
+	 * @return whether the model has changed from a preference change.
+	 */
+	public boolean isPreferenceChange() {
+		return fPreferenceChange;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelContentProvider.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelContentProvider.java
new file mode 100644
index 0000000..602cd61
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelContentProvider.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.model;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+
+public class AntModelContentProvider implements ITreeContentProvider {
+
+	protected static final Object[] EMPTY_ARRAY= new Object[0];
+	
+	/**
+	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+	 */
+	public void dispose() {
+	}
+    
+	/**
+	 * do nothing
+	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object)
+	 */
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(Object)
+	 */
+	public Object[] getChildren(Object parentNode) {
+		if (parentNode instanceof AntElementNode) {
+			AntElementNode parentElement = (AntElementNode)parentNode;
+			if (parentElement.hasChildren()) {
+				List children= parentElement.getChildNodes();
+				return children.toArray();
+			} 
+		} else if (parentNode instanceof IAntModel) {
+			return new Object[] {((IAntModel)parentNode).getProjectNode()};
+		}
+		return EMPTY_ARRAY;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(Object)
+	 */
+	public Object getParent(Object aNode) {
+		AntElementNode tempElement = (AntElementNode)aNode;
+		return tempElement.getParentNode();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(Object)
+	 */
+	public boolean hasChildren(Object aNode) {
+		return ((AntElementNode)aNode).hasChildren();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
+	 */
+	public Object[] getElements(Object inputElement) {
+		if (inputElement instanceof IAntModel ) {
+		    AntProjectNode projectNode= ((IAntModel) inputElement).getProjectNode();
+		    if (projectNode == null) {
+				return new AntElementNode[0];
+			} 
+			
+			return new Object[] {projectNode}; 
+		}
+		
+		if (inputElement instanceof Object[]) {
+			return (Object[])inputElement;
+		}
+		return EMPTY_ARRAY;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelCore.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelCore.java
new file mode 100644
index 0000000..4bb7e82
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelCore.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.internal.launching.debug.model.AntLineBreakpoint;
+import org.eclipse.ant.internal.launching.debug.model.DebugModelMessages;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointsListener;
+import org.eclipse.debug.core.model.IBreakpoint;
+
+import com.ibm.icu.text.MessageFormat;
+
+public class AntModelCore implements IBreakpointsListener {
+	
+	private static AntModelCore inst;
+	
+	public static AntModelCore getDefault() {
+		if (inst == null) {
+			inst= new AntModelCore();
+		}
+			
+		return inst;
+	}
+	
+	private List fModelChangeListeners= new ArrayList();
+	
+	private AntModelCore() { }
+
+	public void addAntModelListener(IAntModelListener listener) {
+		synchronized (fModelChangeListeners) {
+			fModelChangeListeners.add(listener);
+		}
+	}
+	
+	public void removeAntModelListener(IAntModelListener listener) {
+		synchronized (fModelChangeListeners) {
+			fModelChangeListeners.remove(listener);
+		}
+	}
+	
+	public void notifyAntModelListeners(AntModelChangeEvent event) {
+		Iterator i;
+		synchronized (fModelChangeListeners) {
+			i= new ArrayList(fModelChangeListeners).iterator();
+		}
+		while (i.hasNext()) {
+			((IAntModelListener)i.next()).antModelChanged(event);
+		}
+	}
+    
+    /**
+     * Updates message attributes on any Ant line breakpoints if there are active Ant editors
+     * with Ant models
+     * 
+     * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[])
+     */
+    private void updateBreakpointMessages(final IBreakpoint[] breakpoints) {
+        IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+            public void run(IProgressMonitor monitor) throws CoreException {
+                for (int i = 0; i < breakpoints.length; i++) {
+                    IBreakpoint breakpoint= breakpoints[i];
+                    if (breakpoint instanceof AntLineBreakpoint) {
+                        IMarker marker = breakpoint.getMarker();
+                        if (marker.exists()) {
+                        	int lineNumber= marker.getAttribute(IMarker.LINE_NUMBER, 0);
+                        	marker.setAttribute(IMarker.MESSAGE, MessageFormat.format(DebugModelMessages.AntLineBreakpoint_0, new String[] {Integer.toString(lineNumber)}));
+                        }
+                    }
+                }
+            }
+        };
+        try {
+            ResourcesPlugin.getWorkspace().run(runnable, null, 0, null);
+        } catch (CoreException e) {
+            AntUIPlugin.log(e);
+        }
+    }
+
+    public void breakpointsAdded(IBreakpoint[] breakpoints) {
+    }
+
+    public void breakpointsRemoved(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
+    }
+
+    public void breakpointsChanged(IBreakpoint[] breakpoints, IMarkerDelta[] deltas) {
+        updateBreakpointMessages(breakpoints);        
+    }
+
+    public void stopBreakpointListening() {
+        DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener(this);
+    }
+    
+    public void startBreakpointListening() {
+        DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this);
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelLabelProvider.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelLabelProvider.java
new file mode 100644
index 0000000..5f41ad5
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelLabelProvider.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.model;
+
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+
+public class AntModelLabelProvider extends LabelProvider implements IColorProvider {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ILabelProvider#getImage(Object)
+	 */
+	public Image getImage(Object anElement) {
+		AntElementNode node = (AntElementNode)anElement;
+		return node.getImage();
+	}
+    
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ILabelProvider#getText(Object)
+	 */
+	public String getText(Object node) {
+		AntElementNode element= (AntElementNode) node;
+		return element.getLabel();
+	}
+
+	public Color getForeground(Object node) {
+		if (node instanceof AntTargetNode && ((AntTargetNode)node).isDefaultTarget() ) {
+			return Display.getDefault().getSystemColor(SWT.COLOR_BLUE);
+		}
+		
+		return null;
+	}
+
+	public Color getBackground(Object element) {
+		return null;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelMessages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelMessages.java
new file mode 100644
index 0000000..e0db5bc
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelMessages.java
@@ -0,0 +1,37 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.model;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntModelMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.model.AntModelMessages";//$NON-NLS-1$
+
+	public static String AntTargetNode_2;
+	public static String AntImportNode_0;
+	public static String AntTaskNode_0;
+	public static String AntElementNode_9;
+
+	public static String AntModel_1;
+	public static String AntModel_43;
+	public static String AntModel_44;
+	public static String AntProjectNodeProxy_0;
+	public static String AntProjectNodeProxy_1;
+	public static String AntDefiningTaskNode_0;
+	public static String AntDefiningTaskNode_1;
+	public static String AntProjectNode_0;
+	public static String AntPropertyNode_0;
+	public static String AntPropertyNode_1;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntModelMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelMessages.properties b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelMessages.properties
new file mode 100644
index 0000000..88330c6
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelMessages.properties
@@ -0,0 +1,26 @@
+###############################################################################
+# 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
+###############################################################################
+
+AntTargetNode_2=\ [default]
+AntImportNode_0=Security exception during import
+AntTaskNode_0=Security problem configuring task
+AntElementNode_9=\ [from {0}]
+
+AntModel_1=\ line:
+AntModel_43=Default target {0} does not exist in this project
+AntModel_44=Target {0} does not exist in this project
+AntProjectNodeProxy_0=Buildfile not found
+AntProjectNodeProxy_1=No targets could be determined
+AntDefiningTaskNode_0=Task could not be defined within the Ant Editor context
+AntDefiningTaskNode_1=Security exception attempting to define type
+AntProjectNode_0=<Unable to parse as an Ant buildfile>
+AntPropertyNode_0=Property could not be set within the Ant Editor context
+AntPropertyNode_1=Security exception attempting to set property
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelProblem.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelProblem.java
new file mode 100644
index 0000000..b5f31fd
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntModelProblem.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.model;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.Region;
+
+public class AntModelProblem extends Region implements IProblem {
+	
+	public static final int NO_PROBLEM= -1;
+	public static final int SEVERITY_WARNING= 0;
+	public static final int SEVERITY_ERROR= 1;
+	public static final int SEVERITY_FATAL_ERROR= 2;
+	
+	private String fMessage;
+	private String fEscapedMessage;
+	private int fSeverity;
+	private int fAdjustedLength= -1;
+	private int fLineNumber= -1;
+	
+	public AntModelProblem(String message, int severity, int offset, int length, int lineNumber) {
+		super(offset, length);
+		fMessage= message;
+		fEscapedMessage= getEscaped(message);
+		fSeverity= severity;
+		fLineNumber= lineNumber;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblem#getMessage()
+	 */
+	public String getMessage() {
+		return fEscapedMessage;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblem#isError()
+	 */
+	public boolean isError() {
+		return fSeverity == SEVERITY_ERROR || fSeverity == SEVERITY_FATAL_ERROR;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblem#isWarning()
+	 */
+	public boolean isWarning() {
+		return fSeverity == SEVERITY_WARNING;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IRegion#getLength()
+	 */
+	public int getLength() {
+		if (fAdjustedLength != -1) {
+			return fAdjustedLength;
+		}
+		return super.getLength();
+	}
+	
+	/**
+	 * Sets the length for this problem.
+	 */
+	public void setLength(int adjustedLength) {
+		fAdjustedLength= adjustedLength;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblem#getLineNumber()
+	 */
+	public int getLineNumber() {
+		return fLineNumber;
+	}
+	
+	private void appendEscapedChar(StringBuffer buffer, char c) {
+		String replacement= getReplacement(c);
+		if (replacement != null) {
+			buffer.append(replacement);
+		} else {
+			buffer.append(c);
+		}
+	}
+	
+	private String getEscaped(String s) {
+		StringBuffer result= new StringBuffer(s.length() + 10);
+		for (int i= 0; i < s.length(); ++i) {
+			appendEscapedChar(result, s.charAt(i));
+		}
+		return result.toString();
+	}
+	
+	private String getReplacement(char c) {
+		// Encode special characters into the equivalent character references.
+		// Ensures that error messages that include special characters do not get
+		//incorrectly represented as HTML in the text hover (bug 56258)
+		switch (c) {
+			case '<' :
+				return "&lt;"; //$NON-NLS-1$
+			case '>' :
+				return "&gt;"; //$NON-NLS-1$
+			case '"' :
+				return "&quot;"; //$NON-NLS-1$
+			case '&' :
+				return "&amp;"; //$NON-NLS-1$
+		}
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.editor.outline.IProblem#getUnmodifiedMessage()
+	 */
+	public String getUnmodifiedMessage() {
+		return fMessage;
+	}
+	
+	public static int getSeverity(String preferenceKey) {
+		IPreferenceStore store= AntUIPlugin.getDefault().getPreferenceStore();
+		String severityLevel= store.getString(preferenceKey);
+		if (severityLevel.length() == 0 || severityLevel.equals(AntEditorPreferenceConstants.BUILDFILE_ERROR)) {
+			return SEVERITY_ERROR;
+		} else if (severityLevel.equals(AntEditorPreferenceConstants.BUILDFILE_WARNING)) {
+			return SEVERITY_WARNING;
+		} else {
+			return NO_PROBLEM;
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object o) {
+		boolean equal= super.equals(o);
+		if (equal) {
+			return ((AntModelProblem)o).getUnmodifiedMessage().equals(getUnmodifiedMessage());
+		}
+		return false;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntProjectNodeProxy.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntProjectNodeProxy.java
new file mode 100644
index 0000000..9475033
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntProjectNodeProxy.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.model;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.ant.internal.ui.AntUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+
+
+public class AntProjectNodeProxy extends AntProjectNode {
+	
+	private String fBuildFileName;
+	private String fDefaultTargetName;
+	private boolean fParsed= false;
+
+	/**
+	 * Creates a new project node with the given name and the given build file
+	 * name.
+	 * 
+	 * @param name the project's name or <code>null</code> if the project's
+	 * name is not known. If this value is <code>null</code>, the file will be
+	 * parsed the first time a value is requested that requires it.
+	 * @param buildFileName
+	 */
+	public AntProjectNodeProxy(String name, String buildFileName) {
+		super(null, null);
+		fName= name;
+		fBuildFileName= buildFileName;
+	}
+	
+	/**
+	 * Creates a new project node on the given build file.
+	 */
+	public AntProjectNodeProxy(String buildFileName) {
+		this(null, buildFileName);
+	}
+	
+	public void parseBuildFile(boolean force) {
+		if (fParsed && !force) {
+			return;
+		}
+		fChildNodes= null;
+		fParsed= true;
+		AntTargetNode[] nodes = null;
+		IPath buildFilePath= AntUtil.getFile(getBuildFileName()).getLocation();
+		if (buildFilePath == null) {
+			setProblemSeverity(AntModelProblem.SEVERITY_ERROR);
+			setProblemMessage(AntModelMessages.AntProjectNodeProxy_0);
+			return;
+		}
+		nodes = AntUtil.getTargets(buildFilePath.toString());
+		
+		if (nodes == null || nodes.length < 1) {
+			setProblemSeverity(AntModelProblem.SEVERITY_ERROR);
+			setProblemMessage(AntModelMessages.AntProjectNodeProxy_1);
+			return;
+		}
+		
+		AntProjectNode projectNode = nodes[0].getProjectNode();
+        if (nodes[0].getTargetName().length() != 0) {
+            //not just the implicit target
+            for (int i = 0; i < nodes.length; i++) {
+                addChildNode(nodes[i]);
+            }
+        }
+		
+		fModel= projectNode.getAntModel();
+		fProject= (AntModelProject)projectNode.getProject();
+		fLabel= null;
+		fName= null;
+	}
+	
+	public void parseBuildFile() {
+		parseBuildFile(false);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.model.AntProjectNode#getDescription()
+	 */
+	public String getDescription() {
+		if (fProject != null) {
+			return super.getDescription();
+		}
+		return null;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#getLabel()
+	 */
+	public String getLabel() {
+	    if (fName != null) {
+	        return fName;
+	    }
+		if (fProject == null) {
+			parseBuildFile();
+		}
+		StringBuffer name= new StringBuffer(super.getLabel());
+		AntProjectNode realNode= getRealNode();
+		if (realNode != null && realNode.getProblemMessage() != null) {
+			name.append(" <"); //$NON-NLS-1$
+			name.append(getRealNode().getProblemMessage());
+			name.append('>');
+		}
+		fName= name.toString();
+		return fName;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#getChildNodes()
+	 */
+	public List getChildNodes() {
+		if (fProject == null) {
+			parseBuildFile();
+		}
+		List children= super.getChildNodes();
+		if (children == null) {
+		    return Collections.EMPTY_LIST;
+		}
+		return children;
+	}
+	
+	public String getBuildFileName() {
+		return fBuildFileName;
+	}
+
+	public void setDefaultTargetName(String defaultTarget) {
+		fDefaultTargetName= defaultTarget;
+	}
+	
+	public String getDefaultTargetName() {
+		if (fProject == null) {
+			return fDefaultTargetName;
+		}
+		return super.getDefaultTargetName();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#hasChildren()
+	 */
+	public boolean hasChildren() {
+		return true;
+	}
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.ant.internal.ui.model.AntElementNode#dispose()
+     */
+    public void dispose() {
+        if (fProject != null) {
+            super.dispose();
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.ant.internal.ui.model.AntElementNode#isErrorNode()
+     */
+    public boolean isErrorNode() {
+        if (fProject == null) {
+            return super.isErrorNode();
+        } 
+        return getRealNode().isErrorNode();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.ant.internal.ui.model.AntElementNode#getProblemMessage()
+     */
+    public String getProblemMessage() {
+		if (isErrorNode()) {
+			return getBuildFileName();
+		}
+    	return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.ant.internal.ui.model.AntElementNode#isWarningNode()
+     */
+    public boolean isWarningNode() {
+        if (fProject == null) {
+            return super.isWarningNode();
+        } 
+        return getRealNode().isWarningNode();
+    }
+    
+	private AntProjectNode getRealNode() {
+		if (fModel != null) {
+			return fModel.getProjectNode();
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#getAntModel()
+	 */
+	protected IAntModel getAntModel() {
+		if (fProject == null) {
+			parseBuildFile();
+		}
+		return super.getAntModel();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#getLength()
+	 */
+	public int getLength() {
+		if (fProject == null) {
+			parseBuildFile();
+		}
+		AntProjectNode realNode= getRealNode();
+		if (realNode == null) {
+			return -1;
+		}
+		return realNode.getLength();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#getOffset()
+	 */
+	public int getOffset() {
+		if (fProject == null) {
+			parseBuildFile();
+		}
+		AntProjectNode realNode= getRealNode();
+		if (realNode == null) {
+			return -1;
+		}
+		return realNode.getOffset();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#getSelectionLength()
+	 */
+	public int getSelectionLength() {
+		if (fProject == null) {
+			parseBuildFile();
+		}
+		AntProjectNode realNode= getRealNode();
+		if (realNode == null) {
+			return -1;
+		}
+		return realNode.getSelectionLength();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.model.AntElementNode#getBuildFileResource()
+	 */
+	public IFile getBuildFileResource() {
+		if (fProject == null) {
+			if (fBuildFileName != null) {
+				return AntUtil.getFile(fBuildFileName);
+			}
+		}
+		return super.getBuildFileResource();
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+        return getLabel();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntTaskNode.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntTaskNode.java
new file mode 100644
index 0000000..56b4df4
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/AntTaskNode.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.Task;
+import org.eclipse.ant.core.AntSecurityException;
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+
+public class AntTaskNode extends AntElementNode {
+
+	private Task fTask= null;
+	protected String fBaseLabel= null;
+	protected String fLabel;
+	private String fId= null;
+	protected boolean fConfigured= false;
+	
+	public AntTaskNode(Task task) {
+		super(task.getTaskName());
+		fTask= task;
+	}
+	
+	public AntTaskNode(Task task, String label) {
+		super(task.getTaskName());
+		fTask= task;
+		fBaseLabel= label;
+	}	
+	
+	public String getLabel() {
+	    if (fLabel == null) {
+			StringBuffer label= new StringBuffer();
+			if (fBaseLabel != null) {
+				label.append(fBaseLabel);
+			} else if (fId != null) {
+				label.append(fId);
+			} else {
+				label.append(fTask.getTaskName());
+			}
+			if (isExternal()) {
+				appendEntityName(label);
+			}
+			fLabel= label.toString();
+	    }
+	    return fLabel;
+	}
+	
+	public void setBaseLabel(String label) {
+		fBaseLabel= label;
+	}
+	
+	public Task getTask() {
+		return fTask;
+	}
+	
+	public void setTask(Task task) {
+		fTask= task;
+	}
+	
+	protected ImageDescriptor getBaseImageDescriptor() {
+		if (fId != null) {
+			return AntUIImages.getImageDescriptor(IAntUIConstants.IMG_ANT_TYPE);
+		}
+		
+		return super.getBaseImageDescriptor();
+	}
+
+	/**
+	 * The reference id for this task
+	 * @param id The reference id for this task
+	 */
+	public void setId(String id) {
+		fId= id;
+	}
+	
+	/**
+	 * Returns the reference id for this task or <code>null</code>
+	 * if it has no reference id.
+	 * @return The reference id for this task
+	 */
+	public String getId() {
+		return fId;
+	}
+	
+	/**
+	 * Configures the associated task if required.
+	 * Allows subclasses to do specific configuration (such as executing the task) by
+	 * calling <code>nodeSpecificConfigure</code>
+	 * 
+	 * @return whether the configuration of this node could have impact on other nodes
+	 */
+	public boolean configure(boolean validateFully) {
+		if (getId() != null) {
+			//ensure that references are set...new for Ant 1.7
+			try {
+				getProjectNode().getProject().getReference(getId());
+			} catch (BuildException e) {
+				handleBuildException(e, AntEditorPreferenceConstants.PROBLEM_TASKS);
+			}
+		} 
+		if (!validateFully || (getParentNode() instanceof AntTaskNode)) {
+			return false;
+		}
+		if (fConfigured) {
+			return false;
+		}
+		int severity= AntModelProblem.getSeverity(AntEditorPreferenceConstants.PROBLEM_TASKS);
+		if (severity != AntModelProblem.NO_PROBLEM) {
+		    //only configure if the user cares about the problems
+			try {
+				getTask().maybeConfigure();
+				fConfigured= true;
+				return true;
+			} catch (BuildException be) {
+				handleBuildException(be, AntEditorPreferenceConstants.PROBLEM_TASKS);
+			} catch (AntSecurityException se) {
+				//either a system exit or setting of system property was attempted
+				handleBuildException(new BuildException(AntModelMessages.AntTaskNode_0), AntEditorPreferenceConstants.PROBLEM_SECURITY);
+			}
+		}
+		return false;
+	}
+
+	protected void handleBuildException(BuildException be, String preferenceKey) {
+		int severity= AntModelProblem.getSeverity(preferenceKey);
+		if (severity != AntModelProblem.NO_PROBLEM) {
+			getAntModel().handleBuildException(be, this, severity);
+		}
+	}
+	
+	public boolean containsOccurrence(String identifier) {
+		RuntimeConfigurable wrapper= getTask().getRuntimeConfigurableWrapper();
+		Map attributeMap= wrapper.getAttributeMap();
+		Set keys= attributeMap.keySet();
+        boolean lookingForProperty= identifier.startsWith("${") && identifier.endsWith("}"); //$NON-NLS-1$ //$NON-NLS-2$
+		for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
+			String key= (String) iter.next();
+			String value= (String) attributeMap.get(key);
+            if (lookingForProperty && (key.equals("if") || key.equals("unless"))) { //$NON-NLS-1$ //$NON-NLS-2$
+                if (value.indexOf(identifier.substring(2, identifier.length() - 1)) != -1) {
+                    return true;
+                }
+            } else if (value.indexOf(identifier) != -1) {
+				return true;
+			}
+		}
+		StringBuffer text= wrapper.getText();
+		if (text.length() > 0) {
+			if (lookingForProperty && text.indexOf(identifier) != -1) {
+				return true; //property ref in text
+			}
+		}
+	
+		return false;
+	}
+
+	public List computeIdentifierOffsets(String identifier) {
+        String textToSearch= getAntModel().getText(getOffset(), getLength());
+        if (textToSearch == null || textToSearch.length() == 0 || identifier.length() ==0) {
+        	return null;
+        }
+        List results= new ArrayList();
+        RuntimeConfigurable wrapper= getTask().getRuntimeConfigurableWrapper();
+        Map attributeMap= wrapper.getAttributeMap();
+        Set keys= attributeMap.keySet();
+		String lineSep= System.getProperty("line.separator"); //$NON-NLS-1$
+        for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
+            String key = (String) iter.next();
+            String value= (String) attributeMap.get(key);
+			int identifierCorrection= 1;
+            if (value.indexOf(identifier) != -1) {
+                int keyOffset= textToSearch.indexOf(key);
+				while (keyOffset > 0 && !Character.isWhitespace(textToSearch.charAt(keyOffset - 1))) {
+					keyOffset= textToSearch.indexOf(key, keyOffset + 1);
+				}
+                int valueOffset= textToSearch.indexOf('"', keyOffset);
+				int valueLine= ((AntModel)getAntModel()).getLine(getOffset() + valueOffset);
+				
+                int withinValueOffset= value.indexOf(identifier);
+                while (withinValueOffset != -1) {
+					int resultLine= ((AntModel)getAntModel()).getLine(getOffset() + valueOffset + withinValueOffset);
+					//the value stored in the attribute map seems to be modified to not contain control characters
+					//new lines, carriage returns and these are replaced with spaces
+					//so if the line separator is greater than 1 in length we need to correct for this
+					int resultOffset= getOffset() + valueOffset + withinValueOffset + identifierCorrection + ((resultLine - valueLine) * (lineSep.length() - 1));
+                    results.add(new Integer(resultOffset));
+                    withinValueOffset= value.indexOf(identifier, withinValueOffset + 1);
+                }
+            }
+        }
+        
+    	String text= wrapper.getText().toString().trim();
+    	if (text.length() > 0) {
+    		int offset= textToSearch.indexOf(text.toString());
+    		offset= textToSearch.indexOf(identifier, offset);
+    		results.add(new Integer(offset + getOffset()));
+    	}
+        return results;
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IAntElement.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IAntElement.java
new file mode 100644
index 0000000..91918d1
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IAntElement.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.model;
+
+/**
+ * Interface to tag all Ant elements for adapter factory - currently empty.
+ */
+public interface IAntElement {
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IAntModelListener.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IAntModelListener.java
new file mode 100644
index 0000000..5332070
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IAntModelListener.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.model;
+
+
+public interface IAntModelListener {
+	
+	public void antModelChanged(AntModelChangeEvent event);
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IProblem.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IProblem.java
new file mode 100644
index 0000000..ee64481
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IProblem.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.model;
+
+import org.eclipse.jface.text.IRegion;
+
+
+public interface IProblem extends IRegion {
+
+	/**
+	 * Answer a localized, human-readable message string which describes the problem.
+	 * The message has been "escaped" to handle special characters.
+	 *
+	 * @return a localized, human-readable message string which describes the problem
+	 */
+	String getMessage();
+	
+	/**
+	 * Answer a localized, human-readable message string which describes the problem.
+	 * The message is in its original form; special characters have not been escaped.
+	 *
+	 * @return localized, human-readable message string which describes the problem
+	 */
+	String getUnmodifiedMessage();
+
+	/**
+	 * Checks the severity to see if the Error bit is set.
+	 *
+	 * @return true if the Error bit is set for the severity, false otherwise
+	 */
+	boolean isError();
+
+	/**
+	 * Checks the severity to see if the Error bit is not set.
+	 *
+	 * @return true if the Error bit is not set for the severity, false otherwise
+	 */
+	boolean isWarning();
+	
+	/**
+	 * Returns the line number of this problem.
+	 *
+	 * @return the line number of this problem
+	 */
+	int getLineNumber();
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IProblemRequestor.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IProblemRequestor.java
new file mode 100644
index 0000000..245de00
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/IProblemRequestor.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.model;
+
+public interface IProblemRequestor {
+
+	/**
+	 * Notification of a Ant buildfile problem.
+	 *
+	 * @param problem IProblem - The discovered Ant buildfile problem.
+	 */
+	void acceptProblem(IProblem problem);
+
+	/**
+	 * Notification sent before starting the problem detection process.
+	 * Typically, this would tell a problem collector to clear previously recorded problems.
+	 */
+	void beginReporting();
+
+	/**
+	 * Notification sent after having completed problem detection process.
+	 * Typically, this would tell a problem collector that no more problems should be expected in this
+	 * iteration.
+	 */
+	void endReporting();
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/InternalTargetFilter.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/InternalTargetFilter.java
new file mode 100644
index 0000000..3e0daa5
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/InternalTargetFilter.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.model;
+
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+
+public class InternalTargetFilter extends ViewerFilter {
+	
+	private int fFiltered= 0;
+	/**
+	 * Returns whether the given target is an internal target. Internal
+	 * targets are targets which have no description. The default target
+	 * is never considered internal.
+	 */
+	public boolean select(Viewer viewer, Object parentElement, Object element) {
+		boolean result= true;
+		if (viewer instanceof CheckboxTableViewer) {
+		    if (((CheckboxTableViewer)viewer).getChecked(element)) {
+		        //do not filter out (selected) checked items
+		        return true;
+		    }
+		}
+		if (element instanceof AntTargetNode) {
+			result = !((AntTargetNode)element).isInternal();
+		} 
+		if (!result) {
+			fFiltered++;
+		}
+		return result;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ViewerFilter#filter(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object[])
+	 */
+	public Object[] filter(Viewer viewer, Object parent, Object[] elements) {
+		fFiltered= 0;
+		return super.filter(viewer, parent, elements);
+	}
+	
+	public int getNumberOfTargetsFiltered() {
+		return fFiltered;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/LocationProvider.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/LocationProvider.java
new file mode 100644
index 0000000..866e33a
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/model/LocationProvider.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.model;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.editors.text.ILocationProvider;
+
+public class LocationProvider {
+	private IEditorInput fEditorInput;
+	
+	public LocationProvider(IEditorInput input) {
+		fEditorInput= input;
+	}
+
+	public IPath getLocation() {
+		if (fEditorInput instanceof IFileEditorInput) {
+			return ((IFileEditorInput)fEditorInput).getFile().getLocation();
+		}
+		ILocationProvider locationProvider= (ILocationProvider)fEditorInput.getAdapter(ILocationProvider.class);
+		if (locationProvider != null) {
+			return locationProvider.getPath(fEditorInput);
+		}
+		return null;
+	}
+	
+	public IFile getFile() {
+		if(fEditorInput instanceof IFileEditorInput) {
+			return ((IFileEditorInput)fEditorInput).getFile();
+		}
+		return null;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AbstractClasspathEntry.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AbstractClasspathEntry.java
new file mode 100644
index 0000000..f92df36
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AbstractClasspathEntry.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.ant.core.IAntClasspathEntry;
+
+public abstract class AbstractClasspathEntry implements IClasspathEntry {
+
+	protected List fChildEntries = new ArrayList();
+	protected IClasspathEntry fParent = null;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IClasspathEntry#getEntries()
+	 */
+	public IAntClasspathEntry[] getEntries() {
+		return (IAntClasspathEntry[])fChildEntries.toArray(new IAntClasspathEntry[fChildEntries.size()]);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IClasspathEntry#hasEntries()
+	 */
+	public boolean hasEntries() {
+		return !fChildEntries.isEmpty();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IClasspathEntry#getParent()
+	 */
+	public IClasspathEntry getParent() {
+		return fParent;
+	}
+	
+	/**
+	 * @param parent The parent to set.
+	 */
+	public void setParent(IClasspathEntry parent) {
+		fParent = parent;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.core.IAntClasspathEntry#getEntryURL()
+	 */
+	public URL getEntryURL() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.core.IAntClasspathEntry#getLabel()
+	 */
+	public String getLabel() {
+		return toString();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.core.IAntClasspathEntry#isEclipseRuntimeRequired()
+	 */
+	public boolean isEclipseRuntimeRequired() {
+		return false;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AddPropertyDialog.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AddPropertyDialog.java
new file mode 100644
index 0000000..cb25e2b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AddPropertyDialog.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.debug.ui.StringVariableSelectionDialog;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+public class AddPropertyDialog extends Dialog {
+
+	private String fName;
+	private String fValue;
+
+	private String fTitle;
+	
+	private Label fNameLabel;
+	private Text fNameText;
+	private Label fValueLabel;
+	private Text fValueText;
+	
+	private String[] fInitialValues;
+
+	public AddPropertyDialog(Shell shell, String title, String[] initialValues) {
+		super(shell);
+		fTitle = title;
+		fInitialValues= initialValues;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createDialogArea(Composite parent) {
+		Composite comp= (Composite) super.createDialogArea(parent);
+		((GridLayout) comp.getLayout()).numColumns = 2;
+		
+		fNameLabel = new Label(comp, SWT.NONE);
+		fNameLabel.setText(AntPreferencesMessages.AddPropertyDialog__Name__1);
+		fNameLabel.setFont(comp.getFont());
+		
+		fNameText = new Text(comp, SWT.BORDER | SWT.SINGLE);
+		fNameText.setText(fInitialValues[0]);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.widthHint = 300;
+		fNameText.setLayoutData(gd);
+		fNameText.setFont(comp.getFont());
+		fNameText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				updateButtons();
+			}
+		});
+		
+		fValueLabel = new Label(comp, SWT.NONE);
+		fValueLabel.setText(AntPreferencesMessages.AddPropertyDialog__Value__2);
+		fValueLabel.setFont(comp.getFont());
+		
+		fValueText = new Text(comp, SWT.BORDER | SWT.SINGLE);
+		fValueText.setText(fInitialValues[1]);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.widthHint = 300;
+		fValueText.setLayoutData(gd);
+		fValueText.setFont(comp.getFont());
+		fValueText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				updateButtons();
+			}
+		});		
+		
+		Button variablesButton = new Button(comp, SWT.PUSH);
+		variablesButton.setText(AntPreferencesMessages.AddPropertyDialog_2);
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+		gd.horizontalSpan = 2;
+		int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+		gd.widthHint = Math.max(widthHint, variablesButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+		variablesButton.setLayoutData(gd);
+		variablesButton.setFont(comp.getFont());
+		
+		variablesButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent se) {
+				getVariable();
+			}
+		});
+		
+		return comp;
+	}
+	
+	protected void getVariable() {
+		StringVariableSelectionDialog variablesDialog = new StringVariableSelectionDialog(getShell());
+		int returnCode = variablesDialog.open();
+		if (returnCode == IDialogConstants.OK_ID) {
+			String variable = variablesDialog.getVariableExpression();
+			if (variable != null) {
+				fValueText.insert(variable.trim());
+			}
+		}
+	}
+
+	/**
+	 * Return the name/value pair entered in this dialog.  If the cancel button was hit,
+	 * both will be <code>null</code>.
+	 */
+	public String[] getNameValuePair() {
+		return new String[] {fName, fValue};
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
+	 */
+	protected void buttonPressed(int buttonId) {
+		if (buttonId == IDialogConstants.OK_ID) {
+			//https://bugs.eclipse.org/bugs/show_bug.cgi?id=248316
+			fName= fNameText.getText().trim();
+			fValue = fValueText.getText().trim();
+		} else {
+			fName = null;
+			fValue = null;
+		}
+		super.buttonPressed(buttonId);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+	 */
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		if (fTitle != null) {
+			shell.setText(fTitle);
+		}
+		if (fInitialValues[0].length() == 0) {
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IAntUIHelpContextIds.ADD_PROPERTY_DIALOG);
+		} else {
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IAntUIHelpContextIds.EDIT_PROPERTY_DIALOG);
+		}
+	}
+	
+	/**
+	 * Enable the OK button if valid input
+	 */
+	protected void updateButtons() {
+		String name = fNameText.getText().trim();
+		String value = fValueText.getText().trim();
+		getButton(IDialogConstants.OK_ID).setEnabled((name.length() > 0) &&(value.length() > 0));
+	}
+	
+	/**
+	 * Enable the buttons on creation.
+	 * @see org.eclipse.jface.window.Window#create()
+	 */
+	public void create() {
+		super.create();
+		updateButtons();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathContentProvider.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathContentProvider.java
new file mode 100644
index 0000000..4ec0c7e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathContentProvider.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Content provider that maintains a list of classpath entries which are shown in a tree
+ * viewer.
+ */
+public class AntClasspathContentProvider implements ITreeContentProvider {
+	private TreeViewer treeViewer;
+	private ClasspathModel model= null;
+	private boolean refreshEnabled= false;
+	private boolean refreshRequested= false;
+		
+	public void add(IClasspathEntry parent, Object child) {
+		Object newEntry= null;
+		boolean added= false;
+		if (parent == null || parent == model) {
+			added= true;
+			newEntry= model.addEntry(child);
+			if (newEntry == null) {
+				//entry already exists
+				newEntry= model.createEntry(child, model);
+				added= false;
+			}
+			parent= model;
+		} else if (parent instanceof GlobalClasspathEntries) {
+			GlobalClasspathEntries globalParent= (GlobalClasspathEntries) parent;
+			newEntry= model.createEntry(child, globalParent);
+			ClasspathEntry newClasspathEntry= (ClasspathEntry) newEntry;
+			if (!globalParent.contains(newClasspathEntry)) {
+				added= true;
+				globalParent.addEntry(newClasspathEntry);
+			}
+		} 
+		if (newEntry != null) {
+			if (added) {
+				treeViewer.add(parent, newEntry);
+			}
+			treeViewer.setExpandedState(parent, true);
+			treeViewer.setSelection(new StructuredSelection(newEntry), true);
+			refresh();
+		}
+	}
+	
+	public void add(int entryType, Object child) {
+		Object newEntry= model.addEntry(entryType, child);
+		if (newEntry != null) {
+			treeViewer.add(getParent(newEntry), newEntry);
+			refresh();
+		}
+	}
+
+	public void removeAll() {
+		model.removeAll();
+		refresh();
+	}
+	
+	private void refresh() {
+		if (refreshEnabled) {
+			treeViewer.refresh();
+			refreshRequested= false;
+		} else {
+			refreshRequested= true;
+		}
+	}
+	
+	public void removeAllGlobalAntClasspathEntries() {
+		model.removeAll(ClasspathModel.ANT_HOME);
+		refresh();
+	}
+
+	/**
+	 * @see ITreeContentProvider#getParent(Object)
+	 */
+	public Object getParent(Object element) {
+		if (element instanceof ClasspathEntry) {
+			return ((ClasspathEntry)element).getParent();
+		}
+		if (element instanceof GlobalClasspathEntries) {
+			return model;
+		}
+		
+		return null;
+	}
+
+	/**
+	 * @see ITreeContentProvider#hasChildren(Object)
+	 */
+	public boolean hasChildren(Object element) {
+		if (element instanceof ClasspathEntry) {
+			return false;
+		}
+		if (element instanceof GlobalClasspathEntries) {
+			return ((GlobalClasspathEntries)element).hasEntries();
+			
+		} 
+		
+		if (element instanceof ClasspathModel) {
+			return ((ClasspathModel) element).hasEntries();
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+	 */
+	public Object[] getElements(Object inputElement) {
+		return getChildren(inputElement);
+	}
+
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+	 */
+	public void dispose() {
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+	 */
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		treeViewer = (TreeViewer) viewer;
+		
+		if (newInput != null) {
+			model= (ClasspathModel)newInput;
+		} else {
+			if (model != null) {
+				model.removeAll();
+			}
+			model= null;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+	 */
+	public Object[] getChildren(Object parentElement) {
+		if (parentElement instanceof GlobalClasspathEntries) {
+			return ((GlobalClasspathEntries)parentElement).getEntries();
+		}
+		if (parentElement instanceof ClasspathModel) {
+			return ((ClasspathModel)parentElement).getEntries();
+		}
+		if (parentElement == null) {
+			List all= new ArrayList();
+			Object[] topEntries= model.getEntries();
+			for (int i = 0; i < topEntries.length; i++) {
+				Object object = topEntries[i];
+				if (object instanceof ClasspathEntry) {
+					all.add(object);
+				} else if (object instanceof GlobalClasspathEntries) {
+					all.addAll(Arrays.asList(((GlobalClasspathEntries)object).getEntries()));
+				}
+			}
+			return all.toArray();
+		}
+		
+		return null;
+	}
+
+	public void remove(IStructuredSelection selection) {
+		Object[] array= selection.toArray();
+		model.removeAll(array);
+		treeViewer.remove(array);
+		refresh();
+	}
+
+	public ClasspathModel getModel() {
+		return model;
+	}
+
+	public void setRefreshEnabled(boolean refreshEnabled) {
+		this.refreshEnabled = refreshEnabled;
+		treeViewer.getTree().setRedraw(refreshEnabled);
+		if (refreshEnabled && refreshRequested) {
+			refresh();
+		}
+	}
+
+	/**
+	 * @param currentParent
+	 */
+	public void setEntries(IClasspathEntry currentParent, List entries) {
+		if (currentParent instanceof GlobalClasspathEntries) {
+			GlobalClasspathEntries group= (GlobalClasspathEntries) currentParent;
+			group.setEntries(entries);
+		}
+		
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathLabelProvider.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathLabelProvider.java
new file mode 100644
index 0000000..bb4f665
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathLabelProvider.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.IAntClasspathEntry;
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Label provider for classpath elements
+ */
+public class AntClasspathLabelProvider implements ILabelProvider, IColorProvider {
+
+
+	private AntClasspathBlock fBlock;
+	
+	public AntClasspathLabelProvider(AntClasspathBlock block) {
+		fBlock= block;
+	}
+
+	private Image getFolderImage() {
+		return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+	}
+
+	private Image getJarImage() {
+		return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_JAR);
+	}
+
+	public Image getClasspathImage() {
+		return AntUIImages.getImage(IAntUIConstants.IMG_TAB_CLASSPATH);
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+	 */
+	public Image getImage(Object element) {
+		String file;
+		if (element instanceof ClasspathEntry) {
+			ClasspathEntry entry = (ClasspathEntry) element;
+            if (entry.isEclipseRuntimeRequired()) {
+                return AntUIImages.getImage(IAntUIConstants.IMG_ANT_ECLIPSE_RUNTIME_OBJECT);
+            }
+			file= entry.toString();
+			if (file.endsWith("/")) { //$NON-NLS-1$
+				return getFolderImage();
+			} 
+			return getJarImage();
+		}
+		
+		return getClasspathImage();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+	 */
+	public String getText(Object element) {
+		if (element instanceof IAntClasspathEntry) {
+            IAntClasspathEntry entry= (IAntClasspathEntry)element;
+			StringBuffer label= new StringBuffer(entry.getLabel());
+			if (element instanceof GlobalClasspathEntries) {
+                if (((GlobalClasspathEntries)element).getType() == ClasspathModel.ANT_HOME) {
+    				AntCorePreferences prefs= AntCorePlugin.getPlugin().getPreferences();
+    				String defaultAntHome= prefs.getDefaultAntHome();
+    				String currentAntHome= fBlock.getAntHome();
+    				label.append(" ("); //$NON-NLS-1$
+    				if (defaultAntHome == null || defaultAntHome.equals(currentAntHome)) {
+    					label.append(AntPreferencesMessages.AntClasspathLabelProvider_0);
+    				} else {
+    					label.append(fBlock.getAntHome());	
+    				}
+    				label.append(')');
+                }
+			} 
+			return label.toString();
+		}
+		return element.toString();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object)
+	 */
+	public Color getBackground(Object element) {
+		if (element instanceof GlobalClasspathEntries) {
+            int type= ((GlobalClasspathEntries) element).getType();
+            if (type == ClasspathModel.CONTRIBUTED) {
+                Display display= Display.getCurrent();
+                return display.getSystemColor(SWT.COLOR_INFO_BACKGROUND);
+            }
+		} else if (element instanceof ClasspathEntry) {
+            return getBackground(((ClasspathEntry) element).getParent());
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object)
+	 */
+	public Color getForeground(Object element) {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
+	 */
+	public void addListener(ILabelProviderListener listener) {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
+	 */
+	public void dispose() {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
+	 */
+	public boolean isLabelProperty(Object element, String property) {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
+	 */
+	public void removeListener(ILabelProviderListener listener) {
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathPage.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathPage.java
new file mode 100644
index 0000000..653438c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathPage.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.IAntClasspathEntry;
+import org.eclipse.ant.internal.core.AntClasspathEntry;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Sub-page that allows the user to enter custom classpaths
+ * to be used when running Ant build files.
+ */
+public class AntClasspathPage implements IAntBlockContainer {
+
+	private AntClasspathBlock fAntClasspathBlock= new AntClasspathBlock();
+	private AntRuntimePreferencePage fPreferencePage;
+	private ClasspathModel fModel;
+	
+	/**
+	 * Creates an instance.
+	 */
+	public AntClasspathPage(AntRuntimePreferencePage preferencePage) {
+		fPreferencePage = preferencePage;
+	}
+	
+	/**
+	 * Returns the specified user classpath entries
+	 * 
+	 * @return set of user classpath entries
+	 */
+	protected IAntClasspathEntry[] getAdditionalEntries() {
+		return fModel.getEntries(ClasspathModel.GLOBAL_USER);
+	}
+	
+	/**
+	 * Returns the specified ant home classpath entries
+	 */
+	protected IAntClasspathEntry[] getAntHomeEntries() {
+		return fModel.getEntries(ClasspathModel.ANT_HOME);
+	}
+	
+	/**
+	 * Returns the contributed classpath entries
+	 */
+	protected IAntClasspathEntry[] getContributedEntries() {
+		return fModel.getEntries(ClasspathModel.CONTRIBUTED);
+	}
+	
+	protected String getAntHome() {
+		return fAntClasspathBlock.getAntHome();
+	}
+	
+	/**
+	 * Sets the contents of the tables on this page.
+	 */
+	protected void initialize() {
+		
+		AntCorePreferences prefs= AntCorePlugin.getPlugin().getPreferences();
+		createClasspathModel();
+		fAntClasspathBlock.initializeAntHome(prefs.getAntHome());
+		fAntClasspathBlock.setInput(fModel);
+		
+		fPreferencePage.setErrorMessage(null);
+		fPreferencePage.setValid(true);
+	}
+	
+	protected void createClasspathModel() {
+		fModel= new ClasspathModel();
+		AntCorePreferences prefs= AntCorePlugin.getPlugin().getPreferences();
+		fModel.setAntHomeEntries(prefs.getAntHomeClasspathEntries());
+		fModel.setGlobalEntries(prefs.getAdditionalClasspathEntries());
+        fModel.setContributedEntries(prefs.getContributedClasspathEntries());
+	}
+	
+	protected void performDefaults() {
+		AntCorePreferences prefs= AntCorePlugin.getPlugin().getPreferences();
+		fModel= new ClasspathModel();
+		fModel.setAntHomeEntries(prefs.getDefaultAntHomeEntries());
+		List additionalEntries= getDefaultAdditionalEntries();
+		if (additionalEntries != null) {
+			fModel.setGlobalEntries((IAntClasspathEntry[]) additionalEntries.toArray(new IAntClasspathEntry[additionalEntries.size()]));
+		} else {
+			fModel.setGlobalEntries(new IAntClasspathEntry[0]);
+		}
+        fModel.setContributedEntries(prefs.getContributedClasspathEntries());
+		fAntClasspathBlock.initializeAntHome(prefs.getDefaultAntHome());
+		fAntClasspathBlock.setInput(fModel);
+		update();
+	}
+	
+	private List getDefaultAdditionalEntries() {
+		IAntClasspathEntry toolsJarEntry= AntCorePlugin.getPlugin().getPreferences().getToolsJarEntry();
+		//TODO should use AntCorePreferences.getUserLibraries when promoted to API post 3.1
+		File libDir= new File(System.getProperty("user.home"), ".ant" + File.separatorChar + "lib"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		URL[] urls= null;
+		try {
+			urls= getLocationURLs(libDir);
+		} catch (MalformedURLException e) {
+            AntUIPlugin.log(e);
+            return new ArrayList(0);
+		}
+		
+		List entries= new ArrayList(urls.length);
+		for (int i = 0; i < urls.length; i++) {
+			AntClasspathEntry entry= new AntClasspathEntry(urls[i]);
+			entries.add(entry);
+		}
+		if (toolsJarEntry != null) {
+			entries.add(toolsJarEntry);
+		}
+		return entries;
+	}
+	
+	private URL[] getLocationURLs(File location) throws MalformedURLException {
+		 final String extension= ".jar"; //$NON-NLS-1$
+		 URL[] urls = new URL[0];
+		 
+		 if (!location.exists()) {
+			 return urls;
+		 }
+		 
+		 if (!location.isDirectory()) {
+			 urls = new URL[1];
+			 String path = location.getPath();
+			 if (path.toLowerCase().endsWith(extension)) {
+				 urls[0] = location.toURL();
+			 }
+			 return urls;
+		 }
+		 
+		 File[] matches = location.listFiles(
+			 new FilenameFilter() {
+				 public boolean accept(File dir, String name) {
+					return name.toLowerCase().endsWith(extension);
+				 }
+			 });
+		 
+		 urls = new URL[matches.length];
+		 for (int i = 0; i < matches.length; ++i) {
+			 urls[i] = matches[i].toURL();
+		 }
+		 return urls;
+	 }
+	
+	/**
+	 * Creates the tab item that contains this sub-page.
+	 */
+	protected TabItem createTabItem(TabFolder folder) {
+		TabItem item = new TabItem(folder, SWT.NONE);
+		item.setText(AntPreferencesMessages.AntClasspathPage_title);
+		item.setImage(fAntClasspathBlock.getClasspathImage());
+		item.setData(this);
+		item.setControl(createContents(folder));
+		return item;
+	}
+	
+	/**
+	 * Creates this page's controls
+	 */
+	protected Composite createContents(Composite parent) {
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IAntUIHelpContextIds.ANT_CLASSPATH_PAGE);
+		Font font = parent.getFont();
+		
+		Composite top = new Composite(parent, SWT.NONE);
+		top.setFont(font);
+		
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 2;
+		layout.marginWidth = 2;
+		top.setLayout(layout);
+
+		top.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		fAntClasspathBlock.setContainer(this);
+		fAntClasspathBlock.createContents(top);
+		
+		return top;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#update()
+	 */
+	public void update() {
+		if (fAntClasspathBlock.isValidated()){
+			return;
+		}
+		setMessage(null);
+		setErrorMessage(null);
+		boolean valid= fAntClasspathBlock.validateAntHome();
+	
+		if (valid) {
+			valid= fAntClasspathBlock.validateToolsJAR();
+		}
+		
+		fPreferencePage.setValid(valid);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#setMessage(java.lang.String)
+	 */
+	public void setMessage(String message) {
+		fPreferencePage.setMessage(message);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#setErrorMessage(java.lang.String)
+	 */
+	public void setErrorMessage(String message) {
+		fPreferencePage.setErrorMessage(message);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#createPushButton(org.eclipse.swt.widgets.Composite, java.lang.String)
+	 */
+	public Button createPushButton(Composite parent, String buttonText) {
+		Button button = new Button(parent, SWT.PUSH);
+		button.setFont(parent.getFont());
+		button.setText(buttonText);
+		fPreferencePage.setButtonLayoutData(button);
+		return button;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntContentProvider.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntContentProvider.java
new file mode 100644
index 0000000..0d87718
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntContentProvider.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+
+/**
+ * Content provider that maintains a generic list of objects which are shown in
+ * a table viewer.
+ */
+public class AntContentProvider implements IStructuredContentProvider {
+	protected List elements = new ArrayList();
+	protected TableViewer tableViewer;
+	private ViewerComparator fComparator= null;
+	/**
+	 * @since 3.5
+	 */
+	private boolean defaultcomparator = true;
+	
+	
+	/**
+	 * Default Constructor
+	 */
+	public AntContentProvider() {
+	}
+	
+	/**
+	 * Constructor
+	 * 
+	 * @param defaultcomparator if the default comparator should be used for the returned data
+	 * @since 3.5
+	 */
+	public AntContentProvider(boolean defaultcomparator) {
+		this.defaultcomparator = defaultcomparator;
+	}
+	
+	/**
+	 * Add an element to the current listing of elements and to the underlying viewer. Does nothing
+	 * if the listing already contains the given element
+	 * @param o
+	 */
+	public void add(Object o) {
+		if (elements.contains(o)) {
+			return;
+		}
+		elements.add(o);
+		tableViewer.add(o);
+		tableViewer.setSelection(new StructuredSelection(o), true);
+	}
+
+	/**
+	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+	 */
+	public void dispose() {
+	}
+
+	/**
+	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+	 */
+	public Object[] getElements(Object inputElement) {
+		return elements.toArray();
+	}
+
+	/**
+	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+	 */
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		tableViewer = (TableViewer) viewer;
+		elements.clear();
+		if (newInput != null) {
+			if(defaultcomparator) {
+				tableViewer.setComparator(getComparator());
+			}
+			List list;
+			if (newInput instanceof List) {
+				list= (List) newInput;
+			} else {
+				list= Arrays.asList((Object[]) newInput);	
+			}
+			elements.addAll(list);
+		}
+	}
+
+	/**
+	 * Removes the given element from the listing of elements and from the backing viewer.
+	 * @param o
+	 */
+	public void remove(Object o) {
+		elements.remove(o);
+		tableViewer.remove(o);
+	}
+	
+	/**
+	 * Removes the given selection of the listing of elements and from the backing viewer
+	 * @param selection
+	 */
+	public void remove(IStructuredSelection selection) {
+		Object[] array= selection.toArray();
+		elements.removeAll(Arrays.asList(array));
+		tableViewer.remove(array);
+	}
+
+	/**
+	 * Returns the default comparator which compares the {@link #toString()} value of the elements for ordering
+	 * @return the default comparator
+	 */
+	protected ViewerComparator getComparator() {
+		if (fComparator == null) {
+			fComparator= new ViewerComparator() {
+				/* (non-Javadoc)
+				 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+				 */
+				public int compare(Viewer viewer, Object e1, Object e2) {
+					return e1.toString().compareToIgnoreCase(e2.toString());
+				}
+			};
+		}
+		return fComparator;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntEditorPreferenceConstants.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntEditorPreferenceConstants.java
new file mode 100644
index 0000000..e460b0b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntEditorPreferenceConstants.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Preference constants used for the Ant Editor
+ */
+public class AntEditorPreferenceConstants {
+
+	private AntEditorPreferenceConstants() {
+	}
+	
+	/**
+	 * A named preference that controls if the Ant Editor code assist gets auto activated.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 */
+	public final static String CODEASSIST_AUTOACTIVATION= "content_assist_autoactivation"; //$NON-NLS-1$
+
+	/**
+	 * A name preference that holds the auto activation delay time in milli seconds.
+	 * <p>
+	 * Value is of type <code>Int</code>.
+	 * </p>
+	 */
+	public final static String CODEASSIST_AUTOACTIVATION_DELAY= "content_assist_autoactivation_delay"; //$NON-NLS-1$
+
+	/**
+	 * A named preference that controls if the Ant editor code assist inserts a
+	 * proposal automatically if only one proposal is available.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * @since 2.1
+	 */
+	public final static String CODEASSIST_AUTOINSERT= "content_assist_autoinsert"; //$NON-NLS-1$
+
+	/**
+	 * A named preference that holds the characters that auto activate code assist in an Ant buildfile.
+	 * <p>
+	 * Value is of type <code>Sring</code>. All characters that trigger auto code assist in an Ant buildfile.
+	 * </p>
+	 */
+	public final static String CODEASSIST_AUTOACTIVATION_TRIGGERS= "content_assist_autoactivation_triggers_java"; //$NON-NLS-1$
+
+	/**
+	 * A named preference that controls if the Ant editor presents code assist proposals for
+	 * user defined tasks
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * @since 3.0
+	 */
+	public final static String CODEASSIST_USER_DEFINED_TASKS= "content_assist_userDefinedTasks"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that specifies the tab size for the Ant formatter.
+	 * <p>
+	 * Value is of type <code>int</code>.
+	 * </p>
+	 */
+	public static final String FORMATTER_TAB_SIZE= "formatter_tab_size"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that specifies if the Ant formatter uses spaces for tabs.
+	 * <p>
+	 * Value is of type <code>boolean</code>. If <code>false</code> spaces instead of tabs are used
+	 * when formatting. If <code>true</code> the formatter inserts a tab character for indenting.
+	 * </p>
+	 */
+	public static final String FORMATTER_TAB_CHAR= "formatter_tab_char"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that specifies if the Ant formatter aligns the final
+	 * &quote&gt&quote in multi-line element tags
+	 * <p>
+	 * Value is of type <code>Boolean</code>. If <code>true</code> the final
+	 * &quote&gt&quote in multi-line element tags are aligned by the formatter.
+	 * </p>
+	 */
+	public static final String FORMATTER_ALIGN= "formatter_align"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that specifies the maximum line length for the Ant formatter.
+	 * <p>
+	 * Value is of type <code>int</code>.
+	 * </p>
+	 */
+	public static final String FORMATTER_MAX_LINE_LENGTH= "formatter_max_line_length"; //$NON-NLS-1$
+			
+	/**
+	 * A named preference that specifies if the Ant formatter should wrap elements that are longer than
+	 * the maximum line length.
+	 * <p>
+	 * Value is of type <code>Boolean</code>. If <code>true</code> long elements are wrapped
+	 * when formatting in the editor.
+	 * </p>
+	 */
+	public static final String FORMATTER_WRAP_LONG= "formatter_wrap_long"; //$NON-NLS-1$
+	
+	/**
+	 * Boolean preference identifier constant which specifies whether the Ant editor should
+	 * format templates on insert.
+	 */
+	public static final String TEMPLATES_USE_CODEFORMATTER= "templates_use_codeformatter"; //$NON-NLS-1$
+
+	/**
+	 * Preference key suffix for bold text style preference keys.
+	 * 
+	 */
+	public static final String EDITOR_BOLD_SUFFIX= "_bold"; //$NON-NLS-1$
+
+	/**
+	 * Preference key suffix for italic text style preference keys.
+	 */
+	public static final String EDITOR_ITALIC_SUFFIX= "_italic"; //$NON-NLS-1$
+	
+	/**
+	 * Preference key prefix for all problem preference keys.
+	 */
+	public static final String PROBLEM= "problem"; //$NON-NLS-1$
+	
+	/**
+	 * String preference identifier constant which specifies the severity level for problems
+	 * related to classpath in the Ant editor
+	 */
+	public static final String PROBLEM_CLASSPATH= PROBLEM + "_classpath";  //$NON-NLS-1$
+	
+	/**
+	 * String preference identifier constant which specifies the severity level for problems
+	 * related to properties in the Ant editor
+	 */
+	public static final String PROBLEM_PROPERTIES= PROBLEM + "_properties";  //$NON-NLS-1$
+	
+	/**
+	 * String preference identifier constant which specifies the severity level for problems
+	 * related to imports in the Ant editor
+	 */
+	public static final String PROBLEM_IMPORTS= PROBLEM + "_imports";  //$NON-NLS-1$
+	
+	/**
+	 * String preference identifier constant which specifies the severity level for problems
+	 * related to tasks in the Ant editor
+	 */
+	public static final String PROBLEM_TASKS= PROBLEM + "_tasks";  //$NON-NLS-1$
+    
+    /**
+     * String preference identifier constant which specifies the severity level for problems
+     * related to security exceptions in the Ant editor
+     */
+    public static final String PROBLEM_SECURITY= PROBLEM + "_security";  //$NON-NLS-1$
+	
+	/**
+	 * The constants allowable for the severity levels for problem preferences
+	 */
+	public static final String BUILDFILE_ERROR = "error"; //$NON-NLS-1$
+	public static final String BUILDFILE_WARNING = "warning"; //$NON-NLS-1$
+	public static final String BUILDFILE_IGNORE = "ignore"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that controls whether problem reporting is enabled in the Ant editor.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * 
+	 * @since 3.1
+	 */
+	public static String BUILDFILE_IGNORE_ALL = "ignoreAll"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that lists the names of buildfiles to not do problem reporting for
+	 * <p>
+	 * Value is of type <code>String</code>.
+	 * </p>
+	 * 
+	 * @since 3.1
+	 */
+	public static String BUILDFILE_NAMES_TO_IGNORE = "ignoreNames"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that controls whether folding is enabled in the Ant editor.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * 
+	 * @since 3.1
+	 */
+	public static final String EDITOR_FOLDING_ENABLED= "editor_folding_enabled"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that stores the value for comment folding.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * 
+	 * @since 3.1
+	 */
+	public static final String EDITOR_FOLDING_COMMENTS= "editor_folding_comments"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that stores the value for target folding.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * 
+	 * @since 3.1
+	 */
+	public static final String EDITOR_FOLDING_TARGETS= "editor_folding_targets"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that stores the value for DTD folding.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * 
+	 * @since 3.1
+	 */
+	public static final String EDITOR_FOLDING_DTD= "editor_folding_dtd"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that stores the value for defining elements folding.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * 
+	 * @since 3.1
+	 */
+	public static final String EDITOR_FOLDING_DEFINING= "editor_folding_defining"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that controls if segmented view (show selected element only) is turned on or off.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * @since 3.1
+	 */
+	public static final String EDITOR_SHOW_SEGMENTS= "editor_show_segments"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that controls if occurrences are marked in the editor
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 * @since 3.1
+	 */
+	public static final String EDITOR_MARK_OCCURRENCES= "editor_mark_occurrences"; //$NON-NLS-1$
+    
+    /**
+     * A named preference that controls if background reconciling is triggered by the user
+     * typing in the editor
+     * <p>
+     * Value is of type <code>Boolean</code>.
+     * </p>
+     * @since 3.1
+     */
+    public static final String EDITOR_RECONCILE= "editor_reconcile"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference that controls whether occurrences are sticky in the editor.
+	 * <p>
+	 * Value is of type <code>Boolean</code>.
+	 * </p>
+	 *
+	 * @since 3.1
+	 */
+	public static final String EDITOR_STICKY_OCCURRENCES= "stickyOccurrences"; //$NON-NLS-1$
+
+
+	public static void initializeDefaultValues(IPreferenceStore store) {
+		
+		store.setDefault(CODEASSIST_AUTOINSERT, true);
+		store.setDefault(CODEASSIST_USER_DEFINED_TASKS, true);
+		store.setDefault(CODEASSIST_AUTOACTIVATION, true);
+		store.setDefault(CODEASSIST_AUTOACTIVATION_DELAY, 500);
+		store.setDefault(CODEASSIST_AUTOACTIVATION_TRIGGERS, "<${"); //$NON-NLS-1$
+		
+		store.setDefault(FORMATTER_TAB_CHAR, true);
+		store.setDefault(FORMATTER_TAB_SIZE, 4);
+		store.setDefault(FORMATTER_ALIGN, false);
+		store.setDefault(FORMATTER_MAX_LINE_LENGTH, 80);
+		store.setDefault(FORMATTER_WRAP_LONG, false);
+		
+		store.setDefault(TEMPLATES_USE_CODEFORMATTER, true);
+		
+        store.setDefault(PROBLEM_SECURITY, BUILDFILE_WARNING);
+		store.setDefault(PROBLEM_CLASSPATH, BUILDFILE_WARNING);
+		store.setDefault(PROBLEM_PROPERTIES, BUILDFILE_IGNORE);
+		store.setDefault(PROBLEM_IMPORTS, BUILDFILE_WARNING);
+		store.setDefault(PROBLEM_TASKS, BUILDFILE_IGNORE);
+		
+		store.setDefault(EDITOR_FOLDING_ENABLED, true);
+		
+		store.setDefault(EDITOR_SHOW_SEGMENTS, false);
+		
+		store.setDefault(EDITOR_MARK_OCCURRENCES, false);
+		store.setDefault(EDITOR_STICKY_OCCURRENCES, true);
+		
+		store.setDefault(BUILDFILE_IGNORE_ALL, false);
+        
+        store.setDefault(EDITOR_RECONCILE, true);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPage.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPage.java
new file mode 100644
index 0000000..615047a
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPage.java
@@ -0,0 +1,473 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.internal.core.AntObject;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.ColumnSorter;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Provides the generic implementation for a sub-page in the
+ * Ant preference page.
+ */
+public abstract class AntPage {
+    
+    protected static final int ADD_BUTTON = IDialogConstants.CLIENT_ID + 1;
+    protected static final int EDIT_BUTTON = IDialogConstants.CLIENT_ID + 2;
+    protected static final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 3;
+    
+	protected SelectionAdapter selectionAdapter = new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent e) {
+			buttonPressed(((Integer) e.widget.getData()).intValue());
+		}
+	};
+	
+	private AntRuntimePreferencePage preferencePage;
+	private TableViewer tableViewer;
+	private AntContentProvider contentProvider;
+	private AntObjectLabelProvider labelProvider = new AntObjectLabelProvider();
+	
+	protected Button editButton;
+	protected Button removeButton;
+    
+	private final String[] fTableColumnHeaders= {
+	        AntPreferencesMessages.AntPage_0, AntPreferencesMessages.AntPage_1, AntPreferencesMessages.AntPage_2, AntPreferencesMessages.AntPage_3
+	};
+	private final ColumnLayoutData[] fTableColumnLayouts= {
+	        new ColumnWeightData(33),
+	        new ColumnWeightData(23),
+	        new ColumnWeightData(22),
+	        new ColumnWeightData(22)
+	};  
+
+	/**
+	 * Creates an instance of this page.
+	 */
+	public AntPage(AntRuntimePreferencePage preferencePage) {
+		super();
+		this.preferencePage = preferencePage;
+	}
+	
+	/**
+	 * Adds buttons specific to the page.
+	 */
+	protected abstract void addButtonsToButtonGroup(Composite parent);
+	
+	/**
+	 * Give this page a chance to initialize itself
+	 */
+	protected abstract void initialize();
+	
+	/**
+	 * Adds an object to the contents
+	 */
+	protected void addContent(Object o) {
+		if (contentProvider != null) {
+			contentProvider.add(o);
+		}
+	}
+	
+	/* (non-Javadoc)
+     * @see org.eclipse.ant.internal.ui.preferences.AntPage#buttonPressed(int)
+     */
+    private void buttonPressed(int buttonId) {
+        switch (buttonId) {
+            case ADD_BUTTON :
+                add();
+                break;
+            case EDIT_BUTTON :
+                edit(getSelection());
+                break;
+            case REMOVE_BUTTON :
+                remove();
+                break;
+        }
+    }
+    
+	/**
+	 * Creates and returns a button with appropriate size and layout.
+	 * 
+	 * @param parent the control to create the button on
+	 * @param labelKey the key to lookup the button's label
+	 * @param buttonId the id to assign to this button
+	 * @return a new and initialized button
+	 */
+	protected Button createPushButton(Composite parent, String buttonText, int buttonId) {
+		Button button = new Button(parent, SWT.PUSH);
+		button.setFont(parent.getFont());
+		button.setText(buttonText);
+		button.setData(new Integer(buttonId));
+		button.addSelectionListener(selectionAdapter);
+		preferencePage.setButtonLayoutData(button);
+		return button;
+	}
+	
+	/**
+	 * Creates the group which will contain the buttons.
+	 */
+	protected void createButtonGroup(Composite top) {
+		Composite buttonGroup = new Composite(top, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		buttonGroup.setLayout(layout);
+		buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+		buttonGroup.setFont(top.getFont());
+		
+		addButtonsToButtonGroup(buttonGroup);
+	}
+	
+	/**
+	 * Creates the table viewer.
+	 */
+	protected void createTable(Composite parent) {
+		Table table = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
+		GridData data= new GridData(GridData.FILL_BOTH);
+		data.widthHint = 425;
+		data.heightHint = table.getItemHeight();
+		data.horizontalSpan = 1;
+		table.setLayoutData(data);
+		table.setFont(parent.getFont());
+        
+		TableLayout tableLayout = new TableLayout();
+		table.setLayout(tableLayout);
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+		
+		contentProvider = getContentProvider();
+		tableViewer = new TableViewer(table);
+		tableViewer.setContentProvider(contentProvider);
+		tableViewer.setLabelProvider(this.labelProvider);
+		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				tableSelectionChanged((IStructuredSelection) event.getSelection());
+			}
+		});
+		
+		tableViewer.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+				if (!event.getSelection().isEmpty() && editButton.isEnabled()) {
+					edit((IStructuredSelection)event.getSelection());
+				}
+			}
+		});
+		ArrayList sorters = new ArrayList(fTableColumnHeaders.length);
+		for (int i = 0; i < fTableColumnHeaders.length; i++) {
+		    tableLayout.addColumnData(fTableColumnLayouts[i]);
+		    TableColumn column = new TableColumn(table, SWT.NONE, i);
+		    column.setResizable(fTableColumnLayouts[i].resizable);
+		    column.setText(fTableColumnHeaders[i]);
+		    sorters.add(new ColumnSorter(this.tableViewer, column) {
+		    	public String getCompareText(Object obj, int columnindex) {
+		    		return AntPage.this.labelProvider.getColumnText(obj, columnindex);
+		    	}
+		    });
+		}
+		
+		table.addKeyListener(new KeyAdapter() {
+			public void keyPressed(KeyEvent event) {
+				if (editButton.isEnabled() && event.character == SWT.DEL && event.stateMask == 0) {
+					remove(tableViewer);
+				}
+			}
+		});	
+		
+		restoreColumnSettings(AntUIPlugin.getDefault().getDialogSettings(), sorters);
+	}
+	
+	/**
+	 * Persist table settings into the give dialog store, prefixed
+	 * with the given key.
+	 * 
+	 * @param settings dialog store
+	 * @since 3.5
+	 */
+	public void saveColumnSettings(IDialogSettings settings) {
+		Table table = this.tableViewer.getTable();
+        int columnCount = table.getColumnCount();
+		for (int i = 0; i < columnCount; i++) {
+			settings.put(getHelpContextId() + ".columnWidth" + i, table.getColumn(i).getWidth());	 //$NON-NLS-1$
+		}
+		TableColumn column = table.getSortColumn();
+		if(column != null) {
+			settings.put(getHelpContextId() + ".sortColumn", table.indexOf(column)); //$NON-NLS-1$
+			settings.put(getHelpContextId() + ".sortDirection", table.getSortDirection()); //$NON-NLS-1$
+		}
+	}
+	
+	/**
+	 * Restore table settings from the given dialog store using the
+	 * given key.
+	 * 
+	 * @param settings dialog settings store
+	 * @since 3.5
+	 */
+	private void restoreColumnSettings(IDialogSettings settings, ArrayList sorters) {
+        restoreColumnWidths(settings);
+        int idx = 0;
+        int direction = SWT.DOWN;
+		try {
+			idx = settings.getInt(getHelpContextId() + ".sortColumn"); //$NON-NLS-1$
+			direction = settings.getInt(getHelpContextId() + ".sortDirection"); //$NON-NLS-1$
+		} 
+		catch (NumberFormatException e) {}
+		Table table = this.tableViewer.getTable();
+		if(table.getColumnCount() < 1) {
+			return;
+		}
+		TableColumn column = table.getColumn(idx);
+		if(column != null) {
+			table.setSortColumn(column);
+			table.setSortDirection(direction);
+			ColumnSorter sorter = (ColumnSorter) sorters.get(idx);
+			sorter.setDirection(direction);
+		}
+		sorters.clear();
+	}
+	
+	/**
+	 * Restores the column widths from dialog settings
+	 * 
+	 * @param settings
+	 * @since 3.5
+	 */
+	private void restoreColumnWidths(IDialogSettings settings) {
+		Table table = this.tableViewer.getTable();
+        int columnCount = table.getColumnCount();
+        for (int i = 0; i < columnCount; i++) {
+            int width = -1;
+            try {
+                width = settings.getInt(getHelpContextId() + ".columnWidth" + i); //$NON-NLS-1$
+            } catch (NumberFormatException e) {}
+            
+            if ((width <= 0) || (i == table.getColumnCount() - 1)) {
+            	table.getColumn(i).pack();
+            } else {
+            	table.getColumn(i).setWidth(width);
+            }
+        }
+	}
+	
+	/**
+	 * Returns the content provider to use for the table viewer
+	 * 
+	 * @return AntPageContentProvider
+	 */
+	protected AntContentProvider getContentProvider() {
+		return new AntContentProvider(false);
+	}
+
+	/**
+	 * Returns the currently listed objects in the table if the library
+	 * for that entry is still included in the preferences.  Default objects
+	 * are included depending on the value of the <code>forDisplay</code> parameter.
+	 * Returns <code>null</code> if this widget has not yet been created
+	 * or has been disposed.
+	 * @param forDisplay Whether the result is to be displayed in the UI or stored in the preferences
+	 * @return The list of objects currently displayed in the table
+	 */
+	protected List getContents(boolean forDisplay) {
+		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
+			return null;
+		}
+		List entries= getPreferencePage().getLibraryEntries();
+		
+		Object[] elements = contentProvider.getElements(tableViewer.getInput());
+		List contents= new ArrayList(elements.length);
+		Object element;
+		AntObject antObject;
+		for (int i = 0; i < elements.length; i++) {
+			element= elements[i];
+			if (element instanceof AntObject) {
+				antObject= (AntObject)element;
+				if (forDisplay) {
+					if (!antObject.isDefault() && !entries.contains(antObject.getLibraryEntry())) {
+						continue;
+					}
+				} else if (antObject.isDefault() || !entries.contains(antObject.getLibraryEntry())) {
+					continue;
+				}
+			}
+			contents.add(element);
+		}
+		return contents;
+	}
+	
+	/**
+	 * Returns the selection in the viewer, or <code>null</code> if none.
+	 */
+	protected final IStructuredSelection getSelection() {
+		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
+			return null;
+		}
+		return ((IStructuredSelection) tableViewer.getSelection());
+	}
+	
+	/**
+	 * Returns the shell of the sub-page.
+	 */
+	protected final Shell getShell() {
+		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
+			return null;
+		}
+		return tableViewer.getControl().getShell();
+	}
+	
+	/**
+	 * Handles the remove button pressed event
+	 */
+	protected void remove() {
+		remove(tableViewer);
+	}
+	
+	protected void remove(TableViewer viewer) {
+		AntContentProvider antContentProvider= (AntContentProvider)viewer.getContentProvider();
+		IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
+		Iterator itr = sel.iterator();
+		while (itr.hasNext()) {
+			antContentProvider.remove(itr.next());
+		}
+	}
+	
+	/**
+	 * Sets the contents of the table on this page.  Has no effect
+	 * if this widget has not yet been created or has been disposed.
+	 */
+	protected void setInput(List inputs) {
+		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
+			return;
+		}
+		tableViewer.setInput(inputs);
+		tableSelectionChanged((IStructuredSelection) tableViewer.getSelection());
+	}
+
+	/**
+	 * Updates the content element in the table viewer.
+	 */
+	protected final void updateContent(Object element) {
+		if (tableViewer == null || tableViewer.getControl().isDisposed()) {
+			return;
+		}
+		tableViewer.update(element, null);
+	}
+	
+	/**
+	 * Creates the default contents of this page
+	 */
+	protected Composite createContents(Composite top) {
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(top, getHelpContextId());
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 2;
+		layout.marginWidth = 2;
+		top.setLayout(layout);
+		
+		top.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		createTable(top);
+		createButtonGroup(top);
+		
+		return top;
+	}
+	
+	protected AntRuntimePreferencePage getPreferencePage() {
+		return preferencePage;
+	}
+	
+	protected TableViewer getTableViewer() {
+		return tableViewer;
+	}
+
+	/**
+	 * Handles selection changes in the table viewer.
+	 */
+	protected void tableSelectionChanged(IStructuredSelection newSelection) {
+		int size = newSelection.size();
+		boolean enabled= true;
+		
+		Iterator itr= newSelection.iterator();
+		while (itr.hasNext()) {
+			Object element = itr.next();
+			if (element instanceof AntObject) {
+				AntObject antObject= (AntObject)element;
+				if (antObject.isDefault()) {
+					enabled= false;
+					break;
+				}
+			}
+		}
+		editButton.setEnabled(enabled && size == 1);
+		removeButton.setEnabled(enabled && size > 0);
+	}
+	
+	/**
+	 * Allows the user to edit a custom Ant object.
+	 *
+	 * @param selection The selection containing the object to edit
+	 */
+	protected abstract void edit(IStructuredSelection selection);
+    
+    /**
+     * Allows the user to add a custom Ant object.
+     *
+     */
+    protected abstract void add();
+	
+	/**
+	 * Returns this page's help context id, which is hooked
+	 * to this page on creation.
+	 * 
+	 * @return help context id
+	 */
+	protected abstract String getHelpContextId();
+
+	protected void connectToFolder(final TabItem item, TabFolder folder) {
+		folder.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				if (e.item == item) {
+					//remove ant objects whose library has been removed
+					setInput(getContents(true));
+				}
+			}
+		});		
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPreviewerUpdater.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPreviewerUpdater.java
new file mode 100644
index 0000000..a5723f4
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPreviewerUpdater.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.preferences;
+
+import org.eclipse.ant.internal.ui.AntSourceViewerConfiguration;
+import org.eclipse.ant.internal.ui.editor.formatter.FormattingPreferences;
+import org.eclipse.ant.internal.ui.editor.formatter.XmlFormatter;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+
+/**
+ * Handles changes for Ant preview viewers.
+ * 
+ * @since 3.0
+ */
+class AntPreviewerUpdater {
+	
+	private Color fForegroundColor= null;
+	private Color fBackgroundColor= null;
+	private Color fSelectionBackgroundColor= null;
+	private Color fSelectionForegroundColor= null;
+	
+	
+	/**
+	 * Creates a source preview updater for the given viewer, configuration and preference store.
+	 *
+	 * @param viewer the viewer
+	 * @param configuration the configuration
+	 * @param preferenceStore the preference store
+	 */
+	public AntPreviewerUpdater(final SourceViewer viewer, final AntSourceViewerConfiguration configuration, final IPreferenceStore preferenceStore) {
+		
+		initializeViewerColors(viewer, preferenceStore);
+		
+		final IPropertyChangeListener fontChangeListener= new IPropertyChangeListener() {
+			/*
+			 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+			 */
+			public void propertyChange(PropertyChangeEvent event) {
+				if (event.getProperty().equals(JFaceResources.TEXT_FONT)) {
+					Font font= JFaceResources.getFont(JFaceResources.TEXT_FONT);
+					viewer.getTextWidget().setFont(font);
+				}
+			}
+		};
+		final IPropertyChangeListener propertyChangeListener= new IPropertyChangeListener() {
+			/*
+			 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+			 */
+			public void propertyChange(PropertyChangeEvent event) {
+				
+				String property= event.getProperty();
+					
+				if (AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND.equals(property) || AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT.equals(property) ||
+						AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND.equals(property) ||	AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) ||
+						AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND.equals(property) || AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND_SYSTEM_DEFAULT.equals(property) ||
+						AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND.equals(property) ||	AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT.equals(property))
+					{
+						initializeViewerColors(viewer, preferenceStore);
+				} 
+				
+				if (configuration.affectsTextPresentation(event)) {
+					configuration.adaptToPreferenceChange(event);
+					viewer.invalidateTextPresentation();
+				}
+				
+				if (FormattingPreferences.affectsFormatting(event)) {
+					format(viewer, preferenceStore);
+				}
+			}
+
+			/**
+			 * @param viewer
+			 * @param preferenceStore
+			 */
+			private void format(final SourceViewer sourceViewer, final IPreferenceStore store) {
+				String contents= sourceViewer.getDocument().get();
+				FormattingPreferences prefs= new FormattingPreferences();
+				prefs.setPreferenceStore(store);
+				contents= XmlFormatter.format(contents, prefs);
+				viewer.getDocument().set(contents);
+			}
+		};
+		viewer.getTextWidget().addDisposeListener(new DisposeListener() {
+			/*
+			 * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
+			 */
+			public void widgetDisposed(DisposeEvent e) {
+				preferenceStore.removePropertyChangeListener(propertyChangeListener);
+				JFaceResources.getFontRegistry().removeListener(fontChangeListener);
+			}
+		});
+		JFaceResources.getFontRegistry().addListener(fontChangeListener);
+		preferenceStore.addPropertyChangeListener(propertyChangeListener);
+	}
+	
+	/**
+	 * Initializes the given viewer's colors.
+	 * 
+	 * @param viewer the viewer to be initialized
+	 * @since 2.0
+	 */
+	protected void initializeViewerColors(ISourceViewer viewer, IPreferenceStore store) {
+			
+		StyledText styledText= viewer.getTextWidget();
+		
+		// ----------- foreground color --------------------
+		Color color= store.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT)
+			? null
+			: createColor(store, AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND, styledText.getDisplay());
+		styledText.setForeground(color);
+			
+		if (fForegroundColor != null) {
+			fForegroundColor.dispose();
+		}
+		
+		fForegroundColor= color;
+		
+		// ---------- background color ----------------------
+		color= store.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)
+			? null
+			: createColor(store, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, styledText.getDisplay());
+		styledText.setBackground(color);
+			
+		if (fBackgroundColor != null) {
+			fBackgroundColor.dispose();
+		}
+			
+		fBackgroundColor= color;
+		
+		// ----------- selection foreground color --------------------
+		color= store.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND_SYSTEM_DEFAULT)
+			? null
+			: createColor(store, AbstractTextEditor.PREFERENCE_COLOR_SELECTION_FOREGROUND, styledText.getDisplay());
+		styledText.setSelectionForeground(color);
+			
+		if (fSelectionForegroundColor != null) {
+			fSelectionForegroundColor.dispose();
+		}
+		
+		fSelectionForegroundColor= color;
+		
+		// ---------- selection background color ----------------------
+		color= store.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND_SYSTEM_DEFAULT)
+			? null
+			: createColor(store, AbstractTextEditor.PREFERENCE_COLOR_SELECTION_BACKGROUND, styledText.getDisplay());
+		styledText.setSelectionBackground(color);
+			
+		if (fSelectionBackgroundColor != null) {
+			fSelectionBackgroundColor.dispose();
+		}
+			
+		fSelectionBackgroundColor= color;
+	}
+	
+	/**
+	 * Creates a color from the information stored in the given preference store.
+	 * Returns <code>null</code> if there is no such information available.
+	 * 
+	 * @param store the store to read from
+	 * @param key the key used for the lookup in the preference store
+	 * @param display the display used create the color
+	 * @return the created color according to the specification in the preference store
+	 * @since 2.0
+	 */
+	private Color createColor(IPreferenceStore store, String key, Display display) {
+	
+		RGB rgb= null;		
+		
+		if (store.contains(key)) {
+			
+			if (store.isDefault(key))
+				rgb= PreferenceConverter.getDefaultColor(store, key);
+			else
+				rgb= PreferenceConverter.getColor(store, key);
+		
+			if (rgb != null)
+				return new Color(display, rgb);
+		}
+		
+		return null;
+	}
+
+	public void dispose() {
+		if (fForegroundColor != null) {
+			fForegroundColor.dispose();
+			fForegroundColor= null;
+		}
+		
+		if (fBackgroundColor != null) {
+			fBackgroundColor.dispose();
+			fBackgroundColor= null;
+		}
+		
+		if (fSelectionForegroundColor != null) {
+			fSelectionForegroundColor.dispose();
+			fSelectionForegroundColor= null;
+		}
+		
+		if (fSelectionBackgroundColor != null) {
+			fSelectionBackgroundColor.dispose();
+			fSelectionBackgroundColor= null;
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesPage.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesPage.java
new file mode 100644
index 0000000..3828ef3
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesPage.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.Property;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Preference page for setting global Ant user properties.
+ * All properties specified here will be set as user properties on the 
+ * project for any Ant build
+ */
+public class AntPropertiesPage implements IAntBlockContainer {
+	
+	private AntPropertiesBlock antPropertiesBlock= new AntPropertiesBlock(this);
+	private AntRuntimePreferencePage preferencePage;
+	
+	/**
+	 * Creates an instance.
+	 */
+	public AntPropertiesPage(AntRuntimePreferencePage preferencePage) {
+		this.preferencePage= preferencePage;
+	}
+	
+	/**
+	 * Creates the tab item that contains this sub-page.
+	 */
+	protected TabItem createTabItem(TabFolder folder) {
+		TabItem item = new TabItem(folder, SWT.NONE);
+		item.setText(AntPreferencesMessages.AntPropertiesPage_title);
+		item.setImage(AntObjectLabelProvider.getPropertyImage());
+		item.setData(this);
+		item.setControl(createContents(folder));
+		return item;
+	}
+	
+	protected Composite createContents(Composite parent) {
+		Font font = parent.getFont();
+		
+		Composite top = new Composite(parent, SWT.NONE);
+		top.setFont(font);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(top, IAntUIHelpContextIds.ANT_PROPERTIES_PAGE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns= 2;
+		top.setLayout(layout);
+		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+		top.setLayoutData(gridData); 
+				
+		antPropertiesBlock.createControl(top, AntPreferencesMessages.AntPropertiesPage__Global_properties__1, AntPreferencesMessages.AntPropertiesPage_Glo_bal_property_files__2);
+		
+		return top;
+	}
+	
+	/**
+	 * Sets the contents of the tables on this page.
+	 */
+	protected void initialize() {
+		List allProperties= AntCorePlugin.getPlugin().getPreferences().getDefaultProperties();
+		allProperties.addAll(Arrays.asList(AntCorePlugin.getPlugin().getPreferences().getCustomProperties()));
+		antPropertiesBlock.setPropertiesInput((Property[]) allProperties.toArray(new Property[allProperties.size()]));
+		antPropertiesBlock.setPropertyFilesInput(AntCorePlugin.getPlugin().getPreferences().getCustomPropertyFiles(false));
+		antPropertiesBlock.update();
+	}
+	
+	protected void performDefaults() {
+		List defaultProperties= AntCorePlugin.getPlugin().getPreferences().getDefaultProperties();
+		antPropertiesBlock.setPropertiesInput((Property[]) defaultProperties.toArray(new Property[defaultProperties.size()]));
+		antPropertiesBlock.setPropertyFilesInput(new String[0]);
+		antPropertiesBlock.update();
+	}
+	
+	/**
+	 * Delegates to saving any additional table settings when the page is closed
+	 * 
+	 * @since 3.5
+	 */
+	public void saveAdditionalSettings() {
+		antPropertiesBlock.saveSettings();
+	}
+	
+	/**
+	 * Returns the specified property files
+	 * 
+	 * @return String[]
+	 */
+	protected String[] getPropertyFiles() {
+		Object[] elements = antPropertiesBlock.getPropertyFiles();
+		String[] files= new String[elements.length];
+		for (int i = 0; i < elements.length; i++) {
+			files[i] = (String)elements[i];
+		}
+		return files;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#setMessage(java.lang.String)
+	 */
+	public void setMessage(String message) {
+		preferencePage.setMessage(message);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#setErrorMessage(java.lang.String)
+	 */
+	public void setErrorMessage(String message) {
+		preferencePage.setErrorMessage(message);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#createPushButton(org.eclipse.swt.widgets.Composite, java.lang.String)
+	 */
+	public Button createPushButton(Composite parent, String buttonText) {
+		Button button = new Button(parent, SWT.PUSH);
+		button.setFont(parent.getFont());
+		button.setText(buttonText);
+		preferencePage.setButtonLayoutData(button);
+		return button;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.IAntBlockContainer#update()
+	 */
+	public void update() {
+	}
+	
+	protected List getProperties() {
+		Object[] allProperties= antPropertiesBlock.getProperties();
+		List properties= new ArrayList(allProperties.length);
+		for (int i = 0; i < allProperties.length; i++) {
+			Property property = (Property)allProperties[i];
+			if (!property.isDefault()) {
+				properties.add(property);
+			}
+		}
+		return properties;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntRuntimePreferencePage.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntRuntimePreferencePage.java
new file mode 100644
index 0000000..f109745
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntRuntimePreferencePage.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.Property;
+import org.eclipse.ant.core.Task;
+import org.eclipse.ant.core.Type;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Ant preference page to set the classpath, tasks, types and properties.
+ */
+public class AntRuntimePreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+	
+	private AntClasspathPage classpathPage;
+	private AntTasksPage tasksPage;
+	private AntTypesPage typesPage;
+	private AntPropertiesPage propertiesPage;
+	
+	/**
+	 * Creates the preference page
+	 */
+	public AntRuntimePreferencePage() {
+		setDescription(AntPreferencesMessages.AntPreferencePage_description);
+		setPreferenceStore(AntUIPlugin.getDefault().getPreferenceStore());
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+	 */
+	public void init(IWorkbench workbench) {
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createContents(Composite parent) {
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IAntUIHelpContextIds.ANT_RUNTIME_PREFERENCE_PAGE);
+		initializeDialogUnits(parent);
+
+		TabFolder folder = new TabFolder(parent, SWT.NONE);
+		folder.setLayout(new TabFolderLayout());	
+		folder.setLayoutData(new GridData(GridData.FILL_BOTH));
+		folder.setFont(parent.getFont());
+
+		classpathPage = new AntClasspathPage(this);
+		classpathPage.createTabItem(folder);
+		
+		tasksPage = new AntTasksPage(this);
+		tasksPage.createTabItem(folder);
+		
+		typesPage = new AntTypesPage(this);
+		typesPage.createTabItem(folder);
+
+		propertiesPage= new AntPropertiesPage(this);
+		propertiesPage.createTabItem(folder);
+		
+		tasksPage.initialize();
+		typesPage.initialize();
+		classpathPage.initialize();
+		propertiesPage.initialize();
+
+		return folder;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+	 */
+	protected void performDefaults() {
+		super.performDefaults();
+		
+		AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
+		tasksPage.setInput(prefs.getDefaultTasks());
+		typesPage.setInput(prefs.getDefaultTypes());
+		classpathPage.performDefaults();
+		propertiesPage.performDefaults();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+	 */
+	public boolean performOk() {
+		AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
+		IDialogSettings settings = AntUIPlugin.getDefault().getDialogSettings();
+		
+		prefs.setAntHomeClasspathEntries(classpathPage.getAntHomeEntries());
+		
+		
+		prefs.setAdditionalClasspathEntries(classpathPage.getAdditionalEntries());
+		
+		String antHome= classpathPage.getAntHome();
+		prefs.setAntHome(antHome);
+		
+		List contents = tasksPage.getContents(false);
+		if (contents != null) {
+			Task[] tasks = (Task[]) contents.toArray(new Task[contents.size()]);
+			prefs.setCustomTasks(tasks);
+		}
+		
+		tasksPage.saveColumnSettings(settings);
+		
+		contents = typesPage.getContents(false);
+		if (contents != null) {
+			Type[] types = (Type[]) contents.toArray(new Type[contents.size()]);
+			prefs.setCustomTypes(types);
+		}
+		
+		typesPage.saveColumnSettings(settings);
+		
+		contents = propertiesPage.getProperties();
+		if (contents != null) {
+			Property[] properties = (Property[]) contents.toArray(new Property[contents.size()]);
+			prefs.setCustomProperties(properties);
+		}
+		
+		String[] files = propertiesPage.getPropertyFiles();
+		prefs.setCustomPropertyFiles(files);
+		
+		propertiesPage.saveAdditionalSettings();
+		
+		prefs.updatePluginPreferences();
+	
+		return super.performOk();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.DialogPage#setButtonLayoutData(org.eclipse.swt.widgets.Button)
+	 */
+	protected GridData setButtonLayoutData(Button button) {
+		return super.setButtonLayoutData(button);
+	}
+	
+	protected List getLibraryEntries() {
+		List urls= new ArrayList();
+		urls.addAll(Arrays.asList(classpathPage.getAntHomeEntries()));
+		urls.addAll(Arrays.asList(classpathPage.getAdditionalEntries()));
+		urls.addAll(Arrays.asList(classpathPage.getContributedEntries()));
+		return urls;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntTasksPage.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntTasksPage.java
new file mode 100644
index 0000000..688592e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntTasksPage.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.Task;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+/**
+ * Sub-page that allows the user to enter custom tasks
+ * to be used when running Ant build files.
+ */
+public class AntTasksPage extends AntPage {
+    
+	/**
+	 * Creates an instance.
+	 */
+	public AntTasksPage(AntRuntimePreferencePage preferencePage) {
+		super(preferencePage);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.AntPage#addButtonsToButtonGroup(org.eclipse.swt.widgets.Composite)
+	 */
+	protected void addButtonsToButtonGroup(Composite parent) {
+		createPushButton(parent, AntPreferencesMessages.AntTasksPage_1, ADD_BUTTON);
+		editButton = createPushButton(parent, AntPreferencesMessages.AntTasksPage_2, EDIT_BUTTON);
+		removeButton = createPushButton(parent, AntPreferencesMessages.AntTasksPage_3, REMOVE_BUTTON);
+	}
+	
+	/**
+	 * Allows the user to enter a custom task.
+	 */
+	protected void add() {
+		String title = AntPreferencesMessages.AntTasksPage_addTaskDialogTitle;
+		AddCustomDialog dialog = getCustomDialog(title, IAntUIHelpContextIds.ADD_TASK_DIALOG);
+		if (dialog.open() == Window.CANCEL) {
+			return;
+		}
+
+		Task task = new Task();
+		task.setTaskName(dialog.getName());
+		task.setClassName(dialog.getClassName());
+		task.setLibraryEntry(dialog.getLibraryEntry());
+		addContent(task);
+	}
+	
+	private AddCustomDialog getCustomDialog(String title, String helpContext) {
+		Iterator tasks= getContents(true).iterator();
+		List names= new ArrayList();
+		while (tasks.hasNext()) {
+			Task task = (Task) tasks.next();
+			names.add(task.getTaskName());	
+		}
+		AddCustomDialog dialog = new AddCustomDialog(getShell(), getPreferencePage().getLibraryEntries(), names, helpContext);
+		dialog.setTitle(title);
+		dialog.setAlreadyExistsErrorMsg(AntPreferencesMessages.AntTasksPage_8);
+		dialog.setNoNameErrorMsg(AntPreferencesMessages.AntTasksPage_9);
+		return dialog;
+	}
+	
+	/**
+	 * Creates the tab item that contains this sub-page.
+	 */
+	protected TabItem createTabItem(TabFolder folder) {
+		TabItem item = new TabItem(folder, SWT.NONE);
+		item.setText(AntPreferencesMessages.AntTasksPage_title);
+		item.setImage(AntObjectLabelProvider.getTaskImage());
+		item.setData(this);
+		Composite top = new Composite(folder, SWT.NONE);
+		top.setFont(folder.getFont());
+		item.setControl(createContents(top));
+		
+		connectToFolder(item, folder);
+		
+		return item;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.AntPage#edit(org.eclipse.jface.viewers.IStructuredSelection)
+	 */
+	protected void edit(IStructuredSelection selection) {
+		Task task= (Task)selection.getFirstElement();
+		String title = AntPreferencesMessages.AntTasksPage_editTaskDialogTitle;
+		AddCustomDialog dialog = getCustomDialog(title, IAntUIHelpContextIds.EDIT_TASK_DIALOG);
+		dialog.setClassName(task.getClassName());
+		dialog.setName(task.getTaskName());
+		dialog.setLibraryEntry(task.getLibraryEntry());
+		if (dialog.open() == Window.CANCEL) {
+			return;
+		}
+
+		task.setTaskName(dialog.getName());
+		task.setClassName(dialog.getClassName());
+		task.setLibraryEntry(dialog.getLibraryEntry());
+		updateContent(task);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.AntPage#initialize()
+	 */
+	protected void initialize() {
+		AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
+		setInput(prefs.getTasks());
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.AntPage#getHelpContextId()
+	 */
+	protected String getHelpContextId() {
+		return IAntUIHelpContextIds.ANT_TASKS_PAGE;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntTypesPage.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntTypesPage.java
new file mode 100644
index 0000000..9bb971c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntTypesPage.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.core.AntCorePreferences;
+import org.eclipse.ant.core.Type;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+/**
+ * Sub-page that allows the user to enter custom types
+ * to be used when running Ant build files.
+ */
+public class AntTypesPage extends AntPage {
+    
+	/**
+	 * Creates an instance.
+	 */
+	public AntTypesPage(AntRuntimePreferencePage preferencePage) {
+		super(preferencePage);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.AntPage#addButtonsToButtonGroup(org.eclipse.swt.widgets.Composite)
+	 */
+	protected void addButtonsToButtonGroup(Composite parent) {
+		createPushButton(parent, AntPreferencesMessages.AntTypesPage_2, ADD_BUTTON);
+		editButton = createPushButton(parent, AntPreferencesMessages.AntTypesPage_3, EDIT_BUTTON);
+		removeButton = createPushButton(parent, AntPreferencesMessages.AntTypesPage_1, REMOVE_BUTTON);
+	}
+	
+	/**
+	 * Allows the user to enter a custom type.
+	 */
+	protected void add() {
+		String title = AntPreferencesMessages.AntTypesPage_addTypeDialogTitle;
+		AddCustomDialog dialog = getCustomDialog(title, IAntUIHelpContextIds.ADD_TYPE_DIALOG);
+		if (dialog.open() == Window.CANCEL) {
+			return;
+		}
+
+		Type type = new Type();
+		type.setTypeName(dialog.getName());
+		type.setClassName(dialog.getClassName());
+		type.setLibraryEntry(dialog.getLibraryEntry());
+		addContent(type);
+	}
+	
+	/**
+	 * Creates the tab item that contains this sub-page.
+	 */
+	protected TabItem createTabItem(TabFolder folder) {
+		TabItem item = new TabItem(folder, SWT.NONE);
+		item.setText(AntPreferencesMessages.AntTypesPage_typesPageTitle);
+		item.setImage(AntObjectLabelProvider.getTypeImage());
+		item.setData(this);
+		Composite top = new Composite(folder, SWT.NONE);
+		top.setFont(folder.getFont());			
+		item.setControl(createContents(top));
+		
+		connectToFolder(item, folder);
+				
+		return item;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.AntPage#edit(org.eclipse.jface.viewers.IStructuredSelection)
+	 */
+	protected void edit(IStructuredSelection selection) {
+		Type type = (Type) selection.getFirstElement();
+		String title = AntPreferencesMessages.AntTypesPage_editTypeDialogTitle;
+		AddCustomDialog dialog = getCustomDialog(title, IAntUIHelpContextIds.EDIT_TYPE_DIALOG);
+		dialog.setClassName(type.getClassName());
+		dialog.setName(type.getTypeName());
+		dialog.setLibraryEntry(type.getLibraryEntry());
+		if (dialog.open() == Window.CANCEL) {
+			return;
+		}
+
+		type.setTypeName(dialog.getName());
+		type.setClassName(dialog.getClassName());
+		type.setLibraryEntry(dialog.getLibraryEntry());
+		updateContent(type);
+	}
+	
+	private AddCustomDialog getCustomDialog(String title, String helpContext) {
+		Iterator types= getContents(true).iterator();
+		List names= new ArrayList();
+		while (types.hasNext()) {
+			Type aTask = (Type) types.next();
+			names.add(aTask.getTypeName());
+		}
+		
+		AddCustomDialog dialog = new AddCustomDialog(getShell(), getPreferencePage().getLibraryEntries(), names, helpContext);
+		dialog.setTitle(title);
+		dialog.setAlreadyExistsErrorMsg(AntPreferencesMessages.AntTypesPage_8);
+		dialog.setNoNameErrorMsg(AntPreferencesMessages.AntTypesPage_9);
+		return dialog;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.AntPage#initialize()
+	 */
+	protected void initialize() {
+		AntCorePreferences prefs= AntCorePlugin.getPlugin().getPreferences();
+		setInput(prefs.getTypes());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ant.internal.ui.preferences.AntPage#getHelpContextId()
+	 */
+	protected String getHelpContextId() {
+		return IAntUIHelpContextIds.ANT_TYPES_PAGE;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/ClasspathModel.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/ClasspathModel.java
new file mode 100644
index 0000000..d133aab
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/ClasspathModel.java
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.preferences;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.ant.core.IAntClasspathEntry;
+
+public class ClasspathModel extends AbstractClasspathEntry {
+	
+	public static final int ANT_HOME= 0;
+	public static final int GLOBAL_USER= 1;
+	public static final int USER= 2;
+    public static final int CONTRIBUTED= 3;
+	
+	private GlobalClasspathEntries fAntHomeEntry;
+	private GlobalClasspathEntries fUserGlobalEntry;
+    private GlobalClasspathEntries fContributedGlobalEntry;
+	
+	public Object addEntry(Object entry) {
+		if (entry instanceof GlobalClasspathEntries) {
+			if (!fChildEntries.contains(entry)) {
+				fChildEntries.add(entry);
+				return entry;
+			}
+			return null;
+		} 
+		ClasspathEntry newEntry= createEntry(entry, null);
+		Iterator entries= fChildEntries.iterator();
+		while (entries.hasNext()) {
+			Object element = entries.next();
+			if (element instanceof GlobalClasspathEntries) {
+				if(((GlobalClasspathEntries)element).contains(newEntry)) {
+					return null;
+				}
+			} else if (element.equals(newEntry)) {
+				return null;
+			}
+		}
+		fChildEntries.add(newEntry);
+		return newEntry;
+	}
+	
+	public Object addEntry(int entryType, Object entry) {
+		IClasspathEntry entryParent= null;
+		switch (entryType) {
+			case ANT_HOME :
+				if (fAntHomeEntry == null) {
+					String name= AntPreferencesMessages.ClasspathModel_2;
+					fAntHomeEntry= createGlobalEntry(new IAntClasspathEntry[0], name, false, true, ANT_HOME);
+				}
+				entryParent= fAntHomeEntry;
+				break;
+			case GLOBAL_USER :
+				if (fUserGlobalEntry == null) {
+					String name= AntPreferencesMessages.ClasspathModel_3;
+					fUserGlobalEntry= createGlobalEntry(new IAntClasspathEntry[0], name, true, true, GLOBAL_USER);
+				}
+				entryParent= fUserGlobalEntry;
+				break;
+            case CONTRIBUTED :
+                if (fContributedGlobalEntry == null) {
+                    String name= AntPreferencesMessages.ClasspathModel_0;
+                    fContributedGlobalEntry= createGlobalEntry(new IAntClasspathEntry[0], name, true, true, CONTRIBUTED);
+                }
+                entryParent= fContributedGlobalEntry;
+                break;
+			default :
+				break;
+		}
+			
+		ClasspathEntry newEntry= createEntry(entry, entryParent);
+		Iterator entries= fChildEntries.iterator();
+		while (entries.hasNext()) {
+			Object element = entries.next();
+			if (element instanceof GlobalClasspathEntries) {
+				if(((GlobalClasspathEntries)element).contains(newEntry)) {
+					return null;
+				}
+			} else if (element.equals(newEntry)) {
+				return null;
+			}
+		}
+		if (entryParent != null) {
+			((GlobalClasspathEntries)entryParent).addEntry(newEntry);
+		} else {
+			fChildEntries.add(newEntry);
+		}
+		return newEntry;		
+	}
+	
+	/**
+	 * Returns entries of the specified kind, possibly empty.
+	 * 
+	 * @param entryType kind of entries to retrieve
+	 * @return entries of the specified kind, possibly empty
+	 */
+	public IAntClasspathEntry[] getEntries(int entryType) {
+		switch (entryType) {
+			case ANT_HOME :
+				if (fAntHomeEntry != null) {
+					return fAntHomeEntry.getEntries();
+				}
+				break;
+			case GLOBAL_USER :
+				if (fUserGlobalEntry != null) {
+					return fUserGlobalEntry.getEntries();
+				}
+				break;
+			case USER : 
+				return getUserEntries();
+			case CONTRIBUTED : 
+				if (fContributedGlobalEntry != null) {
+					return fContributedGlobalEntry.getEntries();
+				}
+				break;
+		}
+		return new IAntClasspathEntry[0];
+	}
+	
+	public void remove(Object entry) {
+		fChildEntries.remove(entry);
+		if (entry == fUserGlobalEntry) {
+			fUserGlobalEntry= null;
+		}
+	}
+	
+	public ClasspathEntry createEntry(Object entry, IClasspathEntry entryParent) {
+		if (entryParent == null) {
+			entryParent= this;
+		} 
+		return new ClasspathEntry(entry, entryParent);
+	}
+
+	public void removeAll() {
+		if (fAntHomeEntry != null) {
+			fAntHomeEntry.removeAll();
+		} 
+		if (fUserGlobalEntry != null) {
+			fUserGlobalEntry.removeAll();
+		}
+	}
+	
+	public void removeAll(int entryType) {
+		switch (entryType) {
+			case ANT_HOME :
+				if (fAntHomeEntry != null) {
+					fAntHomeEntry.removeAll();
+				}
+				break;
+			case GLOBAL_USER :
+				if (fUserGlobalEntry != null) {
+					fUserGlobalEntry.removeAll();
+				}
+				break;
+			default :
+				break;
+		}
+	}
+	
+	public void removeAll(Object[] entries) {
+		
+		for (int i = 0; i < entries.length; i++) {
+			Object object = entries[i];
+			if (object instanceof ClasspathEntry) {
+				IClasspathEntry entryParent= ((ClasspathEntry)object).getParent();
+				if (entryParent instanceof GlobalClasspathEntries) {
+					((GlobalClasspathEntries)entryParent).removeEntry((ClasspathEntry) object);
+				} else {
+					remove(object);
+				}
+			} else {
+				remove(object);
+			}
+		}
+	}
+
+	public void setAntHomeEntries(IAntClasspathEntry[] entries) {
+		if (fAntHomeEntry == null) {
+			String name= AntPreferencesMessages.ClasspathModel_2;
+			fAntHomeEntry= createGlobalEntry(entries, name, false, true, ANT_HOME);
+		} else {
+			fAntHomeEntry.removeAll();
+			for (int i = 0; i < entries.length; i++) {
+				fAntHomeEntry.addEntry(new ClasspathEntry(entries[i], fAntHomeEntry));
+			}
+		}
+	}
+
+	private GlobalClasspathEntries createGlobalEntry(IAntClasspathEntry[] entries, String name, boolean canBeRemoved, boolean addEntry, int type) {
+		
+		GlobalClasspathEntries global= new GlobalClasspathEntries(name, this, canBeRemoved, type);
+		
+		for (int i = 0; i < entries.length; i++) {
+			global.addEntry(new ClasspathEntry(entries[i], global));
+		}
+		
+		if (addEntry) {
+			addEntry(global);
+		}
+		return global;
+	}
+
+	public void setGlobalEntries(IAntClasspathEntry[] entries) {
+		if (fUserGlobalEntry == null) {
+			String name= AntPreferencesMessages.ClasspathModel_3;
+			fUserGlobalEntry= createGlobalEntry(entries, name, true, true, GLOBAL_USER);
+		} else {
+			fUserGlobalEntry.removeAll();
+			for (int i = 0; i < entries.length; i++) {
+				fUserGlobalEntry.addEntry(new ClasspathEntry(entries[i], fUserGlobalEntry));
+			}
+		}
+	}
+    
+    public void setContributedEntries(IAntClasspathEntry[] entries) {
+        if (fContributedGlobalEntry == null) {
+            String name= AntPreferencesMessages.ClasspathModel_0;
+            fContributedGlobalEntry= createGlobalEntry(entries, name, false, true, CONTRIBUTED);
+        } else {
+            fContributedGlobalEntry.removeAll();
+            for (int i = 0; i < entries.length; i++) {
+                fContributedGlobalEntry.addEntry(new ClasspathEntry(entries[i], fContributedGlobalEntry));
+            }
+        }
+    }
+	
+	private IAntClasspathEntry[] getUserEntries() {
+		List userEntries= new ArrayList(fChildEntries.size());
+		Iterator itr= fChildEntries.iterator();
+		while (itr.hasNext()) {
+			IClasspathEntry element = (IClasspathEntry) itr.next();
+			if (element instanceof GlobalClasspathEntries) {
+				continue;
+			}
+			userEntries.add(element);
+		}
+		return (IAntClasspathEntry[])userEntries.toArray(new IAntClasspathEntry[userEntries.size()]);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/ColorEditor.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/ColorEditor.java
new file mode 100644
index 0000000..05552fb
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/ColorEditor.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.ColorDialog;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.jface.resource.JFaceResources;
+
+/**
+ * A "button" of a certain color determined by the color picker
+ */
+public class ColorEditor {
+	
+	private Point fExtent;
+	private Image fImage;
+	private RGB fColorValue;
+	private Color fColor;
+	private Button fButton;
+	
+	public ColorEditor(Composite parent) {
+		
+		fButton= new Button(parent, SWT.PUSH);
+		fExtent= computeImageSize(parent);
+		fImage= new Image(parent.getDisplay(), fExtent.x, fExtent.y);
+		
+		GC gc= new GC(fImage);
+		gc.setBackground(fButton.getBackground());
+		gc.fillRectangle(0, 0, fExtent.x, fExtent.y);
+		gc.dispose();
+		
+		fButton.setImage(fImage);
+		fButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				ColorDialog colorDialog= new ColorDialog(fButton.getShell());
+				colorDialog.setRGB(fColorValue);
+				RGB newColor = colorDialog.open();
+				if (newColor != null) {
+					fColorValue= newColor;
+					updateColorImage();
+				}
+			}
+		});
+		
+		fButton.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent event) {
+				if (fImage != null)  {
+					fImage.dispose();
+					fImage= null;
+				}
+				if (fColor != null) {
+					fColor.dispose();
+					fColor= null;
+				}
+			}
+		});
+	}
+	
+	public RGB getColorValue() {
+		return fColorValue;
+	}
+	
+	public void setColorValue(RGB rgb) {
+		fColorValue= rgb;
+		updateColorImage();
+	}
+	
+	public Button getButton() {
+		return fButton;
+	}
+	
+	protected void updateColorImage() {
+		
+		Display display= fButton.getDisplay();
+		
+		GC gc= new GC(fImage);
+		gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
+		gc.drawRectangle(0, 2, fExtent.x - 1, fExtent.y - 4);
+		
+		if (fColor != null)
+			fColor.dispose();
+			
+		fColor= new Color(display, fColorValue);
+		gc.setBackground(fColor);
+		gc.fillRectangle(1, 3, fExtent.x - 2, fExtent.y - 5);
+		gc.dispose();
+		
+		fButton.setImage(fImage);
+	}
+	
+	protected Point computeImageSize(Control window) {
+		GC gc= new GC(window);
+		Font f= JFaceResources.getFontRegistry().get(JFaceResources.DEFAULT_FONT);
+		gc.setFont(f);
+		int height= gc.getFontMetrics().getHeight();
+		gc.dispose();
+		Point p= new Point(height * 3 - 6, height);
+		return p;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/FileFilter.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/FileFilter.java
new file mode 100644
index 0000000..7ed9dde
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/FileFilter.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.preferences;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.swt.custom.BusyIndicator;
+
+public class FileFilter extends ViewerFilter {
+
+	/**
+	 * Objects to filter
+	 */
+	private List fFilter;
+	
+	/**
+	 * Collection of files and containers to display
+	 */
+	private Set fFiles;
+	
+	private String fExtension;
+
+    private boolean fConsiderExtension= true;
+
+	/**
+	 * Creates a new filter that filters the given 
+	 * objects.
+	 * Note: considerExtension must be called to initialize the filter
+	 */
+	public FileFilter(List objects, String extension) {
+		fFilter = objects;
+		fExtension= extension;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+	 */
+	public boolean select(Viewer viewer, Object parentElement, Object element) {
+		return fFiles.contains(element) && !fFilter.contains(element);
+	}
+	
+	/**
+	 * Search for all the matching files in the workspace.
+	 */
+	private void init() {
+		BusyIndicator.showWhile(AntUIPlugin.getStandardDisplay(), new Runnable() {
+			public void run() {
+				fFiles = new HashSet();
+				traverse(ResourcesPlugin.getWorkspace().getRoot(), fFiles);
+			}
+		});
+	}
+
+	/**
+	 * Traverse the given container, adding files to the given set.
+	 * Returns whether any files were added
+	 */
+	private boolean traverse(IContainer container, Set set) {
+		boolean added = false;
+		try {
+			IResource[] resources = container.members();
+			for (int i = 0; i < resources.length; i++) {
+				IResource resource = resources[i];
+				if (resource instanceof IFile) {
+					IFile file = (IFile) resource;
+					String ext = file.getFileExtension();
+					if (!fConsiderExtension || (ext != null && ext.equalsIgnoreCase(fExtension))) {
+						set.add(file);
+						added = true;
+					}
+				} else if (resource instanceof IContainer) {
+					if (traverse((IContainer) resource, set)) {
+						set.add(resource);
+						added = true;
+					}
+				}
+			}
+		} catch (CoreException e) {
+		}
+		return added;
+	}
+	
+	/**
+	 * Sets whether this filter will filter based on extension.
+	 * @param considerExtension whether to consider a file's extension when filtering
+	 */
+	public void considerExtension(boolean considerExtension) {
+	    fConsiderExtension= considerExtension;
+	    init();
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/FormatPreviewCode.txt b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/FormatPreviewCode.txt
new file mode 100644
index 0000000..03b202c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/FormatPreviewCode.txt
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ================================================ -->
+<!--  Sample buildfile for jar components             -->
+<!--                                                  -->
+<!-- ================================================ -->
+<project name="sample" default="build">
+
+	<!-- - - - - - - - - - - - - - -->
+	<!--  target: init             -->
+	<!-- - - - - - - - - - - - - - -->
+	<target name="init">
+		<property name="${eclipse.home}" location="/home/eclipse" />
+	</target>
+
+	<!-- ========================= -->
+	<!--   target: build           -->
+	<!-- ========================= -->
+	<target name="build"
+	        depends="init"
+	        description="--> compile and jar this component">
+
+		<javac srcdir="${src.home}"
+		       destdir="${build.home}"
+		       debug="${compile.debug}"
+		       deprecation="${compile.deprecation}"
+		       optimize="${compile.optimize}">
+			<classpath refid="compile.classpath" />
+		</javac>
+
+		<jar destfile="${dist.home}/${app.name}.jar"
+		     basedir="${build.home}"
+		     excludes="**/*UT.class" />
+	</target>
+
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/GlobalClasspathEntries.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/GlobalClasspathEntries.java
new file mode 100644
index 0000000..af44926
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/GlobalClasspathEntries.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.preferences;
+
+import java.util.List;
+
+public class GlobalClasspathEntries extends AbstractClasspathEntry {
+	private String fName;
+	private int fType;
+	private boolean fCanBeRemoved= true;
+	
+	public GlobalClasspathEntries(String name, IClasspathEntry parent, boolean canBeRemoved, int type) {
+		fParent= parent;
+		fName= name;
+		fCanBeRemoved= canBeRemoved;
+		fType= type;
+	}
+		
+	public void addEntry(ClasspathEntry entry) {
+		fChildEntries.add(entry);
+	}
+	
+	public void removeEntry(ClasspathEntry entry) {
+		fChildEntries.remove(entry);
+	}
+	
+	public boolean contains(ClasspathEntry entry) {
+		return fChildEntries.contains(entry);
+	}
+	
+	public String toString() {
+		return fName;
+	}
+
+	public void removeAll() {
+		fChildEntries.clear();
+	}
+	
+	public boolean canBeRemoved() {
+		return fCanBeRemoved;
+	}
+
+	/**
+     * Set the child entries of this classpath entry.
+	 * @param entries The child entries.
+	 */
+	public void setEntries(List entries) {
+		fChildEntries= entries;
+	}
+	/**
+	 * @return Returns the type of this global classpath entry.
+	 * @see ClasspathModel#ANT_HOME
+	 * @see ClasspathModel#GLOBAL_USER
+	 * @see ClasspathModel#CONTRIBUTED
+	 */
+	public int getType() {
+		return fType;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/IAntBlockContainer.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/IAntBlockContainer.java
new file mode 100644
index 0000000..108279f
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/IAntBlockContainer.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+public interface IAntBlockContainer {
+	
+	/**
+	 * Sets the error message for the container.
+	 * May be <code>null</code> to remove the error message.
+	 * 
+	 * @param message A string error message or <code>null</code>
+	 */
+	public void setErrorMessage(String message);
+	
+	/**
+	 * Sets the message for the container.
+	 * May be <code>null</code> to remove the message.
+	 * 
+	 * @param message A string message or <code>null</code>
+	 */
+	public void setMessage(String message);
+	
+	/**
+	 * Creates and returns a properly configured push button with 
+	 * the supplied label
+	 * 
+	 * @param parent The composite parent of the button
+	 * @param label The button label
+	 * 
+	 * @return button the created button
+	 */
+	public Button createPushButton(Composite parent, String label);
+	
+	/**
+	 * Notifies the container that state has changed.
+	 */
+	public void update();
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/IClasspathEntry.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/IClasspathEntry.java
new file mode 100644
index 0000000..8b291e3
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/IClasspathEntry.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.preferences;
+
+import org.eclipse.ant.core.IAntClasspathEntry;
+
+public interface IClasspathEntry extends IAntClasspathEntry {
+	
+	/**
+	 * Returns the classpath entries that are the children of this classpath entry
+	 * 
+	 * @return the child classpath entries of this entry
+	 */
+	public IAntClasspathEntry[] getEntries();
+	
+	/**
+	 * Returns whether this classpath entries has child entries.
+	 * 
+	 * @return whether <code>true</code> if this classpath entry has childern, <code>false</code> otherwise.
+	 */
+	public boolean hasEntries();
+	
+	/**
+	 * Returns the parent of this classpath entry
+	 * 
+	 * @return the parent of this classpath entry, or <code>null</code> if none.
+	 */
+	public IClasspathEntry getParent();
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/MinimizedFileSystemElement.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/MinimizedFileSystemElement.java
new file mode 100644
index 0000000..52b537f
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/MinimizedFileSystemElement.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
+
+class MinimizedFileSystemElement implements IWorkbenchAdapter, IAdaptable {
+	private boolean populated = false;
+	private List folders = null;
+	private List files = null;
+	private String name;
+	private boolean isDirectory = false;
+	private MinimizedFileSystemElement parent;
+	private Object fileSystemObject;
+	
+	/**
+	 * Create a <code>MinimizedFileSystemElement</code> with the supplied name and parent.
+	 * @param name the name of the file element this represents
+	 * @param parent the containing parent
+	 * @param isDirectory indicated if this could have children or not
+	 */
+	public MinimizedFileSystemElement(String name, MinimizedFileSystemElement parent, boolean isDirectory) {
+		this.name = name;
+		this.parent = parent;
+		this.isDirectory = isDirectory;
+		if (parent != null) {
+			parent.addChild(this);
+		}
+	}
+	
+	/**
+	 * Returns the adapter
+	 */
+	public Object getAdapter(Class adapter) {
+		if (adapter == IWorkbenchAdapter.class) {
+			return this;
+		}
+		//defer to the platform
+		return Platform.getAdapterManager().getAdapter(this, adapter);
+	}
+	
+	/**
+	 * Returns true if this element represents a directory, and false
+	 * otherwise.
+	 */
+	public boolean isDirectory() {
+		return isDirectory;
+	}
+	
+	/**
+	 * Adds the passed child to this object's collection of children.
+	 *
+	 * @param child MinimizedFileSystemElement
+	 */
+	private void addChild(MinimizedFileSystemElement child) {
+		if (child.isDirectory()) {
+			if (folders == null) {
+				 folders = new ArrayList(1);
+			}
+			folders.add(child);
+		} else {
+			if (files == null) {
+				 files = new ArrayList(1);
+			}
+			files.add(child);
+		}
+	}
+	/**
+	 * Returns a list of the files that are immediate children. Use the supplied provider
+	 * if it needs to be populated.
+	 */
+	protected List getFiles(IImportStructureProvider provider) {
+		if (!populated) {
+			populate(provider);
+		}
+
+		if (files == null) {
+			 return Collections.EMPTY_LIST;
+		}
+		return files;
+
+	}
+	/**
+	 * Returns a list of the folders that are immediate children. Use the supplied provider
+	 * if it needs to be populated.
+	 */
+	protected List getFolders(IImportStructureProvider provider) {
+		if (!populated) {
+			populate(provider);
+		}
+
+		return getFolders();
+
+	}
+
+	protected List getFolders() {
+		if (folders == null){
+			 return Collections.EMPTY_LIST;
+		}
+		return folders;
+	}
+	/**
+	 * Return whether or not population has happened for the receiver.
+	 */
+	protected boolean isPopulated() {
+		return this.populated;
+	}
+	/**
+	 * Return whether or not population has not happened for the receiver.
+	 */
+	protected boolean notPopulated() {
+		return !this.populated;
+	}
+	/**
+	 * Populate the files and folders of the receiver using the supplied
+	 * structure provider.
+	 * @param provider org.eclipse.ui.wizards.datatransfer.IImportStructureProvider
+	 */
+	private void populate(IImportStructureProvider provider) {
+
+		List children = provider.getChildren(fileSystemObject);
+		if (children == null) {
+			children = new ArrayList(1);
+		}
+		Iterator childrenEnum = children.iterator();
+		while (childrenEnum.hasNext()) {
+			Object child = childrenEnum.next();
+
+			String elementLabel = provider.getLabel(child);
+			boolean isFolder= provider.isFolder(child);
+			if (!isFolder && !elementLabel.endsWith(".class")) { //$NON-NLS-1$
+				continue;
+			}
+			//Create one level below
+			MinimizedFileSystemElement result = new MinimizedFileSystemElement(elementLabel, this, isFolder);
+			result.setFileSystemObject(child);
+		}
+		setPopulated();
+	}
+	
+	/**
+	 *	Returns the file system object property of this element
+	 *
+	 *	@return the file system object
+	 */
+	protected Object getFileSystemObject() {
+		return fileSystemObject;
+	}
+	
+	/**
+	 *	Set the file system object property of this element
+	 *
+	 *	@param value the file system object
+	 */
+	protected void setFileSystemObject(Object value) {
+		fileSystemObject = value;
+	}
+	/**
+	 * Set whether or not population has happened for the receiver to true.
+	 */
+	protected void setPopulated() {
+		this.populated = true;
+	}
+	/**
+	 * @see org.eclipse.ui.model.IWorkbenchAdapter#getChildren(java.lang.Object)
+	 */
+	public Object[] getChildren(Object o) {
+		return getFolders().toArray();
+	}
+
+	/**
+	 * @see org.eclipse.ui.model.IWorkbenchAdapter#getImageDescriptor(java.lang.Object)
+	 */
+	public ImageDescriptor getImageDescriptor(Object object) {
+		if (isDirectory()) {
+			return PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER);
+		}
+		return PlatformUI.getWorkbench().getEditorRegistry().getImageDescriptor(name);
+	}
+
+	/**
+	 * @see org.eclipse.ui.model.IWorkbenchAdapter#getLabel(java.lang.Object)
+	 */
+	public String getLabel(Object o) {
+		return name;
+	}
+
+	/**
+	 * @see org.eclipse.ui.model.IWorkbenchAdapter#getParent(java.lang.Object)
+	 */
+	public Object getParent(Object o) {
+		return parent;
+	}
+
+}
+
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/OverlayPreferenceStore.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/OverlayPreferenceStore.java
new file mode 100644
index 0000000..ed4b7fa
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/OverlayPreferenceStore.java
@@ -0,0 +1,451 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+/**
+ * An overlaying preference store.
+ */
+class OverlayPreferenceStore  implements IPreferenceStore {
+	
+	
+	public static final class TypeDescriptor {
+		private TypeDescriptor() {
+		}
+	}
+	
+	public static final TypeDescriptor BOOLEAN= new TypeDescriptor();
+	public static final TypeDescriptor DOUBLE= new TypeDescriptor();
+	public static final TypeDescriptor FLOAT= new TypeDescriptor();
+	public static final TypeDescriptor INT= new TypeDescriptor();
+	public static final TypeDescriptor LONG= new TypeDescriptor();
+	public static final TypeDescriptor STRING= new TypeDescriptor();
+	
+	public static class OverlayKey {
+		
+		TypeDescriptor fDescriptor;
+		String fKey;
+		
+		public OverlayKey(TypeDescriptor descriptor, String key) {
+			fDescriptor= descriptor;
+			fKey= key;
+		}
+	}
+	
+	private class PropertyListener implements IPropertyChangeListener {
+				
+		/*
+		 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+		 */
+		public void propertyChange(PropertyChangeEvent event) {
+			OverlayKey key= findOverlayKey(event.getProperty());
+			if (key != null)
+				propagateProperty(fParent, key, fStore); 
+		}
+	}
+	
+	
+	private IPreferenceStore fParent;
+	private IPreferenceStore fStore;
+	private OverlayKey[] fOverlayKeys;
+	
+	private PropertyListener fPropertyListener;
+	
+	
+	public OverlayPreferenceStore(IPreferenceStore parent, OverlayKey[] overlayKeys) {
+		fParent= parent;
+		fOverlayKeys= overlayKeys;
+		fStore= new PreferenceStore();
+	}
+	
+	private OverlayKey findOverlayKey(String key) {
+		for (int i= 0; i < fOverlayKeys.length; i++) {
+			if (fOverlayKeys[i].fKey.equals(key))
+				return fOverlayKeys[i];
+		}
+		return null;
+	}
+	
+	private boolean covers(String key) {
+		return (findOverlayKey(key) != null);
+	}
+	
+	private void propagateProperty(IPreferenceStore orgin, OverlayKey key, IPreferenceStore target) {
+		
+		if (orgin.isDefault(key.fKey)) {
+			if (!target.isDefault(key.fKey))
+				target.setToDefault(key.fKey);
+			return;
+		}
+		
+		TypeDescriptor d= key.fDescriptor;
+		if (BOOLEAN == d) {
+			
+			boolean originValue= orgin.getBoolean(key.fKey);
+			boolean targetValue= target.getBoolean(key.fKey);
+			if (targetValue != originValue)
+				target.setValue(key.fKey, originValue);
+				
+		} else if (DOUBLE == d) {
+			
+			double originValue= orgin.getDouble(key.fKey);
+			double targetValue= target.getDouble(key.fKey);
+			if (targetValue != originValue)
+				target.setValue(key.fKey, originValue);
+		
+		} else if (FLOAT == d) {
+			
+			float originValue= orgin.getFloat(key.fKey);
+			float targetValue= target.getFloat(key.fKey);
+			if (targetValue != originValue)
+				target.setValue(key.fKey, originValue);
+				
+		} else if (INT == d) {
+
+			int originValue= orgin.getInt(key.fKey);
+			int targetValue= target.getInt(key.fKey);
+			if (targetValue != originValue)
+				target.setValue(key.fKey, originValue);
+
+		} else if (LONG == d) {
+
+			long originValue= orgin.getLong(key.fKey);
+			long targetValue= target.getLong(key.fKey);
+			if (targetValue != originValue)
+				target.setValue(key.fKey, originValue);
+
+		} else if (STRING == d) {
+
+			String originValue= orgin.getString(key.fKey);
+			String targetValue= target.getString(key.fKey);
+			if (targetValue != null && originValue != null && !targetValue.equals(originValue))
+				target.setValue(key.fKey, originValue);
+
+		}
+	}
+	
+	public void propagate() {
+		for (int i= 0; i < fOverlayKeys.length; i++)
+			propagateProperty(fStore, fOverlayKeys[i], fParent);
+	}
+	
+	private void loadProperty(IPreferenceStore orgin, OverlayKey key, IPreferenceStore target, boolean forceInitialization) {
+		TypeDescriptor d= key.fDescriptor;
+		if (BOOLEAN == d) {
+			
+			if (forceInitialization)
+				target.setValue(key.fKey, true);
+			target.setValue(key.fKey, orgin.getBoolean(key.fKey));
+			target.setDefault(key.fKey, orgin.getDefaultBoolean(key.fKey));
+			
+		} else if (DOUBLE == d) {
+			
+			if (forceInitialization)
+				target.setValue(key.fKey, 1.0D);
+			target.setValue(key.fKey, orgin.getDouble(key.fKey));
+			target.setDefault(key.fKey, orgin.getDefaultDouble(key.fKey));
+			
+		} else if (FLOAT == d) {
+			
+			if (forceInitialization)
+				target.setValue(key.fKey, 1.0F);
+			target.setValue(key.fKey, orgin.getFloat(key.fKey));
+			target.setDefault(key.fKey, orgin.getDefaultFloat(key.fKey));
+			
+		} else if (INT == d) {
+			
+			if (forceInitialization)
+				target.setValue(key.fKey, 1);
+			target.setValue(key.fKey, orgin.getInt(key.fKey));
+			target.setDefault(key.fKey, orgin.getDefaultInt(key.fKey));
+			
+		} else if (LONG == d) {
+			
+			if (forceInitialization)
+				target.setValue(key.fKey, 1L);
+			target.setValue(key.fKey, orgin.getLong(key.fKey));
+			target.setDefault(key.fKey, orgin.getDefaultLong(key.fKey));
+			
+		} else if (STRING == d) {
+			
+			if (forceInitialization)
+				target.setValue(key.fKey, "1"); //$NON-NLS-1$
+			target.setValue(key.fKey, orgin.getString(key.fKey));
+			target.setDefault(key.fKey, orgin.getDefaultString(key.fKey));
+			
+		}
+	}
+	
+	public void load() {
+		for (int i= 0; i < fOverlayKeys.length; i++)
+			loadProperty(fParent, fOverlayKeys[i], fStore, true);
+	}
+	
+	public void loadDefaults() {
+		for (int i= 0; i < fOverlayKeys.length; i++)
+			setToDefault(fOverlayKeys[i].fKey);
+	}
+	
+	public void start() {
+		if (fPropertyListener == null) {
+			fPropertyListener= new PropertyListener();
+			fParent.addPropertyChangeListener(fPropertyListener);
+		}
+	}
+	
+	public void stop() {
+		if (fPropertyListener != null)  {
+			fParent.removePropertyChangeListener(fPropertyListener);
+			fPropertyListener= null;
+		}
+	}
+	
+	/*
+	 * @see IPreferenceStore#addPropertyChangeListener(IPropertyChangeListener)
+	 */
+	public void addPropertyChangeListener(IPropertyChangeListener listener) {
+		fStore.addPropertyChangeListener(listener);
+	}
+	
+	/*
+	 * @see IPreferenceStore#removePropertyChangeListener(IPropertyChangeListener)
+	 */
+	public void removePropertyChangeListener(IPropertyChangeListener listener) {
+		fStore.removePropertyChangeListener(listener);
+	}
+	
+	/*
+	 * @see IPreferenceStore#firePropertyChangeEvent(String, Object, Object)
+	 */
+	public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
+		fStore.firePropertyChangeEvent(name, oldValue, newValue);
+	}
+
+	/*
+	 * @see IPreferenceStore#contains(String)
+	 */
+	public boolean contains(String name) {
+		return fStore.contains(name);
+	}
+	
+	/*
+	 * @see IPreferenceStore#getBoolean(String)
+	 */
+	public boolean getBoolean(String name) {
+		return fStore.getBoolean(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultBoolean(String)
+	 */
+	public boolean getDefaultBoolean(String name) {
+		return fStore.getDefaultBoolean(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultDouble(String)
+	 */
+	public double getDefaultDouble(String name) {
+		return fStore.getDefaultDouble(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultFloat(String)
+	 */
+	public float getDefaultFloat(String name) {
+		return fStore.getDefaultFloat(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultInt(String)
+	 */
+	public int getDefaultInt(String name) {
+		return fStore.getDefaultInt(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultLong(String)
+	 */
+	public long getDefaultLong(String name) {
+		return fStore.getDefaultLong(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDefaultString(String)
+	 */
+	public String getDefaultString(String name) {
+		return fStore.getDefaultString(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getDouble(String)
+	 */
+	public double getDouble(String name) {
+		return fStore.getDouble(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getFloat(String)
+	 */
+	public float getFloat(String name) {
+		return fStore.getFloat(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getInt(String)
+	 */
+	public int getInt(String name) {
+		return fStore.getInt(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getLong(String)
+	 */
+	public long getLong(String name) {
+		return fStore.getLong(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#getString(String)
+	 */
+	public String getString(String name) {
+		return fStore.getString(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#isDefault(String)
+	 */
+	public boolean isDefault(String name) {
+		return fStore.isDefault(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#needsSaving()
+	 */
+	public boolean needsSaving() {
+		return fStore.needsSaving();
+	}
+
+	/*
+	 * @see IPreferenceStore#putValue(String, String)
+	 */
+	public void putValue(String name, String value) {
+		if (covers(name))
+			fStore.putValue(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, double)
+	 */
+	public void setDefault(String name, double value) {
+		if (covers(name))
+			fStore.setDefault(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, float)
+	 */
+	public void setDefault(String name, float value) {
+		if (covers(name))
+			fStore.setDefault(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, int)
+	 */
+	public void setDefault(String name, int value) {
+		if (covers(name))
+			fStore.setDefault(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, long)
+	 */
+	public void setDefault(String name, long value) {
+		if (covers(name))
+			fStore.setDefault(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, String)
+	 */
+	public void setDefault(String name, String value) {
+		if (covers(name))
+			fStore.setDefault(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setDefault(String, boolean)
+	 */
+	public void setDefault(String name, boolean value) {
+		if (covers(name))
+			fStore.setDefault(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setToDefault(String)
+	 */
+	public void setToDefault(String name) {
+		fStore.setToDefault(name);
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, double)
+	 */
+	public void setValue(String name, double value) {
+		if (covers(name))
+			fStore.setValue(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, float)
+	 */
+	public void setValue(String name, float value) {
+		if (covers(name))
+			fStore.setValue(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, int)
+	 */
+	public void setValue(String name, int value) {
+		if (covers(name))
+			fStore.setValue(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, long)
+	 */
+	public void setValue(String name, long value) {
+		if (covers(name))
+			fStore.setValue(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, String)
+	 */
+	public void setValue(String name, String value) {
+		if (covers(name))
+			fStore.setValue(name, value);
+	}
+
+	/*
+	 * @see IPreferenceStore#setValue(String, boolean)
+	 */
+	public void setValue(String name, boolean value) {
+		if (covers(name))
+			fStore.setValue(name, value);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/StatusInfo.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/StatusInfo.java
new file mode 100644
index 0000000..8f52f24
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/StatusInfo.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * A settable IStatus.
+ * Can be an error, warning, info or ok. For error, info and warning states,
+ * a message describes the problem.
+ */
+public class StatusInfo implements IStatus {
+
+	private String fStatusMessage;
+	private int fSeverity;
+
+	/**
+	 * Creates a status set to OK (no message)
+	 */
+	public StatusInfo() {
+		this(OK, null);
+	}
+
+	/**
+	 * Creates a status .
+	 * @param severity The status severity: ERROR, WARNING, INFO and OK.
+	 * @param message The message of the status. Applies only for ERROR,
+	 * WARNING and INFO.
+	 */
+	public StatusInfo(int severity, String message) {
+		fStatusMessage= message;
+		fSeverity= severity;
+	}
+
+	/**
+	 *  Returns if the status' severity is OK.
+	 */
+	public boolean isOK() {
+		return fSeverity == IStatus.OK;
+	}
+
+	/**
+	 *  Returns if the status' severity is WARNING.
+	 */
+	public boolean isWarning() {
+		return fSeverity == IStatus.WARNING;
+	}
+
+	/**
+	 *  Returns if the status' severity is INFO.
+	 */
+	public boolean isInfo() {
+		return fSeverity == IStatus.INFO;
+	}
+
+	/**
+	 *  Returns if the status' severity is ERROR.
+	 */
+	public boolean isError() {
+		return fSeverity == IStatus.ERROR;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IStatus#getMessage()
+	 */
+	public String getMessage() {
+		return fStatusMessage;
+	}
+
+	/**
+	 * Sets the status to ERROR.
+	 * @param errorMessage The error message (can be empty, but not null)
+	 */
+	public void setError(String errorMessage) {
+		Assert.isNotNull(errorMessage);
+		fStatusMessage= errorMessage;
+		fSeverity= IStatus.ERROR;
+	}
+
+	/**
+	 * Sets the status to WARNING.
+	 * @param warningMessage The warning message (can be empty, but not null)
+	 */
+	public void setWarning(String warningMessage) {
+		Assert.isNotNull(warningMessage);
+		fStatusMessage= warningMessage;
+		fSeverity= IStatus.WARNING;
+	}
+
+	/**
+	 * Sets the status to INFO.
+	 * @param infoMessage The info message (can be empty, but not null)
+	 */
+	public void setInfo(String infoMessage) {
+		Assert.isNotNull(infoMessage);
+		fStatusMessage= infoMessage;
+		fSeverity= IStatus.INFO;
+	}
+
+	/**
+	 * Sets the status to OK.
+	 */
+	public void setOK() {
+		fStatusMessage= null;
+		fSeverity= IStatus.OK;
+	}
+
+	/*
+	 * @see IStatus#matches(int)
+	 */
+	public boolean matches(int severityMask) {
+		return (fSeverity & severityMask) != 0;
+	}
+
+	/**
+	 * Returns always <code>false</code>.
+	 * @see IStatus#isMultiStatus()
+	 */
+	public boolean isMultiStatus() {
+		return false;
+	}
+
+	/*
+	 * @see IStatus#getSeverity()
+	 */
+	public int getSeverity() {
+		return fSeverity;
+	}
+
+	/*
+	 * @see IStatus#getPlugin()
+	 */
+	public String getPlugin() {
+		return IAntUIConstants.PLUGIN_ID;
+	}
+
+	/**
+	 * Returns always <code>null</code>.
+	 * @see IStatus#getException()
+	 */
+	public Throwable getException() {
+		return null;
+	}
+
+	/**
+	 * Returns always the error severity.
+	 * @see IStatus#getCode()
+	 */
+	public int getCode() {
+		return fSeverity;
+	}
+
+	/**
+	 * Returns always <code>null</code>.
+	 * @see IStatus#getChildren()
+	 */
+	public IStatus[] getChildren() {
+		return new IStatus[0];
+	}
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/SyntaxPreviewCode.txt b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/SyntaxPreviewCode.txt
new file mode 100644
index 0000000..6f281dd
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/SyntaxPreviewCode.txt
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE project   [
+<!ENTITY common SYSTEM "common.xml">
+]>
+<project default="greetings">
+	&common;
+    <target name="greetings">
+    <!--Saying HI
+    to the world-->
+        <echo>
+             Eclipse!
+        </echo>		  
+    </target>
+</project>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/TabFolderLayout.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/TabFolderLayout.java
new file mode 100644
index 0000000..ad6f3ff
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/TabFolderLayout.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.preferences;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Layout;
+
+public class TabFolderLayout extends Layout {
+
+	protected Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache) {
+		if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT)
+			return new Point(wHint, hHint);
+			
+		Control [] children = composite.getChildren ();
+		int count = children.length;
+		int maxWidth = 0, maxHeight = 0;
+		for (int i=0; i<count; i++) {
+			Control child = children [i];
+			Point pt = child.computeSize (SWT.DEFAULT, SWT.DEFAULT, flushCache);
+			maxWidth = Math.max (maxWidth, pt.x);
+			maxHeight = Math.max (maxHeight, pt.y);
+		}
+		
+		if (wHint != SWT.DEFAULT)
+			maxWidth= wHint;
+		if (hHint != SWT.DEFAULT)
+			maxHeight= hHint;
+		
+		return new Point(maxWidth, maxHeight);	
+		
+	}
+	
+	protected void layout (Composite composite, boolean flushCache) {
+		Rectangle rect= composite.getClientArea();
+	
+		Control[] children = composite.getChildren();
+		for (int i = 0; i < children.length; i++) {
+			children[i].setBounds(rect);
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/URLFieldEditor.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/URLFieldEditor.java
new file mode 100644
index 0000000..045e396
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/URLFieldEditor.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.preferences;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.jface.preference.StringButtonFieldEditor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+
+public class URLFieldEditor extends StringButtonFieldEditor {
+	
+	public URLFieldEditor(String name, String labelText, Composite parent) {
+		super(name, labelText, parent);
+		setEmptyStringAllowed(false);
+		setChangeButtonText(JFaceResources.getString("openBrowse"));//$NON-NLS-1$
+		setErrorMessage(AntPreferencesMessages.URLFieldEditor_0);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.StringFieldEditor#doCheckState()
+	 */
+	protected boolean doCheckState() {
+		String text= getTextControl().getText();
+		if (text != null && text.length() > 0) {
+			try {
+				new URL(text);
+			} catch (MalformedURLException e) {
+				return false;
+			}
+		}
+		return true;
+	}
+	
+	/* (non-Javadoc)
+     * Method declared on StringButtonFieldEditor.
+     * Opens the directory chooser dialog and returns the <code>URL</code> of the selected directory.
+     */
+    protected String changePressed() {
+    	URL url= null;
+		try {
+			url = new URL(getTextControl().getText());
+		} catch (MalformedURLException e1) {
+		}
+		File f = null;
+		if (url != null) {
+			f= new File(url.getFile());
+			if (!f.exists()) {
+	            f = null;
+	        }
+		}
+        
+        File d = getDirectory(f);
+        if (d == null) {
+            return null;
+        }
+
+        try {
+			return d.toURL().toExternalForm();
+		} catch (MalformedURLException e) {
+			AntUIPlugin.log("Internal error setting documentation location", e); //$NON-NLS-1$
+			return null;
+		}
+    }
+    
+    /**
+     * Helper that opens the directory chooser dialog.
+     * @param startingDirectory The directory the dialog will open in.
+     * @return File File or <code>null</code>.
+     */
+    private File getDirectory(File startingDirectory) {
+
+        DirectoryDialog fileDialog = new DirectoryDialog(getShell(), SWT.OPEN);
+        if (startingDirectory != null) {
+            fileDialog.setFilterPath(startingDirectory.getPath());
+        }
+        String dir = fileDialog.open();
+        if (dir != null) {
+            dir = dir.trim();
+            if (dir.length() > 0) {
+                return new File(dir);
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/LaunchConfigurationBuildfileRenameParticipant.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/LaunchConfigurationBuildfileRenameParticipant.java
new file mode 100644
index 0000000..83c1e75
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/LaunchConfigurationBuildfileRenameParticipant.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.refactoring;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
+
+public class LaunchConfigurationBuildfileRenameParticipant extends RenameParticipant {
+
+	private IFile fFile;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#initialize(java.lang.Object)
+	 */
+	protected boolean initialize(Object element) {
+		fFile= (IFile) element;
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#getName()
+	 */
+	public String getName() {
+		return RefactoringMessages.LaunchConfigurationParticipant_0; 
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#checkConditions(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext)
+	 */
+	public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) {
+		return new RefactoringStatus();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#createChange(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public Change createChange(IProgressMonitor pm) throws CoreException {
+        return LaunchConfigurationBuildfileChange.createChangesForBuildfileRename(fFile, getArguments().getNewName());
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/LaunchConfigurationIProjectRenameParticipant.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/LaunchConfigurationIProjectRenameParticipant.java
new file mode 100644
index 0000000..6cc9ef5
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/LaunchConfigurationIProjectRenameParticipant.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.refactoring;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
+import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
+
+public class LaunchConfigurationIProjectRenameParticipant extends RenameParticipant {
+
+	private IProject fProject;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#initialize(java.lang.Object)
+	 */
+	protected boolean initialize(Object element) {
+		fProject= (IProject) element;
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#getName()
+	 */
+	public String getName() {
+		return RefactoringMessages.LaunchConfigurationParticipant_0; 
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant#checkConditions(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext)
+	 */
+	public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context) {
+		return new RefactoringStatus();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.refactoring.participants.IRefactoringParticipant#createChange(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public Change createChange(IProgressMonitor pm) throws CoreException {
+		return LaunchConfigurationBuildfileChange.createChangesForProjectRename(fProject, getArguments().getNewName());
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/RefactoringMessages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/RefactoringMessages.java
new file mode 100644
index 0000000..b9d9896
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/RefactoringMessages.java
@@ -0,0 +1,30 @@
+/**********************************************************************
+ * Copyright (c) 2000, 2006 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.refactoring;
+
+import org.eclipse.osgi.util.NLS;
+
+public class RefactoringMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.refactoring.RefactoringMessages";//$NON-NLS-1$
+
+	public static String LaunchConfigurationParticipant_0;
+	public static String LaunchConfigurationBuildfileChange_0;
+	public static String LaunchConfigurationBuildfileChange_1;
+	public static String LaunchConfigurationBuildfileChange_2;
+	public static String LaunchConfigurationBuildfileChange_4;
+	public static String LaunchConfigurationBuildfileChange_5;
+	public static String LaunchConfigurationBuildfileChange_6;
+	public static String LaunchConfigurationBuildfileChange_7;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, RefactoringMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/RefactoringMessages.properties b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/RefactoringMessages.properties
new file mode 100644
index 0000000..94eac4c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/refactoring/RefactoringMessages.properties
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+###############################################################################
+
+LaunchConfigurationParticipant_0=Ant Launch configuration participant
+LaunchConfigurationBuildfileChange_0=Rename the Ant launch configuration "{0}" to "{1}", update buildfile location attribute
+LaunchConfigurationBuildfileChange_1=Update buildfile of Ant launch configuration "{0}"
+LaunchConfigurationBuildfileChange_2=Update Ant launch configuration "{0}"
+LaunchConfigurationBuildfileChange_4=The project for the Ant launch configuration "{0}" is no longer "{1}".
+LaunchConfigurationBuildfileChange_5=The buildfile location for the Ant launch configuration "{0}" is no longer "{1}".
+LaunchConfigurationBuildfileChange_6=The Ant launch configuration "{0}" no longer exists.
+LaunchConfigurationBuildfileChange_7=Ant Launch configuration updates
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/AntViewContentProvider.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/AntViewContentProvider.java
new file mode 100644
index 0000000..72cc673
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/AntViewContentProvider.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 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 - current implementation
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.views;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.ant.internal.ui.model.AntModelContentProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+
+
+public class AntViewContentProvider extends AntModelContentProvider {
+	
+	private TreeViewer fTreeViewer;
+	private List fElements= new ArrayList();
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
+	 */
+	public Object[] getElements(Object anInputElement) {
+		if (anInputElement instanceof Object[]) {
+			return fElements.toArray();
+		}
+		return EMPTY_ARRAY;
+	}
+	
+	public void add(Object o) {
+		if (fElements.contains(o)) {
+			return;
+		}
+		fElements.add(o);
+		fTreeViewer.add(fTreeViewer.getInput(), o);
+		fTreeViewer.setSelection(new StructuredSelection(o), true);
+	}
+	
+	public void addAll(Object[] o) {
+		fElements.addAll(Arrays.asList(o));
+		fTreeViewer.add(fTreeViewer.getInput(), o);
+	}
+	
+	/**
+	 * do nothing
+	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object)
+	 */
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		fTreeViewer= (TreeViewer)viewer;
+	}
+	
+	public void remove(Object o) {
+		fElements.remove(o);
+		fTreeViewer.remove(o);
+	}
+	
+	public void removeAll() {
+		fTreeViewer.remove(fTreeViewer.getInput(), fElements.toArray());
+		fElements.clear();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+	 */
+	public void dispose() {
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/AntViewMessages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/AntViewMessages.java
new file mode 100644
index 0000000..2569644
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/AntViewMessages.java
@@ -0,0 +1,26 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.views;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntViewMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.views.AntViewMessages";//$NON-NLS-1$
+
+	public static String AntView_1;
+	public static String AntView_3;
+	public static String AntView_4;
+
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntViewMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/AntViewMessages.properties b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/AntViewMessages.properties
new file mode 100644
index 0000000..90becdf
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/AntViewMessages.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# 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
+###############################################################################
+
+AntView_1=&Open With
+AntView_3=\ depends="
+AntView_4=\ description="
+
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AddBuildFilesAction.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AddBuildFilesAction.java
new file mode 100644
index 0000000..fa1cb7d
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AddBuildFilesAction.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.AntUtil;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.ant.internal.ui.model.AntProjectNode;
+import org.eclipse.ant.internal.ui.model.AntProjectNodeProxy;
+import org.eclipse.ant.internal.ui.preferences.FileSelectionDialog;
+import org.eclipse.ant.internal.ui.views.AntView;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Action that prompts the user for build files and adds the selected files to
+ * an <code>AntView</code>
+ */
+public class AddBuildFilesAction extends Action {
+
+	private AntView view;
+
+	public AddBuildFilesAction(AntView view) {
+		super(AntViewActionMessages.AddBuildFilesAction_1, AntUIImages.getImageDescriptor(IAntUIConstants.IMG_ADD));
+		this.view= view;
+		setToolTipText(AntViewActionMessages.AddBuildFilesAction_0);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAntUIHelpContextIds.ADD_BUILDFILE_ACTION);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		String title= AntViewActionMessages.AddBuildFilesAction_2;
+		String message= AntViewActionMessages.AddBuildFilesAction_4;
+		String filterExtension= "xml"; //$NON-NLS-1$
+		String filterMessage= AntViewActionMessages.AddBuildFilesAction_5;
+		
+		FileSelectionDialog dialog = new FileSelectionDialog(Display.getCurrent().getActiveShell(), getBuildFiles(), title, message, filterExtension, filterMessage);
+		dialog.open();
+		final Object[] result= dialog.getResult();
+		if (result == null) {
+			return;
+		}
+
+		try {
+			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
+				public void run(IProgressMonitor monitor) {
+					monitor.beginTask(AntViewActionMessages.AddBuildFilesAction_3, result.length);
+					for (int i = 0; i < result.length && !monitor.isCanceled(); i++) {
+						Object file = result[i];
+						if (file instanceof IFile) {
+							String buildFileName= ((IFile)file).getFullPath().toString();
+							final AntProjectNode project= new AntProjectNodeProxy(buildFileName);
+							project.getName();
+							monitor.worked(1);
+							Display.getDefault().asyncExec(new Runnable() {
+								public void run() {
+									view.addProject(project);
+								}
+							});
+						}
+					}
+				}
+			});
+		} catch (InvocationTargetException e) {
+		} catch (InterruptedException e) {
+		}
+	}
+
+	private List getBuildFiles() {
+		AntProjectNode[] existingProjects= view.getProjects();
+		List buildFiles= new ArrayList(existingProjects.length);
+		for (int j = 0; j < existingProjects.length; j++) {
+			AntProjectNode existingProject = existingProjects[j];
+			buildFiles.add(AntUtil.getFile(existingProject.getBuildFileName()));
+		}
+		return buildFiles;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AntOpenWithMenu.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AntOpenWithMenu.java
new file mode 100644
index 0000000..780bf53
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AntOpenWithMenu.java
@@ -0,0 +1,287 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+
+
+import com.ibm.icu.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.ant.internal.ui.AntUIPlugin;
+import org.eclipse.ant.internal.ui.AntUtil;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.model.AntElementNode;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+
+/**
+ * 
+ * Code mostly a copy of the OpenWithMenu which cannot be effectively subclassed
+ */
+public class AntOpenWithMenu extends ContributionItem {
+
+	private IWorkbenchPage fPage;
+	private IEditorRegistry fRegistry = PlatformUI.getWorkbench().getEditorRegistry();
+	private static final String SYSTEM_EDITOR_ID= PlatformUI.PLUGIN_ID + ".SystemEditor"; //$NON-NLS-1$
+
+	private static Map imageCache = new Hashtable(11);
+
+	private AntElementNode fNode;
+	
+	/**
+	 * The id of this action.
+	 */
+	public static final String ID = IAntUIConstants.PLUGIN_ID + ".AntOpenWithMenu"; //$NON-NLS-1$
+
+	public AntOpenWithMenu(IWorkbenchPage page) {
+		super(ID);
+		this.fPage= page;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IContributionItem#dispose()
+	 */
+	public void dispose() {
+		super.dispose();
+		Iterator iter= imageCache.values().iterator();
+		while (iter.hasNext()) {
+			Image image = (Image) iter.next();
+			image.dispose();
+		}		
+		imageCache.clear();
+	}
+
+	/**
+	 * Returns an image to show for the corresponding editor descriptor.
+	 *
+	 * @param editorDesc the editor descriptor, or <code>null</code> for the system editor
+	 * @return the image or <code>null</code>
+	 */
+	private Image getImage(IEditorDescriptor editorDesc) {
+		ImageDescriptor imageDesc = getImageDescriptor(editorDesc);
+		if (imageDesc == null) {
+			return null;
+		}
+		Image image = (Image) imageCache.get(imageDesc);
+		if (image == null) {
+			image = imageDesc.createImage();
+			imageCache.put(imageDesc, image);
+		}
+		return image;
+	}
+
+	/**
+	 * Returns the image descriptor for the given editor descriptor,
+	 * or <code>null</code> if it has no image.
+	 */
+	private ImageDescriptor getImageDescriptor(IEditorDescriptor editorDesc) {
+		ImageDescriptor imageDesc = null;
+		if (editorDesc == null) {
+			imageDesc = fRegistry.getImageDescriptor(fNode.getIFile().getName());
+		} else {
+			imageDesc = editorDesc.getImageDescriptor();
+		}
+		if (imageDesc == null && editorDesc != null) {
+			if (editorDesc.getId().equals(SYSTEM_EDITOR_ID)) {
+				imageDesc = getSystemEditorImageDescriptor(fNode.getIFile().getFileExtension());
+			}
+		}
+		return imageDesc;
+	}
+
+	/**
+	 * Return the image descriptor of the system editor
+	 * that is registered with the OS to edit files of
+	 * this type. <code>null</code> if none can be found.
+	 */
+	private ImageDescriptor getSystemEditorImageDescriptor(String extension) {
+		Program externalProgram = null;
+		if (extension != null) {
+			externalProgram = Program.findProgram(extension);
+		}
+		if (externalProgram == null) {
+			return null;
+		} 
+		return new EditorImageDescriptor(externalProgram);
+	}
+	/**
+	 * Creates the menu item for the editor descriptor.
+	 *
+	 * @param menu the menu to add the item to
+	 * @param descriptor the editor descriptor, or null for the system editor
+	 * @param preferredEditor the descriptor of the preferred editor, or <code>null</code>
+	 */
+	private void createMenuItem(Menu menu, final IEditorDescriptor descriptor, final IEditorDescriptor preferredEditor) {
+		// XXX: Would be better to use bold here, but SWT does not support it.
+		final MenuItem menuItem = new MenuItem(menu, SWT.RADIO);
+		boolean isPreferred = preferredEditor != null && descriptor.getId().equals(preferredEditor.getId());
+		menuItem.setSelection(isPreferred);
+		menuItem.setText(descriptor.getLabel());
+		Image image = getImage(descriptor);
+		if (image != null) {
+			menuItem.setImage(image);
+		}
+		Listener listener = new Listener() {
+			/* (non-Javadoc)
+			 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+			 */
+			public void handleEvent(Event event) {
+				switch (event.type) {
+					case SWT.Selection :
+						if (menuItem.getSelection()) {
+							openEditor(descriptor);
+						}
+						break;
+				}
+			}
+		};
+		menuItem.addListener(SWT.Selection, listener);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.Menu, int)
+	 */
+	public void fill(Menu menu, int index) {
+		IFile fileResource = fNode.getIFile();
+		if (fileResource == null) {
+			return;
+		}
+
+		IEditorDescriptor defaultEditor = fRegistry.findEditor(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID); // should not be null
+		IEditorDescriptor preferredEditor = IDE.getDefaultEditor(fileResource); // may be null
+		
+		Object[] editors= fRegistry.getEditors(fileResource.getName());
+		Arrays.sort(editors, new Comparator() {
+			/* (non-Javadoc)
+			 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+			 */
+			public int compare(Object o1, Object o2) {
+				String s1 = ((IEditorDescriptor) o1).getLabel();
+				String s2 = ((IEditorDescriptor) o2).getLabel();
+				//Return true if elementTwo is 'greater than' elementOne
+				return s1.compareToIgnoreCase(s2);
+			}
+		});
+		IEditorDescriptor antEditor= fRegistry.findEditor("org.eclipse.ant.internal.ui.editor.AntEditor"); //$NON-NLS-1$
+		
+		boolean defaultFound = false;
+		boolean antFound= false;
+		List alreadyAddedEditors= new ArrayList(editors.length);
+		for (int i = 0; i < editors.length; i++) {
+			IEditorDescriptor editor = (IEditorDescriptor) editors[i];
+			if (alreadyAddedEditors.contains(editor.getId())) {
+				continue;
+			}
+			createMenuItem(menu, editor, preferredEditor);
+			if (defaultEditor != null && editor.getId().equals(defaultEditor.getId())) {
+				defaultFound = true;
+			}
+			if (antEditor != null && editor.getId().equals(antEditor.getId())) {
+				antFound= true;
+			}
+			alreadyAddedEditors.add(editor.getId());
+			
+		}
+
+		// Only add a separator if there is something to separate
+		if (editors.length > 0) {
+			new MenuItem(menu, SWT.SEPARATOR);
+		}
+
+		// Add ant editor.
+		 if (!antFound && antEditor != null) {
+			 createMenuItem(menu, antEditor, preferredEditor);
+		 }
+			 
+		// Add default editor.
+		if (!defaultFound && defaultEditor != null) {
+			createMenuItem(menu, defaultEditor, preferredEditor);
+		}
+
+		// Add system editor.
+		IEditorDescriptor descriptor = fRegistry.findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
+		createMenuItem(menu, descriptor, preferredEditor);
+		createDefaultMenuItem(menu, fileResource);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.action.IContributionItem#isDynamic()
+	 */
+	public boolean isDynamic() {
+		return true;
+	}
+	/**
+	 * Opens the given editor on the selected file.
+	 *
+	 * @param editor the editor descriptor, or <code>null</code> for the system editor
+	 */
+	private void openEditor(IEditorDescriptor editorDescriptor) {
+		AntUtil.openInEditor(fPage, editorDescriptor, fNode);
+	}
+
+	/**
+	 * Creates the menu item for the default editor
+	 *
+	 * @param menu the menu to add the item to
+	 * @param file the file being edited
+	 * @param registry the editor registry
+	 */
+	private void createDefaultMenuItem(Menu menu, final IFile fileResource) {
+		final MenuItem menuItem = new MenuItem(menu, SWT.RADIO);
+		menuItem.setSelection(IDE.getDefaultEditor(fileResource) == null);
+		menuItem.setText(AntViewActionMessages.AntViewOpenWithMenu_Default_Editor_4);
+
+		Listener listener = new Listener() {
+			/* (non-Javadoc)
+			 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+			 */
+			public void handleEvent(Event event) {
+				switch (event.type) {
+					case SWT.Selection :
+						if (menuItem.getSelection()) {
+							IDE.setDefaultEditor(fileResource, null);
+							try {
+								IDE.openEditor(fPage, fileResource, true);
+							} catch (PartInitException e) {
+								AntUIPlugin.log(MessageFormat.format(AntViewActionMessages.AntViewOpenWithMenu_Editor_failed, new String[]{fileResource.getLocation().toOSString()}), e);
+							}
+						}
+						break;
+				}
+			}
+		};
+
+		menuItem.addListener(SWT.Selection, listener);
+	}
+
+	public void setNode(AntElementNode node) {
+		fNode= node;
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AntViewActionMessages.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AntViewActionMessages.java
new file mode 100644
index 0000000..ec3804c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AntViewActionMessages.java
@@ -0,0 +1,59 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+
+import org.eclipse.osgi.util.NLS;
+
+public class AntViewActionMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.views.actions.AntViewActionMessages";//$NON-NLS-1$
+
+	public static String SearchForBuildFilesDialog_Search_for_Build_Files_1;
+	public static String SearchForBuildFilesDialog__Input;
+	public static String SearchForBuildFilesDialog_Build_name_cannot_be_empty_3;
+	public static String SearchForBuildFilesDialog__Search_4;
+	public static String SearchForBuildFilesDialog_Scope_5;
+	public static String SearchForBuildFilesDialog__Workspace_6;
+	public static String SearchForBuildFilesDialog_Wor_king_Set__7;
+	public static String SearchForBuildFilesDialog__Choose____8;
+	public static String SearchForBuildFilesDialog_Include_errors;
+	public static String SearchForBuildFilesDialog_Must_select_a_working_set_10;
+	public static String SearchForBuildFilesDialog_No_searchable;
+	public static String AntViewOpenWithMenu_Editor_failed;
+	public static String AntViewOpenWithMenu_Default_Editor_4;
+	public static String AddBuildFilesAction_0;
+	public static String AddBuildFilesAction_1;
+	public static String AddBuildFilesAction_2;
+	public static String AddBuildFilesAction_3;
+	public static String AddBuildFilesAction_4;
+	public static String AddBuildFilesAction_5;
+	public static String RemoveAllAction_Remove_All;
+	public static String RemoveAllAction_0;
+	public static String RemoveAllAction_1;
+	public static String RemoveProjectAction_Remove;
+	public static String RemoveProjectAction_Remove_2;
+	public static String RunTargetAction_Run_1;
+	public static String RunTargetAction_3;
+	public static String RunTargetAction_4;
+	public static String RunTargetAction_2;
+	public static String RunTargetAction_0;
+	public static String SearchForBuildFilesAction_Search_1;
+	public static String SearchForBuildFilesAction_Add_build_files_with_search_2;
+	public static String SearchForBuildFilesAction_Processing_search_results_3;
+	public static String SearchForBuildFilesAction_Adding__0__4;
+	public static String RefreshBuildFilesAction_Refresh_Buildfiles_1;
+	public static String RefreshBuildFilesAction_Refreshing_buildfiles_3;
+	public static String RefreshBuildFilesAction_Refreshing__0__4;
+	public static String FilterInternalTargetsAction_0;
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, AntViewActionMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AntViewActionMessages.properties b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AntViewActionMessages.properties
new file mode 100644
index 0000000..3882ba9
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/AntViewActionMessages.properties
@@ -0,0 +1,48 @@
+###############################################################################
+# 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
+###############################################################################
+
+SearchForBuildFilesDialog_Search_for_Build_Files_1=Search for Buildfiles
+SearchForBuildFilesDialog__Input=&Input a buildfile name (* = any string, ? = any character):
+SearchForBuildFilesDialog_Build_name_cannot_be_empty_3=Build name cannot be empty
+SearchForBuildFilesDialog__Search_4=&Search
+SearchForBuildFilesDialog_Scope_5=Scope
+SearchForBuildFilesDialog__Workspace_6=&Workspace
+SearchForBuildFilesDialog_Wor_king_Set__7=Wor&king Set:
+SearchForBuildFilesDialog__Choose____8=&Choose...
+SearchForBuildFilesDialog_Include_errors=Include &buildfiles that contain errors
+SearchForBuildFilesDialog_Must_select_a_working_set_10=Must select a working set
+SearchForBuildFilesDialog_No_searchable=No searchable resources found in the selected working set
+AntViewOpenWithMenu_Editor_failed=Editor failed to open for {0}
+AntViewOpenWithMenu_Default_Editor_4=Default Editor
+AddBuildFilesAction_0=Add Buildfiles
+AddBuildFilesAction_1=&Add Buildfiles...
+AddBuildFilesAction_2=Buildfile Selection
+AddBuildFilesAction_3=Adding Buildfile(s)...
+AddBuildFilesAction_4=&Choose the buildfiles to add:
+AddBuildFilesAction_5=&Only show *.xml files
+RemoveAllAction_Remove_All=Remove A&ll Buildfiles
+RemoveAllAction_0=Remove All from View
+RemoveAllAction_1=Are you sure you want to remove all buildfiles from the view?
+RemoveProjectAction_Remove=Remo&ve Buildfile
+RemoveProjectAction_Remove_2=Remove Selected Buildfile
+RunTargetAction_Run_1=R&un
+RunTargetAction_3=Run the Default Target of the Selected Buildfile
+RunTargetAction_4=Run the Selected Target
+RunTargetAction_2=Launching Ant buildfile
+RunTargetAction_0=Run the Owning Target of the Selected Task
+SearchForBuildFilesAction_Search_1=Search
+SearchForBuildFilesAction_Add_build_files_with_search_2=Add Buildfiles with Search
+SearchForBuildFilesAction_Processing_search_results_3=Processing search results...
+SearchForBuildFilesAction_Adding__0__4=Adding {0}
+RefreshBuildFilesAction_Refresh_Buildfiles_1=Re&fresh Buildfiles
+RefreshBuildFilesAction_Refreshing_buildfiles_3=Refreshing buildfiles...
+RefreshBuildFilesAction_Refreshing__0__4=Refreshing {0}
+FilterInternalTargetsAction_0=Hide Internal Targets
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/EditorImageDescriptor.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/EditorImageDescriptor.java
new file mode 100644
index 0000000..0161f23
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/EditorImageDescriptor.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.program.Program;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Copy of org.eclipse.ui.internal.misc.ExternalProgramImageDescriptor for
+ * use in the AntViewOpenWithMenu
+ */
+public class EditorImageDescriptor extends ImageDescriptor {
+
+	public Program program;
+
+	/**
+	 * Creates a new ImageDescriptor. The image is loaded 
+	 * from a file with the given name <code>name</code>.
+	 */
+	public EditorImageDescriptor(Program program) {
+		this.program = program;
+	}
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object o) {
+		if (!(o instanceof EditorImageDescriptor)) {
+			return false;
+		}
+		EditorImageDescriptor other = (EditorImageDescriptor) o;
+
+		//See if there is a name - compare it if so and compare the programs if not
+		String otherName = other.program.getName();
+		if (otherName == null) {
+			return other.program.equals(program);
+		} 
+		return otherName.equals(program.getName());
+	}
+	/**
+	 * Returns an SWT Image that is described by the information
+	 * in this descriptor.  Each call returns a new Image.
+	 */
+	public Image getImage() {
+		return createImage();
+	}
+	
+	/**
+	 * @see org.eclipse.jface.resource.ImageDescriptor#getImageData()
+	 */
+	public ImageData getImageData() {
+		
+		ImageData defaultImage = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FILE).getImageData();
+		if (defaultImage == null) {
+			return null;
+		}
+		ImageData data = null;
+		if (program == null || ((data = program.getImageData()) == null)) {
+			return defaultImage;
+		}
+
+		//The images in GNOME are too big. Scaling them does not give nice result so return defaultImage;
+		if (data.height > defaultImage.height || data.width > defaultImage.width) {
+			return defaultImage;
+		}
+
+		return data;
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode() {
+		String programName = program.getName();
+		if (programName == null) {
+			return program.hashCode();
+		} 
+		return programName.hashCode();
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/FilterInternalTargetsAction.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/FilterInternalTargetsAction.java
new file mode 100644
index 0000000..53cf6c8
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/FilterInternalTargetsAction.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.views.AntView;
+import org.eclipse.jface.action.Action;
+
+/** 
+ * An action which toggles filtering of internal targets from the Ant view.
+ */
+public class FilterInternalTargetsAction extends Action {
+
+	private AntView fView;
+	
+	public FilterInternalTargetsAction(AntView view) {
+		super(AntViewActionMessages.FilterInternalTargetsAction_0);
+		fView = view;
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_FILTER_INTERNAL_TARGETS));
+		setToolTipText(AntViewActionMessages.FilterInternalTargetsAction_0);
+		setChecked(fView.isFilterInternalTargets());
+	}
+	
+	/**
+	 * Toggles the filtering of internal targets from the Ant view
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		fView.setFilterInternalTargets(isChecked());
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RefreshBuildFilesAction.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RefreshBuildFilesAction.java
new file mode 100644
index 0000000..e685ee2
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RefreshBuildFilesAction.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+
+import java.lang.reflect.InvocationTargetException;
+import com.ibm.icu.text.MessageFormat;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.ant.internal.ui.model.AntProjectNode;
+import org.eclipse.ant.internal.ui.model.AntProjectNodeProxy;
+import org.eclipse.ant.internal.ui.model.AntTargetNode;
+import org.eclipse.ant.internal.ui.views.AntView;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * Action which refreshes the selected buildfiles in the Ant view
+ */
+public class RefreshBuildFilesAction extends Action implements IUpdate {
+
+	private AntView fView;
+
+	/**
+	 * Creates a new <code>RefreshBuildFilesAction</code> which will refresh buildfiles 
+	 * in the given Ant view.
+	 * @param view the Ant view whose selection this action will use when
+	 * determining which buildfiles to refresh.
+	 */
+	public RefreshBuildFilesAction(AntView view) {
+		super(AntViewActionMessages.RefreshBuildFilesAction_Refresh_Buildfiles_1, AntUIImages.getImageDescriptor(IAntUIConstants.IMG_REFRESH));
+		setToolTipText(AntViewActionMessages.RefreshBuildFilesAction_Refresh_Buildfiles_1);
+		fView = view;
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAntUIHelpContextIds.REFRESH_BUILDFILE_ACTION);
+	}
+
+	/**
+	 * Refreshes the selected buildfiles (or all buildfiles if none selected) in the Ant view
+	 */
+	public void run() {
+		final Set projects= getSelectedProjects();
+		if (projects.isEmpty()) {
+			// If no selection, add all
+			AntProjectNode[] allProjects= fView.getProjects();
+			for (int i = 0; i < allProjects.length; i++) {
+				projects.add(allProjects[i]);
+			}
+		}
+		final Iterator iter= projects.iterator();
+		if (!iter.hasNext()) {
+			return;
+		}
+		
+		try {
+			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
+				public void run(IProgressMonitor monitor) {
+					monitor.beginTask(AntViewActionMessages.RefreshBuildFilesAction_Refreshing_buildfiles_3, projects.size());
+					AntProjectNodeProxy project;
+					while (iter.hasNext()) {
+						project= (AntProjectNodeProxy) iter.next();
+						monitor.subTask(MessageFormat.format(AntViewActionMessages.RefreshBuildFilesAction_Refreshing__0__4, new String[] {project.getBuildFileName()}));
+						project.parseBuildFile(true);
+						monitor.worked(1);
+					}
+				}
+			});
+		} catch (InvocationTargetException e) {
+		} catch (InterruptedException e) {
+		}
+		fView.getViewer().refresh();
+	}
+
+	/**
+	 * Returns the selected project nodes to refresh
+	 * 
+	 * @return Set the selected <code>ProjectNode</code>s to refresh.
+	 */
+	private Set getSelectedProjects() {
+		IStructuredSelection selection = (IStructuredSelection) fView.getViewer().getSelection();
+		HashSet set= new HashSet();
+		Iterator iter = selection.iterator();
+		Object data;
+		while (iter.hasNext()) {
+			data= iter.next();
+			if (data instanceof AntProjectNode) {
+				set.add(data);
+			} else if (data instanceof AntTargetNode) {
+				set.add(((AntTargetNode) data).getProjectNode());
+			}
+		}
+		return set;
+	}
+
+	/**
+	 * Updates the enablement of this action based on the user's selection
+	 */
+	public void update() {
+		setEnabled(fView.getProjects().length > 0);
+	}
+
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RemoveAllAction.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RemoveAllAction.java
new file mode 100644
index 0000000..fd8ac60
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RemoveAllAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+
+
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.ant.internal.ui.views.AntView;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.IUpdate;
+
+public class RemoveAllAction extends Action implements IUpdate {
+	private AntView view;
+	
+	public RemoveAllAction(AntView view) {
+		super(AntViewActionMessages.RemoveAllAction_Remove_All, AntUIImages.getImageDescriptor(IAntUIConstants.IMG_REMOVE_ALL));
+		setDescription(AntViewActionMessages.RemoveAllAction_Remove_All);
+		setToolTipText(AntViewActionMessages.RemoveAllAction_Remove_All);
+		this.view= view;
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAntUIHelpContextIds.REMOVE_ALL_ACTION);
+	}
+	
+	public void run() {
+		boolean proceed = MessageDialog.openQuestion(view.getViewSite().getShell(), AntViewActionMessages.RemoveAllAction_0, AntViewActionMessages.RemoveAllAction_1);
+		if (proceed) {
+			view.removeAllProjects();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.texteditor.IUpdate#update()
+	 */
+	public void update() {
+		setEnabled(view.getViewer().getTree().getItemCount() != 0);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RemoveProjectAction.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RemoveProjectAction.java
new file mode 100644
index 0000000..dc763e1
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RemoveProjectAction.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.ant.internal.ui.model.AntProjectNode;
+import org.eclipse.ant.internal.ui.views.AntView;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * Action that removes selected build files from an <code>AntView</code>
+ */
+public class RemoveProjectAction extends Action implements IUpdate {
+	
+	private AntView view;
+	
+	public RemoveProjectAction(AntView view) {
+		super(AntViewActionMessages.RemoveProjectAction_Remove, AntUIImages.getImageDescriptor(IAntUIConstants.IMG_REMOVE));
+		this.view= view;
+		setToolTipText(AntViewActionMessages.RemoveProjectAction_Remove_2);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAntUIHelpContextIds.REMOVE_PROJECT_ACTION);
+	}
+
+	/**
+	 * @see org.eclipse.jface.action.IAction#run()
+	 */
+	public void run() {
+		IStructuredSelection selection= (IStructuredSelection) view.getViewer().getSelection();
+		Iterator iter= selection.iterator();
+		Object element;
+		List projectNodes= new ArrayList();
+		while (iter.hasNext()) {
+			element= iter.next();
+			if (element instanceof AntProjectNode) {
+				projectNodes.add(element);
+			}
+		}
+		view.removeProjects(projectNodes);
+	}
+	
+	/**
+	 * @see org.eclipse.ui.texteditor.IUpdate#update()
+	 */
+	public void update() {
+		IStructuredSelection selection= (IStructuredSelection) view.getViewer().getSelection();
+		if (selection.isEmpty()) {
+			setEnabled(false);
+			return;
+		}
+		Object element;
+		Iterator iter= selection.iterator();
+		while (iter.hasNext()) {
+			element= iter.next();
+			if (!(element instanceof AntProjectNode)) {
+				setEnabled(false);
+				return;
+			}
+		}
+		setEnabled(true);
+	}
+	
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RunTargetAction.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RunTargetAction.java
new file mode 100644
index 0000000..08993e6
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/RunTargetAction.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+
+import java.util.Iterator;
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.ant.internal.ui.launchConfigurations.AntLaunchShortcut;
+import org.eclipse.ant.internal.ui.model.AntElementNode;
+import org.eclipse.ant.internal.ui.model.AntProjectNode;
+import org.eclipse.ant.internal.ui.model.AntTargetNode;
+import org.eclipse.ant.internal.ui.model.AntTaskNode;
+import org.eclipse.ant.internal.ui.views.AntView;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.progress.UIJob;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * Action which runs the selected target or the default target of the selected
+ * project in the AntView.
+ */
+public class RunTargetAction extends Action implements IUpdate {
+	
+	private AntView fView;
+	
+	/**
+	 * Creates a new <code>RunTargetAction</code> which will execute
+	 * targets in the given view.
+	 * @param view the Ant view whose selection this action will use when
+	 * determining which target to run.
+	 */
+	public RunTargetAction(AntView view) {
+		
+		setText(AntViewActionMessages.RunTargetAction_Run_1);
+		setImageDescriptor(AntUIImages.getImageDescriptor(IAntUIConstants.IMG_RUN));
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAntUIHelpContextIds.RUN_TARGET_ACTION);
+
+		setToolTipText(AntViewActionMessages.RunTargetAction_3);
+		fView= view;
+	}
+
+	/**
+	 * Executes the appropriate target based on the selection in the Ant view.
+	 */
+	public void run() {
+		run(getSelectedElement());
+	}
+	
+	/**
+     * @param selectedElement The element to use as the context for launching
+     */
+    public void run(final AntElementNode selectedElement) {
+        UIJob job= new UIJob(AntViewActionMessages.RunTargetAction_2) {
+			public IStatus runInUIThread(IProgressMonitor monitor) {
+				launch(selectedElement);
+				return Status.OK_STATUS;
+			}
+		};
+		job.schedule();
+    }
+
+    /**
+	 * Launches the given Ant element node
+	 * @param node the node to use to launch
+	 * @see AntLaunchShortcut#launch(AntElementNode, String)
+	 */
+	public void launch(AntElementNode node) {
+		AntLaunchShortcut shortcut= new AntLaunchShortcut();
+		shortcut.setShowDialog(false);
+		shortcut.launch(node, ILaunchManager.RUN_MODE);
+	}
+
+	/**
+	 * Updates the enablement of this action based on the user's selection
+	 */
+	public void update() {
+		AntElementNode selection= getSelectedElement();
+		boolean enabled= false;
+		if (selection instanceof AntTargetNode) {
+			if (!((AntTargetNode) selection).isErrorNode()) {
+				setToolTipText(AntViewActionMessages.RunTargetAction_4);
+				enabled= true;
+			}
+		} else if (selection instanceof AntProjectNode) {
+			if (!((AntProjectNode) selection).isErrorNode()) {
+				enabled= true;
+				setToolTipText(AntViewActionMessages.RunTargetAction_3);
+			}
+		}  else if (selection instanceof AntTaskNode) {
+			if (!((AntTaskNode) selection).isErrorNode()) {
+				enabled= true;
+				setToolTipText(AntViewActionMessages.RunTargetAction_0);
+			}
+		}
+		setEnabled(enabled);
+	}
+	
+	/**
+	 * Returns the selected node or <code>null</code> if more than one element is selected.
+	 * 
+	 * @return AntElementNode the selected node
+	 */
+	private AntElementNode getSelectedElement() {
+		IStructuredSelection selection= (IStructuredSelection) fView.getViewer().getSelection();
+		if (selection.isEmpty()) {
+			return null;
+		}
+		Iterator iter= selection.iterator();
+		Object data= iter.next();
+		if (iter.hasNext()) {
+			return null;
+		}
+		return (AntElementNode) data;
+	}	
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/SearchForBuildFilesAction.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/SearchForBuildFilesAction.java
new file mode 100644
index 0000000..b13755f
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/views/actions/SearchForBuildFilesAction.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.views.actions;
+import java.lang.reflect.InvocationTargetException;
+import com.ibm.icu.text.MessageFormat;
+import org.eclipse.ant.internal.ui.AntUIImages;
+import org.eclipse.ant.internal.ui.IAntUIConstants;
+import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
+import org.eclipse.ant.internal.ui.model.AntProjectNode;
+import org.eclipse.ant.internal.ui.model.AntProjectNodeProxy;
+import org.eclipse.ant.internal.ui.views.AntView;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * This action opens a dialog to search for build files and adds the resulting
+ * projects to the ant view.
+ */
+public class SearchForBuildFilesAction extends Action {
+	private AntView view;
+	
+	public SearchForBuildFilesAction(AntView view) {
+		super(AntViewActionMessages.SearchForBuildFilesAction_Search_1, AntUIImages.getImageDescriptor(IAntUIConstants.IMG_SEARCH));
+		setToolTipText(AntViewActionMessages.SearchForBuildFilesAction_Add_build_files_with_search_2);
+		this.view= view;
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAntUIHelpContextIds.SEARCH_FOR_BUILDFILES_ACTION);
+	}
+	
+	/**
+	 * Opens the <code>SearchForBuildFilesDialog</code> and adds the results to
+	 * the ant view.
+	 */
+	public void run() {
+		SearchForBuildFilesDialog dialog= new SearchForBuildFilesDialog();
+		if (dialog.open() != Window.CANCEL) {
+			final IFile[] files= dialog.getResults();
+			final boolean includeErrorNodes= dialog.getIncludeErrorResults();
+			final AntProjectNode[] existingProjects= view.getProjects();
+			try {
+				PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
+					public void run(IProgressMonitor monitor) {
+						monitor.beginTask(AntViewActionMessages.SearchForBuildFilesAction_Processing_search_results_3, files.length);
+						for (int i = 0; i < files.length && !monitor.isCanceled(); i++) {
+							String buildFileName= files[i].getFullPath().toString();
+							monitor.subTask(MessageFormat.format(AntViewActionMessages.SearchForBuildFilesAction_Adding__0__4, new String[] {buildFileName}));
+							if (alreadyAdded(buildFileName)) {
+								// Don't parse projects that have already been added.
+								continue;
+							}
+							final AntProjectNodeProxy project= new AntProjectNodeProxy(buildFileName);
+							// Force the project to be parsed so the error state is set.
+							project.parseBuildFile();
+							monitor.worked(1);
+							if (includeErrorNodes || !(project.isErrorNode())) {
+								Display.getDefault().asyncExec(new Runnable() {
+									public void run() {
+										view.addProject(project);
+									}
+								});
+							}
+						}
+					}
+					/**
+					 * Returns whether or not the given build file already
+					 * exists in the ant view.
+					 */
+					private boolean alreadyAdded(String buildFileName) {
+						for (int j = 0; j < existingProjects.length; j++) {
+							AntProjectNode existingProject = existingProjects[j];
+							if (existingProject.getBuildFileName().equals(buildFileName)) {
+								return true;
+							}
+						}
+						return false;
+					}
+				});
+			} catch (InvocationTargetException e) {
+			} catch (InterruptedException e) {
+			}
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/ui/launching/IAntLaunchConfigurationConstants.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/ui/launching/IAntLaunchConfigurationConstants.java
new file mode 100644
index 0000000..a493c00
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/ui/launching/IAntLaunchConfigurationConstants.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.ant.ui.launching;
+
+import org.eclipse.ant.launching.IAntLaunchConstants;
+
+/**
+ * Constant definitions for Ant launch configurations.
+ * 
+ * @since 3.4
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @deprecated use {@link IAntLaunchConstants}
+ */
+public interface IAntLaunchConfigurationConstants {
+
+	/**
+	 * Ant launch configuration type identifier.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ID_ANT_LAUNCH_CONFIGURATION_TYPE}
+	 */
+	public static final String ID_ANT_LAUNCH_CONFIGURATION_TYPE = IAntLaunchConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE;
+
+	/**
+	 * Ant builder launch configuration type identifier. Ant project builders
+	 * are of this type.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE}
+	 */
+	public static final String ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE = IAntLaunchConstants.ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE;
+	
+	/**
+	 * String attribute indicating the Ant targets to execute. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_ANT_TARGETS}
+	 */
+	public static final String ATTR_ANT_TARGETS = IAntLaunchConstants.ATTR_ANT_TARGETS;
+	
+	/**
+	 * String attribute indicating the Ant targets to execute after a clean (full build) for an Ant builder. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_ANT_AFTER_CLEAN_TARGETS}
+	 */
+	public static final String ATTR_ANT_AFTER_CLEAN_TARGETS = IAntLaunchConstants.ATTR_ANT_AFTER_CLEAN_TARGETS;
+	
+	/**
+	 * String attribute indicating the Ant targets to execute during a manual build for an Ant builder. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_ANT_MANUAL_TARGETS}
+	 */
+	public static final String ATTR_ANT_MANUAL_TARGETS = IAntLaunchConstants.ATTR_ANT_MANUAL_TARGETS;
+	
+	/**
+	 * String attribute indicating the Ant targets to execute during an auto build for an Ant builder. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_ANT_AUTO_TARGETS}
+	 */
+	public static final String ATTR_ANT_AUTO_TARGETS = IAntLaunchConstants.ATTR_ANT_AUTO_TARGETS;
+	
+	/**
+	 * String attribute indicating the Ant targets to execute during a clean for an Ant builder. Default value is
+	 * <code>null</code> which indicates that the default target is to be
+	 * executed. Format is a comma separated listing of targets.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_ANT_CLEAN_TARGETS}
+	 */
+	public static final String ATTR_ANT_CLEAN_TARGETS = IAntLaunchConstants.ATTR_ANT_CLEAN_TARGETS;
+	
+	/**
+	 * Boolean attribute indicating whether or not target specification for an Ant builder 
+	 * has been updated for 3.1 
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_TARGETS_UPDATED}
+	 */
+	public static final String ATTR_TARGETS_UPDATED = IAntLaunchConstants.ATTR_TARGETS_UPDATED;
+	
+	/**
+	 * Map attribute indicating the Ant properties to be defined during the
+	 * build. Default value is <code>null</code> which indicates no additional
+	 * properties will be defined.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_ANT_PROPERTIES}
+	 */
+	public static final String ATTR_ANT_PROPERTIES = IAntLaunchConstants.ATTR_ANT_PROPERTIES;					
+	
+	/**
+	 * String attribute indicating the Ant targets to execute. Default value is
+	 * <code>null</code> which indicates that no additional property files
+	 * will be defined. Format is a comma separated listing of property files.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_ANT_PROPERTY_FILES}
+	 */
+	public static final String ATTR_ANT_PROPERTY_FILES = IAntLaunchConstants.ATTR_ANT_PROPERTY_FILES;
+	
+	/**
+	 * Boolean attribute indicating whether or not internal targets (targets with no
+	 * description) should be hidden from the user in the launch configuration dialog.
+	 * Default value is <code>false</code> which indicates that all targets will be
+	 * displayed.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_HIDE_INTERNAL_TARGETS}
+	 */
+	public static final String ATTR_HIDE_INTERNAL_TARGETS = IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS;
+	
+	/**
+	 * Integer attribute indicating which column targets should be sorted on. A
+	 * value of 0 indicates target name, 1 indicates target description, and -1
+	 * indicates no sort. Default value is -1.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_SORT_TARGETS}
+	 */
+	public static final String ATTR_SORT_TARGETS = IAntLaunchConstants.ATTR_SORT_TARGETS;
+
+	/**
+	 * Boolean attribute indicating if the default VM install should be used for the separate JRE build
+	 * Default value is <code>false</code> for backwards compatibility
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ATTR_DEFAULT_VM_INSTALL}
+	 */
+	public static final String ATTR_DEFAULT_VM_INSTALL = IAntLaunchConstants.ATTR_DEFAULT_VM_INSTALL;
+
+	/**
+	 * Identifier for Ant processes (value <code>org.eclipse.ant.ui.antProcess</code>). This identifier is
+	 * set as the value for the <code>IProcess.ATTR_PROCESS_TYPE</code>
+	 * attribute in processes created by the Ant launch delegate.
+	 * 
+	 * @deprecated use {@link IAntLaunchConstants#ID_ANT_PROCESS_TYPE}
+	 */
+	public static final String ID_ANT_PROCESS_TYPE = IAntLaunchConstants.ID_ANT_PROCESS_TYPE;
+}
diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/ui/launching/package.html b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/ui/launching/package.html
new file mode 100644
index 0000000..55fd484
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/ui/launching/package.html
@@ -0,0 +1,13 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides support for Ant launching.
+<h2>
+Package Specification</h2>
+This package defines constants for Ant launch configuration attributes. 
+</body>
+</html>
diff --git a/ant/org.eclipse.ant.ui/Remote Ant Support/META-INF/eclipse.inf b/ant/org.eclipse.ant.ui/Remote Ant Support/META-INF/eclipse.inf
new file mode 100644
index 0000000..b4df3ab
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Remote Ant Support/META-INF/eclipse.inf
@@ -0,0 +1 @@
+jarprocessor.exclude.sign=true
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/ProxyInputHandler.java b/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/ProxyInputHandler.java
new file mode 100644
index 0000000..a8e06c3
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/ProxyInputHandler.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.antsupport.inputhandler;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.input.InputRequest;
+
+public class ProxyInputHandler implements InputHandler {
+	
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.input.InputHandler#handleInput(org.apache.tools.ant.input.InputRequest)
+	 */
+	public void handleInput(InputRequest request) throws BuildException {
+		new SWTInputHandler().handleInput(request);
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/RemoteAntMessages.java b/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/RemoteAntMessages.java
new file mode 100644
index 0000000..c232458
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/RemoteAntMessages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.ant.internal.ui.antsupport.inputhandler;
+
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class RemoteAntMessages {
+
+	private static final String BUNDLE_NAME = "org.eclipse.ant.internal.ui.antsupport.inputhandler.RemoteAntMessages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+	private RemoteAntMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/RemoteAntMessages.properties b/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/RemoteAntMessages.properties
new file mode 100644
index 0000000..3022e69
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/RemoteAntMessages.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+###############################################################################
+
+SWTInputHandler.0=Unable to respond to input request as a result of the user specified -noinput command
+SWTInputHandler.1=Ant Input Request
+SWTInputHandler.2=Unable to respond to <input> request
+SWTInputHandler.3=Input does not match validargs attribute
+SWTInputHandler.4=OK
+SWTInputHandler.5=Cancel
diff --git a/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/SWTInputHandler.java b/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/SWTInputHandler.java
new file mode 100644
index 0000000..6b77f13
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/Remote Ant Support/org/eclipse/ant/internal/ui/antsupport/inputhandler/SWTInputHandler.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *     Brock Janiczak (brockj@tpg.com.au) - Bug 145736
+ *******************************************************************************/
+
+package org.eclipse.ant.internal.ui.antsupport.inputhandler;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputRequest;
+import org.apache.tools.ant.input.MultipleChoiceInputRequest;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class SWTInputHandler extends DefaultInputHandler {
+	
+	private Text fText;
+	private Combo fCombo;
+	private Text fErrorMessageText;
+	private Button fOkButton;
+	private Shell fDialog;
+	private FontMetrics fFontMetrics;
+	protected InputRequest fRequest;
+    private boolean fFirstValidation= true;
+	
+	/* (non-Javadoc)
+	 * @see org.apache.tools.ant.input.InputHandler#handleInput(org.apache.tools.ant.input.InputRequest)
+	 */
+	public void handleInput(InputRequest request) throws BuildException {
+		if (System.getProperty("eclipse.ant.noInput") != null) { //$NON-NLS-1$
+			throw new BuildException(RemoteAntMessages.getString("SWTInputHandler.0")); //$NON-NLS-1$
+		}
+		fFirstValidation= true;
+		fRequest= request;
+		BuildException[] problem= new BuildException[1];
+		Runnable runnable= getHandleInputRunnable(problem);
+		Display.getDefault().syncExec(runnable);
+		if (problem[0] != null) {
+			throw problem[0];
+		}
+	}
+	
+	protected Runnable getHandleInputRunnable(final BuildException[] problem) {
+		return new Runnable() {
+			public void run() {
+				String prompt;
+				if (fRequest instanceof MultipleChoiceInputRequest) {
+					prompt = fRequest.getPrompt();
+				} else {
+					prompt = getPrompt(fRequest);
+				}
+		       	String title= RemoteAntMessages.getString("SWTInputHandler.1"); //$NON-NLS-1$
+		       	boolean[] result = new boolean[1];
+				open(title, prompt, result);
+		
+				if (!result[0]) {
+					problem[0]= new BuildException(RemoteAntMessages.getString("SWTInputHandler.2")); //$NON-NLS-1$
+				}
+			}
+		};
+	}
+	
+	protected void open(String title, String prompt, boolean[] result) {
+		createDialog(title, prompt, result);
+		validateInput();
+		fDialog.open();
+
+		while (!fDialog.isDisposed()) {
+			if (!fDialog.getDisplay().readAndDispatch()) fDialog.getDisplay().sleep();
+		}
+		Display.getDefault().dispose();
+	}
+
+    private void createDialog(String title, String prompt, boolean[] result) {
+        Display display= Display.getDefault();
+		fDialog = new Shell(display, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE);
+		initializeDialogUnits(fDialog);
+		fDialog.setLayout(new GridLayout());
+		
+		GridData gd= new GridData(SWT.FILL);
+		gd.horizontalSpan= 2;
+		fDialog.setLayoutData(gd);
+		fDialog.setText(title);
+		Label label= new Label(fDialog, SWT.WRAP);
+		label.setText(prompt);
+		GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER);
+        
+        data.widthHint = convertHorizontalDLUsToPixels(300); //from IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH
+        label.setLayoutData(data);
+        label.setFont(fDialog.getFont());
+        
+        if (fRequest instanceof MultipleChoiceInputRequest) {
+        	fCombo = new Combo(fDialog, SWT.BORDER | SWT.READ_ONLY);
+        	fCombo.add(""); //$NON-NLS-1$
+        	for (Iterator i = ((MultipleChoiceInputRequest)fRequest).getChoices().iterator();i.hasNext();) {
+        		fCombo.add((String)i.next());
+        		fCombo.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL| GridData.HORIZONTAL_ALIGN_FILL));
+        		fCombo.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						validateInput();
+					}
+				});
+        	}
+        } else {
+	        fText = new Text(fDialog, SWT.SINGLE | SWT.BORDER);
+	        fText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL| GridData.HORIZONTAL_ALIGN_FILL));
+	        fText.addModifyListener(new ModifyListener() {
+	            public void modifyText(ModifyEvent e) {
+	                validateInput();
+	            }
+	        });
+        }
+		
+    	String value = null;
+		try {
+			fRequest.getClass().getMethod("getDefaultValue", new Class[0]); //$NON-NLS-1$
+			value = fRequest.getDefaultValue();
+		} catch (SecurityException e) {
+		} catch (NoSuchMethodException e) {
+			//pre Ant 1.7.0
+		}
+		
+		fErrorMessageText = new Text(fDialog, SWT.READ_ONLY);
+        fErrorMessageText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
+        fErrorMessageText.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+        
+		createButtonBar(fDialog, result);
+		
+		if (value != null) {
+			if (fCombo != null) {
+				fCombo.select(fCombo.indexOf(value));
+			} else {
+				fText.setText(value);
+				fText.selectAll();
+			}
+		}
+		fDialog.pack();
+    }
+
+    protected void setErrorMessage(String errorMessage) {
+        fErrorMessageText.setText(errorMessage == null ? "" : errorMessage); //$NON-NLS-1$
+        fOkButton.setEnabled(errorMessage == null);
+        fErrorMessageText.getParent().update();
+    }
+    
+    protected void validateInput() {
+        String errorMessage = null;
+        if (fRequest instanceof MultipleChoiceInputRequest) {
+        	fRequest.setInput(fCombo.getText());
+        } else {
+        	fRequest.setInput(fText.getText());
+        }
+        if (!fRequest.isInputValid()) {
+            if (fFirstValidation) {
+                errorMessage= ""; //$NON-NLS-1$
+                fFirstValidation= false;
+            } else {
+                errorMessage= RemoteAntMessages.getString("SWTInputHandler.3"); //$NON-NLS-1$
+            } 
+       }
+       
+        setErrorMessage(errorMessage); 
+    }
+    
+    protected Control createButtonBar(Composite parent, boolean[] result) {
+        Composite composite = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout();
+        layout.numColumns = 2; 
+        layout.makeColumnsEqualWidth = true;
+        composite.setLayout(layout);
+        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER);
+        composite.setLayoutData(data);
+        composite.setFont(parent.getFont());
+       
+        createButtonsForButtonBar(composite, result);
+        return composite;
+    }
+    
+    protected void createButtonsForButtonBar(Composite parent, final boolean[] result) {
+    	fOkButton = new Button(parent, SWT.PUSH);
+		fOkButton.setText(RemoteAntMessages.getString("SWTInputHandler.4")); //$NON-NLS-1$
+		setButtonLayoutData(fOkButton);
+		
+		Button cancel = new Button(parent, SWT.PUSH);
+		cancel.setText(RemoteAntMessages.getString("SWTInputHandler.5")); //$NON-NLS-1$
+		Listener listener = new Listener() {
+			public void handleEvent(Event event) {
+				result[0] = event.widget == fOkButton;
+				fDialog.close();
+			}
+		};
+		setButtonLayoutData(cancel);
+		fOkButton.addListener(SWT.Selection, listener);
+		fDialog.setDefaultButton(fOkButton);
+		cancel.addListener(SWT.Selection, listener);
+        //do this here because setting the text will set enablement on the ok button
+		if (fRequest instanceof MultipleChoiceInputRequest) {
+			fCombo.setFocus();
+		} else {
+			fText.setFocus();
+		}
+    }
+    
+    private void setButtonLayoutData(Button button) {
+		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		int widthHint = convertHorizontalDLUsToPixels(61); //from IDialogConstants.BUTTON_WIDTH
+		Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+		data.widthHint = Math.max(widthHint, minSize.x);
+		button.setLayoutData(data);
+	}
+
+	private int convertHorizontalDLUsToPixels(int dlus) {
+        // round to the nearest pixel
+        return (fFontMetrics.getAverageCharWidth() * dlus + 4 / 2) / 4;
+	}
+
+	protected void initializeDialogUnits(Control control) {
+        // Compute and store a font metric
+        GC gc = new GC(control);
+        gc.setFont(control.getFont());
+        fFontMetrics = gc.getFontMetrics();
+        gc.dispose();
+    }
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/about.html b/ant/org.eclipse.ant.ui/about.html
new file mode 100644
index 0000000..1e94d07
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/about.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>October 8, 2009</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
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Third Party Content</h3>
+
+<p>The Content includes items that have been sourced from third parties as set out below. If you 
+did not receive this Content directly from the Eclipse Foundation, the following is provided 
+for informational purposes only, and you should look to the Redistributor&rsquo;s license for 
+terms and conditions of use.</p>
+
+<h4>Ant 1.7.1</h4>
+
+<p>The following classes in the plug-in JAR are based on Ant code developed by The Apache Software Foundation and shall be defined as the &quot;Ant-Derived Work&quot;:</p>
+
+<ul>
+	<li>org.eclipse.ant.internal.ui.editor.utils.ProjectHelper</li>
+</ul>
+
+<p>The object code for ProjectHelper is located
+in the plug-in JAR and the source code is located in src.zip.</p>
+
+<p>Your use of the Ant-Derived Work is subject to the terms and conditions of the Apache Software License 2.0.  A copy of the license is contained
+in the file <a href="about_files/asl-v20.txt" target="_blank">about_files/asl-v20.txt</a> and is also available at 
+<a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">http://www.apache.org/licenses/LICENSE-2.0.html</a>.</p>
+
+<p>The names &quot;Ant&quot; and  &quot;Apache Software Foundation&quot; must not be used to endorse or promote products derived from this 
+software without prior written permission.  For written permission, please contact <a href="mailto:apache@apache.org">apache@apache.org</a>.</p>
+
+<p>The Apache attribution <a href="about_files/NOTICE" target="_blank">NOTICE</a> file is included with the Content in accordance with 4d of the Apache License, Version 2.0.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/about_files/NOTICE b/ant/org.eclipse.ant.ui/about_files/NOTICE
new file mode 100644
index 0000000..1fb6dde
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/about_files/NOTICE
@@ -0,0 +1,15 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Apache Ant distribution.                      ==
+   =========================================================================
+
+   This product includes software developed by
+   The Apache Software Foundation (http://www.apache.org/).
+
+   This product includes also software developed by :
+     - the W3C consortium (http://www.w3c.org) ,
+     - the SAX project (http://www.saxproject.org)
+
+   Please read the different LICENSE files present in the root directory of
+   this distribution.
diff --git a/ant/org.eclipse.ant.ui/about_files/asl-v20.txt b/ant/org.eclipse.ant.ui/about_files/asl-v20.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/about_files/asl-v20.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/ant/org.eclipse.ant.ui/build.properties b/ant/org.eclipse.ant.ui/build.properties
new file mode 100644
index 0000000..99a5cc4
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/build.properties
@@ -0,0 +1,33 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+###############################################################################
+source.. = Ant Tools Support/,\
+                   Ant Editor/
+
+source.lib/antrunner.jar = Ant Runner Support/
+
+source.lib/remoteAnt.jar = Remote Ant Support/
+
+src.includes = about.html,\
+               about_files/
+
+bin.includes = icons/,\
+               plugin.properties,\
+               plugin.xml,\
+               about.html,\
+               templates/,\
+               .,\
+               lib/*.jar,\
+               META-INF/,\
+               about_files/
+				
+jars.compile.order=.,lib/antrunner.jar,lib/remoteAnt.jar
+output.lib/antrunner.jar = ant_runner_support_bin/
+output.lib/remoteAnt.jar = remote_support_bin/
diff --git a/ant/org.eclipse.ant.ui/buildfiles/exportplugin.xml b/ant/org.eclipse.ant.ui/buildfiles/exportplugin.xml
new file mode 100644
index 0000000..a15b9c9
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/buildfiles/exportplugin.xml
@@ -0,0 +1,44 @@
+<!-- Export a jar of .class files for the org.eclipse.ant.ui Eclipse plug-in
+     along with other important plugin files to the "plugin-export" subdirectory
+     of the target Eclipse installation -->
+<project name="Export antui" default="export" basedir="..">
+
+	<!-- Set the timestamp and important properties -->
+	<target name="init">
+		<tstamp/>
+		<property name="destdir" value="../../plugin-export" />
+		<property name="dest"  value="${destdir}/org.eclipse.ant.ui_3.0.0" />
+	</target>
+
+	<!-- Create the jar of .class files, and copy other important files to export dir -->
+	<target name="export" depends="init">
+		<mkdir dir="${destdir}" />
+		<delete dir="${dest}" />
+		<mkdir dir="${dest}" />
+		<delete dir="${dest}/lib"/>
+		<mkdir dir="${dest}/lib"/>
+		<jar destfile="${dest}/antui.jar">
+			<fileset dir="bin">
+				<exclude name="org/eclipse/ant/ui/internal/antsupport/*"/>
+				<exclude name="org/eclipse/ant/ui/internal/antsupport/inputhandler/*"/>
+				<exclude name="org/eclipse/ant/ui/internal/antsupport/logger/*"/>
+			</fileset>
+		</jar>
+		<!-- Create the source zip -->
+		<zip destfile="${dest}/antuisrc.zip">
+			<fileset dir="Ant Tools Support"/>
+			<fileset dir="Ant Runner Support"/>
+			<fileset dir="Ant Editor"/>
+		</zip>
+		<copy file="plugin.xml" todir="${dest}"/>
+		<copy file="plugin.properties" todir="${dest}"/>
+		<copy file=".classpath" todir="${dest}"/>
+		<copy file=".options" todir="${dest}"/>
+		<copy file="lib/antrunner.jar" todir="${dest}/lib"/>
+		<copy file="lib/remoteAnt.jar" todir="${dest}/lib"/>
+		<copy todir="${dest}/icons">
+			<fileset dir="icons" />
+		</copy>		
+	</target>
+	
+</project>
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/add_co.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/add_co.gif
new file mode 100644
index 0000000..0d92598
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/add_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/alpha_mode.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/alpha_mode.gif
new file mode 100644
index 0000000..f1e318e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/alpha_mode.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/ant_targets.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/ant_targets.gif
new file mode 100644
index 0000000..b1cc2cf
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/ant_targets.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/exportAnt_co.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/exportAnt_co.gif
new file mode 100644
index 0000000..952e365
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/exportAnt_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_imported_elements.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_imported_elements.gif
new file mode 100644
index 0000000..aa71721
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_imported_elements.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_internal_targets.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_internal_targets.gif
new file mode 100644
index 0000000..e7da81e
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_internal_targets.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_properties.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_properties.gif
new file mode 100644
index 0000000..cd9ee84
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_properties.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_top_level.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_top_level.gif
new file mode 100644
index 0000000..cc1ce15
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/filter_top_level.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/properties.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/properties.gif
new file mode 100644
index 0000000..0fbf9d0
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/properties.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/refresh.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/refresh.gif
new file mode 100644
index 0000000..e4a1d38
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/refresh.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/remove_co.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/remove_co.gif
new file mode 100644
index 0000000..559e462
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/remove_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/removeall_co.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/removeall_co.gif
new file mode 100644
index 0000000..ecd1be5
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/removeall_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/run_tool.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/run_tool.gif
new file mode 100644
index 0000000..a252bf0
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/run_tool.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/search.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/search.gif
new file mode 100644
index 0000000..f246a63
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/search.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dlcl16/synced.gif b/ant/org.eclipse.ant.ui/icons/full/dlcl16/synced.gif
new file mode 100644
index 0000000..4f6e43a
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dlcl16/synced.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dtool16/mark_occurrences.gif b/ant/org.eclipse.ant.ui/icons/full/dtool16/mark_occurrences.gif
new file mode 100644
index 0000000..1af4d3b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dtool16/mark_occurrences.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/dtool16/segment_edit.gif b/ant/org.eclipse.ant.ui/icons/full/dtool16/segment_edit.gif
new file mode 100644
index 0000000..d3da0f0
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/dtool16/segment_edit.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/add_co.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/add_co.gif
new file mode 100644
index 0000000..aa2eb88
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/add_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/alpha_mode.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/alpha_mode.gif
new file mode 100644
index 0000000..907d34f
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/alpha_mode.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/ant_targets.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/ant_targets.gif
new file mode 100644
index 0000000..cdb0402
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/ant_targets.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/exportAnt_co.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/exportAnt_co.gif
new file mode 100644
index 0000000..b643a35
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/exportAnt_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_imported_elements.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_imported_elements.gif
new file mode 100644
index 0000000..097f8a9
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_imported_elements.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_internal_targets.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_internal_targets.gif
new file mode 100644
index 0000000..ee7387c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_internal_targets.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_properties.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_properties.gif
new file mode 100644
index 0000000..3f46cf0
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_properties.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_top_level.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_top_level.gif
new file mode 100644
index 0000000..f58e082
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/filter_top_level.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/properties.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/properties.gif
new file mode 100644
index 0000000..6223cfc
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/properties.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/refresh.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/refresh.gif
new file mode 100644
index 0000000..3ca04d0
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/refresh.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/remove_co.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/remove_co.gif
new file mode 100644
index 0000000..2cd9c54
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/remove_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/removeall_co.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/removeall_co.gif
new file mode 100644
index 0000000..28a3785
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/removeall_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/run_tool.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/run_tool.gif
new file mode 100644
index 0000000..57f4102
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/run_tool.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/search.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/search.gif
new file mode 100644
index 0000000..d540a01
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/search.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/elcl16/synced.gif b/ant/org.eclipse.ant.ui/icons/full/elcl16/synced.gif
new file mode 100644
index 0000000..870934b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/elcl16/synced.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/etool16/mark_occurrences.gif b/ant/org.eclipse.ant.ui/icons/full/etool16/mark_occurrences.gif
new file mode 100644
index 0000000..fd7c175
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/etool16/mark_occurrences.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/etool16/segment_edit.gif b/ant/org.eclipse.ant.ui/icons/full/etool16/segment_edit.gif
new file mode 100644
index 0000000..acc5fb6
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/etool16/segment_edit.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/eview16/ant_view.gif b/ant/org.eclipse.ant.ui/icons/full/eview16/ant_view.gif
new file mode 100644
index 0000000..68d9564
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/eview16/ant_view.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/ant.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/ant.gif
new file mode 100644
index 0000000..2799542
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/ant.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/ant_buildfile.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/ant_buildfile.gif
new file mode 100644
index 0000000..6df3469
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/ant_buildfile.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/ant_target_err.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/ant_target_err.gif
new file mode 100644
index 0000000..0bc6068
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/ant_target_err.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/classpath.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/classpath.gif
new file mode 100644
index 0000000..fbfc41a
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/classpath.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/defaulttarget_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/defaulttarget_obj.gif
new file mode 100644
index 0000000..fbcf2f8
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/defaulttarget_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/eclipse_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/eclipse_obj.gif
new file mode 100644
index 0000000..eb7b90c
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/eclipse_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/import_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/import_obj.gif
new file mode 100644
index 0000000..b0e9130
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/import_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/macrodef_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/macrodef_obj.gif
new file mode 100644
index 0000000..1753b96
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/macrodef_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/main_tab.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/main_tab.gif
new file mode 100644
index 0000000..9b9f79a
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/main_tab.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/new_ant_project.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/new_ant_project.gif
new file mode 100644
index 0000000..e77d13b
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/new_ant_project.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/prop_ps.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/prop_ps.gif
new file mode 100644
index 0000000..6223cfc
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/prop_ps.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/property_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/property_obj.gif
new file mode 100644
index 0000000..f8277cf
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/property_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/targetinternal_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/targetinternal_obj.gif
new file mode 100644
index 0000000..da1a166
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/targetinternal_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/targetpublic_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/targetpublic_obj.gif
new file mode 100644
index 0000000..146a903
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/targetpublic_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/task_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/task_obj.gif
new file mode 100644
index 0000000..b914ed7
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/task_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/taskdef_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/taskdef_obj.gif
new file mode 100644
index 0000000..807d1f4
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/taskdef_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/template_obj.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/template_obj.gif
new file mode 100644
index 0000000..fdde5fb
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/template_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/obj16/type.gif b/ant/org.eclipse.ant.ui/icons/full/obj16/type.gif
new file mode 100644
index 0000000..76a58c5
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/obj16/type.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/ovr16/error_co.gif b/ant/org.eclipse.ant.ui/icons/full/ovr16/error_co.gif
new file mode 100644
index 0000000..119dccc
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/ovr16/error_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/ovr16/import_co.gif b/ant/org.eclipse.ant.ui/icons/full/ovr16/import_co.gif
new file mode 100644
index 0000000..b0a24b2
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/ovr16/import_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/ovr16/warning_co.gif b/ant/org.eclipse.ant.ui/icons/full/ovr16/warning_co.gif
new file mode 100644
index 0000000..ee2dac4
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/ovr16/warning_co.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/wizban/ant_wiz.png b/ant/org.eclipse.ant.ui/icons/full/wizban/ant_wiz.png
new file mode 100644
index 0000000..a87a775
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/wizban/ant_wiz.png
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/wizban/export_ant_wiz.png b/ant/org.eclipse.ant.ui/icons/full/wizban/export_ant_wiz.png
new file mode 100644
index 0000000..1142bd8
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/wizban/export_ant_wiz.png
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/templates/ant.properties b/ant/org.eclipse.ant.ui/templates/ant.properties
new file mode 100644
index 0000000..b7b3a8f
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/templates/ant.properties
@@ -0,0 +1,28 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+###############################################################################
+
+filesetTemplate1.description= fileset type with include clause
+targetTemplate1.description= public target
+targetTemplate2.description= private target
+propertyTemplate1.description= property with name and location
+propertyTemplate2.description= property with name and value
+macrodefTemplate.description= macrodef with a single attribute
+deleteTemplate1.description= delete files in a fileset
+deleteTemplate2.description= delete files in a referenced fileset
+
+javacTemplate1.description= add a javac task
+buildFileTemplate1.name= Buildfile template
+buildFileTemplate1.description= simple buildfile with two targets
+
+antComment.name= comment
+antComment.description= comments the selected word
+antLineComment.name= comment line
+antLineComment.description= comments the selected line
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/templates/ant.xml b/ant/org.eclipse.ant.ui/templates/ant.xml
new file mode 100644
index 0000000..2e79030
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/templates/ant.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *     Martin Karpisek (martin.karpisek@gmail.com) - bug 199014
+ *******************************************************************************/ 
+-->
+
+<templates>
+
+<template 
+	context="org.eclipse.ant.ui.templateContextType.task" 
+	description="%javacTemplate1.description" 
+	id="org.eclipse.ant.ui.templates.javac1" 
+	name="javac">&lt;javac srcdir=&quot;${src}&quot;
+         destdir=&quot;${dst}&quot;
+         classpath=&quot;${jarfile}&quot;
+         debug=&quot;${on}&quot;
+	/&gt;${cursor}</template>
+
+<template 
+	context="org.eclipse.ant.ui.templateContextType.task" 
+	description="%filesetTemplate1.description" 
+	id="org.eclipse.ant.ui.templates.fileset1" 
+	name="fileset"><![CDATA[<fileset dir="${dir}" id="${id}">
+    <include name="${include}"/>
+    <exclude name="${exclude}"/>
+</fileset>
+${cursor}]]></template>
+
+<template 
+    context="org.eclipse.ant.ui.templateContextType.task" 
+    description="%deleteTemplate1.description" 
+    id="org.eclipse.ant.ui.templates.delete1" 
+    name="delete"><![CDATA[<delete>
+	<fileset dir="${dir}">
+	    <include name="${include}"/>
+	    <exclude name="${exclude}"/>
+	</fileset>
+</delete>
+${cursor}]]></template>
+
+<template 
+    context="org.eclipse.ant.ui.templateContextType.task" 
+    description="%deleteTemplate2.description" 
+    id="org.eclipse.ant.ui.templates.delete2" 
+    name="delete"><![CDATA[<delete>
+    <fileset refid="${cursor}"/>
+</delete>]]>
+</template>
+
+<template 
+    context="org.eclipse.ant.ui.templateContextType.task" 
+    description="%propertyTemplate1.description" 
+    id="org.eclipse.ant.ui.templates.property1" 
+    name="property">&lt;property name=&quot;${name}&quot; location=&quot;${location}&quot;/&gt;
+</template>
+
+<template 
+    context="org.eclipse.ant.ui.templateContextType.task" 
+    description="%propertyTemplate2.description" 
+    id="org.eclipse.ant.ui.templates.property2" 
+    name="property">&lt;property name=&quot;${name}&quot; value=&quot;${value}&quot;/&gt;
+</template>
+
+<template 
+	context="org.eclipse.ant.ui.templateContextType.target" 
+	description="%targetTemplate1.description" 
+	id="org.eclipse.ant.ui.templates.target1" 
+	name="target"><![CDATA[<!-- ================================= 
+          target: ${name}              
+         ================================= -->
+    <target name="${name}" depends="${depends}" description="${description}">
+        ${cursor}
+    </target>
+]]></template>
+
+<template 
+    context="org.eclipse.ant.ui.templateContextType.target" 
+    description="%targetTemplate2.description" 
+    id="org.eclipse.ant.ui.templates.target2" 
+    name="target"><![CDATA[<!-- - - - - - - - - - - - - - - - - - 
+          target: ${name}                      
+         - - - - - - - - - - - - - - - - - -->
+    <target name="${name}">
+            ${cursor}
+    </target>
+]]></template>
+
+<template 
+    context="org.eclipse.ant.ui.templateContextType.task" 
+    description="%macrodefTemplate.description" 
+    id="org.eclipse.ant.ui.templates.macrodef" 
+    name="macrodef"><![CDATA[<!-- = = = = = = = = = = = = = = = = =
+          macrodef: ${name}          
+         = = = = = = = = = = = = = = = = = -->
+    <macrodef name="${name}">
+        <attribute name="${argname}" default="${default}" />
+        <sequential>
+            ${cursor}
+        </sequential>
+    </macrodef>
+]]></template>
+
+<template 
+	context="org.eclipse.ant.ui.templateContextType.buildFile" 
+	description="%buildFileTemplate1.description" 
+	id="org.eclipse.ant.ui.templates.buildFile1" 
+	name="%buildFileTemplate1.name"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<!-- ====================================================================== 
+     ${date} ${time}                                                        
+
+     ${project}    
+     ${description}
+                   
+     ${user}                                                                
+     ====================================================================== -->
+<project name="${project}" default="${default}">
+    <description>
+            ${description}
+    </description>
+
+    <!-- ================================= 
+          target: ${default}              
+         ================================= -->
+    <target name="${default}" depends="${depends}" description="${description}">
+        ${cursor}
+    </target>
+
+    <!-- - - - - - - - - - - - - - - - - - 
+          target: ${depends}                      
+         - - - - - - - - - - - - - - - - - -->
+    <target name="${depends}">
+    </target>
+
+</project>
+]]></template>
+
+<template name="%antComment.name" description="%antComment.description"
+	context="org.eclipse.ant.ui.templateContextType.buildFile" 
+	id="org.eclipse.ant.ui.templates.comment1" ><![CDATA[<!-- ${word_selection}-->]]></template>
+
+<template name="%antComment.name" description="%antComment.description"
+	context="org.eclipse.ant.ui.templateContextType.task" 
+	id="org.eclipse.ant.ui.templates.comment2"><![CDATA[<!-- ${word_selection}-->]]></template>
+
+<template name="%antLineComment.name" description="%antLineComment.description"
+	context="org.eclipse.ant.ui.templateContextType.buildFile" 
+	id="org.eclipse.ant.ui.templates.comment3"><![CDATA[<!--
+${line_selection}
+-->]]></template>
+
+<template name="%antLineComment.name" description="%antLineComment.description"
+	context="org.eclipse.ant.ui.templateContextType.task"
+	id="org.eclipse.ant.ui.templates.comment4"><![CDATA[<!--
+${line_selection}
+-->]]></template>
+
+</templates>
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/templates/resolver.gif b/ant/org.eclipse.ant.ui/templates/resolver.gif
new file mode 100644
index 0000000..4a26673
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/templates/resolver.gif
Binary files differ
diff --git a/update/org.eclipse.update.configurator/.classpath b/update/org.eclipse.update.configurator/.classpath
new file mode 100644
index 0000000..ce73933
--- /dev/null
+++ b/update/org.eclipse.update.configurator/.classpath
@@ -0,0 +1,7 @@
+<?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.4"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/update/org.eclipse.update.configurator/.cvsignore b/update/org.eclipse.update.configurator/.cvsignore
new file mode 100644
index 0000000..60463af
--- /dev/null
+++ b/update/org.eclipse.update.configurator/.cvsignore
@@ -0,0 +1,2 @@
+bin
+build.xml
diff --git a/update/org.eclipse.update.configurator/.options b/update/org.eclipse.update.configurator/.options
new file mode 100644
index 0000000..a2c714f
--- /dev/null
+++ b/update/org.eclipse.update.configurator/.options
@@ -0,0 +1,5 @@
+# Debugging options for the org.eclipse.update.configurator plugin
+
+# Turn on general debugging for the plugin.
+org.eclipse.update.configurator/debug=false
+
diff --git a/update/org.eclipse.update.configurator/.project b/update/org.eclipse.update.configurator/.project
new file mode 100644
index 0000000..1b13a10
--- /dev/null
+++ b/update/org.eclipse.update.configurator/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.update.configurator</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>
+		<buildCommand>
+			<name>org.eclipse.pde.ds.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update.configurator/.settings/org.eclipse.jdt.core.prefs b/update/org.eclipse.update.configurator/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..f790c32
--- /dev/null
+++ b/update/org.eclipse.update.configurator/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,81 @@
+#Fri Nov 07 15:57:54 EST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/update/org.eclipse.update.configurator/OSGI-INF/bundleGroup.xml b/update/org.eclipse.update.configurator/OSGI-INF/bundleGroup.xml
new file mode 100644
index 0000000..2cd3717
--- /dev/null
+++ b/update/org.eclipse.update.configurator/OSGI-INF/bundleGroup.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="false" name="org.eclipse.update.configurator.bundlegroup">
+   <implementation class="org.eclipse.update.internal.configurator.BundleGroupComponent"/>
+   <service>
+      <provide interface="org.eclipse.core.runtime.IBundleGroupProvider"/>
+   </service>
+</scr:component>
diff --git a/update/org.eclipse.update.configurator/about.html b/update/org.eclipse.update.configurator/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/update/org.eclipse.update.configurator/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</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
+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/update/org.eclipse.update.configurator/build.properties b/update/org.eclipse.update.configurator/build.properties
new file mode 100644
index 0000000..7574622
--- /dev/null
+++ b/update/org.eclipse.update.configurator/build.properties
@@ -0,0 +1,18 @@
+###############################################################################
+# Copyright (c) 2005, 2009 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
+###############################################################################
+bin.includes = .options,\
+               about.html,\
+               plugin.properties,\
+               .,\
+               META-INF/,\
+               OSGI-INF/
+src.includes = about.html
+source.. = src/
diff --git a/update/org.eclipse.update.configurator/plugin.properties b/update/org.eclipse.update.configurator/plugin.properties
new file mode 100644
index 0000000..d624a7f
--- /dev/null
+++ b/update/org.eclipse.update.configurator/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2003, 2006 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
+###############################################################################
+pluginName= Install/Update Configurator
+providerName= Eclipse.org
+
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/package.html b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/package.html
new file mode 100644
index 0000000..fa0f9f6
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/package.html
@@ -0,0 +1,22 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.72 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides support for accessing platform configuration data.
+<h2>
+Package Specification</h2>
+This package contains interfaces for accessing and manipulating the local
+system installation and configuration information. 
+<p>
+<b>Note:</b> This package is part of an interim API that is still under development and expected to
+change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+(repeatedly) as the API evolves.
+</p>
+</body>
+</html>
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/BundleManifest.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/BundleManifest.java
new file mode 100644
index 0000000..e26124e
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/BundleManifest.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *     James D Miles (IBM Corp.) - bug 182666, trim spaces from version id
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+import java.io.*;
+import java.util.jar.*;
+
+import org.eclipse.osgi.util.*;
+import org.osgi.framework.*;
+/**
+ * Parses MANIFEST.MF
+ */
+public class BundleManifest implements IConfigurationConstants {
+	private File manifestFile;
+	private PluginEntry pluginEntry;
+	private IOException exception;
+	private String bundleURL;
+	/**
+	 * Constructor for local file
+	 */
+	public BundleManifest(File manifest) {
+		super();
+		manifestFile = manifest;
+		if (manifest.exists() && !manifest.isDirectory()) {
+			FileInputStream fos = null;
+			try {
+				fos = new FileInputStream(manifest);
+				parse(fos);
+			} catch (IOException ioe) {
+			} finally {
+				if (fos != null) {
+					try {
+						fos.close();
+					} catch (IOException e) {
+					}
+				}
+			}
+		}
+	}
+		/**
+		 * Constructor for local file
+		 */
+		public BundleManifest(InputStream input, String bundleUrl) {
+			super();
+			bundleURL = bundleUrl;
+			if (input != null) {
+				parse(input);
+			}
+		}
+	/**
+	 * Parses manifest, creates PluginEntry if manifest is valid, stores
+	 * exception if any occurs
+	 * 
+	 * @param in
+	 *            InputStream
+	 */
+	private void parse(InputStream in) {
+		try {
+			Manifest m = new Manifest(in);
+			Attributes a = m.getMainAttributes();
+			// plugin id
+			String symbolicName = a.getValue(Constants.BUNDLE_SYMBOLICNAME);
+			if (symbolicName == null) {
+				// In Eclipse manifest must have Bundle-SymbolicName attribute
+				return;
+			}
+			String id;
+			try {
+				ManifestElement[] elements = ManifestElement.parseHeader(
+						Constants.BUNDLE_SYMBOLICNAME, symbolicName);
+				id = elements[0].getValue();
+			} catch (BundleException be) {
+				throw new IOException(be.getMessage());
+			}
+			// plugin version
+			String version = a.getValue(Constants.BUNDLE_VERSION);
+			if (version == null) {
+				Utils.log(NLS.bind(Messages.BundleManifest_noVersion, (new String[] { Constants.BUNDLE_VERSION, id })));
+				return;
+			}
+			version = version.trim();
+			String hostPlugin = a.getValue(Constants.FRAGMENT_HOST);
+			pluginEntry = new PluginEntry();
+			pluginEntry.setVersionedIdentifier(new VersionedIdentifier(id,
+					version));
+			pluginEntry.isFragment(hostPlugin != null
+					&& hostPlugin.length() > 0);
+			// Set URL
+			if(bundleURL!=null){
+				pluginEntry.setURL(bundleURL);
+			}else{
+				File pluginDir = manifestFile.getParentFile();
+				if (pluginDir != null) {
+					pluginDir = pluginDir.getParentFile();
+				}
+				if (pluginDir != null){
+					pluginEntry.setURL(PLUGINS + "/" + pluginDir.getName() + "/"); //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
+			//
+		} catch (IOException ioe) {
+			exception = ioe;
+		}
+	}
+	public boolean exists() {
+		return exception != null || pluginEntry != null;
+	}
+	/**
+	 * Obtains PluginEntry from a manifest.
+	 * 
+	 * @return PluginEntry or null if valid manifest does not exist
+	 * @throws IOException
+	 *             if exception during parsing
+	 */
+	public PluginEntry getPluginEntry() throws IOException {
+		if (exception != null) {
+			throw exception;
+		} 
+		return pluginEntry;		
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Configuration.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Configuration.java
new file mode 100644
index 0000000..ef83bb1
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Configuration.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *     James D Miles (IBM Corp.) - bug 176250, Configurator needs to handle more platform urls 
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import java.io.IOException;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configurator.*;
+import org.w3c.dom.*;
+
+public class Configuration implements IConfigurationConstants {
+	
+	private HashMap sites = new HashMap();
+	private HashMap platformURLs = new HashMap();
+	private Date date;
+	private long lastModified; // needed to account for file system limitations
+	private URL url;
+	private boolean transientConfig;
+	private boolean isDirty;
+	private Configuration linkedConfig; // shared configuration
+	private URL associatedInstallURL = Utils.getInstallURL();
+	
+	public Configuration() {
+		this(new Date());
+		// the config is created now or out of a platform.xml without a date
+		isDirty = true;
+	}
+	public Configuration(Date date)  {
+		this.date = date;
+	}
+	
+	public void setURL(URL url) {
+		this.url = url;
+	}
+	
+	public URL getURL() {
+		return url;
+	}
+	
+	public void setLinkedConfig(Configuration linkedConfig) {
+		this.linkedConfig = linkedConfig;
+		// make all the sites read-only
+		SiteEntry[] linkedSites = linkedConfig.getSites();
+		for (int i=0; i<linkedSites.length; i++)
+			linkedSites[i].setUpdateable(false);
+	}
+	
+	public Configuration getLinkedConfig() {
+		return linkedConfig;
+	}
+	
+	/**
+	 * @return true if the config needs to be saved
+	 */
+	public boolean isDirty() {
+		return isDirty;
+	}
+	
+	public void setDirty(boolean dirty) {
+		isDirty = dirty;
+	}
+	
+	public void addSiteEntry(String url, SiteEntry site) {
+		url = Utils.canonicalizeURL(url);
+		// only add the same site once
+		if (sites.get(url) == null && (linkedConfig == null || linkedConfig.sites.get(url) == null)) {
+			site.setConfig(this);
+			sites.put(url, site);
+			if(url.startsWith("platform:")){//$NON-NLS-1$
+				URL pURL;
+				try {
+					URL relSite= null;
+					if (url != null && url.startsWith("platform:/config")) {
+						// url for location of configuration is relative to platform.xml
+						URL config_loc = getURL();
+						relSite = new URL(config_loc, "..");
+					}else{
+						relSite = getInstallURL();
+					}
+					
+					pURL = new URL(url);
+					URL rURL = PlatformConfiguration.resolvePlatformURL(pURL, relSite);
+					String resolvedURL = rURL.toExternalForm();
+					platformURLs.put(resolvedURL, pURL);
+				} catch (IOException e) {
+					// can't resolve so can't have look up.
+				}
+			}
+		}
+	}
+	
+	public void removeSiteEntry(String url) {
+		url =Utils.canonicalizeURL(url);		
+		sites.remove(url);
+		if(url.startsWith("platform:")){ //$NON-NLS-1$
+			URL pURL;
+			try {
+				URL relSite= null;
+				if (url != null && url.startsWith("platform:/config")) {
+					// url for location of configuration is relative to platform.xml
+					URL config_loc = getURL();
+					relSite = new URL(config_loc, "..");
+				}else{
+					relSite = getInstallURL();
+				}
+				
+				pURL = new URL(url);
+				URL rURL = PlatformConfiguration.resolvePlatformURL(pURL, relSite);
+				String resolvedURL = rURL.toExternalForm();
+				platformURLs.remove(resolvedURL);
+			} catch (IOException e) {
+				// can't resolve so can't have look up.
+			}
+		}
+	}
+	
+	public SiteEntry getSiteEntry(String url) {
+		url = Utils.canonicalizeURL(url);		
+		SiteEntry site = (SiteEntry)sites.get(url);
+		if (site == null && linkedConfig != null)
+			site = linkedConfig.getSiteEntry(url);
+		return site;
+	}
+	
+	public SiteEntry[] getSites() {
+		if (linkedConfig == null)
+			return (SiteEntry[]) sites.values().toArray(new SiteEntry[sites.size()]);
+		ArrayList combinedSites = new ArrayList(sites.values());
+		combinedSites.addAll(linkedConfig.sites.values());
+		return (SiteEntry[]) combinedSites.toArray(new SiteEntry[combinedSites.size()]);
+	}
+	
+	public Element toXML(Document doc) throws CoreException {	
+		try {
+			Element configElement = doc.createElement(CFG);
+
+			configElement.setAttribute(CFG_VERSION, VERSION);
+			configElement.setAttribute(CFG_DATE, String.valueOf(date.getTime()));
+			String transitory = isTransient() ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
+			configElement.setAttribute(CFG_TRANSIENT, transitory);
+						
+			if (linkedConfig != null) {
+				// make externalized URL install relative 
+				configElement.setAttribute(CFG_SHARED_URL, Utils.makeRelative(getInstallURL(), linkedConfig.getURL()).toExternalForm());
+			}
+
+			// collect site entries
+			SiteEntry[] list = (SiteEntry[]) sites.values().toArray(new SiteEntry[0]);
+			for (int i = 0; i < list.length; i++) {
+				if (linkedConfig != null && linkedConfig.getSiteEntry(list[i].getURL().toExternalForm()) != null)
+					continue;
+				Element siteElement = list[i].toXML(doc);
+				configElement.appendChild(siteElement);
+			}
+			
+			return configElement;
+			
+		} catch (Exception e) {
+			throw Utils.newCoreException("", e); //$NON-NLS-1$
+		} 
+	}
+	
+	public boolean isTransient() {
+		return transientConfig;
+	}
+	
+	public void setTransient(boolean isTransient) {
+		this.transientConfig = isTransient;
+	}
+	
+	public Date getDate() {
+		return date;
+	}
+	
+	public void setDate(Date date) {
+		this.date = date;
+	}
+	
+	public boolean unconfigureFeatureEntry(IPlatformConfiguration.IFeatureEntry feature) {
+		SiteEntry[] sites = getSites();
+		for (int i=0; i<sites.length; i++)
+			if (sites[i].unconfigureFeatureEntry(feature))
+				return true;
+		return false;
+	}
+	
+	public void setLastModified(long lastModified) {
+		this.lastModified = lastModified;
+	}
+	
+	public long lastModified() {
+		return (lastModified != 0) ? lastModified : date.getTime();
+	}
+	
+	/**
+	 * Returns the url as a platform:/ url, if possible, else leaves it unchanged
+	 * @param url
+	 * @return
+	 */
+	public URL asPlatformURL(URL url) {
+		try {
+			if (url.getProtocol().equals("file")) {//$NON-NLS-1$
+				String rUrl = url.toExternalForm();
+				URL pUrl = (URL)platformURLs.get(rUrl);
+				if(pUrl == null)
+					return url;
+				return pUrl;
+			}
+			return url;
+		} catch (Exception e) {
+			return url;
+		}
+	}
+		
+	public URL getInstallURL() {
+		return associatedInstallURL;
+	}
+		
+	public void setInstallLocation(URL installURL) {
+		associatedInstallURL = installURL;
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureEntry.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureEntry.java
new file mode 100644
index 0000000..7c1912f
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureEntry.java
@@ -0,0 +1,367 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import java.net.*;
+import java.util.ArrayList;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.internal.configurator.branding.*;
+import org.osgi.framework.*;
+import org.w3c.dom.*;
+
+
+/**
+ * 
+ * Feature information
+ */
+public class FeatureEntry
+		implements
+			IPlatformConfiguration.IFeatureEntry,
+			IConfigurationConstants,
+			IBundleGroup,
+			IBundleGroupConstants,
+			IProductConstants {
+	private String id;
+	private String version;
+	private String pluginVersion;
+	private String application;
+	private URL[] root;
+	private boolean primary;
+	private String pluginIdentifier;
+	private String url;
+	private String description;
+	private String licenseURL;
+	private ArrayList plugins;
+	private AboutInfo branding;
+	private SiteEntry site;
+	private ResourceBundle resourceBundle;
+	private boolean fullyParsed;
+
+	public FeatureEntry(String id, String version, String pluginIdentifier, String pluginVersion, boolean primary, String application, URL[] root) {
+		if (id == null)
+			throw new IllegalArgumentException();
+		this.id = id;
+		this.version = version;
+		this.pluginVersion = pluginVersion;
+		this.pluginIdentifier = pluginIdentifier;
+		this.primary = primary;
+		this.application = application;
+		this.root = (root == null ? new URL[0] : root);
+	}
+
+	public FeatureEntry( String id, String version, String pluginVersion, boolean primary, String application, URL[] root) {
+		this(id, version, id, pluginVersion, primary, application, root);
+	}
+
+	public void setSite(SiteEntry site) {
+		this.site = site;
+	}
+	
+	public SiteEntry getSite() {
+		return this.site;
+	}
+	
+	public void addPlugin(PluginEntry plugin) {
+		if (plugins == null)
+			plugins = new ArrayList();
+		plugins.add(plugin);
+	}
+	
+	public PluginEntry[] getPluginEntries() {
+		if (plugins == null)
+			fullParse();
+		return (PluginEntry[])plugins.toArray(new PluginEntry[plugins.size()]);
+	}
+	
+	/**
+	 * Sets the url string (relative to the site url)
+	 * @param url
+	 */
+	public void setURL(String url) {
+		this.url = url;
+	}
+	
+	/**
+	 * @return the feature url (relative to the site): features/org.eclipse.platform/
+	 */
+	public String getURL() {
+//		if (url == null)
+//			url = FEATURES + "/" + id + "_" + version + "/";
+		return url;
+	}
+	
+	/*
+	 * @see IFeatureEntry#getFeatureIdentifier()
+	 */
+	public String getFeatureIdentifier() {
+		return id;
+	}
+
+	/*
+	 * @see IFeatureEntry#getFeatureVersion()
+	 */
+	public String getFeatureVersion() {
+		return version;
+	}
+
+	/*
+	 * @see IFeatureEntry#getFeaturePluginVersion()
+	 */
+	public String getFeaturePluginVersion() {
+		return pluginVersion != null && pluginVersion.length() > 0 ? pluginVersion : null;
+	}
+
+	/*
+	 * @see IFeatureEntry#getFeaturePluginIdentifier()
+	 */
+	public String getFeaturePluginIdentifier() {
+		// if no plugin is specified, use the feature id
+		return pluginIdentifier != null && pluginIdentifier.length() > 0 ? pluginIdentifier : id;
+	}
+	
+	/*
+	 * @see IFeatureEntry#getFeatureApplication()
+	 */
+	public String getFeatureApplication() {
+		return application;
+	}
+
+	/*
+	 * @see IFeatureEntry#getFeatureRootURLs()
+	 */
+	public URL[] getFeatureRootURLs() {
+		return root;
+	}
+
+	/*
+	 * @see IFeatureEntry#canBePrimary()
+	 */
+	public boolean canBePrimary() {
+		return primary;
+	}
+
+	public Element toXML(Document doc) {
+		URL installURL = getSite().getConfig().getInstallURL();	
+		
+		Element featureElement = doc.createElement(CFG_FEATURE_ENTRY);		
+		// write out feature entry settings
+		if (id != null)
+			featureElement.setAttribute(CFG_FEATURE_ENTRY_ID, id); 
+		if (primary)
+			featureElement.setAttribute(CFG_FEATURE_ENTRY_PRIMARY, "true"); //$NON-NLS-1$
+		if (version != null)
+			featureElement.setAttribute(CFG_FEATURE_ENTRY_VERSION, version); 
+		if (pluginVersion != null && !pluginVersion.equals(version) && pluginVersion.length() > 0)
+			featureElement.setAttribute(CFG_FEATURE_ENTRY_PLUGIN_VERSION, pluginVersion); 
+		if (pluginIdentifier != null && !pluginIdentifier.equals(id) && pluginIdentifier.length() > 0)
+			featureElement.setAttribute(CFG_FEATURE_ENTRY_PLUGIN_IDENTIFIER, pluginIdentifier);
+		if (application != null)
+			featureElement.setAttribute(CFG_FEATURE_ENTRY_APPLICATION, application);
+		if (url != null)
+			// make externalized URL install relative
+			featureElement.setAttribute(CFG_URL, Utils.makeRelative(installURL, url));
+		
+		URL[] roots = getFeatureRootURLs();
+		for (int i=0; i<roots.length; i++) {
+			// make externalized URL install relative
+			String root = Utils.makeRelative(installURL, roots[i]).toExternalForm();
+			if (root.trim().length() > 0){
+				Element rootElement = doc.createElement(CFG_FEATURE_ENTRY_ROOT);
+				rootElement.appendChild(doc.createTextNode(root));
+				featureElement.appendChild(rootElement);
+			}
+		}
+		
+		return featureElement;
+	}
+	
+	public void setDescription(String description) {
+		this.description = description;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IBundleGroup#getBundles()
+	 */
+	public Bundle[] getBundles() {
+		if (plugins == null)
+			fullParse();
+		
+		ArrayList bundles = new ArrayList(plugins.size());
+		for (int i=0; i<plugins.size(); i++) {
+			PluginEntry plugin = (PluginEntry)plugins.get(i);
+			// get the highest version for the plugin
+			Bundle bundle = Utils.getBundle(plugin.getPluginIdentifier());
+			if (bundle != null)
+				bundles.add(bundle);
+		}
+		return (Bundle[])bundles.toArray(new Bundle[bundles.size()]);
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IBundleGroup#getDescription()
+	 */
+	public String getDescription() {
+		if (description == null)
+			fullParse();
+		return description;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IBundleGroup#getIdentifier()
+	 */
+	public String getIdentifier() {
+		return id;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IBundleGroup#getName()
+	 */
+	public String getName() {
+		if (branding == null)
+			branding = AboutInfo.readFeatureInfo(id, version, getFeaturePluginIdentifier());
+		return branding.getProductName();
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IBundleGroup#getProperty(java.lang.String)
+	 */
+	public String getProperty(String key) {
+		if (key == null)
+			return null;
+		
+		if (branding == null)
+			branding = AboutInfo.readFeatureInfo(id, version, getFeaturePluginIdentifier());
+		
+		// IBundleGroupConstants
+		if (key.equals(FEATURE_IMAGE))
+			return branding.getFeatureImageURL() == null ? null : branding.getFeatureImageURL().toExternalForm();
+		else if (key.equals(TIPS_AND_TRICKS_HREF)) 
+			return branding.getTipsAndTricksHref();
+		else if (key.equals(IBundleGroupConstants.WELCOME_PAGE)) // same value is used by product and bundle group
+			return branding.getWelcomePageURL() == null ? null : branding.getWelcomePageURL().toExternalForm();
+		else if (key.equals(WELCOME_PERSPECTIVE))
+			return branding.getWelcomePerspectiveId();
+		else if (key.equals(BRANDING_BUNDLE_ID))
+			return pluginIdentifier;
+		else if (key.equals(BRANDING_BUNDLE_VERSION))
+			return pluginVersion;
+		// IProductConstants
+		else if (key.equals(APP_NAME)) 
+			return branding.getAppName();
+		else if (key.equals(ABOUT_TEXT))
+			return branding.getAboutText();
+		else if (key.equals(ABOUT_IMAGE))
+			return branding.getAboutImageURL() == null ? null : branding.getAboutImageURL().toExternalForm();
+		else if (key.equals(WINDOW_IMAGE))
+			return branding.getWindowImageURL()== null ? null : branding.getWindowImageURL().toExternalForm();
+		else if (key.equals(WINDOW_IMAGES)) {
+			URL[] urls = branding.getWindowImagesURLs();
+			if (urls == null)
+				return null;
+			StringBuffer windowImagesURLs = new StringBuffer();
+			for (int i=0; i<urls.length; i++){
+				windowImagesURLs.append(urls[i].toExternalForm());
+				if (i != urls.length-1)
+					windowImagesURLs.append(',');
+			}
+			return windowImagesURLs.toString();
+		} else if (key.equals(LICENSE_HREF))
+			return getLicenseURL();
+		
+		return null;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IBundleGroup#getProviderName()
+	 */
+	public String getProviderName() {
+		if (branding == null)
+			branding = AboutInfo.readFeatureInfo(id, version, getFeaturePluginIdentifier());
+		return branding.getProviderName();
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IBundleGroup#getVersion()
+	 */
+	public String getVersion() {
+		return version;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProduct#getApplication()
+	 */
+	public String getApplication() {
+		return application;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProduct#getId()
+	 */
+	public String getId() {
+		return id;
+	}
+	
+	public ResourceBundle getResourceBundle(){
+		if (resourceBundle != null)
+			return resourceBundle;
+		
+		// Determine the properties file location
+		if (site == null)
+			return null;
+		
+		ResourceBundle bundle = null;
+		try {
+			URL propertiesURL = new URL(site.getResolvedURL(), getURL());
+			ClassLoader l = new URLClassLoader(new URL[] { propertiesURL }, null);
+			bundle = ResourceBundle.getBundle(IConfigurationConstants.CFG_FEATURE_ENTRY, Utils.getDefaultLocale(), l);
+		} catch (MissingResourceException e) {
+			Utils.log(e.getLocalizedMessage()); 
+		} catch (MalformedURLException e) {
+			Utils.log(e.getLocalizedMessage()); 
+		}
+		return bundle;
+	}
+	
+	public void setLicenseURL(String licenseURL) {
+		this.licenseURL = licenseURL;
+	}
+	
+	public String getLicenseURL() {
+		if (licenseURL == null)
+			fullParse();
+		if (licenseURL == null)
+			return null;
+		
+		String resolvedURL = Utils.getResourceString(getResourceBundle(), licenseURL);
+		if (resolvedURL.startsWith("http://")) //$NON-NLS-1$
+			return resolvedURL;
+		try {
+			return new URL(getSite().getResolvedURL(), getURL() + resolvedURL).toExternalForm();
+		} catch (MalformedURLException e) {
+			return resolvedURL;
+		}
+	}
+	
+	private void fullParse() {
+		if (fullyParsed)
+			return;
+		fullyParsed = true;
+		if (plugins == null) 
+			plugins = new ArrayList();
+		FullFeatureParser parser = new FullFeatureParser(this);
+		parser.parse();
+	}
+	
+	public Bundle getDefiningBundle() {
+		return Utils.getBundle(getFeaturePluginIdentifier());
+	}
+	
+	public boolean hasBranding() {
+        String bundleId = getFeaturePluginIdentifier();
+		return bundleId != null && Utils.getBundle(bundleId) != null;
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureParser.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureParser.java
new file mode 100644
index 0000000..e2ce599
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureParser.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+
+import java.io.*;
+import java.net.*;
+
+import javax.xml.parsers.*;
+
+import org.eclipse.osgi.util.NLS;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+/**
+ * Default feature parser.
+ * Parses the feature manifest file as defined by the platform.
+ * 
+ * @since 3.0
+ */
+public class FeatureParser extends DefaultHandler {
+
+	private SAXParser parser;
+	private FeatureEntry feature;
+	private URL url;
+
+	private final static SAXParserFactory parserFactory =
+		SAXParserFactory.newInstance();
+
+	/**
+	 * Constructs a feature parser.
+	 */
+	public FeatureParser() {
+		super();
+		try {
+			parserFactory.setNamespaceAware(true);
+			this.parser = parserFactory.newSAXParser();
+		} catch (ParserConfigurationException e) {
+			System.out.println(e);
+		} catch (SAXException e) {
+			System.out.println(e);
+		}
+	}
+	/**
+	 * Parses the specified url and constructs a feature
+	 */
+	public FeatureEntry parse(URL featureURL){
+		feature=null;
+		InputStream in = null;
+		try {
+			this.url = featureURL;
+			in = featureURL.openStream();
+			parser.parse(new InputSource(in), this);
+		} catch (SAXException e) {
+		} catch (IOException e) {
+		} finally {
+			if (in != null)
+				try {
+					in.close();
+				} catch (IOException e1) {
+					Utils.log(e1.getLocalizedMessage());
+				}
+		}
+		return feature;
+	}
+
+	/**
+	 * Handle start of element tags
+	 * @see DefaultHandler#startElement(String, String, String, Attributes)
+	 * @since 2.0
+	 */
+	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+
+		Utils.debug("Start Element: uri:" + uri + " local Name:" + localName + " qName:" + qName); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+		if ("feature".equals(localName)) { //$NON-NLS-1$
+			processFeature(attributes);
+			// stop parsing now
+			throw new SAXException(""); //$NON-NLS-1$
+		} 
+	}
+
+	/*
+	 * Process feature information
+	 */
+	private void processFeature(Attributes attributes) {
+
+		// identifier and version
+		String id = attributes.getValue("id"); //$NON-NLS-1$
+		String ver = attributes.getValue("version"); //$NON-NLS-1$
+
+		if (id == null || id.trim().equals("") //$NON-NLS-1$
+		|| ver == null || ver.trim().equals("")) { //$NON-NLS-1$
+			System.out.println(NLS.bind(Messages.FeatureParser_IdOrVersionInvalid, (new String[] { id, ver})));
+		} else {
+//			String label = attributes.getValue("label"); //$NON-NLS-1$
+//			String provider = attributes.getValue("provider-name"); //$NON-NLS-1$
+//			String imageURL = attributes.getValue("image"); //$NON-NLS-1$
+			String os = attributes.getValue("os"); //$NON-NLS-1$
+			String ws = attributes.getValue("ws"); //$NON-NLS-1$
+			String nl = attributes.getValue("nl"); //$NON-NLS-1$
+			String arch = attributes.getValue("arch"); //$NON-NLS-1$
+			if (!Utils.isValidEnvironment(os, ws, arch, nl)) 
+				return;
+//			String exclusive = attributes.getValue("exclusive"); //$NON-NLS-1$
+//			String affinity = attributes.getValue("colocation-affinity"); //$NON-NLS-1$
+
+			String primary = attributes.getValue("primary"); //$NON-NLS-1$
+			boolean isPrimary = "true".equals(primary); //$NON-NLS-1$
+			String application = attributes.getValue("application"); //$NON-NLS-1$
+			String plugin = attributes.getValue("plugin"); //$NON-NLS-1$
+
+			//TODO rootURLs
+			feature = new FeatureEntry(id, ver, plugin, "", isPrimary, application, null ); //$NON-NLS-1$
+			if ("file".equals(url.getProtocol())) { //$NON-NLS-1$
+				File f = new File(url.getFile().replace('/', File.separatorChar));
+				feature.setURL("features" + "/" + f.getParentFile().getName() + "/");// + f.getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			} else {
+				// externalized URLs might be in relative form, ensure they are absolute				
+				feature.setURL(Utils.makeAbsolute(Utils.getInstallURL(), url).toExternalForm());
+			}
+
+			Utils.
+				debug("End process DefaultFeature tag: id:" +id + " ver:" +ver + " url:" + feature.getURL()); 	 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		}
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FullFeatureParser.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FullFeatureParser.java
new file mode 100644
index 0000000..3475626
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FullFeatureParser.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+
+import java.io.*;
+import java.net.*;
+import java.util.ResourceBundle;
+
+import javax.xml.parsers.*;
+
+import org.eclipse.osgi.util.NLS;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+/**
+ * A more complete feature parser. It adds the plugins listed to the feature.
+ */
+public class FullFeatureParser extends DefaultHandler implements IConfigurationConstants{
+
+	private SAXParser parser;
+	private FeatureEntry feature;
+	private URL url;
+	private boolean isDescription;
+	private StringBuffer description = new StringBuffer();
+
+	private final static SAXParserFactory parserFactory =
+		SAXParserFactory.newInstance();
+
+	/**
+	 * Constructs a feature parser.
+	 */
+	public FullFeatureParser(FeatureEntry feature) {
+		super();
+		this.feature = feature;
+		try {
+			parserFactory.setNamespaceAware(true);
+			this.parser = parserFactory.newSAXParser();
+		} catch (ParserConfigurationException e) {
+			System.out.println(e);
+		} catch (SAXException e) {
+			System.out.println(e);
+		}
+	}
+	/**
+	 */
+	public void parse(){
+		InputStream in = null;
+		try {
+			if (feature.getSite() == null)
+				return;
+			this.url = new URL(feature.getSite().getResolvedURL(), feature.getURL() + FEATURE_XML);
+			in = url.openStream();
+			parser.parse(new InputSource(in), this);
+		} catch (SAXException e) {
+		} catch (IOException e) {
+		} finally {
+			if (in != null)
+				try {
+					in.close();
+				} catch (IOException e1) {
+					Utils.log(e1.getLocalizedMessage());
+				}
+		}
+	}
+
+	/**
+	 * Handle start of element tags
+	 * @see DefaultHandler#startElement(String, String, String, Attributes)
+	 * @since 2.0
+	 */
+	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+
+		Utils.debug("Start Element: uri:" + uri + " local Name:" + localName + " qName:" + qName); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+		if ("plugin".equals(localName)) { //$NON-NLS-1$
+			processPlugin(attributes);
+		} else if ("description".equals(localName)){ //$NON-NLS-1$
+			isDescription = true;
+		} else if ("license".equals(localName)) { //$NON-NLS-1$
+			processLicense(attributes);
+		}
+	}
+
+	/*
+	 * Process feature information
+	 */
+	private void processPlugin(Attributes attributes) {
+
+		// identifier and version
+		String id = attributes.getValue("id"); //$NON-NLS-1$
+		String ver = attributes.getValue("version"); //$NON-NLS-1$
+
+		if (id == null || id.trim().equals("") //$NON-NLS-1$
+		|| ver == null || ver.trim().equals("")) { //$NON-NLS-1$
+			System.out.println(NLS.bind(Messages.FeatureParser_IdOrVersionInvalid, (new String[] { id, ver})));
+		} else {
+//			String label = attributes.getValue("label"); //$NON-NLS-1$
+//			String provider = attributes.getValue("provider-name"); //$NON-NLS-1$
+			String nl = attributes.getValue("nl"); //$NON-NLS-1$
+			String os = attributes.getValue("os"); //$NON-NLS-1$
+			String ws = attributes.getValue("ws"); //$NON-NLS-1$
+			String arch = attributes.getValue("arch"); //$NON-NLS-1$
+			if (!Utils.isValidEnvironment(os, ws, arch,nl))
+				return;
+
+			PluginEntry plugin = new PluginEntry();
+			plugin.setPluginIdentifier(id);
+			plugin.setPluginVersion(ver);
+			feature.addPlugin(plugin);
+			
+			Utils.
+				debug("End process DefaultFeature tag: id:" +id + " ver:" +ver + " url:" + feature.getURL()); 	 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		}
+	}
+	
+	private void processLicense(Attributes attributes ){
+		feature.setLicenseURL(attributes.getValue("url")); //$NON-NLS-1$
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+	 */
+	public void characters(char[] ch, int start, int length)
+			throws SAXException {
+		if (!isDescription)
+			return;
+		description.append(ch, start, length);
+	}
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public void endElement(String uri, String localName, String qName)
+			throws SAXException {
+		if ("description".equals(localName)) { //$NON-NLS-1$
+			isDescription = false;
+			String d = description.toString().trim();
+			ResourceBundle bundle = feature.getResourceBundle();
+			feature.setDescription(Utils.getResourceString(bundle, d));
+		}
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/IConfigurationConstants.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/IConfigurationConstants.java
new file mode 100644
index 0000000..e7205bc
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/IConfigurationConstants.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import org.eclipse.update.configurator.IPlatformConfiguration.*;
+
+/**
+ * Constants
+ */
+public interface IConfigurationConstants {
+	public static final String ECLIPSE_PRODUCT = "eclipse.product"; //$NON-NLS-1$
+	public static final String ECLIPSE_APPLICATION = "eclipse.application"; //$NON-NLS-1$
+	public static final String CFG = "config"; //$NON-NLS-1$
+	public static final String CFG_SITE = "site"; //$NON-NLS-1$
+	public static final String CFG_URL = "url"; //$NON-NLS-1$
+	public static final String CFG_POLICY = "policy"; //$NON-NLS-1$
+	public static final String[] CFG_POLICY_TYPE = { "USER-INCLUDE", "USER-EXCLUDE", "MANAGED-ONLY" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	public static final String CFG_POLICY_TYPE_UNKNOWN = "UNKNOWN"; //$NON-NLS-1$
+	public static final String CFG_LIST = "list"; //$NON-NLS-1$
+	public static final String CFG_UPDATEABLE = "updateable"; //$NON-NLS-1$
+	public static final String CFG_LINK_FILE = "linkfile"; //$NON-NLS-1$
+	public static final String CFG_FEATURE_ENTRY = "feature"; //$NON-NLS-1$
+	public static final String CFG_FEATURE_ENTRY_ID = "id"; //$NON-NLS-1$
+	public static final String CFG_FEATURE_ENTRY_PRIMARY = "primary"; //$NON-NLS-1$
+	public static final String CFG_FEATURE_ENTRY_VERSION = "version"; //$NON-NLS-1$
+	public static final String CFG_FEATURE_ENTRY_PLUGIN_VERSION = "plugin-version"; //$NON-NLS-1$
+	public static final String CFG_FEATURE_ENTRY_PLUGIN_IDENTIFIER = "plugin-identifier"; //$NON-NLS-1$
+	public static final String CFG_FEATURE_ENTRY_APPLICATION = "application"; //$NON-NLS-1$
+	public static final String CFG_FEATURE_ENTRY_ROOT = "root"; //$NON-NLS-1$
+	public static final String CFG_DATE = "date"; //$NON-NLS-1$
+	public static final String CFG_PLUGIN = "plugin"; //$NON-NLS-1$
+	public static final String CFG_FRAGMENT = "fragment"; //$NON-NLS-1$
+	public static final String CFG_ENABLED = "enabled"; //$NON-NLS-1$
+	public static final String CFG_SHARED_URL = "shared_ur"; //$NON-NLS-1$
+	
+
+	public static final String CFG_VERSION = "version"; //$NON-NLS-1$
+	public static final String CFG_TRANSIENT = "transient"; //$NON-NLS-1$
+	public static final String VERSION = "3.0"; //$NON-NLS-1$
+
+	public static final int DEFAULT_POLICY_TYPE = ISitePolicy.USER_EXCLUDE;
+	public static final String[] DEFAULT_POLICY_LIST = new String[0];
+	
+	public static final String PLUGINS = "plugins"; //$NON-NLS-1$
+	public static final String FEATURES = "features"; //$NON-NLS-1$
+	public static final String PLUGIN_XML = "plugin.xml"; //$NON-NLS-1$
+	public static final String FRAGMENT_XML = "fragment.xml"; //$NON-NLS-1$
+	public static final String META_MANIFEST_MF = "META-INF/MANIFEST.MF"; //$NON-NLS-1$
+	public static final String FEATURE_XML = "feature.xml"; //$NON-NLS-1$
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Locker.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Locker.java
new file mode 100644
index 0000000..2176eab
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Locker.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import java.io.IOException;
+
+/**
+ * Internal class.
+ */
+public interface Locker {
+	public boolean lock() throws IOException;
+	public void release();
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Locker_JavaIo.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Locker_JavaIo.java
new file mode 100644
index 0000000..482ea1e
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Locker_JavaIo.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import java.io.*;
+
+/**
+ * Internal class.
+ */
+public class Locker_JavaIo implements Locker {
+	private File lockFile;
+	private RandomAccessFile lockRAF;
+
+	public Locker_JavaIo(File lockFile) {
+		this.lockFile = lockFile;
+	}
+
+	public synchronized boolean lock() throws IOException {
+		//if the lock file already exists, try to delete,
+		//assume failure means another eclipse has it open
+		if (lockFile.exists())
+			lockFile.delete();
+		if (lockFile.exists())
+			return false;
+
+		//open the lock file so other instances can't co-exist
+		lockRAF = new RandomAccessFile(lockFile, "rw"); //$NON-NLS-1$
+		lockRAF.writeByte(0);
+
+		return true;
+	}
+
+	public synchronized void release() {
+		try {
+			if (lockRAF != null) {
+				lockRAF.close();
+				lockRAF = null;
+			}
+		} catch (IOException e) {
+			//don't complain, we're making a best effort to clean up
+		}
+		if (lockFile != null)
+			lockFile.delete();
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Locker_JavaNio.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Locker_JavaNio.java
new file mode 100644
index 0000000..b3fad34
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Locker_JavaNio.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 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
+ *  *    Andrei Loskutov - bug 44735
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import java.io.*;
+import java.nio.channels.FileLock;
+import java.nio.channels.OverlappingFileLockException;
+
+/**
+ * Internal class.
+ */
+public class Locker_JavaNio implements Locker {
+	private File lockFile;
+	private RandomAccessFile raf;
+	private FileLock fileLock;
+
+	public Locker_JavaNio(File lockFile) {
+		this.lockFile = lockFile;
+	}
+
+	public synchronized boolean lock() throws IOException {
+		raf = new RandomAccessFile(lockFile, "rw"); //$NON-NLS-1$
+		try{
+			/*
+			 * fix for bug http://bugs.sun.com/view_bug.do?bug_id=6628575 and
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=44735#c17
+			 */
+			fileLock = raf.getChannel().tryLock(0, 1, false);
+		} catch(OverlappingFileLockException e) {
+			fileLock = null;
+		} finally {
+			if (fileLock != null)
+				return true;
+			raf.close();
+			raf = null;
+		}
+		return false;
+	}
+
+	public synchronized void release() {
+		if (fileLock != null) {
+			try {
+				fileLock.release();
+			} catch (IOException e) {
+				//don't complain, we're making a best effort to clean up
+			}
+			fileLock = null;
+		}
+		if (raf != null) {
+			try {
+				raf.close();
+			} catch (IOException e) {
+				//don't complain, we're making a best effort to clean up
+			}
+			raf = null;
+		}
+		if (lockFile != null) {
+			lockFile.delete();
+			lockFile = null;
+		}
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Messages.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Messages.java
new file mode 100644
index 0000000..66888a6
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/Messages.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class Messages extends NLS {
+
+	private static final String BUNDLE_NAME = "org.eclipse.update.internal.configurator.messages";//$NON-NLS-1$
+
+	private Messages() {
+		// Do not instantiate
+	}
+
+	public static String cfig_unableToLoad_noURL;
+	public static String cfig_unableToSave_noURL;
+	public static String cfig_unableToSave;
+	public static String InstalledSiteParser_UnableToCreateURL;
+	public static String InstalledSiteParser_UnableToCreateURLForFile;
+	public static String InstalledSiteParser_ErrorParsingFile;
+	public static String InstalledSiteParser_ErrorAccessing;
+	public static String InstalledSiteParser_date;
+	public static String BundleManifest_noVersion;
+	public static String FeatureParser_IdOrVersionInvalid;
+	public static String BundleGroupProvider;
+	public static String ConfigurationActivator_initialize;
+	public static String ConfigurationActivator_createConfig;
+	public static String ConfigurationActivator_uninstallBundle;
+	public static String ConfigurationParser_cannotLoadSharedInstall;
+	public static String ConfigurationActivator_installBundle;
+	public static String PluginEntry_versionError;
+	public static String IniFileReader_MissingDesc;
+	public static String IniFileReader_OpenINIError;
+	public static String IniFileReader_ReadIniError;
+	public static String IniFileReader_ReadPropError;
+	public static String IniFileReader_ReadMapError;
+	public static String SiteEntry_computePluginStamp;
+	public static String SiteEntry_cannotFindFeatureInDir;
+	public static String SiteEntry_duplicateFeature;
+	public static String SiteEntry_pluginsDir;
+	public static String PlatformConfiguration_expectingPlatformXMLorDirectory;
+	public static String PlatformConfiguration_cannotBackupConfig;
+	public static String PlatformConfiguration_cannotCloseStream;
+	public static String PlatformConfiguration_cannotCloseTempFile;
+	public static String PlatformConfiguration_cannotRenameTempFile;
+	public static String PlatformConfiguration_cannotLoadConfig;
+	public static String PlatformConfiguration_cannotLoadDefaultSite;
+	public static String PlatformConfiguration_cannotFindConfigFile;
+	public static String PlatformConfiguration_cannotSaveNonExistingConfig;
+	public static String PluginParser_plugin_no_id;
+	public static String PluginParser_plugin_no_version;
+
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	public static String XMLPrintHandler_unsupportedNodeType;
+}
\ No newline at end of file
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PlatformConfigurationFactory.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PlatformConfigurationFactory.java
new file mode 100644
index 0000000..c9c4448
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PlatformConfigurationFactory.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.configurator.IPlatformConfigurationFactory;
+
+public class PlatformConfigurationFactory implements IPlatformConfigurationFactory {
+	public IPlatformConfiguration getCurrentPlatformConfiguration() {
+		return PlatformConfiguration.getCurrent();
+	}
+	
+	public IPlatformConfiguration getPlatformConfiguration(URL url)	throws IOException {
+		try {
+			return new PlatformConfiguration(url);
+		} catch (Exception e) {
+			if (e instanceof IOException)
+				throw (IOException)e;
+			throw new IOException(e.getMessage());
+		}
+	}
+	
+	public IPlatformConfiguration getPlatformConfiguration(URL url, URL loc) throws IOException {
+		try {
+			return new PlatformConfiguration(url, loc);
+		} catch (Exception e) {
+			if (e instanceof IOException)
+				throw (IOException)e;
+			throw new IOException(e.getMessage());
+		}
+	}
+	
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PluginEntry.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PluginEntry.java
new file mode 100644
index 0000000..7ca4f23
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PluginEntry.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import org.eclipse.osgi.util.NLS;
+
+
+/**
+ */
+public class PluginEntry {
+
+	private String pluginId;
+	private String pluginVersion;
+	private boolean isFragment = false;
+	private VersionedIdentifier versionId;
+	private String url;
+	
+	public PluginEntry() {
+		super();
+	}
+
+	/**
+	 * @return url relative to the site location: plugins/org.eclipse.foo/plugin.xml
+	 * Note: to do: we should probably only use plugins/org.eclipse.foo/ in the future
+	 */
+	public String getURL() {
+		return url;
+	}
+	
+	/**
+	 * url is relative to the site
+	 */
+	public void setURL(String url) {
+		this.url = url;
+	}
+
+	/**
+	 * Returns the plug-in identifier for this entry.
+	 * 
+	 * @return the plug-in identifier, or <code>null</code>
+	 */
+	public String getPluginIdentifier() {
+		return pluginId;
+	}
+
+	/**
+	 * Returns the plug-in version for this entry.
+	 * 
+	 * @return the plug-in version, or <code>null</code>
+	 */
+	public String getPluginVersion() {
+		return pluginVersion;
+	}
+
+	/**
+	 * Indicates whether the entry describes a full plug-in, or 
+	 * a plug-in fragment.
+	 * 
+	 * @return <code>true</code> if the entry is a plug-in fragment, 
+	 * <code>false</code> if the entry is a plug-in
+	 */
+	public boolean isFragment() {
+		return isFragment;
+	}
+
+	/**
+	 * Sets the entry plug-in identifier.
+	 * Throws a runtime exception if this object is marked read-only.
+	 *
+	 * @param pluginId the entry identifier.
+	 */
+	void setPluginIdentifier(String pluginId) {
+		this.pluginId = pluginId;
+	}
+
+	/**
+	 * Sets the entry plug-in version.
+	 * Throws a runtime exception if this object is marked read-only.
+	 *
+	 * @param pluginVersion the entry version.
+	 */
+	void setPluginVersion(String pluginVersion) {
+		this.pluginVersion = pluginVersion;
+	}
+
+	/**
+	 * Indicates whether this entry represents a fragment or plug-in.
+	 * Throws a runtime exception if this object is marked read-only.
+	 *
+	 * @param isFragment fragment setting
+	 */
+	public void isFragment(boolean isFragment) {
+		this.isFragment = isFragment;
+	}
+
+	/**
+	 * @see Object#toString()
+	 */
+	public String toString() {
+		String msg = (getPluginIdentifier()!=null)?getPluginIdentifier().toString():""; //$NON-NLS-1$
+		msg += getPluginVersion()!=null?" "+getPluginVersion().toString():""; //$NON-NLS-1$ //$NON-NLS-2$
+		msg += isFragment()?" fragment":" plugin"; //$NON-NLS-1$ //$NON-NLS-2$
+		return msg;
+	}
+
+
+	/**
+	 * Returns the identifier of this plugin entry
+	 */
+	public VersionedIdentifier getVersionedIdentifier() {
+		if (versionId != null)
+			return versionId;
+
+		String id = getPluginIdentifier();
+		String ver = getPluginVersion();
+		if (id != null && ver != null) {
+			try {
+				versionId = new VersionedIdentifier(id, ver);
+				return versionId;
+			} catch (Exception e) {
+				Utils.log(NLS.bind(Messages.PluginEntry_versionError, (new String[] { id, ver })));
+			}
+		}
+
+		versionId = new VersionedIdentifier("",null); //$NON-NLS-1$
+		return versionId;
+	}
+
+	/**
+	 * Sets the identifier of this plugin entry. 
+	 * 
+	 */
+	void setVersionedIdentifier(VersionedIdentifier identifier) {
+		setPluginIdentifier(identifier.getIdentifier());
+		setPluginVersion(identifier.getVersion().toString());
+	}	
+
+	/**
+	 * Compares two plugin entries for equality
+	 * 
+	 * @param object plugin entry object to compare with
+	 * @return <code>true</code> if the two entries are equal, 
+	 * <code>false</code> otherwise
+	 */
+	public boolean equals(Object object) {
+		if (!(object instanceof PluginEntry))
+			return false;
+		PluginEntry e = (PluginEntry) object;
+		return getVersionedIdentifier().equals(e.getVersionedIdentifier());
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode() {
+		return getVersionedIdentifier().hashCode();
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PluginParser.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PluginParser.java
new file mode 100644
index 0000000..1188a64
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PluginParser.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+
+import java.io.*;
+
+import javax.xml.parsers.*;
+
+import org.eclipse.osgi.util.NLS;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+/**
+ * Parse default feature.xml
+ */
+
+public class PluginParser extends DefaultHandler implements IConfigurationConstants {
+	private final static SAXParserFactory parserFactory =
+		SAXParserFactory.newInstance();
+	private SAXParser parser;
+	private PluginEntry pluginEntry;
+    private String location;
+
+	private class ParseCompleteException extends SAXException {
+		
+        private static final long serialVersionUID = 1L;
+
+        public ParseCompleteException(String arg0) {
+			super(arg0);
+		}
+	}
+
+	/**
+	 * Constructor for DefaultFeatureParser
+	 */
+	public PluginParser() {
+		super();
+		try {
+			parserFactory.setNamespaceAware(true);
+			this.parser = parserFactory.newSAXParser();
+		} catch (ParserConfigurationException e) {
+			System.out.println(e);
+		} catch (SAXException e) {
+			System.out.println(e);
+		}
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public synchronized PluginEntry parse(File pluginFile) throws SAXException, IOException {
+		FileInputStream in = null;
+		try{
+			in = new FileInputStream(pluginFile);
+			return parse(in, PLUGINS + "/" + pluginFile.getParentFile().getName() + "/"); //$NON-NLS-1$ //$NON-NLS-2$
+		}finally{
+			if (in != null){
+				try{
+					in.close();
+				}catch(IOException e){
+				}
+			}
+		}
+	}
+	/**
+	 * @since 3.0
+	 */
+	public synchronized PluginEntry parse(InputStream in, String bundleUrl) throws SAXException, IOException {
+		try {
+            location = bundleUrl;
+			pluginEntry = new PluginEntry();
+			pluginEntry.setURL(bundleUrl);
+			parser.parse(new InputSource(in), this);
+		} catch (ParseCompleteException e) {
+			// expected, we stopped the parsing when we have the information we need
+			/// no need to pursue the parsing
+		}
+		return pluginEntry;
+	}
+
+	/**
+	 * @see DefaultHandler#startElement(String, String, String, Attributes)
+	 */
+	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+
+		String tag = localName.trim();
+
+		if (tag.equalsIgnoreCase(CFG_PLUGIN)) {
+			pluginEntry.isFragment(false);			
+			processPlugin(attributes);
+			return;
+		}
+
+		if (tag.equalsIgnoreCase(CFG_FRAGMENT)) {
+			pluginEntry.isFragment(true);			
+			processPlugin(attributes);
+			return;
+		}
+	}
+
+	/** 
+	 * process plugin entry info
+	 */
+	private void processPlugin(Attributes attributes) throws ParseCompleteException {
+		String id = attributes.getValue("id"); //$NON-NLS-1$
+		String version = attributes.getValue("version"); //$NON-NLS-1$
+		if (id == null || id.trim().length() == 0) {
+			id = "_no_id_"; //$NON-NLS-1$
+            Utils.log(NLS.bind(Messages.PluginParser_plugin_no_id, (new String[] { location })));
+        }
+        if (version == null || version.trim().length() == 0) {
+            version = "0.0.0"; //$NON-NLS-1$
+            Utils.log(NLS.bind(Messages.PluginParser_plugin_no_version, (new String[] { location })));
+        }
+		pluginEntry.setVersionedIdentifier(new VersionedIdentifier(id, version));
+		
+		// stop parsing now
+		throw new ParseCompleteException(""); //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/SiteEntry.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/SiteEntry.java
new file mode 100644
index 0000000..e97cbc8
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/SiteEntry.java
@@ -0,0 +1,771 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import java.io.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.zip.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.service.environment.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.configurator.IPlatformConfiguration.*;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+
+public class SiteEntry implements IPlatformConfiguration.ISiteEntry, IConfigurationConstants{	
+	private static final String MAC_OS_MARKER = ".DS_Store"; //$NON-NLS-1$
+	
+	private URL url; // this is the external URL for the site
+	private URL resolvedURL; // this is the resolved URL used internally
+	private ISitePolicy policy;
+	private boolean updateable = true;
+	private Map featureEntries;
+	private ArrayList pluginEntries;
+	private long changeStamp;
+	private long featuresChangeStamp;
+	private long pluginsChangeStamp;
+	private String linkFileName;
+	private boolean enabled = true;
+	private Configuration config;
+	
+	private static FeatureParser featureParser = new FeatureParser();
+	private static PluginParser pluginParser = new PluginParser();
+	private static boolean isMacOS = Utils.getOS().equals(Constants.OS_MACOSX);
+
+	public SiteEntry(URL url) {
+		this(url,null);
+	}
+	
+	public SiteEntry(URL url, ISitePolicy policy) {
+		if (url == null)
+			try {
+				url = new URL("platform:/base/"); //$NON-NLS-1$ try using platform-relative URL
+			} catch (MalformedURLException e) {
+				url = PlatformConfiguration.getInstallURL(); // ensure we come up ... use absolute file URL
+			}
+			
+		if (policy == null)
+			policy = new SitePolicy(PlatformConfiguration.getDefaultPolicy(), DEFAULT_POLICY_LIST);
+
+		if (url.getProtocol().equals("file")) { //$NON-NLS-1$
+			try {
+				// TODO remove this when platform fixes local file url's
+				this.url = new File(url.getFile()).toURL(); 
+			} catch (MalformedURLException e1) {
+				this.url = url;
+			}
+		} else
+			this.url = url;
+		
+		this.policy = policy;
+		this.resolvedURL = this.url;
+	}
+
+	public void setConfig(Configuration config) {
+		this.config = config;
+		if (url.getProtocol().equals("platform")) { //$NON-NLS-1$
+			try {
+				// resolve the config location relative to the configURL
+				if (url.getPath().startsWith("/config")) {	
+					URL configURL = config.getURL();
+					URL config_loc = new URL(configURL, "..");
+					resolvedURL = PlatformConfiguration.resolvePlatformURL(url, config_loc); // 19536
+				}
+				else 
+					resolvedURL = PlatformConfiguration.resolvePlatformURL(url, config.getInstallURL()); // 19536
+			} catch (IOException e) {
+				// will use the baseline URL ...
+			}
+		}
+	}
+	
+	public Configuration getConfig() {
+		return config;
+	}
+	
+	/*
+	 * @see ISiteEntry#getURL()
+	 */
+	public URL getURL() {
+		return url;
+	}
+
+	/*
+	* @see ISiteEntry#getSitePolicy()
+	*/
+	public ISitePolicy getSitePolicy() {
+		return policy;
+	}
+
+	/*
+	 * @see ISiteEntry#setSitePolicy(ISitePolicy)
+	 */
+	public synchronized void setSitePolicy(ISitePolicy policy) {
+		if (policy == null)
+			throw new IllegalArgumentException();
+		this.policy = policy;
+	}
+
+	/*
+	 * @see ISiteEntry#getFeatures()
+	 */
+	public String[] getFeatures() {
+		return getDetectedFeatures();
+	}
+
+	/*
+	 * @see ISiteEntry#getPlugins()
+	 */
+	public String[] getPlugins() {
+
+		ISitePolicy policy = getSitePolicy();
+
+		if (policy.getType() == ISitePolicy.USER_INCLUDE)
+			return policy.getList();
+
+		if (policy.getType() == ISitePolicy.USER_EXCLUDE) {
+			ArrayList detectedPlugins = new ArrayList(Arrays.asList(getDetectedPlugins()));
+			String[] excludedPlugins = policy.getList();
+			for (int i = 0; i < excludedPlugins.length; i++) {
+				if (detectedPlugins.contains(excludedPlugins[i]))
+					detectedPlugins.remove(excludedPlugins[i]);
+			}
+			return (String[]) detectedPlugins.toArray(new String[0]);
+		}
+		
+		if (policy.getType() == ISitePolicy.MANAGED_ONLY) {
+			PluginEntry[] managedPlugins = getManagedPlugins();
+			String[] managedPluginsURLs = new String[managedPlugins.length];
+			for (int i=0; i<managedPlugins.length; i++)
+				managedPluginsURLs[i] = managedPlugins[i].getURL();
+			
+			return managedPluginsURLs;
+		}
+
+		// bad policy type
+		return new String[0];
+	}
+
+	private PluginEntry[] getManagedPlugins() {
+		// Note:
+		// We detect all the plugins on the site, but it would be faster
+		// to just lookup the plugins that correspond to the entries found in each feature.
+		// TODO fix the above
+		if (pluginEntries == null)
+			detectPlugins();
+		if (featureEntries == null)
+			detectFeatures();
+		
+		// cache all the plugin entries for faster lookup later
+		Map cachedPlugins = new HashMap(pluginEntries.size());
+		for (int i=0; i<pluginEntries.size(); i++) {
+			PluginEntry p = (PluginEntry)pluginEntries.get(i);
+			cachedPlugins.put(p.getVersionedIdentifier(), p);
+		}
+		
+		ArrayList managedPlugins = new ArrayList();
+		for (Iterator iterator=featureEntries.values().iterator(); iterator.hasNext();) {
+			Object feature = iterator.next();
+			if (!(feature instanceof FeatureEntry))
+				continue;
+			
+			PluginEntry[] plugins = ((FeatureEntry)feature).getPluginEntries();
+			for (int i=0; i<plugins.length; i++)
+				if (cachedPlugins.containsKey(plugins[i].getVersionedIdentifier()))
+					managedPlugins.add(cachedPlugins.get(plugins[i].getVersionedIdentifier()));
+					
+		}
+		return (PluginEntry[])managedPlugins.toArray(new PluginEntry[managedPlugins.size()]);
+	}
+	
+	public PluginEntry[] getPluginEntries() {
+		String[] pluginURLs = getPlugins();
+		// hash the array, for faster lookups
+		HashMap map = new HashMap(pluginURLs.length);
+		for (int i=0; i<pluginURLs.length; i++)
+			map.put(pluginURLs[i], pluginURLs[i]);
+		
+		if (pluginEntries == null)
+				detectPlugins();
+		
+		ArrayList plugins = new ArrayList(pluginURLs.length);
+		for (int i=0; i<pluginEntries.size(); i++) {
+			PluginEntry p = (PluginEntry)pluginEntries.get(i);
+			if (map.containsKey(p.getURL()))
+				plugins.add(p);
+		}
+		return (PluginEntry[])plugins.toArray(new PluginEntry[plugins.size()]);
+	}
+	
+	/*
+	 * @see ISiteEntry#getChangeStamp()
+	 */
+	public long getChangeStamp() {
+		if (changeStamp == 0)
+			computeChangeStamp();
+		return changeStamp;
+	}
+
+	/*
+	 * @see ISiteEntry#getFeaturesChangeStamp()
+	 */
+	public long getFeaturesChangeStamp() {
+		if (featuresChangeStamp == 0)
+			computeFeaturesChangeStamp();
+		return featuresChangeStamp;
+	}
+
+	/*
+	 * @see ISiteEntry#getPluginsChangeStamp()
+	 */
+	public long getPluginsChangeStamp() {
+		if (pluginsChangeStamp == 0)
+			computePluginsChangeStamp();
+		return pluginsChangeStamp;
+	}
+
+	/*
+	 * @see ISiteEntry#isUpdateable()
+	 */
+	public boolean isUpdateable() {
+		return updateable;
+	}
+	
+	public void setUpdateable(boolean updateable) {
+		this.updateable = updateable;
+	}
+
+	/*
+	 * @see ISiteEntry#isNativelyLinked()
+	 */
+	public boolean isNativelyLinked() {
+		return isExternallyLinkedSite();
+	}
+
+	public URL getResolvedURL() {
+		return resolvedURL;
+	}
+	
+	/**
+	 * Detect new features (timestamp > current site timestamp)
+	 * and validates existing features (they might have been removed)
+	 */
+	private void detectFeatures() {
+
+		if (featureEntries != null)
+			validateFeatureEntries();
+		else
+			featureEntries = new HashMap();
+
+		if (!PlatformConfiguration.supportsDetection(resolvedURL, config.getInstallURL()))
+			return;
+
+		// locate feature entries on site
+		File siteRoot = new File(resolvedURL.getFile().replace('/', File.separatorChar));
+		File featuresDir = new File(siteRoot, FEATURES);
+		if (featuresDir.exists()) {
+			// handle the installed features under the features directory
+			File[] dirs = featuresDir.listFiles(new FileFilter() {
+				public boolean accept(File f) {
+					// mac os folders contain a file .DS_Store in each folder, and we need to skip it (bug 76869) 
+					if (isMacOS && f.getName().equals(MAC_OS_MARKER))
+						return false;
+					boolean valid = f.isDirectory() && (new File(f,FEATURE_XML).exists());
+					if (!valid)
+						Utils.log(NLS.bind(Messages.SiteEntry_cannotFindFeatureInDir, (new String[] { f.getAbsolutePath() })));
+					return valid;
+				}
+			});
+		
+			for (int index = 0; index < dirs.length; index++) {
+				try {
+					File featureXML = new File(dirs[index], FEATURE_XML);
+					if (featureXML.lastModified() <= featuresChangeStamp &&
+						dirs[index].lastModified() <= featuresChangeStamp)
+						continue;
+					URL featureURL = featureXML.toURL();
+					FeatureEntry featureEntry = featureParser.parse(featureURL);
+					if (featureEntry != null)
+						addFeatureEntry(featureEntry);
+				} catch (MalformedURLException e) {
+					Utils.log(NLS.bind(Messages.InstalledSiteParser_UnableToCreateURLForFile, (new String[] { featuresDir.getAbsolutePath() })));
+				}
+			}
+		}
+		
+		Utils.debug(resolvedURL.toString() + " located  " + featureEntries.size() + " feature(s)"); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+	
+	/**
+	 * Detect new plugins (timestamp > current site timestamp)
+	 * and validates existing plugins (they might have been removed)
+	 */
+	private void detectPlugins() {
+		boolean compareTimeStamps = false;
+		if (pluginEntries != null) {
+			validatePluginEntries();
+			compareTimeStamps = true; // only pick up newer plugins
+		} else
+			pluginEntries = new ArrayList();
+
+		if (!PlatformConfiguration.supportsDetection(resolvedURL, config.getInstallURL()))
+			return;
+
+		// locate plugin entries on site
+		File pluginsDir = new File(resolvedURL.getFile(), PLUGINS);
+		
+		if (pluginsDir.exists() && pluginsDir.isDirectory()) {
+			File[] files = pluginsDir.listFiles();
+			for (int i = 0; i < files.length; i++) {
+				if(files[i].isDirectory()){
+					detectUnpackedPlugin(files[i], compareTimeStamps);
+				}else if(files[i].getName().endsWith(".jar")){ //$NON-NLS-1$
+					detectPackedPlugin(files[i], compareTimeStamps);
+				}else{
+					// not bundle file
+				}
+			}
+		} 
+		
+		Utils.debug(resolvedURL.toString() + " located  " + pluginEntries.size() + " plugin(s)"); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * @param file a plugin jar
+	 * @param compareTimeStamps set to true when looking for plugins changed since last time they were detected
+	 */
+	private void detectPackedPlugin(File file, boolean compareTimeStamps) {
+		// plugin to run directly from jar
+		if (compareTimeStamps && file.lastModified() <= pluginsChangeStamp) {
+			return;
+		}
+		String entryName = META_MANIFEST_MF;
+		ZipFile z = null;
+		InputStream bundleManifestIn = null;
+		InputStream pluginManifestIn = null;
+		String pluginURL = PLUGINS + "/" + file.getName(); //$NON-NLS-1$
+		try {
+			// First, check if has valid bundle manifest
+			z = new ZipFile(file);
+			if (z.getEntry(entryName) != null) {
+				bundleManifestIn = z.getInputStream(new ZipEntry(entryName));
+				BundleManifest manifest = new BundleManifest(bundleManifestIn,
+						pluginURL);
+				if (manifest.exists()) {
+					addPluginEntry(manifest.getPluginEntry());
+					return;
+				}
+			}
+			// no bundle manifest, check for plugin.xml or fragment.xml
+			entryName = PLUGIN_XML;
+			if (z.getEntry(entryName) == null) {
+				entryName = FRAGMENT_XML;
+			}
+			if (z.getEntry(entryName) != null) {
+				pluginManifestIn = z.getInputStream(new ZipEntry(entryName));
+				PluginEntry entry1 = pluginParser.parse(pluginManifestIn,
+						pluginURL);
+				addPluginEntry(entry1);
+			}
+		} catch (IOException e5) {
+			String pluginFileString2 = pluginURL + "!" + entryName; //$NON-NLS-1$
+			Utils.log(NLS.bind(Messages.InstalledSiteParser_ErrorAccessing, (new String[] { pluginFileString2 })));
+		} catch (SAXException e3) {
+			String pluginFileString1 = pluginURL + "!" + entryName; //$NON-NLS-1$
+			Utils.log(NLS.bind(Messages.InstalledSiteParser_ErrorParsingFile, (new String[] { pluginFileString1 })));
+		} finally {
+			if (bundleManifestIn != null) {
+				try {
+					bundleManifestIn.close();
+				} catch (IOException e4) {
+				}
+			}
+			if (pluginManifestIn != null) {
+				try {
+					pluginManifestIn.close();
+				} catch (IOException e2) {
+				}
+			}
+			if (z != null) {
+				try {
+					z.close();
+				} catch (IOException e1) {
+				}
+			}
+		}
+	}
+	/**
+	 * @param file a plugin directory
+	 * @param compareTimeStamps set to true when looking for plugins changed since last time they were detected
+	 */
+	private void detectUnpackedPlugin(File file, boolean compareTimeStamps) {
+		// unpacked plugin
+		long dirTimestamp = file.lastModified();
+		File pluginFile = new File(file, META_MANIFEST_MF);
+		try {
+			// First, check if has valid bundle manifest
+			BundleManifest bundleManifest = new BundleManifest(pluginFile);
+			if (bundleManifest.exists()) {
+				if (compareTimeStamps
+						&& dirTimestamp <= pluginsChangeStamp
+						&& pluginFile.lastModified() <= pluginsChangeStamp)
+					return;
+				PluginEntry entry = bundleManifest.getPluginEntry();
+				addPluginEntry(entry);
+			} else {
+				// no bundle manifest, check for plugin.xml or fragment.xml
+				pluginFile = new File(file, PLUGIN_XML);
+				if (!pluginFile.exists()) { 
+					pluginFile = new File(file, FRAGMENT_XML); 
+				}
+				if (pluginFile.exists() && !pluginFile.isDirectory()) {
+					// TODO in the future, assume that the timestamps are not
+					// reliable,
+					// or that the user manually modified an existing plugin,
+					// so
+					// the apparently modifed plugin may actually be configured
+					// already.
+					// We will need to double check for this. END to do.
+					if (compareTimeStamps 
+							&& dirTimestamp <= pluginsChangeStamp
+							&& pluginFile.lastModified() <= pluginsChangeStamp)
+						return;
+					PluginEntry entry = pluginParser.parse(pluginFile);
+					addPluginEntry(entry);
+				}
+			}
+		} catch (IOException e) {
+			String pluginFileString = pluginFile.getAbsolutePath();
+			if (ConfigurationActivator.DEBUG)
+				Utils.log(Utils.newStatus(NLS.bind(Messages.InstalledSiteParser_ErrorParsingFile, (new String[] { pluginFileString })), e));
+			else
+				Utils.log(NLS.bind(Messages.InstalledSiteParser_ErrorAccessing, (new String[] { pluginFileString })));
+		} catch (SAXException e) {
+			String pluginFileString = pluginFile.getAbsolutePath();
+			Utils.log(NLS.bind(Messages.InstalledSiteParser_ErrorParsingFile, (new String[] { pluginFileString })));
+        }
+	}
+
+	/**
+	 * @return list of feature url's (relative to site)
+	 */
+	private synchronized String[] getDetectedFeatures() {
+		if (featureEntries == null)
+			detectFeatures();
+		String[] features = new String[featureEntries.size()];
+		Iterator iterator = featureEntries.values().iterator();
+		for (int i=0; i<features.length; i++)
+			features[i] = ((FeatureEntry)iterator.next()).getURL();
+		return features;
+	}
+
+	/**
+	 * @return list of plugin url's (relative to site)
+	 */
+	private synchronized String[] getDetectedPlugins() {
+		if (pluginEntries == null)
+			detectPlugins();
+		
+		String[] plugins = new String[pluginEntries.size()];
+		for (int i=0; i<plugins.length; i++)
+			plugins[i] = ((PluginEntry)pluginEntries.get(i)).getURL();
+		return plugins;
+	}
+
+	private void computeChangeStamp() {
+		changeStamp = Math.max(computeFeaturesChangeStamp(), computePluginsChangeStamp());
+//		changeStampIsValid = true;
+	}
+
+	private synchronized long computeFeaturesChangeStamp() {
+		if (featuresChangeStamp > 0)
+			return featuresChangeStamp;
+		
+		long start = 0;
+		if (ConfigurationActivator.DEBUG)
+			start = (new Date()).getTime();
+		String[] features = getFeatures();
+	
+		// compute stamp for the features directory
+		long dirStamp = 0;
+		if (PlatformConfiguration.supportsDetection(resolvedURL, config.getInstallURL())) {
+			File root = new File(resolvedURL.getFile().replace('/', File.separatorChar));
+			File featuresDir = new File(root, FEATURES);
+			dirStamp = featuresDir.lastModified();
+		}
+		featuresChangeStamp = Math.max(dirStamp, computeStamp(features));
+		if (ConfigurationActivator.DEBUG) {
+			long end = (new Date()).getTime();
+			Utils.debug(resolvedURL.toString() + " feature stamp: " + featuresChangeStamp + " in " + (end - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$   
+		}
+		return featuresChangeStamp;
+	}
+
+	private synchronized long computePluginsChangeStamp() {
+		if (pluginsChangeStamp > 0)
+			return pluginsChangeStamp;
+		
+		if (!PlatformConfiguration.supportsDetection(resolvedURL, config.getInstallURL())) {
+			Utils.log(NLS.bind(Messages.SiteEntry_computePluginStamp, (new String[] { resolvedURL.toExternalForm() })));
+			return 0;
+		}
+
+		// compute stamp for the plugins directory
+		File root = new File(resolvedURL.getFile().replace('/', File.separatorChar));
+		File pluginsDir = new File(root, PLUGINS);
+		if (!pluginsDir.exists() || !pluginsDir.isDirectory()) {
+			Utils.debug(NLS.bind(Messages.SiteEntry_pluginsDir, (new String[] { pluginsDir.getAbsolutePath() })));
+			return 0;
+		}
+
+		pluginsChangeStamp = pluginsDir.lastModified();
+		return pluginsChangeStamp;
+	}
+
+	private long computeStamp(String[] targets) {
+
+		long result = 0;
+		if (!PlatformConfiguration.supportsDetection(resolvedURL, config.getInstallURL())) {
+			// NOTE:  this path should not be executed until we support running
+			//        from an arbitrary URL (in particular from http server). For
+			//        now just compute stamp across the list of names. Eventually
+			//        when general URLs are supported we need to do better (factor
+			//        in at least the existence of the target). However, given this
+			//        code executes early on the startup sequence we need to be
+			//        extremely mindful of performance issues.
+			// In fact, we should get the last modified from the connection
+			for (int i = 0; i < targets.length; i++)
+				result ^= targets[i].hashCode();
+			Utils.debug("*WARNING* computing stamp using URL hashcodes only"); //$NON-NLS-1$
+		} else {
+			// compute stamp across local targets
+			File rootFile = new File(resolvedURL.getFile().replace('/', File.separatorChar));
+			if (rootFile.exists()) {
+				File f = null;
+				for (int i = 0; i < targets.length; i++) {
+					f = new File(rootFile, targets[i]);
+					if (f.exists())
+						result = Math.max(result, f.lastModified());
+				}
+			}
+		}
+
+		return result;
+	}
+	
+	public void setLinkFileName(String linkFileName) {
+		this.linkFileName = linkFileName;
+	}
+	
+	public String getLinkFileName() {
+		return linkFileName;
+	}
+
+	public boolean isExternallyLinkedSite() {
+		return (linkFileName != null && !linkFileName.trim().equals("")); //$NON-NLS-1$
+	}
+
+	public synchronized void refresh() {
+		// reset computed values. Will be updated on next access.
+		featuresChangeStamp = 0;
+		pluginsChangeStamp = 0;
+		changeStamp = 0;
+		featureEntries = null;
+		pluginEntries = null;
+	}
+	
+	public void refreshPlugins() {
+		// reset computed values. Will be updated on next access.
+		pluginsChangeStamp = 0;
+		changeStamp = 0;
+		pluginEntries = null;
+	}
+	
+	public void addFeatureEntry(IFeatureEntry feature) {
+		if (featureEntries == null)
+			featureEntries = new HashMap();
+		// Make sure we keep the larger version of same feature
+		IFeatureEntry existing = (FeatureEntry)featureEntries.get(feature.getFeatureIdentifier());
+		if (existing != null) {
+			VersionedIdentifier existingVersion = new VersionedIdentifier(existing.getFeatureIdentifier(), existing.getFeatureVersion());
+			VersionedIdentifier newVersion = new VersionedIdentifier(feature.getFeatureIdentifier(), feature.getFeatureVersion());
+			if (existingVersion.getVersion().compareTo(newVersion.getVersion()) < 0) {
+				featureEntries.put(feature.getFeatureIdentifier(), feature);
+				pluginsChangeStamp = 0;
+			} else if (existingVersion.equals(newVersion)) {
+				// log error if same feature version/id but a different url
+				if (feature instanceof FeatureEntry && existing instanceof FeatureEntry &&
+						!((FeatureEntry)feature).getURL().equals(((FeatureEntry)existing).getURL()))
+				Utils.log(NLS.bind(Messages.SiteEntry_duplicateFeature, (new String[] { getURL().toExternalForm(), existing.getFeatureIdentifier() })));
+			}
+		} else {
+			featureEntries.put(feature.getFeatureIdentifier(), feature);
+			pluginsChangeStamp = 0;
+		}
+		if (feature instanceof FeatureEntry)
+			((FeatureEntry)feature).setSite(this);
+	}
+	
+	public FeatureEntry[] getFeatureEntries() {
+		if (featureEntries == null)
+			detectFeatures();
+		
+		if (featureEntries == null)
+			return new FeatureEntry[0];
+		return (FeatureEntry[])featureEntries.values().toArray(new FeatureEntry[featureEntries.size()]);
+	}
+	
+	public void addPluginEntry(PluginEntry plugin) {
+		if (pluginEntries == null)
+			pluginEntries = new ArrayList();
+		// Note: we could use the latest version of the same plugin, like we do for features, but we let the runtime figure it out
+		pluginEntries.add(plugin);
+	}
+	
+	public PluginEntry[] getAllPluginEntries() {
+		if (pluginEntries == null)
+			detectPlugins();
+		return (PluginEntry[])pluginEntries.toArray(new PluginEntry[pluginEntries.size()]);
+	}
+	
+	public void loadFromDisk(long lastChange) throws CoreException{
+		featuresChangeStamp = lastChange;
+		pluginsChangeStamp = lastChange;
+		detectFeatures();
+		detectPlugins();
+	}
+	
+	/**
+	 * Saves state as xml content in a given parent element
+	 * @param doc
+	 */
+	public Element toXML(Document doc) {
+
+		Element siteElement = doc.createElement(CFG_SITE);
+		
+		if (getURL() != null) {
+			URL toPersist = (config == null || config.isTransient()) ? getURL() : Utils.makeRelative(Utils.getInstallURL(), getURL());
+			siteElement.setAttribute(CFG_URL, toPersist.toString());
+		}
+		
+		siteElement.setAttribute(CFG_ENABLED, isEnabled() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+		siteElement.setAttribute(CFG_UPDATEABLE, isUpdateable() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+		if (isExternallyLinkedSite()) 
+			siteElement.setAttribute(CFG_LINK_FILE, getLinkFileName().trim().replace(File.separatorChar, '/')); 
+
+		int type = getSitePolicy().getType();
+		String typeString = CFG_POLICY_TYPE_UNKNOWN;
+		try {
+			typeString = CFG_POLICY_TYPE[type];
+		} catch (IndexOutOfBoundsException e) {
+			// ignore bad attribute ...
+		}
+		siteElement.setAttribute(CFG_POLICY, typeString); 
+		String[] list = getSitePolicy().getList();
+		if (list.length > 0) {
+			StringBuffer sb = new StringBuffer(256);
+			for (int i=0; i<list.length-1; i++) {
+				sb.append(list[i]);
+				sb.append(',');
+			}
+			sb.append(list[list.length-1]);
+			siteElement.setAttribute(CFG_LIST, sb.toString());
+		}
+//		// note: we don't save features inside the site element.
+		
+		// collect feature entries
+//		configElement.setAttribute(CFG_FEATURE_ENTRY_DEFAULT, defaultFeature);
+		FeatureEntry[] feats = getFeatureEntries();
+		for (int i = 0; i < feats.length; i++) {
+			Element featureElement = feats[i].toXML(doc);
+			siteElement.appendChild(featureElement);
+		}
+		
+		return siteElement;
+	}
+	
+	private void validateFeatureEntries() {
+		File root = new File(resolvedURL.getFile().replace('/', File.separatorChar));
+		Iterator iterator = featureEntries.values().iterator();
+		Collection deletedFeatures = new ArrayList();
+		while(iterator.hasNext()) {
+			FeatureEntry feature = (FeatureEntry)iterator.next();
+			// Note: in the future, we can check for absolute url as well.
+			//       For now, feature url is features/org.eclipse.foo/feature.xml
+			File featureXML = new File(root, feature.getURL());
+			if (!featureXML.exists())
+				deletedFeatures.add(feature.getFeatureIdentifier());
+		}
+		for(Iterator it=deletedFeatures.iterator(); it.hasNext();){
+			featureEntries.remove(it.next());
+		}
+	}
+	
+	private void validatePluginEntries() {
+		File root = new File(resolvedURL.getFile().replace('/', File.separatorChar));
+		Collection deletedPlugins = new ArrayList();
+		for (int i=0; i<pluginEntries.size(); i++) {
+			PluginEntry plugin = (PluginEntry)pluginEntries.get(i);
+			// Note: in the future, we can check for absolute url as well.
+			//       For now, feature url is plugins/org.eclipse.foo/plugin.xml
+			File pluginLocation = new File(root, plugin.getURL());
+			if (!pluginLocation.exists())
+				deletedPlugins.add(plugin);
+		}
+		for(Iterator it=deletedPlugins.iterator(); it.hasNext();){
+			pluginEntries.remove(it.next());
+		}
+	}
+	
+	public boolean isEnabled() {
+		return enabled;
+	}
+	
+	public void setEnabled(boolean enable) {
+		this.enabled = enable;
+	}
+	
+	public FeatureEntry getFeatureEntry(String id) {
+		FeatureEntry[] features = getFeatureEntries();
+		for (int i=0; i<features.length; i++)
+			if (features[i].getFeatureIdentifier().equals(id)) 
+				return features[i];
+		return null;
+	}
+	
+	
+	public boolean unconfigureFeatureEntry(IFeatureEntry feature) {
+		FeatureEntry existingFeature = getFeatureEntry(feature.getFeatureIdentifier());
+		if (existingFeature != null)
+			featureEntries.remove(existingFeature.getFeatureIdentifier());
+		return existingFeature != null;
+	}
+	
+	/*
+	 * This is a bit of a hack.
+	 * When no features were added to the site, but the site is initialized from platform.xml 
+	 * we need to set the feature set to empty, so we don't try to detect them.
+	 */
+	public void initialized() { 
+		if (featureEntries == null)
+			featureEntries = new HashMap();
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/SitePolicy.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/SitePolicy.java
new file mode 100644
index 0000000..27c37b9
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/SitePolicy.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.configurator.IPlatformConfiguration.*;
+
+
+public class SitePolicy implements IPlatformConfiguration.ISitePolicy {
+
+	private int type;
+	private String[] list;
+
+	public SitePolicy() {
+	}
+	public SitePolicy(int type, String[] list) {
+		if (type != ISitePolicy.USER_INCLUDE && type != ISitePolicy.USER_EXCLUDE && type != ISitePolicy.MANAGED_ONLY)
+			throw new IllegalArgumentException();
+		this.type = type;
+
+		if (list == null)
+			this.list = new String[0];
+		else
+			this.list = list;
+	}
+
+	/*
+	 * @see ISitePolicy#getType()
+	 */
+	public int getType() {
+		return type;
+	}
+
+	/*
+	* @see ISitePolicy#getList()
+	*/
+	public String[] getList() {
+		return list;
+	}
+
+	/*
+	 * @see ISitePolicy#setList(String[])
+	 */
+	public synchronized void setList(String[] list) {
+		if (list == null)
+			this.list = new String[0];
+		else
+			this.list = list;
+	}
+
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/UpdateURLDecoder.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/UpdateURLDecoder.java
new file mode 100644
index 0000000..633b49f
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/UpdateURLDecoder.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+public class UpdateURLDecoder {
+	static boolean init=false;
+	static boolean useEnc=true;
+	
+	public static String decode(String s, String enc) throws UnsupportedEncodingException {
+		if (!init) {
+			init = true;
+			try {
+				return URLDecoder.decode(s, enc);
+			} catch (NoSuchMethodError e) {
+				useEnc=false;				
+			}
+		}
+		
+		if (useEnc) {
+			return URLDecoder.decode(s, enc);
+		} 			
+		return URLDecoder.decode(s);
+	}
+
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/VersionedIdentifier.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/VersionedIdentifier.java
new file mode 100644
index 0000000..a36e253
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/VersionedIdentifier.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator;
+
+import org.osgi.framework.Version;
+
+public class VersionedIdentifier {
+	private String identifier;
+	private Version version;
+
+	public VersionedIdentifier(String id, String version) {
+		this.identifier = id;
+		this.version = Version.parseVersion(version);
+	}
+
+	public Version getVersion() {
+		return version;
+	}
+
+	public String getIdentifier() {
+		return identifier;
+	}
+
+	private boolean equalIdentifiers(VersionedIdentifier id) {
+		if (id == null)
+			return identifier == null;
+		return id.identifier.equals(identifier);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (!(obj instanceof VersionedIdentifier))
+			return false;
+
+		VersionedIdentifier other = (VersionedIdentifier) obj;
+		if (!equalIdentifiers(other))
+			return false;
+		return version.equals(other.getVersion());
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode() {
+		return (identifier + "_" + getVersion()).hashCode(); //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return identifier + "_" + getVersion(); //$NON-NLS-1$
+	}
+}
\ No newline at end of file
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/XMLPrintHandler.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/XMLPrintHandler.java
new file mode 100644
index 0000000..ba4982a
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/XMLPrintHandler.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.configurator;
+
+import java.io.*;
+
+import org.w3c.dom.*;
+
+
+public class XMLPrintHandler {
+	//	used to print XML file
+	public static final String XML_HEAD = "<?xml version=\"1.0\" encoding=\""; //$NON-NLS-1$
+	public static final String XML_HEAD_END_TAG = "?>"; //$NON-NLS-1$
+	public static final String XML_DBL_QUOTES = "\""; //$NON-NLS-1$
+	public static final String XML_SPACE = " "; //$NON-NLS-1$
+	public static final String XML_BEGIN_TAG = "<"; //$NON-NLS-1$
+	public static final String XML_END_TAG = ">"; //$NON-NLS-1$
+	public static final String XML_EQUAL = "="; //$NON-NLS-1$
+	public static final String XML_SLASH = "/"; //$NON-NLS-1$
+
+	public static void printBeginElement(Writer xmlWriter, String elementString) throws IOException{
+		StringBuffer temp = new StringBuffer(XML_BEGIN_TAG);
+		temp.append(elementString).append(XML_END_TAG).append("\n"); //$NON-NLS-1$
+		xmlWriter.write(temp.toString());
+
+	}
+
+	public static void printEndElement(Writer xmlWriter, String elementString) throws IOException{
+		StringBuffer temp = new StringBuffer(XML_BEGIN_TAG);
+		temp.append(XML_SLASH).append(elementString).append(XML_END_TAG).append("\n"); //$NON-NLS-1$
+		xmlWriter.write(temp.toString());
+
+	}
+
+	public static void printHead(Writer xmlWriter, String encoding) throws IOException {
+		StringBuffer temp = new StringBuffer(XML_HEAD);
+		temp.append(encoding).append(XML_DBL_QUOTES).append(XML_HEAD_END_TAG).append("\n"); //$NON-NLS-1$
+		xmlWriter.write(temp.toString());
+	}
+
+	public static String wrapAttributeForPrint(String attribute, String value) throws IOException {
+		StringBuffer temp = new StringBuffer(XML_SPACE);
+		temp.append(attribute).append(XML_EQUAL).append(XML_DBL_QUOTES)
+				.append(encode(value).toString()).append(XML_DBL_QUOTES);
+		return temp.toString();
+
+	}
+
+	public static void printNode(Writer xmlWriter, Node node,String encoding)  throws Exception{
+		if (node == null) {
+			return;
+		}
+
+		switch (node.getNodeType()) {
+		case Node.DOCUMENT_NODE: {
+			printHead(xmlWriter,encoding);
+			printNode(xmlWriter, ((Document) node).getDocumentElement(),encoding);
+			break;
+		}
+		case Node.ELEMENT_NODE: {
+			//get the attribute list for this node.
+			StringBuffer tempElementString = new StringBuffer(node.getNodeName());
+			NamedNodeMap attributeList = node.getAttributes();
+			if ( attributeList != null ) {
+				for(int i= 0; i <attributeList.getLength();i++){
+					Node attribute = attributeList.item(i);
+					tempElementString.append(wrapAttributeForPrint(attribute.getNodeName(),attribute.getNodeValue()));
+				}
+			}
+			printBeginElement(xmlWriter,tempElementString.toString());
+			
+			// do this recursively for the child nodes.
+			NodeList childNodes = node.getChildNodes();
+			if (childNodes != null) {
+				int length = childNodes.getLength();
+				for (int i = 0; i < length; i++) {
+					printNode(xmlWriter, childNodes.item(i),encoding);
+				}
+			}
+			
+			printEndElement(xmlWriter,node.getNodeName());
+			break;
+		}
+		
+		case Node.TEXT_NODE: {
+			xmlWriter.write(encode(node.getNodeValue()).toString());
+			break;
+		}
+		default: {
+			throw new UnsupportedOperationException(Messages.XMLPrintHandler_unsupportedNodeType);
+			
+		}
+		}
+
+	}
+
+	public static StringBuffer encode(String value) {
+		StringBuffer buf = new StringBuffer();
+		for (int i = 0; i < value.length(); i++) {
+			char c = value.charAt(i);
+			switch (c) {
+				case '&' :
+					buf.append("&amp;"); //$NON-NLS-1$
+					break;
+				case '<' :
+					buf.append("&lt;"); //$NON-NLS-1$
+					break;
+				case '>' :
+					buf.append("&gt;"); //$NON-NLS-1$
+					break;
+				case '\'' :
+					buf.append("&apos;"); //$NON-NLS-1$
+					break;
+				case '\"' :
+					buf.append("&quot;"); //$NON-NLS-1$
+					break;
+				default :
+					buf.append(c);
+					break;
+			}
+		}
+		return buf;
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/AboutInfo.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/AboutInfo.java
new file mode 100644
index 0000000..655530b
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/AboutInfo.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator.branding;
+
+import java.net.*;
+import java.util.Hashtable;
+
+import org.eclipse.core.runtime.*;
+
+
+/**
+ * The information within this object is obtained from the about INI file.
+ * This file resides within an install configurations directory and must be a 
+ * standard java property file.  
+ * <p>
+ * This class is not intended to be instantiated or subclassed by clients.
+ * </p>
+ */
+public final class AboutInfo {
+	private final static String INI_FILENAME = "about.ini"; //$NON-NLS-1$
+	private final static String PROPERTIES_FILENAME = "about.properties"; //$NON-NLS-1$
+	private final static String MAPPINGS_FILENAME = "about.mappings"; //$NON-NLS-1$
+
+	private String featureId;
+	private String versionId = ""; //$NON-NLS-1$
+	private String featurePluginLabel;
+	private String providerName;
+	private String appName;
+	private URL windowImageURL;
+	private URL[] windowImagesURLs;
+	private URL aboutImageURL;
+	private URL featureImageURL;
+	private URL welcomePageURL;
+	private String aboutText;
+	private String welcomePerspective;
+	private String tipsAndTricksHref;
+
+
+	/*
+	 * Create a new about info for a feature with the given id.
+	 */
+	/* package */ AboutInfo(String featureId) {
+		super();
+		this.featureId = featureId;
+	}
+
+	/**
+	 * Returns the configuration information for the feature with the 
+	 * given id.
+	 * 
+	 * @param featureId the feature id
+	 * @param versionId the version id (of the feature)
+	 * @param pluginId the plug-in id
+	 * @return the configuration information for the feature
+	 */
+	public static AboutInfo readFeatureInfo(String featureId, String versionId, String pluginId) {
+//		Assert.isNotNull(featureId);
+//		Assert.isNotNull(versionId);
+//		Assert.isNotNull(pluginId);
+		IniFileReader reader = new IniFileReader(featureId, pluginId, INI_FILENAME, PROPERTIES_FILENAME, MAPPINGS_FILENAME);
+		reader.load();
+// bug 78031
+//		if (!status.isOK()) {
+//			//return null;
+//			return new AboutInfo(featureId); // dummy about info
+//		}
+		
+		AboutInfo info = new AboutInfo(featureId);
+		Hashtable runtimeMappings  = new Hashtable();
+		runtimeMappings.put("{featureVersion}", versionId); //$NON-NLS-1$
+		info.versionId = versionId;
+		info.featurePluginLabel = reader.getFeaturePluginLabel();
+		info.providerName = reader.getProviderName();
+		info.appName = reader.getString("appName", true, runtimeMappings); //$NON-NLS-1$
+		info.aboutText = reader.getString("aboutText", true, runtimeMappings); //$NON-NLS-1$
+		info.windowImageURL = reader.getURL("windowImage"); //$NON-NLS-1$
+		// look for the newer array, but if its not there then use the older,
+		// single image definition
+		info.windowImagesURLs = reader.getURLs("windowImages"); //$NON-NLS-1$
+		info.aboutImageURL = reader.getURL("aboutImage"); //$NON-NLS-1$
+		info.featureImageURL = reader.getURL("featureImage"); //$NON-NLS-1$
+		info.welcomePageURL = reader.getURL("welcomePage"); //$NON-NLS-1$
+		info.welcomePerspective = reader.getString("welcomePerspective", false, runtimeMappings); //$NON-NLS-1$
+		info.tipsAndTricksHref = reader.getString("tipsAndTricksHref", false, runtimeMappings); //$NON-NLS-1$
+		return info;
+	}
+	
+	/**
+	 * Returns the URL for an image which can be shown in an "about" dialog 
+	 * for this product. Products designed to run "headless" typically would not 
+	 * have such an image.
+	 * 
+	 * @return the URL for an about image, or <code>null</code> if none
+	 */
+	public URL getAboutImageURL() {
+		return aboutImageURL;
+	}
+
+	/**
+	 * Returns the URL for an image which can be shown in an "about features" 
+	 * dialog. Products designed to run "headless" typically would not have such an image.
+	 * 
+	 * @return the URL for a feature image, or <code>null</code> if none
+	 */
+	public URL getFeatureImageURL() {
+		return featureImageURL;
+	}
+
+	/**
+	 * Returns the simple name of the feature image file.
+	 * 
+	 * @return the simple name of the feature image file,
+	 * or <code>null</code> if none
+	 */
+	public String getFeatureImageName() {
+		if (featureImageURL != null) {
+			IPath path = new Path(featureImageURL.getPath());
+			return path.lastSegment();
+		} 
+		return null;
+	}
+
+		
+	/**
+	 * Returns a label for the feature plugn, or <code>null</code>.
+	 */
+	public String getFeatureLabel() {
+		return featurePluginLabel;
+	}
+
+	/**
+	 * Returns the id for this feature.
+	 * 
+	 * @return the feature id
+	 */
+	public String getFeatureId() {
+		return featureId;
+	}
+	
+	/**
+	 * Returns the text to show in an "about" dialog for this product.
+	 * Products designed to run "headless" typically would not have such text.
+	 * 
+	 * @return the about text, or <code>null</code> if none
+	 */
+	public String getAboutText() {
+		return aboutText;
+	}
+
+	/**
+	 * Returns the application name or <code>null</code>.
+	 * Note this is never shown to the user.
+	 * It is used to initialize the SWT Display.
+	 * <p>
+	 * On Motif, for example, this can be used
+	 * to set the name used for resource lookup.
+	 * </p>
+	 *
+	 * @return the application name, or <code>null</code>
+	 */
+	public String getAppName() {
+		return appName;
+	}
+
+	/**
+	 * Returns the product name or <code>null</code>.
+	 * This is shown in the window title and the About action.
+	 *
+	 * @return the product name, or <code>null</code>
+	 */
+	public String getProductName() {
+		return featurePluginLabel;
+	}
+
+	/**
+	 * Returns the provider name or <code>null</code>.
+	 *
+	 * @return the provider name, or <code>null</code>
+	 */
+	public String getProviderName() {
+		return providerName;
+	}
+
+	/**
+	 * Returns the feature version id.
+	 *
+	 * @return the version id of the feature
+	 */
+	public String getVersionId() {
+		return versionId;
+	}
+
+	/**
+	 * Returns a <code>URL</code> for the welcome page.
+	 * Products designed to run "headless" typically would not have such an page.
+	 * 
+	 * @return the welcome page, or <code>null</code> if none
+	 */
+	public URL getWelcomePageURL() {
+		return welcomePageURL;
+	}
+
+	/**
+	 * Returns the ID of a perspective in which to show the welcome page.
+	 * May be <code>null</code>.
+	 * 
+	 * @return the welcome page perspective id, or <code>null</code> if none
+	 */
+	public String getWelcomePerspectiveId() {
+		return welcomePerspective;
+	}
+
+	/**
+	 * Returns a <code>String</code> for the tips and trick href.
+	 * 
+	 * @return the tips and tricks href, or <code>null</code> if none
+	 */
+	public String getTipsAndTricksHref() {
+		return tipsAndTricksHref;
+	}
+
+	/**
+	 * Returns the image url for the window image to use for this product.
+	 * Products designed to run "headless" typically would not have such an image.
+	 * 
+	 * @return the image url for the window image, or <code>null</code> if none
+	 */
+	public URL getWindowImageURL() {
+		return windowImageURL;
+	}
+	
+	/**
+	 * Return an array of image URLs for the window images to use for
+	 * this product. The expectations is that the elements will be the same
+	 * image rendered at different sizes. Products designed to run "headless"
+	 * typically would not have such images.
+	 * 
+	 * @return an array of the image descriptors for the window images, or
+	 *         <code>null</code> if none
+	 * @since 3.0
+	 */
+	public URL[] getWindowImagesURLs() {
+		return windowImagesURLs;
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IBundleGroupConstants.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IBundleGroupConstants.java
new file mode 100644
index 0000000..94f66cd
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IBundleGroupConstants.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator.branding;
+
+import org.eclipse.update.configurator.IPlatformConfiguration.IFeatureEntry;
+
+/**
+ * These constants define the set of properties that the UI expects to
+ * be available via <code>IBundleGroup.getProperty(String)</code>.
+ * 
+ * @since 3.0
+ * @see org.eclipse.core.runtime.IBundleGroup#getProperty(String)
+ */
+public interface IBundleGroupConstants {
+	/**
+	 * An image which can be shown in an "about features" dialog (32x32).
+	 */
+	public static final String FEATURE_IMAGE = "featureImage"; //$NON-NLS-1$
+
+	/**
+	 * A help reference for the feature's tips and tricks page (optional).
+	 */
+	public static final String TIPS_AND_TRICKS_HREF = "tipsAndTricksHref"; //$NON-NLS-1$
+
+	/**
+	 * A URL for the feature's welcome page (special XML-based format)
+     * ($nl$/ prefix to permit locale-specific translations of entire file).
+	 * Products designed to run "headless" typically would not have such a page.
+	 */
+	public static final String WELCOME_PAGE = "welcomePage"; //$NON-NLS-1$
+
+	/**
+	 * The id of a perspective in which to show the welcome page
+	 * (optional).
+	 */
+	public static final String WELCOME_PERSPECTIVE = "welcomePerspective"; //$NON-NLS-1$
+	
+	/**
+	 * The URL of the license page for the feature
+	 * (optional).
+	 */
+	public static final String LICENSE_HREF = "licenseHref"; //$NON-NLS-1$
+	
+	/**
+	 * The id of the bundle group's branding bundle.
+	 * @see IFeatureEntry#getFeaturePluginIdentifier()
+	 * @since 3.3
+	 */
+	public static final String BRANDING_BUNDLE_ID= "brandingBundleId"; //$NON-NLS-1$
+
+	/**
+	 * The version of the feature branding bundle.
+	 * @see IFeatureEntry#getFeaturePluginVersion()
+	 * @since 3.3
+	 */
+	public static final String BRANDING_BUNDLE_VERSION= "brandingBundleVersion"; //$NON-NLS-1$
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IProductConstants.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IProductConstants.java
new file mode 100644
index 0000000..f5620db
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IProductConstants.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator.branding;
+
+/**
+ * These constants define the set of properties that the UI expects to
+ * be available via <code>IProduct.getProperty(String)</code>.
+ * 
+ * @since 3.0
+ * @see org.eclipse.core.runtime.IProduct#getProperty(String)
+ */
+public interface IProductConstants {
+	/**
+	 * The application name, used to initialize the SWT Display.  This
+	 * value is distinct from the string displayed in the application
+	 * title bar.
+	 * <p>
+	 * E.g., On motif, this can be used to set the name used for
+	 * resource lookup.
+	 * </p>
+	 */
+	public static final String APP_NAME = "appName"; //$NON-NLS-1$
+
+	/**
+	 * The text to show in an "about" dialog for this product.
+	 * Products designed to run "headless" typically would not
+	 * have such text.
+	 */
+	public static final String ABOUT_TEXT = "aboutText"; //$NON-NLS-1$
+
+	/**
+	 * An image which can be shown in an "about" dialog for this
+	 * product. Products designed to run "headless" typically would not 
+	 * have such an image.
+	 * <p>
+     * A full-sized product image (no larger than 500x330 pixels) is
+     * shown without the "aboutText" blurb.  A half-sized product image
+     * (no larger than 250x330 pixels) is shown with the "aboutText"
+     * blurb beside it.
+     */
+	public static final String ABOUT_IMAGE = "aboutImage"; //$NON-NLS-1$
+
+	/**
+	 * An image to be used as the window icon for this product (16x16).  
+	 * Products designed to run "headless" typically would not have such an image.
+	 * <p>
+	 * If the <code>WINDOW_IMAGES</code> property is given, then it supercedes
+	 * this one.
+	 * </p>
+	 */
+	public static final String WINDOW_IMAGE = "windowImage"; //$NON-NLS-1$
+
+	/**
+	 * An array of one or more images to be used for this product.  The
+	 * expectation is that the array will contain the same image rendered
+	 * at different sizes (16x16 and 32x32).  
+	 * Products designed to run "headless" typically would not have such images.
+	 * <p>
+	 * If this property is given, then it supercedes <code>WINDOW_IMAGE</code>.
+	 * </p>
+	 */
+	public static final String WINDOW_IMAGES = "windowImages"; //$NON-NLS-1$
+	/**
+	 * A URL for the products's welcome page (special XML-based format)
+	 * ($nl$/ prefix to permit locale-specific translations of entire file).
+	 * Products designed to run "headless" typically would not have such a page.
+	 */
+	public static final String WELCOME_PAGE = "welcomePage";  //$NON-NLS-1$
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IniFileReader.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IniFileReader.java
new file mode 100644
index 0000000..0e2d4bd
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IniFileReader.java
@@ -0,0 +1,366 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.internal.configurator.branding;
+
+import java.io.*;
+import java.net.*;
+import java.text.MessageFormat; // Can't use ICU, possible launch problem?
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.PropertyResourceBundle;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.internal.configurator.Messages;
+import org.eclipse.update.internal.configurator.Utils;
+import org.osgi.framework.*;
+
+/**
+ * Reads the information found in an "INI" file. This file must be in a
+ * standard Java properties format. A properties file may also be provided
+ * to NL values in the INI file - values must start with the % prefix. A
+ * mapping file may also be provided that contains "fill-ins" for the
+ * properties file - format being "n = some text", where n is a number.
+ */
+public class IniFileReader {
+	private static final String PID = "org.eclipse.update.configurator"; //$NON-NLS-1$
+	private static final Status OK_STATUS = new Status(IStatus.OK, PID, 0, "", null); //$NON-NLS-1$
+	private static final String KEY_PREFIX = "%"; //$NON-NLS-1$
+	private static final String KEY_DOUBLE_PREFIX = "%%"; //$NON-NLS-1$
+	private static final String NLS_TAG = "$nl$"; //$NON-NLS-1$
+
+	private String featureId;
+	private String pluginId;
+	private String iniFilename;
+	private String propertiesFilename;
+	private String mappingsFilename;
+	private Properties ini = null;
+	private PropertyResourceBundle properties = null;
+	private String[] mappings = null;
+	private Bundle bundle;
+
+	/**
+	 * Creates an INI file reader that can parse the contents into key,value pairs.
+	 * 
+	 * @param featureId the unique identifier of the feature, must not be <code>null</code>
+	 * @param pluginId the unique identifier of the feature plug-in, must not be <code>null</code>
+	 * @param iniFilename the INI file name, must not be <code>null</code>
+	 * @param propertiesFilename the properties filename, can be <code>null</code> if not required
+	 * @param mappingsFilename the mappings filename, can be <code>null</code> if not required
+	 */
+	public IniFileReader(String featureId, String pluginId, String iniFilename, String propertiesFilename, String mappingsFilename) {
+		super();
+		
+		if (featureId == null || pluginId == null || iniFilename == null) {
+			throw new IllegalArgumentException();
+		}
+			
+		this.featureId = featureId;
+		this.pluginId = pluginId;
+		this.iniFilename = iniFilename;
+		this.propertiesFilename = propertiesFilename;
+		this.mappingsFilename = mappingsFilename;
+	}
+
+	/**
+	 * Read the contents of the INI, properties, and mappings files.
+	 * Does nothing if the content has already been read and parsed.
+	 * 
+	 * @return an <code>IStatus</code> indicating the success or failure
+	 * 	of reading and parsing the INI file content
+	 */
+	public IStatus load() {
+		if (ini != null)
+			return OK_STATUS;
+			
+		// attempt to locate the corresponding plugin
+		bundle = Utils.getBundle(pluginId);
+		if (bundle == null || bundle.getState() == Bundle.UNINSTALLED || bundle.getState() == Bundle.INSTALLED) {
+			bundle = null; // make it null for other test down the road
+			String message = NLS.bind(Messages.IniFileReader_MissingDesc, (new String[] { featureId }));
+			return new Status(IStatus.ERROR, PID, 0, message, null);
+		}
+
+		// Determine the ini file location
+		URL iniURL = null;
+		IOException ioe = null;
+		iniURL = FileLocator.find(bundle, new Path(NLS_TAG).append(iniFilename), null);
+		if (iniURL == null) {
+			String message = NLS.bind(Messages.IniFileReader_OpenINIError, (new String[] { iniFilename }));
+			return new Status(IStatus.ERROR, PID, 0, message, ioe);
+		}
+		
+		// Determine the properties file location
+		URL propertiesURL = null;
+		if (propertiesFilename != null & propertiesFilename.length() > 0) {
+			propertiesURL = FileLocator.find(bundle, new Path(NLS_TAG).append(propertiesFilename), null);
+		}
+
+		// Determine the mappings file location
+		URL mappingsURL = null;
+		if (mappingsFilename != null && mappingsFilename.length() > 0) {
+			mappingsURL = FileLocator.find(bundle, new Path(NLS_TAG).append(mappingsFilename), null);
+		}
+
+		// OK to pass null properties and/or mapping file
+		return load(iniURL, propertiesURL, mappingsURL);
+	}
+		
+	/**
+	 * Returns the string value for the given key, or <code>null</code>.
+	 * The string value is NLS if requested.
+	 * 
+	 * @return the string value for the given key, or <code>null</code>
+	 */
+	public String getString(String key, boolean doNls, Hashtable runtimeMappings) {
+		if (ini == null)
+			return null;
+		String value = ini.getProperty(key);
+		if (value != null && doNls)
+			return getResourceString(value, runtimeMappings);
+		return value;
+	}
+
+
+	/**
+	 * Returns a URL for the given key, or <code>null</code>.
+	 * 
+	 * @return a URL for the given key, or <code>null</code>
+	 */
+	public URL getURL(String key) {
+		if (ini == null)
+			return null;
+
+		URL url = null;
+		String fileName = ini.getProperty(key);
+		if (fileName != null) {
+			if (bundle == null)
+				return null;
+			url = FileLocator.find(bundle, new Path(fileName), null);
+		}
+		return url;
+	}
+	
+	/**
+	 * Returns a array of URL for the given key, or <code>null</code>. The
+	 * property value should be a comma separated list of urls, tokens for
+	 * which bundle cannot build an url will have a null entry.
+	 * 
+	 * @param key name of the property containing the requested urls
+	 * @return a URL for the given key, or <code>null</code>
+	 * @since 3.0
+	 */
+	public URL[] getURLs(String key) {
+		if (ini == null || bundle == null)
+			return null;
+
+		String value = ini.getProperty(key);
+		if (value == null)
+			return null;
+
+		StringTokenizer tokens = new StringTokenizer(value, ","); //$NON-NLS-1$
+		ArrayList array = new ArrayList(10);
+		while (tokens.hasMoreTokens()) {
+			String str = tokens.nextToken().trim();
+			array.add(FileLocator.find(bundle, new Path(str), null));
+		}
+
+		URL[] urls = new URL[array.size()];
+		array.toArray(urls);
+		return urls;
+	}
+
+	/**
+	 * Returns the feature plugin label, or <code>null</code>.
+	 * 
+	 * @return the feature plugin lable, or <code>null</code> if none.
+	 */
+	public String getFeaturePluginLabel() {
+		if (bundle == null)
+			return null;
+		return (String)bundle.getHeaders().get(Constants.BUNDLE_NAME);
+	}
+	
+	/**
+	 * Returns the provider name for this feature, or <code>null</code>.
+	 * 
+	 * @return the provider name for this feature, or <code>null</code>
+	 */
+	public String getProviderName() {
+		if (bundle == null)
+			return null;
+		return (String)bundle.getHeaders().get(Constants.BUNDLE_VENDOR);
+	}
+	
+	/*
+	 * Returns a resource string corresponding to the given argument 
+	 * value and bundle.
+	 * If the argument value specifies a resource key, the string
+	 * is looked up in the given resource bundle. If the argument does not
+	 * specify a valid key, the argument itself is returned as the
+	 * resource string. The key lookup is performed against the
+	 * specified resource bundle. If a resource string 
+	 * corresponding to the key is not found in the resource bundle
+	 * the key value, or any default text following the key in the
+	 * argument value is returned as the resource string.
+	 * A key is identified as a string begining with the "%" character.
+	 * Note that the "%" character is stripped off prior to lookup
+	 * in the resource bundle.
+	 * <p>
+	 * For example, assume resource bundle plugin.properties contains
+	 * name = Project Name
+	 * <pre>
+	 *     <li>getResourceString("Hello World") returns "Hello World"</li>
+	 *     <li>getResourceString("%name") returns "Project Name"</li>
+	 *     <li>getResourceString("%name Hello World") returns "Project Name"</li>
+	 *     <li>getResourceString("%abcd Hello World") returns "Hello World"</li>
+	 *     <li>getResourceString("%abcd") returns "%abcd"</li>
+	 *     <li>getResourceString("%%name") returns "%name"</li>
+	 *     <li>getResourceString(<code>null</code>) returns <code>null</code></li>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param value the value or <code>null</code>
+	 * @param runtimeMappings runtime mappings or <code>null</code>
+	 * @return the resource string
+	 */
+	 public String getResourceString(String value, Hashtable runtimeMappings) {
+		
+		if (value == null)
+			return null;
+		String s = value.trim();
+
+		if (!s.startsWith(KEY_PREFIX))
+			return s;
+
+		if (s.startsWith(KEY_DOUBLE_PREFIX))
+			return s.substring(1);
+
+		int ix = s.indexOf(" "); //$NON-NLS-1$
+		String key = ix == -1 ? s : s.substring(0, ix);
+		String dflt = ix == -1 ? s : s.substring(ix + 1);
+
+		if (properties == null)
+			return dflt;
+
+		String result = null;
+		try {
+			result = properties.getString(key.substring(1));
+		} catch (MissingResourceException e) {
+			return dflt;
+		}
+		if (runtimeMappings != null) {
+			for (Enumeration e = runtimeMappings.keys(); e.hasMoreElements();) {
+				String keyValue = (String) e.nextElement();
+				int i = result.indexOf(keyValue);
+				if (i != -1) {
+					String s1 = result.substring(0,i);
+					String s2 = (String) runtimeMappings.get(keyValue);
+					String s3 = result.substring(i+keyValue.length());
+					result = s1 + s2 + s3;
+				}
+			}
+		}
+	
+		if (result.indexOf('{') != -1) {
+			// We test for the curly braces since due to NL issues we do not
+			// want to use MessageFormat unless we have to.
+			try {
+				result = MessageFormat.format(result, mappings);
+			} catch (IllegalArgumentException e) {
+				//ignore and return string without bound parameters
+			}
+		}
+		
+		return result;	
+	}
+
+	/*
+	 * Read the contents of the ini, properties, and mappings files.
+	 */
+	private IStatus load(URL iniURL, URL propertiesURL, URL mappingsURL) {
+
+		InputStream is = null;
+		try {
+			is = iniURL.openStream();
+			ini = new Properties();
+			ini.load(is);
+		} catch (IOException e) {
+			ini = null;
+			String message = NLS.bind(Messages.IniFileReader_ReadIniError, (new String[] { iniURL.toExternalForm() }));
+			return new Status(IStatus.ERROR, PID, 0, message, e);
+		} finally {
+			try {
+				if (is != null)
+					is.close();
+			} catch (IOException e) {
+			}
+		}
+
+		if (propertiesURL != null) {
+			is = null;
+			try {
+				is = propertiesURL.openStream();
+				properties = new PropertyResourceBundle(is);
+			} catch (IOException e) {
+				properties = null;
+				String message = NLS.bind(Messages.IniFileReader_ReadPropError, (new String[] { propertiesURL.toExternalForm() }));
+				return new Status(IStatus.ERROR, PID, 0, message, e);
+			} finally {
+				try {
+					if (is != null)
+						is.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+
+		PropertyResourceBundle bundle = null;
+		if (mappingsURL != null) {
+			is = null;
+			try {
+				is = mappingsURL.openStream();
+				bundle = new PropertyResourceBundle(is);
+			} catch (IOException e) {
+				bundle = null;
+				String message = NLS.bind(Messages.IniFileReader_ReadMapError, (new String[] { mappingsURL.toExternalForm() }));
+				return new Status(IStatus.ERROR, PID, 0, message, e);
+			} finally {
+				try {
+					if (is != null)
+						is.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+
+		ArrayList mappingsList = new ArrayList();
+		if (bundle != null) {
+			boolean found = true;
+			int i = 0;
+			while (found) {
+				try {
+					mappingsList.add(bundle.getString(Integer.toString(i)));
+				} catch (MissingResourceException e) {
+					found = false;
+				}
+				i++;
+			}
+		}
+		mappings = (String[])mappingsList.toArray(new String[mappingsList.size()]);
+		
+		return OK_STATUS;
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/messages.properties b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/messages.properties
new file mode 100644
index 0000000..cbc0c6a
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/messages.properties
@@ -0,0 +1,58 @@
+###############################################################################
+# Copyright (c) 2000, 2008 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
+###############################################################################
+### Boot plugin message catalog
+
+### Platform Configuration
+cfig_unableToLoad_noURL=Configuration file location not specified
+cfig_unableToSave_noURL=Configuration file save location not specified
+cfig_unableToSave=Unable to save configuration file \"{0}\"
+
+InstalledSiteParser_UnableToCreateURL= Internal Error. Unable to create URL from \"{0}\".
+InstalledSiteParser_UnableToCreateURLForFile= Unable to create URL from \"{0}\".
+InstalledSiteParser_ErrorParsingFile= Unable to parse file \"{0}\".
+InstalledSiteParser_ErrorAccessing= Unable to access file \"{0}\".
+InstalledSiteParser_date = Invalid date attribute {0}
+BundleManifest_noVersion = {0} attribute not found in manifest for bundle \"{1}\".  Bundle will be ignored.
+
+FeatureParser_IdOrVersionInvalid= Error parsing feature stream. The unique identifier or the version is null or empty: unique identifier=\"{0}\" version=\"{1}\".
+
+BundleGroupProvider=Update Manager Configurator
+
+ConfigurationActivator_initialize=Cannot initialize the Update Configurator
+ConfigurationActivator_createConfig=Cannot create configuration in {0}
+ConfigurationActivator_uninstallBundle=Could not uninstall unused bundle {0}
+ConfigurationParser_cannotLoadSharedInstall=Could not load from shared install
+ConfigurationActivator_installBundle=Could not install bundle {0}
+PluginEntry_versionError=Unable to create versioned identifier: {0} {1}
+
+IniFileReader_MissingDesc = Cannot find plugin for feature {0}
+IniFileReader_OpenINIError = Cannot open branding file {0}
+IniFileReader_ReadIniError = Error reading branding file {0}
+IniFileReader_ReadPropError = Error reading branding properties file {0}
+IniFileReader_ReadMapError = Error reading mapping files {0}
+
+SiteEntry_computePluginStamp = Cannot compute plugins change stamp for site {0} because it does not support plugin detection.
+SiteEntry_cannotFindFeatureInDir=Unable to find feature.xml in directory: {0}
+SiteEntry_duplicateFeature=Duplicate feature found on site {0} : {1}
+SiteEntry_pluginsDir = {0} is not a valid plugins directory.
+PlatformConfiguration_expectingPlatformXMLorDirectory=Either specify the configuration directory or a file named platform.xml
+PlatformConfiguration_cannotBackupConfig=Cannot backup current configuration
+PlatformConfiguration_cannotCloseStream=Could not close output stream for
+PlatformConfiguration_cannotCloseTempFile=Could not close output stream for temp file
+PlatformConfiguration_cannotRenameTempFile=Could not rename configuration temp file
+PlatformConfiguration_cannotLoadConfig=Cannot load configuration from
+PlatformConfiguration_cannotLoadDefaultSite=Cannot load default site
+PlatformConfiguration_cannotFindConfigFile=Platform configuration file cannot be found
+PlatformConfiguration_cannotSaveNonExistingConfig=Configuration cannot be saved because it does not exist
+
+PluginParser_plugin_no_id = Plugin does not have a valid identifier: {0}
+PluginParser_plugin_no_version = Plugin does not have a valid version: {0}
+XMLPrintHandler_unsupportedNodeType=Unsupported XML Node Type.
diff --git a/update/org.eclipse.update.core.linux/.classpath b/update/org.eclipse.update.core.linux/.classpath
new file mode 100644
index 0000000..4848249
--- /dev/null
+++ b/update/org.eclipse.update.core.linux/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/update/org.eclipse.update.core.linux/.cvsignore b/update/org.eclipse.update.core.linux/.cvsignore
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/update/org.eclipse.update.core.linux/.cvsignore
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/update/org.eclipse.update.core.linux/.project b/update/org.eclipse.update.core.linux/.project
new file mode 100644
index 0000000..178e2b7
--- /dev/null
+++ b/update/org.eclipse.update.core.linux/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.update.core.linux</name>

+	<comment></comment>

+	<projects>

+		<project>org.eclipse.core.boot</project>

+		<project>org.eclipse.core.runtime</project>

+		<project>org.eclipse.core.runtime.compatibility</project>

+		<project>org.eclipse.update.configurator</project>

+		<project>org.eclipse.update.core</project>

+	</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.jdt.core.javanature</nature>

+		<nature>org.eclipse.pde.PluginNature</nature>

+	</natures>

+</projectDescription>

diff --git a/update/org.eclipse.update.core.linux/about.html b/update/org.eclipse.update.core.linux/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/update/org.eclipse.update.core.linux/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</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
+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/update/org.eclipse.update.core.linux/build.properties b/update/org.eclipse.update.core.linux/build.properties
new file mode 100644
index 0000000..6b5010c
--- /dev/null
+++ b/update/org.eclipse.update.core.linux/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# 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
+###############################################################################
+bin.includes = os/,\
+               fragment.properties,\
+               about.html,\
+               META-INF/
+src.includes = src/,\
+               about.html
diff --git a/update/org.eclipse.update.core.linux/os/linux/x86/libupdate.so b/update/org.eclipse.update.core.linux/os/linux/x86/libupdate.so
new file mode 100644
index 0000000..04710be
--- /dev/null
+++ b/update/org.eclipse.update.core.linux/os/linux/x86/libupdate.so
Binary files differ
diff --git a/update/org.eclipse.update.core.linux/src/build.xml b/update/org.eclipse.update.core.linux/src/build.xml
new file mode 100644
index 0000000..39a4e63
--- /dev/null
+++ b/update/org.eclipse.update.core.linux/src/build.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="buildlibrary" default="run" basedir="."> 
+  
+  <!-- The properties ${eclipse-home} ${jdk-path} should be passed into this script -->
+  <!-- Set a meaningful default value for when it is not. -->
+  <property name="eclipse-home" value="${basedir}/../.."/>
+  <property name="jdk-path" value="${java.home}"/>
+  <property name="installArch" value="x86" />
+  <property name="destination" value="${eclipse-home}/org.eclipse.update.core.linux/os/linux/${installArch}/"/>
+  <property name="obj-path" value="${eclipse-home}/org.eclipse.update.core.linux/src/"/>
+  <property name="src-path" value="${eclipse-home}/org.eclipse.update.core.linux/src/"/>  
+  
+  <!-- sets the properties -->
+  <property name="library-name" value="libupdate"/>  
+  <property name="library-platform" value="so"/>    
+  <property name="library-file" value="${library-name}.${library-platform}"/>
+  
+  <!-- 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="${obj-path}" includes="${library-file}"/>
+      <fileset dir="${obj-path}" includes="${library-name}.o"/>
+    </delete>
+  </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">
+      <delete>
+      <fileset dir="${obj-path}" includes="${library-file}"/>
+      <fileset dir="${obj-path}" includes="${library-name}.o"/>
+    </delete>
+  </target>
+  
+  
+  <!-- This target runs the build. -->
+  <target name="run" depends="init,build,cleanup">
+  </target>
+  
+  <!-- This target build the library -->
+  <target name="build">
+    <echo message="Building ${library-file}"/>
+
+    <property name="header-path" value="${jdk-path}/../include"/>
+    <property name="header-linux-path" value="${header-path}/linux" />
+
+	<echo message="gcc -o  ${library-file} -shared -I${src-path} -I${header-linux-path} -fPIC ${library-file}"/>
+
+    <apply executable="gcc" dest="${eclipse-home}/" parallel="false">
+      <arg value="-o"/>
+      <arg value="${library-file}"/>
+      <arg value="-shared"/>
+      <arg value="-I${src-path}"/>
+      <arg value="-I${header-path}"/>      
+      <arg value="-I${header-linux-path}"/>
+      <arg value="-fPIC"/>
+	  <srcfile/>
+      <fileset dir="${src-path}" includes="*.c"/>
+      <mapper type="glob" from="*.c" to="*.o"/>
+    </apply>
+    
+	<move file="${library-file}" todir="${destination}"/>
+  </target>
+  
+  
+</project>
\ No newline at end of file
diff --git a/update/org.eclipse.update.core.linux/src/update.h b/update/org.eclipse.update.core.linux/src/update.h
new file mode 100644
index 0000000..6cddb8c
--- /dev/null
+++ b/update/org.eclipse.update.core.linux/src/update.h
@@ -0,0 +1,76 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */

+

+/**********************************************************************

+ * 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

+ **********************************************************************/

+ 

+#include <jni.h>

+/* Header for class org_eclipse_update_configuration_LocalSystemInfo */

+

+#ifndef _Included_org_eclipse_update_configuration_LocalSystemInfo

+#define _Included_org_eclipse_update_configuration_LocalSystemInfo

+#ifdef __cplusplus

+extern "C" {

+#endif

+#undef org_eclipse_update_configuration_LocalSystemInfo_SIZE_UNKNOWN

+#define org_eclipse_update_configuration_LocalSystemInfo_SIZE_UNKNOWN -1L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_UNKNOWN

+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_UNKNOWN -1L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_INVALID_PATH

+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_INVALID_PATH -2L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOVABLE

+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOVABLE 1L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FIXED

+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FIXED 2L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOTE

+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOTE 3L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_CDROM

+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_CDROM 4L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_RAMDISK

+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_RAMDISK 5L

+/* Inaccessible static: listeners */

+/* Inaccessible static: hasNatives */

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeGetFreeSpace

+ * Signature: (Ljava/io/File;)J

+ */

+JNIEXPORT jlong JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetFreeSpace

+  (JNIEnv *, jclass, jobject);

+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeGetLabel

+ * Signature: (Ljava/io/File;)Ljava/lang/String;

+ */

+JNIEXPORT jstring JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetLabel

+  (JNIEnv *, jclass, jobject);

+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeGetType

+ * Signature: (Ljava/io/File;)I

+ */

+JNIEXPORT jint JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetType

+  (JNIEnv *, jclass, jobject);

+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeListMountPoints

+ * Signature: ()[Ljava/lang/String;

+ */

+JNIEXPORT jobjectArray JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeListMountPoints

+  (JNIEnv *, jclass);

+

+#ifdef __cplusplus

+}

+

+#endif

+#endif

diff --git a/update/org.eclipse.update.core.win32/.project b/update/org.eclipse.update.core.win32/.project
new file mode 100644
index 0000000..8c9b28f
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/.project
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.update.core.win32</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/update/org.eclipse.update.core.win32/about.html b/update/org.eclipse.update.core.win32/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</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
+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/update/org.eclipse.update.core.win32/build.properties b/update/org.eclipse.update.core.win32/build.properties
new file mode 100644
index 0000000..27ddaca
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# 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
+###############################################################################
+bin.includes = os/,\
+               fragment.properties,\
+               about.html,\
+               META-INF/
+src.includes = about.html,\
+               src/
diff --git a/update/org.eclipse.update.core.win32/os/win32/ia64/update.dll b/update/org.eclipse.update.core.win32/os/win32/ia64/update.dll
new file mode 100644
index 0000000..8ce4694
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/os/win32/ia64/update.dll
Binary files differ
diff --git a/update/org.eclipse.update.core.win32/os/win32/x86/update.dll b/update/org.eclipse.update.core.win32/os/win32/x86/update.dll
new file mode 100644
index 0000000..cb194d2
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/os/win32/x86/update.dll
Binary files differ
diff --git a/update/org.eclipse.update.core.win32/src/build.xml b/update/org.eclipse.update.core.win32/src/build.xml
new file mode 100644
index 0000000..92286b7
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/src/build.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="buildlibrary" default="run" basedir="."> 
+  
+  <!-- The properties ${eclipse-home} ${jdk-path} should be passed into this script -->
+  <!-- The Path should point to the bin directory of BCC55 -->
+  <!-- http://www.borland.com/products/downloads/download_cbuilder.html -->
+  
+  <!-- Set a meaningful default value for when it is not. -->
+  <property name="eclipse-home" value="${basedir}/../.."/>
+  <property name="jdk-path" value="${java.home}"/>  
+  <property name="destination" value="${eclipse-home}/org.eclipse.update.core.win32/os/win32/x86/"/>
+  <property name="obj-path" value="${eclipse-home}/org.eclipse.update.core.win32/src"/>
+  <property name="src-path" value="${eclipse-home}/org.eclipse.update.core.win32/src/"/>  
+  
+  <!-- sets the properties -->
+  <property name="library-name" value="update"/>  
+  <property name="library-platform" value="dll"/>    
+  <property name="library-file" value="${library-name}.${library-platform}"/>
+  
+  <!-- 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="${obj-path}" includes="${library-file}"/>
+      <fileset dir="${obj-path}" includes="${library-name}.obj"/>
+      <fileset dir="${obj-path}" includes="${library-name}.tds"/>            
+    </delete>
+  </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">
+      <delete>
+      <fileset dir="${obj-path}" includes="${library-file}"/>
+      <fileset dir="${obj-path}" includes="${library-name}.obj"/>
+      <fileset dir="${obj-path}" includes="${library-name}.tds"/>            
+    </delete>
+  </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,build,cleanup">
+  </target>
+  
+  <!-- This target build the dll -->
+  <target name="build">
+    <echo message="Building ${library-file}"/>
+
+    <property name="header-path" value="${jdk-path}/include"/>
+    <property name="header-windows-path" value="${header-path}/win32" />
+
+	<echo message="bcc32 -I${src-path} -I${header-windows-path} -WD"/>
+
+    <apply executable="bcc32" dest="${eclipse-home}/" parallel="false">
+      <arg value="-I${src-path}"/>
+      <arg value="-I${header-path}"/>      
+      <arg value="-I${header-windows-path}"/> 
+      <!-- arg value="-DUNICODE" --> 
+	  <arg value="-w-8057"/>           
+      <arg value="-WD"/>
+	  <srcfile/>
+      <fileset dir="${src-path}" includes="*.cpp"/>
+      <mapper type="glob" from="*.cpp" to="*.obj"/>
+    </apply>
+    
+	<move file="${library-file}" todir="${destination}"/>
+  </target>
+  
+  
+</project>
\ No newline at end of file
diff --git a/update/org.eclipse.update.core.win32/src/make.bat b/update/org.eclipse.update.core.win32/src/make.bat
new file mode 100644
index 0000000..52105b0
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/src/make.bat
@@ -0,0 +1,17 @@
+rem *******************************************************************************
+rem  Copyright (c) 2005, 2006 IBM Corporation and others.
+rem  All rights reserved. This program and the accompanying materials
+rem  are made available under the terms of the Eclipse Public License v1.0
+rem  which accompanies this distribution, and is available at
+rem  http://www.eclipse.org/legal/epl-v10.html
+rem 
+rem  Contributors:
+rem      IBM Corporation - initial API and implementation
+rem *******************************************************************************
+del update.obj
+del update.dll
+set win_include=k:\msvc60\vc98\include
+set lib_includes=K:\Msvc60\VC98\Lib\UUID.LIB K:\Msvc60\VC98\Lib\LIBCMT.LIB K:\Msvc60\VC98\Lib\OLDNAMES.LIB K:\Msvc60\VC98\Lib\KERNEL32.LIB
+set jdk_include=d:\vm\jdk1.4.2\include
+set dll_name=update
+cl -I%win_include% -I%jdk_include% -I%jdk_include%\win32 -LD update.cpp -Fe%dll_name% /link %lib_includes%
diff --git a/update/org.eclipse.update.core.win32/src/setup.bat b/update/org.eclipse.update.core.win32/src/setup.bat
new file mode 100644
index 0000000..4ff5746
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/src/setup.bat
@@ -0,0 +1,13 @@
+rem *******************************************************************************
+rem  Copyright (c) 2005, 2006 IBM Corporation and others.
+rem  All rights reserved. This program and the accompanying materials
+rem  are made available under the terms of the Eclipse Public License v1.0
+rem  which accompanies this distribution, and is available at
+rem  http://www.eclipse.org/legal/epl-v10.html
+rem 
+rem  Contributors:
+rem      IBM Corporation - initial API and implementation
+rem *******************************************************************************
+set path=%path%;K:\msvc60\vc98\bin;K:\msvc60\Common\MSDev98\Bin
+set temp=d:\temp
+set tmp=d:\temp
diff --git a/update/org.eclipse.update.core.win32/src/update.cpp b/update/org.eclipse.update.core.win32/src/update.cpp
new file mode 100644
index 0000000..66cae43
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/src/update.cpp
@@ -0,0 +1,381 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2006 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

+ *******************************************************************************/

+

+# include "update.h"

+# include <windows.h>

+# include <winioctl.h> // IOCTL codes: MediaType

+

+// set to 1 for DEBUG

+int DEBUG = 0;

+

+// GLOBAL METHODS

+// ---------------

+

+/*

+ *

+ */

+jstring WindowsTojstring( JNIEnv* jnienv, char* buf )

+{

+  jstring rtn = 0;

+  wchar_t* buffer = 0;

+  int bufferLen = strlen(buf);  

+  if( bufferLen == 0 ){

+    rtn = jnienv ->NewStringUTF(buf);

+	if (DEBUG)

+		printf("WindowsToJString Buffer is empty\n");    

+  } else {

+    int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)buf, bufferLen, NULL, 0 );

+    buffer = (wchar_t*)malloc( length*2 + 1 );

+    if(int err=MultiByteToWideChar( CP_ACP, 0, (LPCSTR)buf, bufferLen, (LPWSTR)buffer, length ) >0 ){

+      rtn = jnienv->NewString((jchar*)buffer, length );

+    } else {

+		if (DEBUG)

+			printf("MultiByteToWideChar %i\n",err);    

+    }

+  }

+  if( buffer )

+   free( buffer );

+  return rtn;

+}

+

+

+

+/*

+ * calls GetVolumeInformation to retrive the label of the volume

+ * Returns NULL if an error occurs

+ * @param driveLetter path to the drive "c:\\"

+ * @prama jnienv JNIEnvironment

+ */

+jstring getLabel(TCHAR driveLetter[],JNIEnv * jnienv){

+

+	jstring result = NULL;

+	TCHAR buf[128];	

+	

+	// always return null as UNICODE is not implemented

+	// how can we get the label of a volume as UNICODE char ?

+	return result;

+	

+	int err = GetVolumeInformation(

+		driveLetter,

+		buf,

+		sizeof(buf) - 1,

+		NULL,

+		NULL,

+		NULL,

+		NULL,

+		0);

+	if (err){

+		result = WindowsTojstring(jnienv, buf);

+	} else {

+		if (DEBUG)

+			printf("Error GetVolumeInformation %i\n",err);				

+ 	}

+	return result;

+}

+

+/*

+ * Returns the type of Removable Drive 

+ * Returns 

+ * org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_3

+ * org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_5

+ * org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOVABLE

+ */

+jlong getFloppy(TCHAR driveLetter[]){

+

+	TCHAR floppyPath[8];

+	HANDLE handle;

+	DISK_GEOMETRY geometry[20];

+	DWORD dw;

+	jlong UNKNOWN = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOVABLE;

+

+	sprintf(floppyPath, "\\\\.\\%c:", driveLetter[0]);

+	if (DEBUG)

+		printf("Path %s\n",floppyPath);

+	// BUG 25719

+    SetErrorMode( SEM_FAILCRITICALERRORS ); 		

+	handle=CreateFile(floppyPath,0,FILE_SHARE_READ,NULL,OPEN_ALWAYS,0,NULL);

+	if (handle==INVALID_HANDLE_VALUE){

+		if (DEBUG)

+			printf("Invalid Handle %s\n",floppyPath);

+		return UNKNOWN;

+	} else {

+		if(DeviceIoControl(handle,

+			IOCTL_DISK_GET_MEDIA_TYPES,0,0,

+			geometry,sizeof(geometry),&dw,0) 

+			&& dw>0) {

+			switch(geometry[0].MediaType){

+			 case F5_160_512:

+			 case F5_180_512:

+			 case F5_320_512:

+			 case F5_320_1024:

+			 case F5_360_512:

+			 case F5_1Pt2_512:

+				if (DEBUG)

+					printf("Found 5 1/4 Drive\n");				 	

+			 	return org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_5;

+			 case F3_720_512:			 				 				 				 				 

+			 case F3_1Pt44_512:

+			 case F3_2Pt88_512:

+			 case F3_20Pt8_512:				 				 				 

+				if (DEBUG)

+					printf("Found 3 1/2 Drive\n");				 	

+			 	return org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_3;

+			 default:

+			 	return UNKNOWN;

+			}

+		}

+	}

+	return UNKNOWN;	

+}

+

+/*

+ * Returns the UNC name of a remote drive

+ * (\\Machine\path\path1\path2$)

+ * returns NULL if an error occurs

+ */

+ jstring getRemoteNetworkName(TCHAR driveLetter[],JNIEnv * jnienv){

+ 	

+ 	unsigned long size =256;

+ 	TCHAR buf[256];	

+ 	TCHAR drivePath[2];

+ 	DWORD err;

+ 	jstring result = NULL;

+ 	

+ 	// always return NULL as UNICODE not implemented

+	// how can we get the label of a remote network name as UNICODE char ? 	

+ 	return result;

+ 	

+	sprintf(drivePath, "%c:", driveLetter[0]); 	

+ 	err = WNetGetConnection(drivePath,buf,&size);

+ 	

+ 	if (err==WN_SUCCESS){

+		result = WindowsTojstring(jnienv,buf);

+	} else {

+		if (DEBUG)

+			printf("Error WNEtGetConnection %i",err);				

+ 	}

+	return result;

+ }

+

+

+// JNI METHODS

+// ---------------

+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeGetFreeSpace

+ * Signature: (Ljava/io/File;)J

+ */

+JNIEXPORT jlong JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetFreeSpace(

+	JNIEnv * jnienv,

+	jclass javaClass,

+	jobject file) {

+

+	// to retrive the String

+	jclass cls;

+	jmethodID id;

+	jobject obj;

+

+	// java.io.File.getAbsolutePath()

+	const TCHAR * lpDirectoryName;

+

+	// Windows Parameters

+	__int64 i64FreeBytesAvailableToCaller;

+	__int64 i64TotalNumberOfBytes;

+	__int64 i64TotalNumberOfFreeBytes;

+

+	// first, obtain the Path from the java.io.File parameter

+	cls = jnienv -> GetObjectClass(file);

+	id = jnienv -> GetMethodID(cls, "getAbsolutePath", "()Ljava/lang/String;");

+	obj = jnienv -> CallObjectMethod(file, id);

+	lpDirectoryName = jnienv -> GetStringUTFChars((jstring) obj, 0);

+	if (DEBUG)

+		printf("Directory: [%s]\n",lpDirectoryName);

+

+	int success = GetDiskFreeSpaceEx(

+				lpDirectoryName,

+				(PULARGE_INTEGER) & i64FreeBytesAvailableToCaller,

+				(PULARGE_INTEGER) & i64TotalNumberOfBytes,

+				(PULARGE_INTEGER) & i64TotalNumberOfFreeBytes);

+			

+	if (success) {

+		return (jlong) i64FreeBytesAvailableToCaller;

+	} else {

+		return org_eclipse_update_configuration_LocalSystemInfo_SIZE_UNKNOWN;

+	}

+}

+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeGetLabel

+ * Signature: (Ljava/io/File;)Ljava/lang/String;

+ */

+JNIEXPORT jstring JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetLabel(

+	JNIEnv * jnienv,

+	jclass javaClass,

+	jobject file) {

+

+	// to retrive the String

+	jclass cls;

+	jmethodID id;

+	jobject obj;

+

+	// java.io.File.getAbsolutePath()

+	const TCHAR * lpDirectoryName;

+

+	// obtain the String from the parameter

+	cls = jnienv -> GetObjectClass(file);

+	id = jnienv -> GetMethodID(cls, "getAbsolutePath", "()Ljava/lang/String;");

+	obj = jnienv -> CallObjectMethod(file, id);

+	lpDirectoryName = jnienv -> GetStringUTFChars((jstring) obj, 0);

+	if (DEBUG)

+		printf("Directory: [%s]\n",lpDirectoryName);

+

+	//

+	jstring result = NULL;

+	

+	// Make sure we have a String of the Form: <letter>:

+	if (':' == lpDirectoryName[1]) {

+		TCHAR driveLetter[4]; // C:\\ for example

+		memcpy(driveLetter, lpDirectoryName, 2);

+		strcpy(driveLetter + 2, "\\");

+		switch (GetDriveType(driveLetter)) {

+			case DRIVE_REMOTE :

+				// check name of machine and path of remote

+				if (DEBUG)

+					printf("Remote Drive");

+				result = getRemoteNetworkName(driveLetter,jnienv);				

+				break;

+			default :

+				if (DEBUG)

+					printf("Another Drive at %s", driveLetter);

+				result = getLabel(driveLetter,jnienv);

+				break;

+		} 

+	} 

+

+	return result;

+}

+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeGetType

+ * Signature: (Ljava/io/File;)I

+ */

+JNIEXPORT jint JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetType(

+	JNIEnv * jnienv,

+	jclass javaClass,

+	jobject file) {

+

+	// to retrive the String

+	jclass cls;

+	jmethodID id;

+	jobject obj;

+

+	// java.io.File.getAbsolutePath()

+	const TCHAR * lpDirectoryName;

+

+	// obtain the String from the parameter

+	cls = jnienv -> GetObjectClass(file);

+	id = jnienv -> GetMethodID(cls, "getAbsolutePath", "()Ljava/lang/String;");

+	obj = jnienv -> CallObjectMethod(file, id);

+	lpDirectoryName = jnienv -> GetStringUTFChars((jstring) obj, 0);

+	if (DEBUG)

+		printf("Directory: [%s]\n",lpDirectoryName);

+

+	int result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_UNKNOWN;

+	

+	// Make sure we have a String of the Form: <letter>:

+	if (':' == lpDirectoryName[1]) {

+		TCHAR driveLetter[4]; //C:\\ for example

+		memcpy(driveLetter, lpDirectoryName, 2);

+		strcpy(driveLetter + 2, "\\");

+

+		switch (GetDriveType(driveLetter)) {

+			case DRIVE_REMOVABLE :

+				// check if floppy 3.5, floppy 5.25	

+				// or other removable device (USB,PCMCIA ...)

+				if (DEBUG)

+					printf("Removable Device");

+				result = getFloppy(driveLetter);					

+				break;

+			case DRIVE_CDROM :

+				result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_CDROM;

+				break;

+			case DRIVE_FIXED :

+				result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FIXED;

+				break;

+			case DRIVE_REMOTE :

+				result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOTE;

+				break;

+			case DRIVE_NO_ROOT_DIR :

+				result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_INVALID_PATH;

+				break;

+			case DRIVE_RAMDISK :

+				result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_RAMDISK;

+				break;			

+			case DRIVE_UNKNOWN :

+			default :

+				result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_UNKNOWN;

+				break;

+		}

+	} else {

+		result = org_eclipse_update_configuration_LocalSystemInfo_VOLUME_INVALID_PATH;

+	}

+

+	return result;

+}

+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeListMountPoints

+ * Signature: ()[Ljava/lang/String;

+ */

+JNIEXPORT jobjectArray JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeListMountPoints(

+	JNIEnv * jnienv,

+	jclass javaClass) {

+

+	//

+	DWORD logDrives;

+	UINT drive;

+	TCHAR driveName[100];

+	jobjectArray returnArray;

+	int nDrive = 0;

+

+	// 

+	jclass stringClass;

+	jobject empty;

+	int index = 0;

+	jobject str;

+

+

+	logDrives = GetLogicalDrives();

+	for (drive = 0; drive < 32; drive++) {

+		if (logDrives & (1 << drive)) {

+			nDrive++;

+		}

+	}

+

+	stringClass = jnienv -> FindClass("java/lang/String");

+	empty = jnienv -> NewStringUTF("");

+	returnArray = jnienv -> NewObjectArray(nDrive, stringClass, empty);

+

+	for (drive = 0; drive < 32; drive++) {

+		if (logDrives & (1 << drive)) {

+			sprintf(driveName, "%c:\\", drive + 'A');

+			str = jnienv -> NewStringUTF(driveName);

+			jnienv -> SetObjectArrayElement(returnArray, index, str);

+			index++;

+		}

+	}

+

+	return returnArray;

+}

diff --git a/update/org.eclipse.update.core.win32/src/update.h b/update/org.eclipse.update.core.win32/src/update.h
new file mode 100644
index 0000000..d3ca7e0
--- /dev/null
+++ b/update/org.eclipse.update.core.win32/src/update.h
@@ -0,0 +1,79 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+
+/**********************************************************************
+ * 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
+ **********************************************************************/
+#include <jni.h>

+/* Header for class org_eclipse_update_configuration_LocalSystemInfo */
+
+#ifndef _Included_org_eclipse_update_configuration_LocalSystemInfo
+#define _Included_org_eclipse_update_configuration_LocalSystemInfo

+#ifdef __cplusplus
+extern "C" {
+#endif

+#undef org_eclipse_update_configuration_LocalSystemInfo_SIZE_UNKNOWN
+#define org_eclipse_update_configuration_LocalSystemInfo_SIZE_UNKNOWN -1L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_UNKNOWN
+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_UNKNOWN -1L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_INVALID_PATH
+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_INVALID_PATH -2L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOVABLE
+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOVABLE 1L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FIXED
+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FIXED 2L

+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOTE
+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_REMOTE 3L
+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_CDROM
+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_CDROM 4L
+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_RAMDISK
+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_RAMDISK 5L
+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_5
+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_5 6L
+#undef org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_3
+#define org_eclipse_update_configuration_LocalSystemInfo_VOLUME_FLOPPY_3 7L

+/* Inaccessible static: listeners */

+/* Inaccessible static: hasNatives */

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeGetFreeSpace

+ * Signature: (Ljava/io/File;)J

+ */

+JNIEXPORT jlong JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetFreeSpace

+  (JNIEnv *, jclass, jobject);
+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeGetLabel

+ * Signature: (Ljava/io/File;)Ljava/lang/String;

+ */

+JNIEXPORT jstring JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetLabel

+  (JNIEnv *, jclass, jobject);
+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeGetType

+ * Signature: (Ljava/io/File;)I

+ */

+JNIEXPORT jint JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeGetType

+  (JNIEnv *, jclass, jobject);
+

+/*

+ * Class:     org_eclipse_update_configuration_LocalSystemInfo

+ * Method:    nativeListMountPoints

+ * Signature: ()[Ljava/lang/String;

+ */

+JNIEXPORT jobjectArray JNICALL Java_org_eclipse_update_configuration_LocalSystemInfo_nativeListMountPoints

+  (JNIEnv *, jclass);
+

+#ifdef __cplusplus
+}
+
+#endif

+#endif

diff --git a/update/org.eclipse.update.core/.classpath b/update/org.eclipse.update.core/.classpath
new file mode 100644
index 0000000..b54a094
--- /dev/null
+++ b/update/org.eclipse.update.core/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="src" path="jarprocessor"/>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/update/org.eclipse.update.core/.cvsignore b/update/org.eclipse.update.core/.cvsignore
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/update/org.eclipse.update.core/.cvsignore
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/update/org.eclipse.update.core/.options b/update/org.eclipse.update.core/.options
new file mode 100644
index 0000000..7bf6197
--- /dev/null
+++ b/update/org.eclipse.update.core/.options
@@ -0,0 +1,9 @@
+org.eclipse.update.core/debug=true

+org.eclipse.update.core/debug/warning=false

+org.eclipse.update.core/debug/parsing=false

+org.eclipse.update.core/debug/install=false

+org.eclipse.update.core/debug/configuration=false

+org.eclipse.update.core/debug/type=false

+org.eclipse.update.core/debug/web=false

+org.eclipse.update.core/debug/installhandler=false

+org.eclipse.update.core/debug/reconciler=false

diff --git a/update/org.eclipse.update.core/.project b/update/org.eclipse.update.core/.project
new file mode 100644
index 0000000..e358fd4
--- /dev/null
+++ b/update/org.eclipse.update.core/.project
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.update.core</name>

+	<comment></comment>

+	<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.jdt.core.javanature</nature>

+		<nature>org.eclipse.pde.PluginNature</nature>

+	</natures>

+</projectDescription>

diff --git a/update/org.eclipse.update.core/.settings/org.eclipse.jdt.core.prefs b/update/org.eclipse.update.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..23d6e87
--- /dev/null
+++ b/update/org.eclipse.update.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,86 @@
+#Wed Feb 11 12:06:10 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=ignore
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/update/org.eclipse.update.core/about.html b/update/org.eclipse.update.core/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/update/org.eclipse.update.core/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</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
+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/update/org.eclipse.update.core/build.properties b/update/org.eclipse.update.core/build.properties
new file mode 100644
index 0000000..cc35d07
--- /dev/null
+++ b/update/org.eclipse.update.core/build.properties
@@ -0,0 +1,22 @@
+###############################################################################

+# Copyright (c) 2000, 2008 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

+###############################################################################

+source.. = src/,\

+           jarprocessor/

+bin.includes = plugin.xml,\

+               plugin.properties,\

+               .,\

+               about.html,\

+               .options,\

+               META-INF/

+src.includes = about.html,\

+               schema/

+output.. = bin/

+customBuildCallbacks=customBuildCallbacks.xml

diff --git a/update/org.eclipse.update.core/customBuildCallbacks.xml b/update/org.eclipse.update.core/customBuildCallbacks.xml
new file mode 100644
index 0000000..a26456f
--- /dev/null
+++ b/update/org.eclipse.update.core/customBuildCallbacks.xml
Binary files differ
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/CommandStep.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/CommandStep.java
new file mode 100644
index 0000000..39c17d3
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/CommandStep.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * @author aniefer@ca.ibm.com
+ *
+ */
+public abstract class CommandStep implements IProcessStep {
+	protected String command = null;
+	protected String extension = null;
+	private  Properties options = null;
+	protected boolean verbose = false;
+	
+	public CommandStep(Properties options, String command, String extension, boolean verbose) {
+		this.command = command;
+		this.extension = extension;
+		this.options = options;
+		this.verbose = verbose;
+	}
+
+	protected static int execute(String[] cmd) {
+		return execute(cmd, false);
+	}
+	
+	protected static int execute(String[] cmd, boolean verbose) {
+		Runtime runtime = Runtime.getRuntime();
+		Process proc = null;
+		try {
+			proc = runtime.exec(cmd);
+			StreamProcessor errorStreamProcessor = new StreamProcessor(proc.getErrorStream(), StreamProcessor.STDERR, verbose); //$NON-NLS-1$
+			StreamProcessor outputStreamProcessor = new StreamProcessor(proc.getInputStream(), StreamProcessor.STDOUT, verbose); //$NON-NLS-1$
+			errorStreamProcessor.start();
+			outputStreamProcessor.start();
+		} catch (Exception e) {
+			if(verbose) {
+				System.out.println("Error executing command " + Utils.concat(cmd)); //$NON-NLS-1$
+				e.printStackTrace();
+			}
+			return -1;
+		}
+		try {
+			int result = proc.waitFor();
+			return result;
+		} catch (InterruptedException e) {
+			if(verbose)
+				e.printStackTrace();
+		}
+		return -1;
+	}
+	
+	public Properties getOptions() {
+		if(options == null)
+			options = new Properties();
+		return options;
+	}
+	
+	public void adjustInf(File input, Properties inf, List containers) {
+		//nothing
+	}
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/IProcessStep.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/IProcessStep.java
new file mode 100644
index 0000000..18c438e
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/IProcessStep.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * @author aniefer@ca.ibm.com
+ *
+ */
+public interface IProcessStep {
+	
+	/**
+	 * The effect of this processing step if the JarProcessor was to recurse on this entry.
+	 * Return null if this step will not do anything with this entry.
+	 * Return the new entryName if this step will modify this entry on recursion.
+	 * @param entryName
+	 * @return
+	 */
+	public String recursionEffect(String entryName);
+	
+	/**
+	 * Perform some processing on the input file before the JarProcessor considers the entries for recursion.
+	 *  return the file containing the result of the processing
+	 * @param input
+	 * @param workingDirectory
+	 * @param containers: inf properties for containing jars, innermost jar is first on the list
+	 * @return
+	 */
+	public File preProcess(File input, File workingDirectory, List containers);
+	
+	/**
+	 * Perform some processing on the input file after the JarProcessor returns from recursion
+	 * return the file containing the result of the processing
+	 * @param input
+	 * @param workingDirectory
+	 * @param containers: inf properties for containing jars, innermost jar is first on the list
+	 * @return
+	 */
+	public File postProcess(File input, File workingDirectory, List containers);
+	
+	/**
+	 * Return the name of this process step
+	 * @return
+	 */
+	public String getStepName();
+
+	/**
+	 * Adjust any properties in the eclipse.inf as appropriate for this step
+	 * @param input
+	 * @param inf
+	 * @param containers: inf properties for containing jars, innermost jar is first on the list
+	 */
+	public void adjustInf(File input, Properties inf, List containers);
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/JarProcessor.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/JarProcessor.java
new file mode 100644
index 0000000..aef3704
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/JarProcessor.java
@@ -0,0 +1,393 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+/**
+ * @author aniefer@ca.ibm.com
+ *
+ */
+public class JarProcessor {
+	private List steps = new ArrayList();
+	private String workingDirectory = ""; //$NON-NLS-1$
+	private int depth = -1;
+	private boolean verbose = false;
+	private boolean processAll = false;
+	private LinkedList containingInfs = new LinkedList();
+
+	static public JarProcessor getUnpackProcessor(Properties properties) {
+		if (!canPerformUnpack())
+			throw new UnsupportedOperationException();
+		JarProcessor processor = new JarProcessor();
+		processor.addProcessStep(new UnpackStep(properties));
+		return processor;
+	}
+
+	static public JarProcessor getPackProcessor(Properties properties) {
+		if (!canPerformPack())
+			throw new UnsupportedOperationException();
+		JarProcessor processor = new JarProcessor();
+		processor.addProcessStep(new PackStep(properties));
+		return processor;
+	}
+
+	static public boolean canPerformPack() {
+		return PackStep.canPack();
+	}
+
+	static public boolean canPerformUnpack() {
+		return UnpackStep.canUnpack();
+	}
+
+	public String getWorkingDirectory() {
+		return workingDirectory;
+	}
+
+	public void setWorkingDirectory(String dir) {
+		if(dir != null)
+			workingDirectory = dir;
+	}
+	
+	public void setVerbose(boolean verbose) {
+		this.verbose = verbose;
+	}
+	
+	public void setProcessAll(boolean all){
+		this.processAll = all;
+	}
+
+	public void addProcessStep(IProcessStep step) {
+		steps.add(step);
+	}
+
+	public void clearProcessSteps() {
+		steps.clear();
+	}
+
+	/**
+	 * Recreate a jar file.  The replacements map specifies entry names to be replaced, the replacements are
+	 * expected to be found in directory.
+	 * 
+	 * @param jar - The input jar
+	 * @param outputJar - the output
+	 * @param replacements - map of entryName -> new entryName
+	 * @param directory - location to find file for new entryName
+	 * @throws IOException
+	 */
+	private void recreateJar(JarFile jar, JarOutputStream outputJar, Map replacements, File directory, Properties inf) throws IOException {
+		InputStream in = null;
+		boolean marked = false;
+		try {
+			Enumeration entries = jar.entries();
+			for (JarEntry entry = (JarEntry) entries.nextElement(); entry != null; entry = entries.hasMoreElements() ? (JarEntry) entries.nextElement() : null) {
+				File replacement = null;
+				JarEntry newEntry = null;
+				if (replacements.containsKey(entry.getName())) {
+					String name = (String) replacements.get(entry.getName());
+					replacement = new File(directory, name);
+					if (name != null) {
+						if (replacement.exists()) {
+							try {
+								in = new BufferedInputStream(new FileInputStream(replacement));
+								newEntry = new JarEntry(name);
+							} catch (Exception e) {
+								if (verbose) {
+									e.printStackTrace();
+									System.out.println("Warning: Problem reading " +replacement.getPath() + ", using " + jar.getName() + File.separator + entry.getName()  + " instead.");
+								}
+							}
+						} else if (verbose) {
+							System.out.println("Warning: " + replacement.getPath() + " not found, using " + jar.getName() + File.separator + entry.getName() + " instead.");	
+						}
+					}
+				}
+				if (newEntry == null) {
+					try {
+						in = new BufferedInputStream(jar.getInputStream(entry));
+						newEntry = new JarEntry(entry.getName());
+					} catch( Exception e ) {
+						if(verbose) {
+							e.printStackTrace();
+							System.out.println("ERROR: problem reading " + entry.getName() + " from " + jar.getName());
+						}
+						continue;
+					}
+				}
+				newEntry.setTime(entry.getTime());
+				outputJar.putNextEntry(newEntry);
+				if (entry.getName().equals(Utils.MARK_FILE_NAME)) {
+					//The eclipse.inf file was read in earlier, don't need to reread it, just write it out now
+					Utils.storeProperties(inf, outputJar);
+					marked = true;
+				} else {
+					Utils.transferStreams(in, outputJar, false);
+				}
+				outputJar.closeEntry();
+				in.close();
+
+				//delete the nested jar file
+				if (replacement != null) {
+					replacement.delete();
+				}
+			}
+			if (!marked) {
+				JarEntry entry = new JarEntry(Utils.MARK_FILE_NAME);
+				outputJar.putNextEntry(entry);
+				Utils.storeProperties(inf, outputJar);
+				outputJar.closeEntry();
+			}
+		} finally {
+			Utils.close(outputJar);
+			Utils.close(jar);
+			Utils.close(in);
+		}
+	}
+
+	private String recursionEffect(String entryName) {
+		String result = null;
+		for (Iterator iter = steps.iterator(); iter.hasNext();) {
+			IProcessStep step = (IProcessStep) iter.next();
+
+			result = step.recursionEffect(entryName);
+			if (result != null)
+				entryName = result;
+		}
+		return result;
+	}
+
+	private void extractEntries(JarFile jar, File tempDir, Map data, Properties inf) throws IOException {
+		if(inf != null ) {
+			//skip if excluding children
+			if(inf.containsKey(Utils.MARK_EXCLUDE_CHILDREN)){
+				String excludeChildren = inf.getProperty(Utils.MARK_EXCLUDE_CHILDREN);
+				if( Boolean.valueOf(excludeChildren).booleanValue() )
+					if(verbose){
+						for(int i = 0; i <= depth; i++)
+							System.out.print("  "); //$NON-NLS-1$
+						System.out.println("Children of " + jar.getName() + "are excluded from processing.");
+					}
+					return;
+			}
+		}
+		
+		Enumeration entries = jar.entries();
+		if (entries.hasMoreElements()) {
+			for (JarEntry entry = (JarEntry) entries.nextElement(); entry != null; entry = entries.hasMoreElements() ? (JarEntry) entries.nextElement() : null) {
+				String name = entry.getName();
+				String newName = recursionEffect(name);
+				if (newName != null) {
+					if(verbose){
+						for(int i = 0; i <= depth; i++)
+							System.out.print("  "); //$NON-NLS-1$
+						System.out.println("Processing nested file: " + name); //$NON-NLS-1$
+					}
+					//extract entry to temp directory
+					File extracted = new File(tempDir, name);
+					File parentDir = extracted.getParentFile();
+					if (!parentDir.exists())
+						parentDir.mkdirs();
+
+					InputStream in = null;
+					OutputStream out = null;
+					try {
+						in = jar.getInputStream(entry);
+						out = new BufferedOutputStream(new FileOutputStream(extracted));
+						Utils.transferStreams(in, out, true); //this will close both streams
+					} finally {
+						Utils.close(in);
+						Utils.close(out);
+					}
+					extracted.setLastModified(entry.getTime());
+
+					//recurse
+					containingInfs.addFirst(inf);
+					String dir = getWorkingDirectory();
+					setWorkingDirectory(parentDir.getCanonicalPath());
+					File result = processJar(extracted);
+
+					newName = name.substring(0, name.length() - extracted.getName().length()) + result.getName();
+					data.put(name, newName);
+
+					setWorkingDirectory(dir);
+					containingInfs.removeFirst();
+
+					//delete the extracted item leaving the recursion result
+					if (!name.equals(newName))
+						extracted.delete();
+				}
+			}
+		}
+	}
+
+	private File preProcess(File input, File tempDir) {
+		File result = null;
+		for (Iterator iter = steps.iterator(); iter.hasNext();) {
+			IProcessStep step = (IProcessStep) iter.next();
+			result = step.preProcess(input, tempDir, containingInfs);
+			if (result != null)
+				input = result;
+		}
+		return input;
+	}
+
+	private File postProcess(File input, File tempDir) {
+		File result = null;
+		for (Iterator iter = steps.iterator(); iter.hasNext();) {
+			IProcessStep step = (IProcessStep) iter.next();
+			result = step.postProcess(input, tempDir, containingInfs);
+			if (result != null)
+				input = result;
+		}
+		return input;
+	}
+
+	private void adjustInf(File input, Properties inf) {
+		for (Iterator iter = steps.iterator(); iter.hasNext();) {
+			IProcessStep step = (IProcessStep) iter.next();
+			step.adjustInf(input, inf, containingInfs);
+		}
+	}
+
+	public File processJar(File input) throws IOException {
+		++depth;
+		long lastModified = input.lastModified();
+		File workingDir = new File(getWorkingDirectory());
+		if (!workingDir.exists())
+			workingDir.mkdirs();
+
+		boolean skip = Utils.shouldSkipJar(input, processAll, verbose);
+		if (depth == 0 && verbose) {
+			if (skip)
+				System.out.println("Skipping " + input.getPath()); //$NON-NLS-1$
+			else {
+				System.out.print("Running "); //$NON-NLS-1$ 
+				for (Iterator iter = steps.iterator(); iter.hasNext();) {
+					IProcessStep step = (IProcessStep) iter.next();
+					System.out.print(step.getStepName() + " "); //$NON-NLS-1$
+				}
+				System.out.println("on " + input.getPath()); //$NON-NLS-1$
+			}
+		}
+
+		if (skip) {
+			//This jar was not marked as conditioned, and we are only processing conditioned jars, so do nothing
+			--depth;
+			return input;
+		}
+
+		//pre
+		File workingFile = preProcess(input, workingDir);
+
+		//Extract entries from jar and recurse on them
+		File tempDir = null;
+		if (depth == 0) {
+			tempDir = new File(workingDir, "temp." + workingFile.getName()); //$NON-NLS-1$
+		} else {
+			File parent = workingDir.getParentFile();
+			tempDir = new File(parent, "temp_" + depth + '_' + workingFile.getName()); //$NON-NLS-1$
+		}
+
+		JarFile jar = new JarFile(workingFile, false);
+		Map replacements = new HashMap();
+		Properties inf = Utils.getEclipseInf(workingFile, verbose);
+		extractEntries(jar, tempDir, replacements, inf);
+
+		if (inf != null)
+			adjustInf(workingFile, inf);
+
+		//Recreate the jar with replacements. 
+		//TODO: This is not strictly necessary if we didn't change the inf file and didn't change any content
+		File tempJar = null;
+		tempJar = new File(tempDir, workingFile.getName());
+		File parent = tempJar.getParentFile();
+		if (!parent.exists())
+			parent.mkdirs();
+		JarOutputStream jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(tempJar)));
+		recreateJar(jar, jarOut, replacements, tempDir, inf);
+
+		jar.close();
+		if (tempJar != null) {
+			if (!workingFile.equals(input)) {
+				workingFile.delete();
+			}
+			workingFile = tempJar;
+		}
+
+		//post
+		File result = postProcess(workingFile, workingDir);
+		
+		//have to normalize after the post steps
+		normalize(result, workingDir);
+		
+		if (!result.equals(workingFile) && !workingFile.equals(input))
+			workingFile.delete();
+		if (!result.getParentFile().equals(workingDir)) {
+			File finalFile = new File(workingDir, result.getName());
+			if (finalFile.exists())
+				finalFile.delete();
+			result.renameTo(finalFile);
+			result = finalFile;
+		}
+
+		if (tempDir.exists())
+			Utils.clear(tempDir);
+
+		result.setLastModified(lastModified);
+		--depth;
+		return result;
+	}
+	
+	private void normalize(File input, File workingDirectory) {
+		if(input.getName().endsWith(Utils.PACKED_SUFFIX)) {
+			//not a jar
+			return;
+		}
+		try {
+			File tempJar = new File(workingDirectory, "temp_" + input.getName()); //$NON-NLS-1$
+			JarFile jar = null;
+			try {
+				jar = new JarFile(input, false);
+			} catch (JarException e) {
+				//not a jar
+				return ;
+			}
+			JarOutputStream jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(tempJar)));
+			InputStream in = null;
+			try {
+				Enumeration entries = jar.entries();
+				for (JarEntry entry = (JarEntry) entries.nextElement(); entry != null; entry = entries.hasMoreElements() ? (JarEntry) entries.nextElement() : null) {
+					JarEntry newEntry = new JarEntry(entry.getName());
+					newEntry.setTime(entry.getTime());
+					in = new BufferedInputStream(jar.getInputStream(entry));
+					jarOut.putNextEntry(newEntry);
+					Utils.transferStreams(in, jarOut, false);
+					jarOut.closeEntry();
+					in.close();
+				}
+			} finally {
+				Utils.close(jarOut);
+				Utils.close(jar);
+				Utils.close(in);
+			}
+			tempJar.setLastModified(input.lastModified());
+			input.delete();
+			tempJar.renameTo(input);
+		} catch (IOException e) {
+			if (verbose) {
+				System.out.println("Error normalizing jar " + input.getName()); //$NON-NLS-1$
+				e.printStackTrace();
+			}
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/JarProcessorExecutor.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/JarProcessorExecutor.java
new file mode 100644
index 0000000..160785d
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/JarProcessorExecutor.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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 - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.*;
+import java.util.Properties;
+import java.util.zip.ZipException;
+import org.eclipse.update.internal.jarprocessor.Main.Options;
+
+public class JarProcessorExecutor {
+	public void runJarProcessor(Options options) {
+		if (options.input.isFile() && options.input.getName().endsWith(".zip")) { //$NON-NLS-1$
+			ZipProcessor processor = new ZipProcessor();
+			processor.setWorkingDirectory(options.outputDir);
+			processor.setSignCommand(options.signCommand);
+			processor.setPack(options.pack);
+			processor.setRepack(options.repack || (options.pack && options.signCommand != null));
+			processor.setUnpack(options.unpack);
+			processor.setVerbose(options.verbose);
+			processor.setProcessAll(options.processAll);
+			try {
+				processor.processZip(options.input);
+			} catch (ZipException e) {
+				if (options.verbose)
+					e.printStackTrace();
+			} catch (IOException e) {
+				if (options.verbose)
+					e.printStackTrace();
+			}
+		} else {
+			JarProcessor processor = new JarProcessor();
+			JarProcessor packProcessor = null;
+
+			processor.setWorkingDirectory(options.outputDir);
+			processor.setProcessAll(options.processAll);
+			processor.setVerbose(options.verbose);
+
+			//load options file
+			Properties properties = new Properties();
+			if (options.input.isDirectory()) {
+				File packProperties = new File(options.input, "pack.properties");
+				if (packProperties.exists() && packProperties.isFile()) {
+					InputStream in = null;
+					try {
+						in = new BufferedInputStream(new FileInputStream(packProperties));
+						properties.load(in);
+					} catch (IOException e) {
+						if (options.verbose)
+							e.printStackTrace();
+					} finally {
+						Utils.close(in);
+					}
+				}
+			}
+
+			if (options.unpack)
+				addUnpackStep(processor, properties, options);
+
+			if (options.repack || (options.pack && options.signCommand != null))
+				addPackUnpackStep(processor, properties, options);
+
+			if (options.signCommand != null)
+				addSignStep(processor, properties, options);
+
+			if (options.pack) {
+				packProcessor = new JarProcessor();
+				packProcessor.setWorkingDirectory(options.outputDir);
+				packProcessor.setProcessAll(options.processAll);
+				packProcessor.setVerbose(options.verbose);
+				addPackStep(packProcessor, properties, options);
+			}
+
+			try {
+				process(options.input, options.unpack ? Utils.PACK_GZ_FILTER : Utils.JAR_FILTER, options.verbose, processor, packProcessor);
+			} catch (FileNotFoundException e) {
+				if (options.verbose)
+					e.printStackTrace();
+			}
+		}
+	}
+
+	protected void process(File input, FileFilter filter, boolean verbose, JarProcessor processor, JarProcessor packProcessor) throws FileNotFoundException {
+		if (!input.exists())
+			throw new FileNotFoundException();
+
+		File[] files = null;
+		if (input.isDirectory()) {
+			files = input.listFiles();
+		} else if (filter.accept(input)) {
+			files = new File[] {input};
+		}
+		for (int i = 0; i < files.length; i++) {
+			if (files[i].isDirectory()) {
+				String dir = processor.getWorkingDirectory();
+				processor.setWorkingDirectory(dir + "/" + files[i].getName()); //$NON-NLS-1$
+				if (packProcessor != null)
+					packProcessor.setWorkingDirectory(dir + "/" + files[i].getName());
+				process(files[i], filter, verbose, processor, packProcessor);
+				processor.setWorkingDirectory(dir);
+				if (packProcessor != null)
+					packProcessor.setWorkingDirectory(dir);
+			} else if (filter.accept(files[i])) {
+				try {
+					File result = processor.processJar(files[i]);
+					if (packProcessor != null && result != null && result.exists()) {
+						packProcessor.processJar(result);
+					}
+				} catch (IOException e) {
+					if (verbose)
+						e.printStackTrace();
+				}
+			}
+		}
+	}
+
+	public void addPackUnpackStep(JarProcessor processor, Properties properties, Options options) {
+		processor.addProcessStep(new PackUnpackStep(properties, options.verbose));
+	}
+
+	public void addSignStep(JarProcessor processor, Properties properties, Options options) {
+		processor.addProcessStep(new SignCommandStep(properties, options.signCommand, options.verbose));
+	}
+
+	public void addPackStep(JarProcessor processor, Properties properties, Options options) {
+		processor.addProcessStep(new PackStep(properties, options.verbose));
+	}
+
+	public void addUnpackStep(JarProcessor processor, Properties properties, Options options) {
+		processor.addProcessStep(new UnpackStep(properties, options.verbose));
+	}
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/Main.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/Main.java
new file mode 100644
index 0000000..43d8e0a
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/Main.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2007 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.File;
+
+public class Main {
+
+	public static class Options {
+		public String outputDir = "."; //$NON-NLS-1$
+		public String signCommand = null;
+		public boolean pack = false;
+		public boolean repack = false;
+		public boolean unpack = false;
+		public boolean verbose = false;
+		public boolean processAll = false;
+		public File input = null;
+	}
+
+	private static void printUsage() {
+		System.out.println("[-option ...]... input"); //$NON-NLS-1$
+		System.out.println("The following options are supported:"); //$NON-NLS-1$
+		System.out.println("-processAll     process all jars, regardless of whether they were previously normalized"); //$NON-NLS-1$
+		System.out.println("                By default only normalized jars will be processed."); //$NON-NLS-1$
+		System.out.println("-repack         normalize jars "); //$NON-NLS-1$
+		System.out.println("-sign <command> sign jars using <command>"); //$NON-NLS-1$
+		System.out.println("-pack           pack the jars.  pack and repack are redundant unless"); //$NON-NLS-1$
+		System.out.println("                sign is also specified."); //$NON-NLS-1$
+		System.out.println("-unpack         unpack pack.gz files. Unpack is mutually exclusive"); //$NON-NLS-1$
+		System.out.println("                with repack, sign and pack."); //$NON-NLS-1$
+		System.out.println();
+		System.out.println("-outputDir <dir>  the output directory"); //$NON-NLS-1$
+		System.out.println("-verbose        verbose mode "); //$NON-NLS-1$
+	}
+
+	public static Options processArguments(String[] args) {
+		if (args.length == 0) {
+			printUsage();
+			return null;
+		}
+
+		Options options = new Options();
+		int i = 0;
+		for (; i < args.length - 1; i++) {
+			if (args[i].equals("-pack")) {//$NON-NLS-1$
+				options.pack = true;
+			} else if (args[i].equals("-unpack")) { //$NON-NLS-1$
+				options.unpack = true;
+			} else if (args[i].equals("-sign") && i < args.length - 2) { //$NON-NLS-1$
+				if (args[i + 1].startsWith("-")) { //$NON-NLS-1$
+					printUsage();
+					return null;
+				}
+				options.signCommand = args[++i];
+			} else if (args[i].equals("-repack")) { //$NON-NLS-1$
+				options.repack = true;
+			} else if (args[i].equals("-outputDir") && i < args.length - 2) { //$NON-NLS-1$
+				if (args[i + 1].startsWith("-")) { //$NON-NLS-1$
+					printUsage();
+					return null;
+				}
+				options.outputDir = args[++i];
+			} else if (args[i].equals("-verbose")) { //$NON-NLS-1$
+				options.verbose = true;
+			}  else if (args[i].equals("-processAll")) { //$NON-NLS-1$
+				options.processAll = true;
+			} 
+		}
+
+		options.input = new File(args[i]);
+
+		String problemMessage = null;
+		String inputName = options.input.getName();
+		if (options.unpack) {
+			if (!JarProcessor.canPerformUnpack()) {
+				problemMessage = "The unpack200 command cannot be found."; //$NON-NLS-1$
+			} else 	if (options.input.isFile() && !inputName.endsWith(".zip") && !inputName.endsWith(".pack.gz")) { //$NON-NLS-1$ //$NON-NLS-2$
+				problemMessage = "Input file is not a pack.gz file."; //$NON-NLS-1$
+			} else 	if (options.pack || options.repack || options.signCommand != null) {
+				problemMessage = "Pack, repack or sign cannot be specified with unpack."; //$NON-NLS-1$
+			}
+		} else {
+			if (options.input.isFile() && !inputName.endsWith(".zip") && !inputName.endsWith(".jar")) { //$NON-NLS-1$ //$NON-NLS-2$
+				problemMessage = "Input file is not a jar file."; //$NON-NLS-1$
+			} else	if ((options.pack || options.repack) && !JarProcessor.canPerformPack()) {
+				problemMessage = "The pack200 command can not be found."; //$NON-NLS-1$
+			}
+		}
+		if(problemMessage != null){
+			System.out.println(problemMessage);
+			System.out.println();
+			printUsage();
+			return null;
+		}
+
+		return options;
+	}
+	
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		Options options = processArguments(args);
+		if (options == null)
+			return;
+		new JarProcessorExecutor().runJarProcessor(options);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/PackStep.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/PackStep.java
new file mode 100644
index 0000000..4afd638
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/PackStep.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+public class PackStep extends CommandStep {
+
+	protected static String packCommand = null;
+	private static Boolean canPack = null;
+
+	private Set exclusions = Collections.EMPTY_SET;
+
+	public static boolean canPack() {
+		if (canPack != null)
+			return canPack.booleanValue();
+
+		String[] locations = Utils.getPack200Commands("pack200"); //$NON-NLS-1$
+		if (locations == null) {
+			canPack = Boolean.FALSE;
+			packCommand = null;
+			return false;
+		}
+
+		int result;
+		for (int i = 0; i < locations.length; i++) {
+			if (locations[i] == null)
+				continue;
+			result = execute(new String[] {locations[i], "-V"}); //$NON-NLS-1$
+			if (result == 0) {
+				packCommand = locations[i];
+				canPack = Boolean.TRUE;
+				return true;
+			}
+		}
+
+		canPack = Boolean.FALSE;
+		return false;
+	}
+
+	public PackStep(Properties options) {
+		super(options, null, null, false);
+		exclusions = Utils.getPackExclusions(options);
+	}
+
+	public PackStep(Properties options, boolean verbose) {
+		super(options, null, null, verbose);
+		exclusions = Utils.getPackExclusions(options);
+	}
+
+	public String recursionEffect(String entryName) {
+		if (canPack() && entryName.endsWith(".jar") && !exclusions.contains(entryName)) { //$NON-NLS-1$
+			return entryName + Utils.PACKED_SUFFIX;
+		}
+		return null;
+	}
+
+	public File preProcess(File input, File workingDirectory, List containers) {
+		return null;
+	}
+
+	public File postProcess(File input, File workingDirectory, List containers) {
+		if (canPack() && packCommand != null) {
+			Properties inf = Utils.getEclipseInf(input, verbose);
+			if (!shouldPack(input, containers, inf))
+				return null;
+			File outputFile = new File(workingDirectory, input.getName() + Utils.PACKED_SUFFIX);
+			try {
+				String[] cmd = getCommand(input, outputFile, inf, containers);
+				int result = execute(cmd, verbose);
+				if (result != 0 && verbose)
+					System.out.println("Error: " + result + " was returned from command: " + Utils.concat(cmd)); //$NON-NLS-1$ //$NON-NLS-2$
+			} catch (IOException e) {
+				if (verbose)
+					e.printStackTrace();
+				return null;
+			}
+			return outputFile;
+		}
+		return null;
+	}
+
+	protected boolean shouldPack(File input, List containers, Properties inf) {
+		//1: exclude by containers
+		// innermost jar is first on the list, it can override outer jars
+		for (Iterator iterator = containers.iterator(); iterator.hasNext();) {
+			Properties container = (Properties) iterator.next();
+			if (container.containsKey(Utils.MARK_EXCLUDE_CHILDREN_PACK)) {
+				if (Boolean.valueOf(container.getProperty(Utils.MARK_EXCLUDE_CHILDREN_PACK)).booleanValue()) {
+					if (verbose)
+						System.out.println(input.getName() + " is excluded from pack200 by its containers.");
+					return false;
+				}
+				break;
+			}
+		}
+
+		//2: excluded by self
+		if (inf != null && inf.containsKey(Utils.MARK_EXCLUDE_PACK) && Boolean.valueOf(inf.getProperty(Utils.MARK_EXCLUDE_PACK)).booleanValue()) {
+			if (verbose)
+				System.out.println("Excluding " + input.getName() + " from " + getStepName()); //$NON-NLS-1$ //$NON-NLS-2$
+			return false;
+		}
+
+		return true;
+	}
+
+	protected String[] getCommand(File input, File outputFile, Properties inf, List containers) throws IOException {
+		String[] cmd = null;
+		String arguments = getArguments(input, inf, containers);
+		if (arguments != null && arguments.length() > 0) {
+			String[] args = Utils.toStringArray(arguments, ","); //$NON-NLS-1$
+			cmd = new String[3 + args.length];
+			cmd[0] = packCommand;
+			System.arraycopy(args, 0, cmd, 1, args.length);
+			cmd[cmd.length - 2] = outputFile.getCanonicalPath();
+			cmd[cmd.length - 1] = input.getCanonicalPath();
+		} else {
+			cmd = new String[] {packCommand, outputFile.getCanonicalPath(), input.getCanonicalPath()};
+		}
+		return cmd;
+	}
+
+	protected String getArguments(File input, Properties inf, List containers) {	
+		//1: Explicitly marked in our .inf file
+		if (inf != null && inf.containsKey(Utils.PACK_ARGS)) {
+			return  inf.getProperty(Utils.PACK_ARGS);
+		}
+
+		//2: Defaults set in one of our containing jars
+		for (Iterator iterator = containers.iterator(); iterator.hasNext();) {
+			Properties container = (Properties) iterator.next();
+			if (container.containsKey(Utils.DEFAULT_PACK_ARGS)) {
+				return container.getProperty(Utils.DEFAULT_PACK_ARGS);
+			}
+		}
+
+		//3: Set by name in outside pack.properties file
+		Properties options = getOptions();
+		String argsKey = input.getName() + Utils.PACK_ARGS_SUFFIX;
+		if (options.containsKey(argsKey)) {
+			return options.getProperty(argsKey);
+		}
+
+		//4: Set by default in outside pack.properties file
+		if (options.containsKey(Utils.DEFAULT_PACK_ARGS)) {
+			return options.getProperty(Utils.DEFAULT_PACK_ARGS);
+		}
+
+		return ""; //$NON-NLS-1$
+	}
+
+	public String getStepName() {
+		return "Pack"; //$NON-NLS-1$
+	}
+
+	public void adjustInf(File input, Properties inf, List containers) {
+		if (input == null || inf == null)
+			return;
+
+		//don't be verbose to check if we should mark the inf
+		boolean v = verbose;
+		verbose = false;
+		if (!shouldPack(input, containers, inf)) {
+			verbose = v;
+			return;
+		}
+		verbose = v;
+
+		//mark as conditioned if not previously marked.  A signed jar is assumed to be previously conditioned.
+		if (inf.getProperty(Utils.MARK_PROPERTY) == null) {
+			inf.put(Utils.MARK_PROPERTY, "true"); //$NON-NLS-1$
+	
+			//record arguments used
+			String arguments = inf.getProperty(Utils.PACK_ARGS);
+			if (arguments == null) {
+				arguments = getArguments(input, inf, containers);
+				if (arguments != null && arguments.length() > 0)
+					inf.put(Utils.PACK_ARGS, arguments);
+			}
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/PackUnpackStep.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/PackUnpackStep.java
new file mode 100644
index 0000000..019812b
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/PackUnpackStep.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * @author aniefer@ca.ibm.com
+ *
+ */
+public class PackUnpackStep extends PackStep {
+	private Set exclusions = null;
+
+	public PackUnpackStep(Properties options) {
+		super(options);
+		exclusions = Utils.getPackExclusions(options);
+	}
+
+	public PackUnpackStep(Properties options, boolean verbose) {
+		super(options, verbose);
+		exclusions = Utils.getPackExclusions(options);
+	}
+
+	public String recursionEffect(String entryName) {
+		if (canPack() && entryName.endsWith(".jar") && !exclusions.contains(entryName)) { //$NON-NLS-1$
+			return entryName;
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.internal.jarprocessor.PackStep#postProcess(java.io.File, java.io.File, java.util.LinkedList)
+	 */
+	public File postProcess(File input, File workingDirectory, List containers) {
+		if (canPack() && packCommand != null && input != null) {
+			Properties inf = Utils.getEclipseInf(input, verbose);
+			if (!shouldPack(input, containers, inf))
+				return null;
+			File tempFile = new File(workingDirectory, "temp_" + input.getName()); //$NON-NLS-1$
+			try {
+				String[] tmp = getCommand(input, tempFile, inf, containers);
+				String[] cmd = new String[tmp.length + 1];
+				cmd[0] = tmp[0];
+				cmd[1] = "-r"; //$NON-NLS-1$
+				System.arraycopy(tmp, 1, cmd, 2, tmp.length - 1);
+
+				int result = execute(cmd, verbose);
+				if (result == 0 && tempFile.exists()) {
+					File finalFile = new File(workingDirectory, input.getName());
+					if (finalFile.exists())
+						finalFile.delete();
+					tempFile.renameTo(finalFile);
+					return finalFile;
+				} else if (verbose) {
+					System.out.println("Error: " + result + " was returned from command: " + Utils.concat(cmd)); //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			} catch (IOException e) {
+				if (verbose)
+					e.printStackTrace();
+				return null;
+			}
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.internal.jarprocessor.PackStep#preProcess(java.io.File, java.io.File, java.util.LinkedList)
+	 */
+	public File preProcess(File input, File workingDirectory, List containers) {
+		return null;
+	}
+
+	public String getStepName() {
+		return "Repack"; //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/SignCommandStep.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/SignCommandStep.java
new file mode 100644
index 0000000..282ed75
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/SignCommandStep.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2006-2007 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+public class SignCommandStep extends CommandStep {
+	private Set exclusions = null;
+
+	public SignCommandStep(Properties options, String command) {
+		super(options, command, ".jar", false); //$NON-NLS-1$
+		exclusions = Utils.getSignExclusions(options);
+	}
+
+	public SignCommandStep(Properties options, String command, boolean verbose) {
+		super(options, command, ".jar", verbose); //$NON-NLS-1$
+		exclusions = Utils.getSignExclusions(options);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.jarprocessor.IProcessStep#recursionEffect(java.lang.String)
+	 */
+	public String recursionEffect(String entryName) {
+		if (entryName.endsWith(extension) && !exclusions.contains(entryName))
+			return entryName;
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.jarprocessor.IProcessStep#preProcess(java.io.File, java.io.File)
+	 */
+	public File preProcess(File input, File workingDirectory, List containers) {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.jarprocessor.IProcessStep#postProcess(java.io.File, java.io.File)
+	 */
+	public File postProcess(File input, File workingDirectory, List containers) {
+		if (command != null && input != null && shouldSign(input, containers)) {
+			try {
+				String[] cmd = new String[] {command, input.getCanonicalPath()};
+				int result = execute(cmd, verbose);
+				if (result == 0) {
+					return input;
+				} else if (verbose) {
+					System.out.println("Error: " + result + " was returned from command: " + Utils.concat(cmd)); //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			} catch (IOException e) {
+				if (verbose) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return null;
+	}
+
+	public boolean shouldSign(File input, List containers) {
+		Properties inf = null;
+
+		//1: Are we excluded from signing by our parents?
+		//innermost jar is first on the list, it overrides outer jars
+		for (Iterator iterator = containers.iterator(); iterator.hasNext();) {
+			inf = (Properties) iterator.next();
+			if (inf.containsKey(Utils.MARK_EXCLUDE_CHILDREN_SIGN)){
+				if(Boolean.valueOf(inf.getProperty(Utils.MARK_EXCLUDE_CHILDREN_SIGN)).booleanValue()) {
+					if (verbose)
+						System.out.println(input.getName() + "is excluded from signing by its containers."); //$NON-NLS-1$ //$NON-NLS-2$
+					return false;
+				}
+				break;
+			}
+		}
+
+		//2: Is this jar itself marked as exclude?
+		inf = Utils.getEclipseInf(input, verbose);
+		if (inf != null && inf.containsKey(Utils.MARK_EXCLUDE_SIGN) && Boolean.valueOf(inf.getProperty(Utils.MARK_EXCLUDE_SIGN)).booleanValue()) {
+			if (verbose)
+				System.out.println("Excluding " + input.getName() + " from signing."); //$NON-NLS-1$ //$NON-NLS-2$
+			return false;
+		}
+		return true;
+	}
+
+	public String getStepName() {
+		return "Sign"; //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/StreamProcessor.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/StreamProcessor.java
new file mode 100644
index 0000000..e0b5c3a
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/StreamProcessor.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class StreamProcessor extends Thread {
+	public static final String STDERR = "STDERR"; //$NON-NLS-1$
+	public static final String STDOUT = "STDOUT"; //$NON-NLS-1$
+
+	private InputStream inputStream;
+	private String name;
+	private boolean verbose;
+
+	public StreamProcessor(InputStream is, String name, boolean verbose) {
+		this.inputStream = is;
+		this.name = name;
+		this.verbose = verbose;
+	}
+
+	public void run() {
+		try {
+			InputStreamReader isr = new InputStreamReader(inputStream);
+			BufferedReader br = new BufferedReader(isr);
+			while (true) {
+				String s = br.readLine();
+				if (s == null) {
+					break;
+				}
+				if (verbose) {
+					if (STDERR.equals(name))
+						System.err.println(name + ": " + s); //$NON-NLS-1$
+					else
+						System.out.println(name + ": " + s); //$NON-NLS-1$
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/UnpackStep.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/UnpackStep.java
new file mode 100644
index 0000000..1d30dd8
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/UnpackStep.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * @author aniefer
+ *
+ */
+public class UnpackStep extends CommandStep {
+	public static final String UNPACKER_PROPERTY = "org.eclipse.update.jarprocessor.Unpacker"; //$NON-NLS-1$
+	private static Boolean canUnpack = null;
+	private static String unpackCommand = null;
+
+	public static boolean canUnpack() {
+		if (canUnpack != null)
+			return canUnpack.booleanValue();
+
+		String[] locations = Utils.getPack200Commands("unpack200"); //$NON-NLS-1$
+		if (locations == null) {
+			canUnpack = Boolean.FALSE;
+			unpackCommand = null;
+			return false;
+		}
+
+		int result;
+		for (int i = 0; i < locations.length; i++) {
+			if (locations[i] == null)
+				continue;
+			result = execute(new String[] {locations[i], "-V"}); //$NON-NLS-1$
+			if (result == 0) {
+				unpackCommand = locations[i];
+				canUnpack = Boolean.TRUE;
+				return true;
+			}
+		}
+
+		canUnpack = Boolean.FALSE;
+		return false;
+	}
+
+	public UnpackStep(Properties options) {
+		super(options, null, null, false);
+	}
+
+	public UnpackStep(Properties options, boolean verbose) {
+		super(options, null, null, verbose);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.jarprocessor.IProcessStep#recursionEffect(java.lang.String)
+	 */
+	public String recursionEffect(String entryName) {
+		if (canUnpack() && entryName.endsWith(Utils.PACKED_SUFFIX)) {
+			return entryName.substring(0, entryName.length() - Utils.PACKED_SUFFIX.length());
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.jarprocessor.IProcessStep#preProcess(java.io.File, java.io.File)
+	 */
+	public File preProcess(File input, File workingDirectory, List containers) {
+		if (canUnpack() && unpackCommand != null) {
+			String name = input.getName();
+			if (name.endsWith(Utils.PACKED_SUFFIX)) {
+				name = name.substring(0, name.length() - Utils.PACKED_SUFFIX.length());
+
+				File unpacked = new File(workingDirectory, name);
+				File parent = unpacked.getParentFile();
+				if (!parent.exists())
+					parent.mkdirs();
+				try {
+					String options = getOptions().getProperty(input.getName() + ".unpack.args"); //$NON-NLS-1$
+					String[] cmd = null;
+					if (options != null) {
+						cmd = new String[] {unpackCommand, options, input.getCanonicalPath(), unpacked.getCanonicalPath()};
+					} else {
+						cmd = new String[] {unpackCommand, input.getCanonicalPath(), unpacked.getCanonicalPath()};
+					}
+					int result = execute(cmd, verbose);
+					if (result != 0 && verbose)
+						System.out.println("Error: " + result + " was returned from command: " + Utils.concat(cmd)); //$NON-NLS-1$ //$NON-NLS-2$
+				} catch (IOException e) {
+					if (verbose)
+						e.printStackTrace();
+					return null;
+				}
+				return unpacked;
+			}
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.jarprocessor.IProcessStep#postProcess(java.io.File, java.io.File)
+	 */
+	public File postProcess(File input, File workingDirectory, List containers) {
+		return null;
+	}
+
+	public String getStepName() {
+		return "Unpack"; //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/Utils.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/Utils.java
new file mode 100644
index 0000000..0f4ebbf
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/Utils.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.zip.ZipException;
+
+/**
+ * @author aniefer@ca.ibm.com
+ *
+ */
+public class Utils {
+	public static final String MARK_FILE_NAME = "META-INF/eclipse.inf"; //$NON-NLS-1$
+	
+	/*
+	 * Properties found in outer pack.properties file
+	 */
+	//comma separated list of jars to exclude from sigining
+	public static final String SIGN_EXCLUDES = "sign.excludes"; //$NON-NLS-1$
+	//comma separated list of jars to exlclude from packing
+	public static final String PACK_EXCLUDES = "pack.excludes"; //$NON-NLS-1$
+	//Suffix used when specifying arguments to use when running pack200 on a jar
+	public static final String PACK_ARGS_SUFFIX = ".pack.args"; //$NON-NLS-1$
+	
+	/*
+	 * Properties found in both pack.properties and eclipse.inf
+	 */
+	//	Default arguments to use when running pack200.
+	// Affects all jars when specified in pack.properties, affects children when specified in eclipse.inf
+	public static final String DEFAULT_PACK_ARGS = "pack200.default.args"; //$NON-NLS-1$
+	
+	/*
+	 * Properties found in eclipse.inf file
+	 */
+	//This jar has been conditioned with pack200
+	public static final String MARK_PROPERTY = "pack200.conditioned"; //$NON-NLS-1$
+	//Exclude this jar from processing
+	public static final String MARK_EXCLUDE = "jarprocessor.exclude"; //$NON-NLS-1$
+	//Exclude this jar from pack200
+	public static final String MARK_EXCLUDE_PACK = "jarprocessor.exclude.pack"; //$NON-NLS-1$
+	//Exclude this jar from signing
+	public static final String MARK_EXCLUDE_SIGN = "jarprocessor.exclude.sign"; //$NON-NLS-1$
+	//Exclude this jar's children from processing
+	public static final String MARK_EXCLUDE_CHILDREN = "jarprocessor.exclude.children";
+	//Exclude this jar's children from pack200
+	public static final String MARK_EXCLUDE_CHILDREN_PACK = "jarprocessor.exclude.children.pack";
+	//Exclude this jar's children from signing
+	public static final String MARK_EXCLUDE_CHILDREN_SIGN = "jarprocessor.exclude.children.sign";
+	//Arguments used in pack200 for this jar
+	public static final String PACK_ARGS = "pack200.args"; //$NON-NLS-1$
+	
+	public static final String PACK200_PROPERTY = "org.eclipse.update.jarprocessor.pack200"; //$NON-NLS-1$
+	public static final String JRE = "@jre"; //$NON-NLS-1$
+	public static final String PATH = "@path"; //$NON-NLS-1$
+	public static final String NONE = "@none"; //$NON-NLS-1$
+
+	public static final String PACKED_SUFFIX = ".pack.gz"; //$NON-NLS-1$
+	public static final String JAR_SUFFIX = ".jar"; //$NON-NLS-1$
+
+	public static final FileFilter JAR_FILTER = new FileFilter() {
+		public boolean accept(File pathname) {
+			return pathname.isFile() && pathname.getName().endsWith(".jar"); //$NON-NLS-1$
+		}
+	};
+
+	public static final FileFilter PACK_GZ_FILTER = new FileFilter() {
+		public boolean accept(File pathname) {
+			return pathname.isFile() && pathname.getName().endsWith(PACKED_SUFFIX);
+		}
+	};
+
+	public static void close(Object stream) {
+		if (stream != null) {
+			try {
+				if (stream instanceof InputStream)
+					((InputStream) stream).close();
+				else if (stream instanceof OutputStream)
+					((OutputStream) stream).close();
+				else if (stream instanceof JarFile)
+					((JarFile) stream).close();
+			} catch (IOException e) {
+				//ignore
+			}
+		}
+	}
+
+	/**
+	 * get the set of commands to try to execute pack/unpack 
+	 * @param cmd, the command, either "pack200" or "unpack200"
+	 * @return String [] or null
+	 */
+	public static String[] getPack200Commands(String cmd) {
+		String[] locations = null;
+		String prop = System.getProperty(PACK200_PROPERTY);
+		String javaHome = System.getProperty("java.home"); //$NON-NLS-1$
+		if (NONE.equals(prop)) {
+			return null;
+		} else if (JRE.equals(prop)) {
+			locations = new String[] {javaHome + "/bin/" + cmd}; //$NON-NLS-1$
+		} else if (PATH.equals(prop)) {
+			locations = new String[] {cmd};
+		} else if (prop == null) {
+			locations = new String[] {javaHome + "/bin/" + cmd, cmd}; //$NON-NLS-1$ 
+		} else {
+			locations = new String[] {prop + "/" + cmd}; //$NON-NLS-1$
+		}
+		return locations;
+	}
+
+	/**
+	 * Transfers all available bytes from the given input stream to the given
+	 * output stream. Closes both streams if close == true, regardless of failure. 
+	 * Flushes the destination stream if close == false
+	 * 
+	 * @param source
+	 * @param destination
+	 * @param close 
+	 * @throws IOException
+	 */
+	public static void transferStreams(InputStream source, OutputStream destination, boolean close) throws IOException {
+		source = new BufferedInputStream(source);
+		destination = new BufferedOutputStream(destination);
+		try {
+			byte[] buffer = new byte[8192];
+			while (true) {
+				int bytesRead = -1;
+				if ((bytesRead = source.read(buffer)) == -1)
+					break;
+				destination.write(buffer, 0, bytesRead);
+			}
+		} finally {
+			if (close) {
+				close(source);
+				close(destination);
+			} else {
+				destination.flush();
+			}
+		}
+	}
+
+	/**
+	 * Deletes all the files and directories from the given root down (inclusive).
+	 * Returns false if we could not delete some file or an exception occurred
+	 * at any point in the deletion.
+	 * Even if an exception occurs, a best effort is made to continue deleting.
+	 */
+	public static boolean clear(java.io.File root) {
+		boolean result = clearChildren(root);
+		try {
+			if (root.exists())
+				result &= root.delete();
+		} catch (Exception e) {
+			result = false;
+		}
+		return result;
+	}
+
+	/**
+	 * Deletes all the files and directories from the given root down, except for 
+	 * the root itself.
+	 * Returns false if we could not delete some file or an exception occurred
+	 * at any point in the deletion.
+	 * Even if an exception occurs, a best effort is made to continue deleting.
+	 */
+	public static boolean clearChildren(java.io.File root) {
+		boolean result = true;
+		if (root.isDirectory()) {
+			String[] list = root.list();
+			// for some unknown reason, list() can return null.  
+			// Just skip the children If it does.
+			if (list != null)
+				for (int i = 0; i < list.length; i++)
+					result &= clear(new java.io.File(root, list[i]));
+		}
+		return result;
+	}
+
+	public static Set getPackExclusions(Properties properties) {
+		if (properties == null)
+			return Collections.EMPTY_SET;
+
+		String packExcludes = properties.getProperty(PACK_EXCLUDES);
+		if (packExcludes != null) {
+			String[] excludes = toStringArray(packExcludes, ","); //$NON-NLS-1$
+			Set packExclusions = new HashSet();
+			for (int i = 0; i < excludes.length; i++) {
+				packExclusions.add(excludes[i]);
+			}
+			return packExclusions;
+		}
+		return Collections.EMPTY_SET;
+	}
+
+	public static Set getSignExclusions(Properties properties) {
+		if (properties == null)
+			return Collections.EMPTY_SET;
+		String signExcludes = properties.getProperty(SIGN_EXCLUDES);
+		if (signExcludes != null) {
+			String[] excludes = toStringArray(signExcludes, ","); //$NON-NLS-1$
+			Set signExclusions = new HashSet();
+			for (int i = 0; i < excludes.length; i++) {
+				signExclusions.add(excludes[i]);
+			}
+			return signExclusions;
+		}
+		return Collections.EMPTY_SET;
+	}
+
+	public static String concat(String[] array) {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0; i < array.length; i++) {
+			if (i > 0)
+				buffer.append(' ');
+			buffer.append(array[i]);
+		}
+		return buffer.toString();
+	}
+
+	public static String[] toStringArray(String input, String separator) {
+		StringTokenizer tokenizer = new StringTokenizer(input, separator);
+		int count = tokenizer.countTokens();
+		String[] result = new String[count];
+		for (int i = 0; i < count; i++) {
+			result[i] = tokenizer.nextToken().trim();
+		}
+		return result;
+	}
+
+	/**
+	 * Get the properties from the eclipse.inf file from the given jar.  If the file is not a jar, null is returned.
+	 * If the file is a jar, but does not contain an eclipse.inf file, an empty Properties object is returned.
+	 * @param jarFile
+	 * @return The eclipse.inf properties for the given jar file
+	 */
+	public static Properties getEclipseInf(File jarFile, boolean verbose) {
+		if (jarFile == null || !jarFile.exists()) {
+			if (verbose)
+				System.out.println("Failed to obtain eclipse.inf due to missing jar file: " + jarFile);
+			return null;
+		}
+		JarFile jar = null;
+		try {
+			jar = new JarFile(jarFile, false);
+		} catch (ZipException e) {
+			//not a jar, don't bother logging this.
+			return null;
+		} catch (IOException e) {
+			if (verbose) {
+				System.out.println("Failed to obtain eclipse.inf due to IOException: " + jarFile);
+				e.printStackTrace();
+			}
+			return null;
+		}
+		try {
+			JarEntry mark = jar.getJarEntry(MARK_FILE_NAME);
+			if (mark != null) {
+				InputStream in = jar.getInputStream(mark);
+				Properties props = new Properties();
+				props.load(in);
+				in.close();
+				return props;
+			}
+			return new Properties();
+		} catch (IOException e) {
+			if (verbose) {
+				System.out.println("Failed to obtain eclipse.inf due to IOException: " + jarFile);
+				e.printStackTrace();
+			}
+			return null;
+		} finally {
+			close(jar);
+		}
+	}
+
+	public static boolean shouldSkipJar(File input, boolean processAll, boolean verbose) {
+		Properties inf = getEclipseInf(input, verbose);
+		if (inf == null) {
+			//not a jar, could be a pack.gz
+			return false;
+		}
+		String exclude = inf.getProperty(MARK_EXCLUDE);
+
+		//was marked as exclude, we should skip
+		if (exclude != null && Boolean.valueOf(exclude).booleanValue())
+			return true;
+
+		//process all was set, don't skip
+		if (processAll)
+			return false;
+
+		//otherwise, we skip if not marked marked
+		String marked = inf.getProperty(MARK_PROPERTY);
+		return !Boolean.valueOf(marked).booleanValue();
+	}
+
+	/**
+	 * Stores the given properties in the output stream.  We store the properties 
+	 * in sorted order so that the signing hash doesn't change if the properties didn't change. 
+	 * @param props
+	 * @param stream
+	 */
+	public static void storeProperties(Properties props, OutputStream stream) {
+		PrintStream printStream = new PrintStream(stream);
+		printStream.print("#Processed using Jarprocessor\n"); //$NON-NLS-1$
+		SortedMap sorted = new TreeMap(props);
+		for (Iterator iter = sorted.keySet().iterator(); iter.hasNext();) {
+			String key = (String) iter.next();
+			printStream.print(key);
+			printStream.print(" = "); //$NON-NLS-1$
+			printStream.print(sorted.get(key));
+			printStream.print("\n");
+
+		}
+		printStream.flush();
+	}
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/ZipProcessor.java b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/ZipProcessor.java
new file mode 100644
index 0000000..118b667
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/ZipProcessor.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.jarprocessor;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+/**
+ * @author aniefer@ca.ibm.com
+ *
+ */
+public class ZipProcessor {
+
+	private IProcessStep signStep = null;
+	private IProcessStep packStep = null;
+	private IProcessStep packUnpackStep = null;
+	private IProcessStep unpackStep = null;
+
+	private String workingDirectory = null;
+	private Properties properties = null;
+	private Set packExclusions = null;
+	private Set signExclusions = null;
+	private String command = null;
+	private boolean packing = false;
+	private boolean signing = false;
+	private boolean repacking = false;
+	private boolean unpacking = false;
+	private boolean verbose = false;
+	private boolean processAll = false;
+
+	public void setWorkingDirectory(String dir) {
+		workingDirectory = dir;
+	}
+
+	public String getWorkingDirectory() {
+		if (workingDirectory == null)
+			workingDirectory = "."; //$NON-NLS-1$
+		return workingDirectory;
+	}
+
+	public void setSignCommand(String command) {
+		this.command = command;
+		this.signing = (command != null);
+	}
+
+	public void setPack(boolean pack) {
+		this.packing = pack;
+	}
+
+	public void setRepack(boolean repack) {
+		this.repacking = repack;
+	}
+
+	public void setUnpack(boolean unpack) {
+		this.unpacking = unpack;
+	}
+
+	public void setVerbose(boolean verbose) {
+		this.verbose = verbose;
+	}
+
+	public void setProcessAll(boolean all) {
+		this.processAll = all;
+	}
+
+	public void processZip(File zipFile) throws ZipException, IOException {
+		if (verbose)
+			System.out.println("Processing " + zipFile.getPath()); //$NON-NLS-1$
+		ZipFile zip = new ZipFile(zipFile);
+		initialize(zip);
+
+		String extension = unpacking ? "pack.gz" : ".jar"; //$NON-NLS-1$ //$NON-NLS-2$
+		File tempDir = new File(getWorkingDirectory(), "temp_" + zipFile.getName()); //$NON-NLS-1$
+		JarProcessor processor = new JarProcessor();
+		processor.setVerbose(verbose);
+		processor.setProcessAll(processAll);
+		processor.setWorkingDirectory(tempDir.getCanonicalPath());
+		if (unpacking) {
+			processor.addProcessStep(unpackStep);
+		}
+
+		File outputFile = new File(getWorkingDirectory(), zipFile.getName() + ".temp"); //$NON-NLS-1$
+		File parent = outputFile.getParentFile();
+		if (!parent.exists())
+			parent.mkdirs();
+		ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(outputFile));
+		Enumeration entries = zip.entries();
+		if (entries.hasMoreElements()) {
+			for (ZipEntry entry = (ZipEntry) entries.nextElement(); entry != null; entry = entries.hasMoreElements() ? (ZipEntry) entries.nextElement() : null) {
+				String name = entry.getName();
+
+				InputStream entryStream = zip.getInputStream(entry);
+
+				boolean pack = packing && !packExclusions.contains(name);
+				boolean sign = signing && !signExclusions.contains(name);
+				boolean repack = repacking && !packExclusions.contains(name);
+
+				File extractedFile = null;
+
+				if (entry.getName().endsWith(extension) && (pack || sign || repack || unpacking)) {
+					extractedFile = new File(tempDir, name);
+					parent = extractedFile.getParentFile();
+					if (!parent.exists())
+						parent.mkdirs();
+					if (verbose)
+						System.out.println("Extracting " + entry.getName()); //$NON-NLS-1$
+					FileOutputStream extracted = new FileOutputStream(extractedFile);
+					Utils.transferStreams(entryStream, extracted, true); // this will close the stream
+					entryStream = null;
+
+					boolean skip = Utils.shouldSkipJar(extractedFile, processAll, verbose);
+					if (skip) {
+						//skipping this file 
+						entryStream = new FileInputStream(extractedFile);
+						if (verbose)
+							System.out.println(entry.getName() + " is not marked, skipping."); //$NON-NLS-1$
+					} else {
+						if (unpacking) {
+							File result = processor.processJar(extractedFile);
+							name = name.substring(0, name.length() - extractedFile.getName().length()) + result.getName();
+							extractedFile = result;
+						} else {
+							if (repack || sign) {
+								processor.clearProcessSteps();
+								if (repack)
+									processor.addProcessStep(packUnpackStep);
+								if (sign)
+									processor.addProcessStep(signStep);
+								extractedFile = processor.processJar(extractedFile);
+							}
+							if (pack) {
+								processor.clearProcessSteps();
+								processor.addProcessStep(packStep);
+								File modifiedFile = processor.processJar(extractedFile);
+								if (modifiedFile.exists()) {
+									try {
+										String newName = name.substring(0, name.length() - extractedFile.getName().length()) + modifiedFile.getName();
+										if (verbose) {
+											System.out.println("Adding " + newName + " to " + outputFile.getPath()); //$NON-NLS-1$ //$NON-NLS-2$
+											System.out.println();
+										}
+										ZipEntry zipEntry = new ZipEntry(newName);
+										entryStream = new FileInputStream(modifiedFile);
+										zipOut.putNextEntry(zipEntry);
+										Utils.transferStreams(entryStream, zipOut, false); //we want to keep zipOut open
+										entryStream.close();
+										Utils.clear(modifiedFile);
+									} catch (IOException e) {
+										Utils.close(entryStream);
+										if (verbose) {
+											e.printStackTrace();
+											System.out.println("Warning: Problem reading " + modifiedFile.getPath() + ".");
+										}
+									}
+									entryStream = null;
+								} else if (verbose) {
+									System.out.println("Warning: " + modifiedFile.getPath() + " not found.");
+								}
+							}
+						}
+						if (extractedFile.exists()) {
+							try {
+								entryStream = new FileInputStream(extractedFile);
+							} catch (IOException e) {
+								if (verbose) {
+									e.printStackTrace();
+									System.out.println("Warning: Problem reading " + extractedFile.getPath() + ".");
+								}
+							}
+						}
+
+						if (verbose && entryStream != null) {
+							System.out.println("Adding " + name + " to " + outputFile.getPath()); //$NON-NLS-1$ //$NON-NLS-2$
+						}
+					}
+				}
+				if (entryStream != null) {
+					ZipEntry newEntry = new ZipEntry(name);
+					try {
+						zipOut.putNextEntry(newEntry);
+						Utils.transferStreams(entryStream, zipOut, false);
+						zipOut.closeEntry();
+					} catch (ZipException e) {
+						if(verbose) {
+							System.out.println("Warning: " + name + " already exists in " + outputFile.getName() + ".  Skipping.");
+						}
+					}
+					entryStream.close();
+				}
+
+				if (extractedFile != null)
+					Utils.clear(extractedFile);
+				
+				if (verbose) {
+					System.out.println();
+					System.out.println("Processing " + zipFile.getPath()); //$NON-NLS-1$
+				}
+			}
+		}
+		zipOut.close();
+		zip.close();
+
+		File finalFile = new File(getWorkingDirectory(), zipFile.getName());
+		if (finalFile.exists())
+			finalFile.delete();
+		outputFile.renameTo(finalFile);
+		Utils.clear(tempDir);
+	}
+
+	private void initialize(ZipFile zip) {
+		ZipEntry entry = zip.getEntry("pack.properties"); //$NON-NLS-1$
+		properties = new Properties();
+		if (entry != null) {
+			InputStream stream = null;
+			try {
+				stream = zip.getInputStream(entry);
+				properties.load(stream);
+			} catch (IOException e) {
+				if (verbose)
+					e.printStackTrace();
+			} finally {
+				Utils.close(stream);
+			}
+		}
+
+		packExclusions = Utils.getPackExclusions(properties);
+		signExclusions = Utils.getSignExclusions(properties);
+
+		packUnpackStep = new PackUnpackStep(properties, verbose);
+		packStep = new PackStep(properties, verbose);
+		signStep = new SignCommandStep(properties, command, verbose);
+		unpackStep = new UnpackStep(properties, verbose);
+	}
+}
diff --git a/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/pack-readme.html b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/pack-readme.html
new file mode 100644
index 0000000..ef5fe5e
--- /dev/null
+++ b/update/org.eclipse.update.core/jarprocessor/org/eclipse/update/internal/jarprocessor/pack-readme.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+  <title>Eclipse update packing tool readme</title>
+</head>
+<body>
+<h1>Eclipse update packing tool</h1>
+
+<h3>Overview</h3>
+The update packing tool processes a hierarchy of arbitrarily nested
+JARs and ZIP files.  It is a generic utility that performs a depth first traversal of 
+a nested hierarchy of ZIPs and JARs, performs various commands on
+each of the JARs in the hierarchy, and then rebuilds the same hierarchy
+of ZIPs and JARs again.  Currently its main functions are:
+<ul>
+	<li>Packing JARs using the Java 1.5 <a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/pack200.html">pack200</a>
+	 command.</li>
+	 <li>Unpacking PACK.GZs using the Java 1.5 <a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/unpack200.html">unpack200</a>
+	 command.</li>
+	 <li>Normalizing JARs for future compression by pack200. This is accomplished
+	 by running the pack200 command with the <tt>--repack</tt> command line argument.</li>
+	 <li>Signing JARs to allow for authentication of the origin of JARs. This is accomplished by
+	 running a supplied command (typically the command will just be a wrapper around
+	 the Java <a href="http://java.sun.com/j2se/1.3/docs/tooldocs/win32/jarsigner.html">jarsigner</a> tool).</li>
+</ul>
+The packing tool is used in the following contexts:
+<ul>
+	<li>During a PDE build, to prepare JARs for uploading to an Eclipse
+	update site.  In this usage, it is used to both nomalize JAR contents
+	(pack200 -repack), and sign JARs.</li>
+	<li>On an update site, to convert traditional JAR content into the 
+	compressed pack200 format.</li>
+	<li>From an Eclipse client application during update, to convert
+	compressed pack200 format content into executable JAR files.</li>
+</ul>
+<h3>Tool usage</h3>
+To run the packing tool, you need a 1.5 JRE installed. The tool is run
+by invoking Java as follows:
+
+<pre>
+	java jarprocessor.jar [options] input
+</pre>
+
+Where <tt>input</tt> is either a zip file, a directory, or a JAR (or a pack.gz file). All files ending 
+in ".jar" or ".pack.gz" in the provided zip or directory hierarchy
+will be processed. 
+The following additional command line arguments are supported:
+<ul>
+<li>-repack : Normalize the jars using pack200 <tt>--repack</tt></li>
+<li>-sign &lt;cmd&gt; : signs the jars by executing the provided command.  
+The command will be provided a single argument that will be the full path of the JAR to process.
+</li>
+<li>-pack : for each input in JAR form, produce a corresponding output
+in packed form.  For an input "a.jar", the output is a.jar.pack.gz.  
+</li>
+<li>-unpack : for each input in packed form, produce a corresponding output
+in unpacked form.  For an input "a.jar.pack.gz", the output is "a.jar". -unpack is mutually exclusive with -repack, -pack and -sign.</li>
+<li>-outputDir &lt;dir&gt; : The directory to put the tool's output into.  If the input was a zip file, then an output zip file will be
+created containg all the output files.  If the input was a directory, for each input file there is a corresponding output file in the output directory. By default the current working directory is used.  If the input is in the same
+directory as the output, the input files may be overwritten.</li>
+</ul>
+
+Additionally, when the input is a zip file, it may contain a file called
+<tt>pack.properties</tt>.  The pack.properties file supports the following values:
+<ul>
+<li>pack.excludes =  jarName[, jarName]* : A comma-delimited list of JARs that should not be packed or repacked.
+</li>
+<li>sign.excludes =  jarName[, jarName]* : A comma-delimited list of JARs that should not be signed.
+</li>
+<li>&lt;jarname&gt;.pack.args = option[, option]* : A comma-delimited list of additional arguments that should
+be passed to pack200 when packing any jar with name &lt;jarname&gt;.
+</ul>
+</p>
+<p>
+<font size=-1>
+Copyright (c) IBM Corporation and others 2006. All rights reserved. This program and the accompanying materials
+are made available under the terms of the 
+<a href="http://www.eclipse.org/legal/epl-v10.html">Eclipse Public License v1.0</a>.
+</font>
+</body>
+</html>
diff --git a/update/org.eclipse.update.core/preferences.ini b/update/org.eclipse.update.core/preferences.ini
new file mode 100644
index 0000000..7936e7f
--- /dev/null
+++ b/update/org.eclipse.update.core/preferences.ini
@@ -0,0 +1,8 @@
+# The port number on which the sever listens for http requests.
+# If the port is 0 and arbitrary port is picked by the system.
+
+# Defines the policy url that contains directives for redirecting 
+# updates to different update sites.
+#updatePolicyURL=
+
+
diff --git a/update/org.eclipse.update.core/schema/featureTypes.exsd b/update/org.eclipse.update.core/schema/featureTypes.exsd
new file mode 100644
index 0000000..0517f10
--- /dev/null
+++ b/update/org.eclipse.update.core/schema/featureTypes.exsd
@@ -0,0 +1,122 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.update.core">

+<annotation>

+      <appInfo>

+         <meta.schema plugin="org.eclipse.update.core" id="featureTypes" name="Feature Type Factory"/>

+      </appInfo>

+      <documentation>

+         The platform update mechanism supports pluggable feature type
+implementations. A new feature type can be registered in order
+to support
+alternate packaging and verification schemes.
+&lt;p&gt;
+The &lt;code&gt;featureTypes&lt;/code&gt;
+extension point allows alternate feature implementations to be
+registered using a symbolic type identifier. Whenever the 
+type is referenced using this identifier, the supplied factory
+is used to create the correct concrete feature implementation.
+&lt;/p&gt;

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <complexType>

+         <sequence>

+            <element ref="feature-factory" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  must be specified as &lt;b&gt;org.eclipse.update.core.featureTypes&lt;/b&gt;

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  must be specified. Identifies the new feature type

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  optional displayable label for the new feature type

+               </documentation>

+               <appInfo>

+                  <meta.attribute translatable="true"/>

+               </appInfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="feature-factory">

+      <complexType>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  fully qualified name of the factory class for the identified feature type

+               </documentation>

+               <appInfo>

+                  <meta.attribute kind="java" basedOn="org.eclipse.update.configuration.IInstallDeltaHandler"/>

+               </appInfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="examples"/>

+      </appInfo>

+      <documentation>

+         The following is an example of new feature type registration:
+&lt;p&gt;
+&lt;pre&gt;
+   &lt;extension
+      id=&quot;custom&quot;
+      point=&quot;org.eclipse.update.core.featureTypes&quot;
+      name=&quot;Custom packaged feature&quot;&gt;
+      &lt;feature-factory
+          class=&quot;com.xyz.update.CustomFeatureFactory&quot;&gt;
+      &lt;/feature-factory&gt;
+   &lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="apiInfo"/>

+      </appInfo>

+      <documentation>

+         Registered factory classes must implement 
+&lt;code&gt;&lt;b&gt;org.eclipse.update.core.IFeatureFactory&lt;/b&gt;&lt;/code&gt;

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="implementation"/>

+      </appInfo>

+      <documentation>

+         The platform supplies two standard implementations of feature
+types. One representing the default packaged feature type, and
+the other representing an installed feature type.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="copyright"/>

+      </appInfo>

+      <documentation>

+         Copyright (c) 2004 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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;.

+      </documentation>

+   </annotation>

+

+</schema>

diff --git a/update/org.eclipse.update.core/schema/installHandlers.exsd b/update/org.eclipse.update.core/schema/installHandlers.exsd
new file mode 100644
index 0000000..084a25f
--- /dev/null
+++ b/update/org.eclipse.update.core/schema/installHandlers.exsd
@@ -0,0 +1,113 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.update.core">

+<annotation>

+      <appInfo>

+         <meta.schema plugin="org.eclipse.update.core" id="installHandlers" name="Global Install Handlers"/>

+      </appInfo>

+      <documentation>

+         Extension point for registering global install handlers. Global
+install handlers can be referenced by features 
+(using the &lt;code&gt;&amp;lt;feature&amp;gt; &amp;lt;install-handler&amp;gt;&lt;/code&gt;
+tags) without having to include a copy of the handler code as
+part of the downloadable feature.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <complexType>

+         <sequence>

+            <element ref="install-handler" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  must be specified as &lt;b&gt;org.eclipse.update.core.installHandlers&lt;/b&gt;

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  must be specified. Identifies the new install handler

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  optional displayable label for the new install handler

+               </documentation>

+               <appInfo>

+                  <meta.attribute translatable="true"/>

+               </appInfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="install-handler">

+      <complexType>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  fully qualified name of the handler implementation class for the identified
+install handler

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="examples"/>

+      </appInfo>

+      <documentation>

+         The following is an example of new global install handler registration:
+&lt;p&gt;
+&lt;pre&gt;
+   &lt;extension
+        id=&quot;custom&quot;
+        point=&quot;org.eclipse.update.core.installHandlers&quot;
+        name=&quot;Custom install handler&quot;&gt;
+     &lt;install-handler
+        class=&quot;com.xyz.update.CustomInstallHandler&quot;&gt;
+     &lt;/install-handler&gt;
+   &lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="apiInfo"/>

+      </appInfo>

+      <documentation>

+         Registered install handler classes must implement 
+&lt;code&gt;org.eclipse.update.core.IInstallHandler&lt;/code&gt; interface.
+Implementers should extend base class &lt;code&gt;org.eclipse.update.core.BaseInstallHandler&lt;/code&gt;.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="implementation"/>

+      </appInfo>

+      <documentation>

+         The platform supplies a simple install handler that is registered as &lt;code&gt;org.eclipse.update.core.DefaultInstallHandler&lt;/code&gt;. If used, it will copy any non-plug-in data entries provided with the feature into the feature installation directory.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="copyright"/>

+      </appInfo>

+      <documentation>

+         Copyright (c) 2004 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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;.

+      </documentation>

+   </annotation>

+

+</schema>

diff --git a/update/org.eclipse.update.core/schema/siteTypes.exsd b/update/org.eclipse.update.core/schema/siteTypes.exsd
new file mode 100644
index 0000000..102dc16
--- /dev/null
+++ b/update/org.eclipse.update.core/schema/siteTypes.exsd
@@ -0,0 +1,119 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.update.core">

+<annotation>

+      <appInfo>

+         <meta.schema plugin="org.eclipse.update.core" id="siteTypes" name="Site Type Factory"/>

+      </appInfo>

+      <documentation>

+         The platform update mechanism supports pluggable site type
+implementations. A new site type can be registered in order
+to support alternate site layout schemes.
+&lt;p&gt;
+The &lt;code&gt;siteTypes&lt;/code&gt;
+extension point allows alternate site implementations to be
+registered using a symbolic type identifier. Whenever the 
+type is referenced using this identifier, the supplied factory
+is used to create the correct concrete site implementation.
+&lt;/p&gt;

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <complexType>

+         <sequence>

+            <element ref="site-factory" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  must be specified as &lt;b&gt;org.eclipse.update.core.siteTypes&lt;/b&gt;

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  must be specified. Identifies the new site type

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  optional displayable label for the new site type

+               </documentation>

+               <appInfo>

+                  <meta.attribute translatable="true"/>

+               </appInfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="site-factory">

+      <complexType>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  fully qualified name of the factory class for the identified
+site type

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="examples"/>

+      </appInfo>

+      <documentation>

+         The following is an example of new site type registration.
+&lt;p&gt;
+&lt;pre&gt;
+   &lt;extension
+        id=&quot;custom&quot;
+        point=&quot;org.eclipse.update.core.siteTypes&quot;
+        name=&quot;Custom site&quot;&gt;
+      &lt;site-factory
+          class=&quot;com.xyz.update.CustomSiteFactory&quot;&gt;
+      &lt;/site-factory&gt;
+   &lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="apiInfo"/>

+      </appInfo>

+      <documentation>

+         Registered factory classes must implement 
+&lt;code&gt;&lt;b&gt;org.eclipse.update.core.ISiteFactory&lt;/b&gt;&lt;/code&gt;

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="implementation"/>

+      </appInfo>

+      <documentation>

+         The platform supplies two standard implementations of site
+types. One representing the default update server type, and
+the other representing the local file system site.

+      </documentation>

+   </annotation>

+

+   <annotation>

+      <appInfo>

+         <meta.section type="copyright"/>

+      </appInfo>

+      <documentation>

+         Copyright (c) 2004 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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;.

+      </documentation>

+   </annotation>

+

+</schema>

diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/BaseSiteLocalFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/BaseSiteLocalFactory.java
new file mode 100644
index 0000000..2ab5714
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/BaseSiteLocalFactory.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.model.*;
+/**
+ * 
+ */
+public class BaseSiteLocalFactory {
+	/*
+	 * 
+	 */
+	public InstallConfigurationModel createInstallConfigurationModel() {
+		return new InstallConfiguration();
+	}
+	/*
+	 * 
+	 */
+	public ConfigurationActivityModel createConfigurationActivityModel() {
+		return new ConfigurationActivity();
+	}
+	/*
+	 * 
+	 */
+	public ConfiguredSiteModel createConfigurationSiteModel() {
+		return new ConfiguredSite();
+	}
+	/*
+	 * 
+	 */
+	public ConfigurationPolicyModel createConfigurationPolicyModel() {
+		return new ConfigurationPolicy();
+	}
+	/**
+	 * 
+	 */
+	public ConfiguredSiteModel createConfigurationSiteModel(SiteModel site, int policy) {
+		//create config site
+		ConfiguredSiteModel configSite = this.createConfigurationSiteModel();
+		configSite.setSiteModel(site);
+		ConfigurationPolicyModel policyModel = this.createConfigurationPolicyModel();
+		policyModel.setPolicy(policy);
+		configSite.setConfigurationPolicyModel(policyModel);
+		((ConfigurationPolicy) policyModel).setConfiguredSiteModel(configSite);
+		return configSite;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ConfigurationActivity.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ConfigurationActivity.java
new file mode 100644
index 0000000..d6bbc84
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ConfigurationActivity.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+import org.eclipse.update.configuration.IActivity;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.internal.model.ConfigurationActivityModel;
+public class ConfigurationActivity
+	extends ConfigurationActivityModel
+	implements IActivity {
+		
+	/**
+	 * Default constructor
+	 */		
+	public ConfigurationActivity() {
+	}
+	
+	/**
+	 * Constructor with action
+	 */
+	public ConfigurationActivity(int action) {
+		super();
+		setAction(action);
+		setStatus(STATUS_NOK);
+	}
+	
+	/*
+	 * @see IActivity#getInstallConfiguration()
+	 */
+	public IInstallConfiguration getInstallConfiguration() {
+		return (IInstallConfiguration) getInstallConfigurationModel();
+	}
+	
+	public boolean equals(Object other) {
+		if (!(other instanceof ConfigurationActivity))
+			return false;
+		if (this == other)
+			return true;
+		
+		ConfigurationActivity activity = (ConfigurationActivity) other;
+		return getAction() == activity.getAction()
+				&& getLabel().equals(activity.getLabel())
+				&& getStatus() == activity.getStatus();
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ConfigurationPolicy.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ConfigurationPolicy.java
new file mode 100644
index 0000000..5d7e482
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ConfigurationPolicy.java
@@ -0,0 +1,524 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+import java.io.*;
+import java.net.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.model.*;
+
+/**
+ * 
+ */
+public class ConfigurationPolicy extends ConfigurationPolicyModel {
+
+	/**
+	 * Constructor for ConfigurationPolicyModel.
+	 */
+	public ConfigurationPolicy() {
+	}
+
+	/**
+	 * Copy Constructor for ConfigurationPolicyModel.
+	 */
+	public ConfigurationPolicy(ConfigurationPolicy configPolicy) {
+		super();
+		setPolicy(configPolicy.getPolicy());
+		setConfiguredFeatureReferences(configPolicy.getConfiguredFeatures());
+		setUnconfiguredFeatureReferences(configPolicy.getUnconfiguredFeatures());
+		setConfiguredSiteModel(configPolicy.getConfiguredSiteModel());
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	private boolean isUnconfigured(IFeatureReference featureReference) {
+
+		if (featureReference == null)
+			return false;
+
+		// returns true if the feature is part of the configured list
+		IFeatureReference[] refs = getUnconfiguredFeatures();
+		for (int i = 0; i < refs.length; i++) {
+			if (featureReference.equals(refs[i])) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public boolean isConfigured(IFeatureReference featureReference) {
+
+		if (featureReference == null)
+			return false;
+
+		// returns true if the feature is part of the configured list
+		IFeatureReference[] refs = getConfiguredFeatures();
+		for (int i = 0; i < refs.length; i++) {
+			if (featureReference.equals(refs[i])) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * adds the feature to the list of features if the policy is USER_INCLUDE
+	 */
+	public void configure(IFeatureReference featureReference, boolean callInstallHandler, boolean createActivity) throws CoreException {
+
+		if (isConfigured(featureReference)) // already configured
+			return;
+
+		if (featureReference == null) {
+			UpdateCore.warn("The feature reference to configure is null"); //$NON-NLS-1$
+			return;
+		}
+
+		IFeature feature = null;
+		try {
+			feature = featureReference.getFeature(null);
+		} catch (CoreException e) {
+			if (!UpdateManagerUtils.isOptional(featureReference)) {
+				URL url = featureReference.getURL();
+				String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
+				UpdateCore.warn("Error retrieving feature:" + urlString, e); //$NON-NLS-1$
+				return;
+			}
+		}
+		if (feature == null) {
+			URL url = featureReference.getURL();
+			String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
+			UpdateCore.warn("The feature to unconfigure is null: feature reference is:" + urlString); //$NON-NLS-1$
+		}
+
+		// Setup optional install handler
+		InstallHandlerProxy handler = null;
+		if (callInstallHandler && feature.getInstallHandlerEntry() != null)
+			handler = new InstallHandlerProxy(IInstallHandler.HANDLER_ACTION_CONFIGURE, feature, feature.getInstallHandlerEntry(), null);
+		boolean success = false;
+		Throwable originalException = null;
+
+		// do the configure action
+		try {
+			if (handler != null)
+				handler.configureInitiated();
+
+			ConfigurationActivity activity = null;
+			if (createActivity) {
+				activity = new ConfigurationActivity(IActivity.ACTION_CONFIGURE);
+				activity.setLabel(feature.getVersionedIdentifier().toString());
+				activity.setDate(new Date());
+			}
+
+			addConfiguredFeatureReference((FeatureReferenceModel) featureReference);
+
+			// everything done ok
+			if (activity != null) {
+				InstallConfiguration installConfig = (InstallConfiguration) SiteManager.getLocalSite().getCurrentConfiguration();
+				activity.setStatus(IActivity.STATUS_OK);
+				installConfig.addActivity(activity);
+			}
+
+			if (handler != null)
+				handler.completeConfigure();
+
+			success = true;
+		} catch (Throwable t) {
+			originalException = t;
+		} finally {
+			Throwable newException = null;
+			try {
+				if (handler != null)
+					handler.configureCompleted(success);
+			} catch (Throwable t) {
+				newException = t;
+			}
+			if (originalException != null) // original exception wins
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallHandler_error, (new String[] { feature.getLabel() })), originalException);
+			if (newException != null)
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallHandler_error, (new String[] { feature.getLabel() })), newException);
+		}
+	}
+
+	/**
+	 * check if the plugins to unconfigure are required by other configured feature and
+	 * adds the feature to the list of unconfigured features 
+	 */
+	public boolean unconfigure(IFeatureReference featureReference, boolean callInstallHandler, boolean createActivity) throws CoreException {
+
+		if (isUnconfigured(featureReference)) {
+			UpdateCore.warn("Feature already unconfigured"); //$NON-NLS-1$
+			return true;
+		}
+
+		if (featureReference == null) {
+			UpdateCore.warn("The feature reference to unconfigure is null"); //$NON-NLS-1$
+			return false;
+		}
+
+		IFeature feature = null;
+		try {
+			feature = featureReference.getFeature(null);
+		} catch (CoreException e) {
+			if (!UpdateManagerUtils.isOptional(featureReference)) {
+				URL url = featureReference.getURL();
+				String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
+				UpdateCore.warn("Error retrieving feature:" + urlString, e); //$NON-NLS-1$
+				return false;
+			}
+		}
+
+		if (feature == null) {
+			URL url = featureReference.getURL();
+			String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
+			UpdateCore.warn("The feature to unconfigure is null: feature reference is:" + urlString); //$NON-NLS-1$
+			return false;
+		}
+
+		// Setup optional install handler
+		InstallHandlerProxy handler = null;
+		if (callInstallHandler && feature.getInstallHandlerEntry() != null) {
+			handler = new InstallHandlerProxy(IInstallHandler.HANDLER_ACTION_UNCONFIGURE, feature, feature.getInstallHandlerEntry(), null);
+		}
+
+		boolean success = false;
+		Throwable originalException = null;
+
+		// do the unconfigure action
+		try {
+
+			ConfigurationActivity activity = null;
+			if (createActivity) {
+				activity = new ConfigurationActivity(IActivity.ACTION_UNCONFIGURE);
+				activity.setLabel(feature.getVersionedIdentifier().toString());
+				activity.setDate(new Date());
+			}
+
+			InstallConfiguration installConfig = null;
+
+			// only ask for install config is activity created.
+			// prevents loops during reconciliation
+			if (activity != null)
+				installConfig = ((InstallConfiguration) SiteManager.getLocalSite().getCurrentConfiguration());
+
+			// Allow unconfigure if the feature is optional from all the parents
+			// or if the feature is mandatory and non of its parent are configured
+			// removed, not a core issue (so deep down)
+			//if (validateNoConfiguredParents(feature)) {
+			if (handler != null)
+				handler.unconfigureInitiated();
+			addUnconfiguredFeatureReference((FeatureReferenceModel) featureReference);
+			if (handler != null)
+				handler.completeUnconfigure();
+
+			// everything done ok
+			if (activity != null) {
+				activity.setStatus(IActivity.STATUS_OK);
+				installConfig.addActivity(activity);
+			}
+			success = true;
+			//} else {
+			//	if (activity != null) {
+			//		activity.setStatus(IActivity.STATUS_NOK);
+			//		installConfig.addActivityModel((ConfigurationActivityModel) activity);
+			//	}
+			//}
+		} catch (Throwable t) {
+			originalException = t;
+		} finally {
+			Throwable newException = null;
+			try {
+				if (handler != null)
+					handler.unconfigureCompleted(success);
+			} catch (Throwable t) {
+				newException = t;
+			}
+			if (originalException != null) // original exception wins
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallHandler_error, (new String[] { feature.getLabel() })), originalException);
+			if (newException != null)
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallHandler_error, (new String[] { feature.getLabel() })), newException);
+		}
+
+		if (!success) {
+			URL url = featureReference.getURL();
+			String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
+			UpdateCore.warn("Unable to unconfigure:" + urlString); //$NON-NLS-1$
+		}
+		return success;
+	}
+
+	/**
+	 * Calculates the plugin list for the policy. For "INCLUDE" policy, this
+	 * corresponds to the plugins for configured features. For "EXCLUDE"
+	 * policy, this corresponds to the plugins for unconfigured features that
+	 * are not referenced by any configured features.
+	 */
+	public String[] getPluginPath(ISite site) throws CoreException {
+		// TODO we may need to exclude patched plugins here, but this should be good enough for now
+		if (getPolicy() == IPlatformConfiguration.ISitePolicy.MANAGED_ONLY)
+			return new String[0];
+			
+		String[] pluginPaths;
+		// Note: Since 3.0M7 we leave patched features configured,
+		// and take this into account when computing configured plugins
+		// all unconfigured features. Note that patched features are still
+		// configured
+		IFeatureReference[] unconfiguredFeatures = getUnconfiguredFeatures();
+		// all configured features, including patches and patched features
+		IFeatureReference[] configuredFeatures = getConfiguredFeatures();
+		if (!isEnabled()) {
+			if (getPolicy() == IPlatformConfiguration.ISitePolicy.USER_INCLUDE) {
+				// disabled site, INCLUDE policy
+				pluginPaths = new String[0];
+			} else {
+				// disabled site, EXCLUDE policy
+				pluginPaths = getAllKnownPluginStrings(site,
+						configuredFeatures, unconfiguredFeatures);
+			}
+		} else {
+			// PatchedFeatures (may have no patches) with corresponding patches
+			PatchedFeature[] patchedFeatures = buildPatchedFeatures(configuredFeatures);
+			if (getPolicy() == IPlatformConfiguration.ISitePolicy.USER_INCLUDE) {
+				// enabled site, INCLUDE policy
+				pluginPaths = getConfiguredPluginStrings(site, patchedFeatures);
+			} else {
+				// enabled site, EXCLUDE policy - the usual scenario for local
+				// site.
+				// return all known MINUS configured plugins
+				pluginPaths = subtract(getAllKnownPluginStrings(site,
+						configuredFeatures, unconfiguredFeatures),
+						getConfiguredPluginStrings(site, patchedFeatures));
+			}
+		}
+		//TRACE
+		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) {
+			UpdateCore
+					.debug("GetPluginPath for: " //$NON-NLS-1$
+							+ ((site == null) ? "<No site>" : site.getURL() //$NON-NLS-1$
+									.toString()));
+			for (int i = 0; i < pluginPaths.length; i++) {
+				UpdateCore.debug("To write:" + pluginPaths[i]); //$NON-NLS-1$
+			}
+		}
+		return pluginPaths;
+	}
+	
+	/**
+	 * Obtains PatchedFeatures - non patch features with corresponding patches if any
+	 * 
+	 * @param features
+	 *            array of features to operate with
+	 * @return Patches
+	 */
+	private PatchedFeature[] buildPatchedFeatures(IFeatureReference[] features) {
+		// PatchedFeatures by VersionedIdentifier
+		Map map = new HashMap();
+		// Create a map of features (not patches)
+		for (int f = 0; f < features.length; f++) {
+			IFeatureReference featureRef = features[f];
+			try {
+				if(featureRef.isPatch()){
+					continue;
+				}
+				VersionedIdentifier vi = featureRef.getVersionedIdentifier();
+				map.put(vi, new PatchedFeature(features[f]));
+			} catch (CoreException e) {
+				UpdateCore.warn(null, e);
+			}
+		}
+		// attach patches to features
+		for (int f = 0; f < features.length; f++) {
+			IFeatureReference patchCandidate = features[f];
+			try {
+				IFeature feature = patchCandidate.getFeature(null);
+				IImport[] imports = feature.getImports();
+				for (int i = 0; i < imports.length; i++) {
+					IImport oneImport = imports[i];
+					if (!oneImport.isPatch())
+						continue;
+					// it is a patch for
+					VersionedIdentifier patchedIdentifier =
+						oneImport.getVersionedIdentifier();
+					PatchedFeature pf=(PatchedFeature) map.get(patchedIdentifier);
+					if (pf!=null) {
+						pf.addPatch(patchCandidate);
+					} else {
+						// patched feature not enabled
+					}
+				}
+			} catch (CoreException e) {
+				UpdateCore.warn(null, e);
+			}
+		}
+		Collection patchedFeatures=map.values();
+		return (PatchedFeature[])patchedFeatures.toArray(new PatchedFeature[patchedFeatures.size()]);
+	}
+	
+	/**
+	 * @since 2.0
+	 */
+	public IFeatureReference[] getConfiguredFeatures() {
+		FeatureReferenceModel[] result = getConfiguredFeaturesModel();
+		if (result.length == 0)
+			return new IFeatureReference[0];
+		else
+			return (IFeatureReference[]) result;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public IFeatureReference[] getUnconfiguredFeatures() {
+		FeatureReferenceModel[] result = getUnconfiguredFeaturesModel();
+		if (result.length == 0)
+			return new IFeatureReference[0];
+		else
+			return (IFeatureReference[]) result;
+	}
+
+	/**
+	 * Gets the configuredSite.
+	 * @return Returns a IConfiguredSite
+	 */
+	public IConfiguredSite getConfiguredSite() {
+		return (IConfiguredSite) getConfiguredSiteModel();
+	}
+
+	/**
+	 * removes a feature reference
+	 */
+	public void removeFeatureReference(IFeatureReference featureRef) {
+		if (featureRef instanceof FeatureReferenceModel) {
+			removeFeatureReference((FeatureReferenceModel) featureRef);
+		}
+	}
+
+	/**
+	 * @return an array of plugin path for the array of feature reference. For
+	 *         features that have patches, plugin path will
+	 *         point to plugin with the same ID provided by the patch if it
+	 *         exists. Each plugin path only appears once [bug 21750]
+	 */
+	private String[] getConfiguredPluginStrings(ISite site, PatchedFeature[] features) throws CoreException {
+		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION){
+			UpdateCore.warn("CONFIGURED PLUGINS"); //$NON-NLS-1$
+		}
+	
+		// Use set to eliminate plugins with same ID and version.
+		// Different versions of plugins with same ID are allowed if coming from different features
+		Set featurePlugins = new HashSet();
+		for (int i = 0; i < features.length; i++) {
+			FeaturePlugin[] plugins = features[i].getPlugins();
+			featurePlugins.addAll(Arrays.asList(plugins));
+		}
+		Set pluginStrings = getPluginStrings(site, (FeaturePlugin[]) featurePlugins.toArray(new FeaturePlugin[featurePlugins.size()]));
+		return (String[]) pluginStrings.toArray(new String[pluginStrings.size()]);
+	}
+	/**
+	 * @return an array of plugin path for every plugin in known features
+	 */
+	private String[] getAllKnownPluginStrings(ISite site, IFeatureReference[] configured,IFeatureReference[] unconfigured) throws CoreException {
+		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION){
+			UpdateCore.warn("ALL PLUGINS"); //$NON-NLS-1$
+		}
+		// Add features, patched features, or patches
+		IFeatureReference[] all=new IFeatureReference[configured.length+unconfigured.length];
+		System.arraycopy(configured, 0, all, 0, configured.length);
+		System.arraycopy(unconfigured, 0, all, configured.length, unconfigured.length);
+		//
+		Set patchedPlugins = new HashSet();
+		for (int i=0; i< all.length; i++) {
+			try {
+				IFeature feature = all[i].getFeature(null);
+				if (feature == null) {
+					UpdateCore.warn("Null Feature", new Exception()); //$NON-NLS-1$
+					continue;
+				}
+
+				IPluginEntry[] entries = feature.getPluginEntries();
+				// add every plugin to the map
+				for (int entr = 0; entr < entries.length; entr++) {
+					patchedPlugins.add(new FeaturePlugin(entries[entr], feature));
+				}
+
+			} catch (CoreException e) {
+				UpdateCore.warn(null, e);
+			}
+		}
+		Set pluginStrings = getPluginStrings(site,  (FeaturePlugin[])patchedPlugins.toArray(new FeaturePlugin[patchedPlugins.size()]));
+		return (String[]) pluginStrings.toArray(new String[pluginStrings.size()]);
+	}
+	/**
+	 * @param site
+	 * @param plugins[]
+	 * @return valid string pointing to plugins in given features
+	 * @throws CoreException
+	 */
+	private Set getPluginStrings(ISite site, FeaturePlugin[] plugins) throws CoreException {
+		Set pluginStrings=new HashSet();
+		for (int i=0; i< plugins.length; i++) {
+			IPluginEntry entry = plugins[i].getEntry();
+			IFeature feature=plugins[i].getFeature();
+
+			// obtain the path of the plugin directories on the site
+			ContentReference[] featureContentReference = null;
+			try {
+				featureContentReference = feature.getFeatureContentProvider().getPluginEntryArchiveReferences(entry, null /*IProgressMonitor*/
+				);
+			} catch (CoreException e) {
+				UpdateCore.warn(null, e);
+			}
+
+			// transform into a valid String
+			if (featureContentReference != null) {
+				for (int j = 0; j < featureContentReference.length; j++) {
+					URL url = site.getSiteContentProvider().getArchiveReference(featureContentReference[j].getIdentifier());
+					if (url != null) {
+						// make it relative to the site
+						String path = UpdateManagerUtils.getURLAsString(site.getURL(), url);
+						// add end "/"
+						if(!path.endsWith(".jar")) //$NON-NLS-1$
+							path += (path.endsWith(File.separator) || path.endsWith("/")) ? "" : "/"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+						pluginStrings.add(path);
+						if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION)
+							UpdateCore.warn("Add plugin: " + path + " to the list"); //$NON-NLS-1$ //$NON-NLS-2$
+					}
+				}
+			}
+		}
+		return pluginStrings;
+	}
+
+	/**
+	 *	 Obtains strings existing in the allStrings array, but not in the stringsToRemove
+	 */
+	private String[] subtract(String[] allStrings, String[] stringsToRemove) {
+		HashSet resultList = new HashSet(Arrays.asList(allStrings));
+		resultList.removeAll(Arrays.asList(stringsToRemove));
+		return (String[])resultList.toArray(new String[resultList.size()]);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ConfiguredSite.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ConfiguredSite.java
new file mode 100644
index 0000000..3b59270
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ConfiguredSite.java
@@ -0,0 +1,1136 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+
+import org.eclipse.core.runtime.ListenerList;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.PropertyResourceBundle;
+import java.util.Set;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.IActivity;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configuration.IConfiguredSiteChangedListener;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.configuration.IProblemHandler;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IIncludedFeatureReference;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.core.IVerificationListener;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.eclipse.update.core.model.InstallAbortedException;
+import org.eclipse.update.internal.model.ConfiguredSiteModel;
+import org.eclipse.update.internal.operations.UpdateUtils;
+
+/**
+ * A Configured site manages the Configured and unconfigured features of a Site
+ */
+public class ConfiguredSite extends ConfiguredSiteModel implements IConfiguredSite {
+
+	private static final String PRODUCT_SITE_MARKER = ".eclipseproduct"; //$NON-NLS-1$
+	private static final String EXTENSION_SITE_MARKER = ".eclipseextension"; //$NON-NLS-1$
+
+	// listeners	
+	private ListenerList listeners = new ListenerList(ListenerList.IDENTITY);
+
+	// verification status
+	private IStatus verifyStatus;
+
+	// transient: true if the site was just created so we can remove it
+	private transient boolean justCreated = false;
+
+	/*
+	 * Default Constructor
+	 */
+	public ConfiguredSite() {
+	}
+
+	/*
+	 * Copy Constructor
+	 * As of now, configSite can only be of type ConfiguredSite
+	 */
+	public ConfiguredSite(IConfiguredSite configSite) {
+		ConfiguredSite cSite = (ConfiguredSite) configSite;
+		setSiteModel(cSite.getSiteModel());
+		setConfigurationPolicyModel(new ConfigurationPolicy(cSite.getConfigurationPolicy()));
+		setUpdatable(cSite.isUpdatable());
+		setEnabled(cSite.isEnabled());
+		setPreviousPluginPath(cSite.getPreviousPluginPath());
+		setPlatformURLString(cSite.getPlatformURLString());
+	}
+
+	/*
+	 *  Adds a listener
+	 */
+	public void addConfiguredSiteChangedListener(IConfiguredSiteChangedListener listener) {
+		listeners.add(listener);
+	}
+
+	/*
+	 * Removes a listener
+	 */
+	public void removeConfiguredSiteChangedListener(IConfiguredSiteChangedListener listener) {
+		listeners.remove(listener);
+	}
+
+	/*
+	 * @see IConfiguredSite#install(IFeature,IVerificationListener, IProgressMonitor)
+	 */
+	public IFeatureReference install(IFeature feature, IVerificationListener verificationListener, IProgressMonitor monitor) throws InstallAbortedException, CoreException {
+		return install(feature, null, verificationListener, monitor);
+	}
+
+	/*
+	 * @see IConfiguredSite#install(IFeature, IFeatureReference, IVerificationListener, IProgressMonitor)
+	 */
+	public IFeatureReference install(IFeature feature, IFeatureReference[] optionalFeatures, IVerificationListener verificationListener, IProgressMonitor monitor) throws InstallAbortedException, CoreException {
+
+		// change the status if justCreated
+		if (justCreated) justCreated=false;
+
+		// ConfigSite is read only 
+		if (!isUpdatable()) {
+			String errorMessage = NLS.bind(Messages.ConfiguredSite_NonInstallableSite, (new String[] { getSite().getURL().toExternalForm() }));
+			IStatus status = verifyUpdatableStatus();
+			if (status != null)
+				errorMessage += " " + status.getMessage(); //$NON-NLS-1$
+			throw Utilities.newCoreException(errorMessage, null);
+		}
+
+		// feature is null
+		if (feature == null) {
+			String errorMessage = Messages.ConfiguredSite_NullFeatureToInstall; 
+			throw Utilities.newCoreException(errorMessage, null);
+		}
+
+		// feature reference to return
+		IFeatureReference installedFeatureRef;
+		IFeature installedFeature = null;
+
+		// create the Activity (INSTALL)
+		ConfigurationActivity activity = new ConfigurationActivity(IActivity.ACTION_FEATURE_INSTALL);
+		activity.setLabel(feature.getVersionedIdentifier().toString());
+		activity.setDate(new Date());
+
+		try {
+			installedFeatureRef = getSite().install(feature, optionalFeatures, verificationListener, monitor);
+
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_INSTALL) {
+				UpdateCore.debug("Sucessfully installed: " + installedFeatureRef.getURL().toExternalForm()); //$NON-NLS-1$
+			}
+
+			if (installedFeatureRef != null) {
+				try {
+					installedFeature = installedFeatureRef.getFeature(null);
+				} catch (CoreException e) {
+					UpdateCore.warn(null, e);
+				}
+			}
+
+			// everything done ok
+			activity.setStatus(IActivity.STATUS_OK);
+
+			// notify listeners
+			Object[] siteListeners = listeners.getListeners();
+			for (int i = 0; i < siteListeners.length; i++) {
+				if (installedFeature != null) {
+					IConfiguredSiteChangedListener listener = ((IConfiguredSiteChangedListener) siteListeners[i]);
+					listener.featureInstalled(installedFeature);
+				}
+			}
+		} catch (CoreException e) {
+			// not ok, set Activity status
+			activity.setStatus(IActivity.STATUS_NOK);
+			throw e;
+		} finally {
+			IInstallConfiguration current = SiteManager.getLocalSite().getCurrentConfiguration();
+			((InstallConfiguration) current).addActivity(activity);
+		}
+		// call the configure task	
+		if (installedFeature != null)
+			configure(installedFeature, optionalFeatures, true);
+		/*callInstallHandler*/
+
+		return installedFeatureRef;
+	}
+
+	/*
+	 * @see IConfiguredSite#remove(IFeature, IProgressMonitor)
+	 */
+	public void remove(IFeature feature, IProgressMonitor monitor) throws CoreException {
+
+		// ConfigSite is read only
+		if (!isUpdatable()) {
+			String errorMessage = NLS.bind(Messages.ConfiguredSite_NonUninstallableSite, (new String[] { getSite().getURL().toExternalForm() }));
+			throw Utilities.newCoreException(errorMessage, null);
+		}
+
+		// create the Activity
+		ConfigurationActivity activity = new ConfigurationActivity(IActivity.ACTION_FEATURE_REMOVE);
+		activity.setLabel(feature.getVersionedIdentifier().toString());
+		activity.setDate(new Date());
+
+		try {
+			IFeatureReference referenceToRemove = null;
+			ISiteFeatureReference[] featureRef = getSite().getFeatureReferences();
+			ISiteFeatureReference ref = getSite().getFeatureReference(feature);
+			for (int i = 0; i < featureRef.length; i++) {
+				if (featureRef[i].equals(ref)) {
+					referenceToRemove = featureRef[i];
+					break;
+				}
+			}
+
+			// we found a feature reference on the site matching the feature			
+			if (referenceToRemove != null) {
+				// Check if feature is unconfigured before we remove it
+				// our UI will check.
+				// For non-UI application, throw error is feature is configured
+				if (getConfigurationPolicy().isConfigured(referenceToRemove)) {
+					IFeature featureToRemove = referenceToRemove.getFeature(null);
+					String featureLabel = (featureToRemove == null) ? null : featureToRemove.getLabel();
+					throw Utilities.newCoreException(NLS.bind(Messages.ConfiguredSite_UnableToRemoveConfiguredFeature, (new String[] { featureLabel })), null);
+				}
+			} else {
+				throw Utilities.newCoreException(NLS.bind(Messages.ConfiguredSite_UnableToFindFeature, (new String[] { feature.getURL().toString() })),
+				null);
+			}
+
+			// remove the feature
+			getSite().remove(feature, monitor);
+			getConfigurationPolicy().removeFeatureReference(referenceToRemove);
+			// everything done ok
+			activity.setStatus(IActivity.STATUS_OK);
+			// notify listeners
+			Object[] siteListeners = listeners.getListeners();
+			for (int i = 0; i < siteListeners.length; i++) {
+				((IConfiguredSiteChangedListener) siteListeners[i]).featureRemoved(feature);
+			}
+		} catch (CoreException e) {
+			activity.setStatus(IActivity.STATUS_NOK);
+			throw e;
+		} finally {
+			IInstallConfiguration current = SiteManager.getLocalSite().getCurrentConfiguration();
+			((InstallConfiguration) current).addActivity(activity);
+		}
+	}
+
+	/*
+	 * @see IConfiguredSite#configure(IFeature) 
+	 */
+	public void configure(IFeature feature) throws CoreException {
+		configure(feature, null, true /*callInstallHandler*/
+		);
+	}
+
+	/*
+	 * 
+	 */
+	private void configure(IFeature feature, IFeatureReference[] optionalFeatures, boolean callInstallHandler) throws CoreException {
+
+		if (feature == null) {
+			UpdateCore.warn("Attempting to configure a null feature in site:" + getSite().getURL().toExternalForm()); //$NON-NLS-1$
+			return;
+		}
+
+		ConfigurationPolicy configPolicy = getConfigurationPolicy();
+		if (configPolicy == null)
+			return;
+
+		// bottom up approach, same configuredSite
+		IIncludedFeatureReference[] childrenRef = feature.getIncludedFeatureReferences();
+		if (optionalFeatures != null) {
+			childrenRef = childrenToConfigure(childrenRef, optionalFeatures);
+		}
+
+		for (int i = 0; i < childrenRef.length; i++) {
+			try {
+				IFeature child = childrenRef[i].getFeature(null);
+				configure(child, optionalFeatures, callInstallHandler);
+			} catch (CoreException e) {
+				// if not an optional feature, throw exception
+				if (!childrenRef[i].isOptional()) {
+					UpdateCore.warn("Unable to configure child feature: " + childrenRef[i] + " " + e); //$NON-NLS-1$ //$NON-NLS-2$
+					throw e;
+				}
+			}
+		}
+
+		// configure root feature 	
+		IFeatureReference featureReference = getSite().getFeatureReference(feature);
+		configPolicy.configure(featureReference, callInstallHandler, true);
+
+		// notify listeners
+		Object[] siteListeners = listeners.getListeners();
+		for (int i = 0; i < siteListeners.length; i++) {
+			((IConfiguredSiteChangedListener) siteListeners[i]).featureConfigured(feature);
+		}
+	}
+
+	/*
+	 * Return the optional children to configure
+	 * 
+	 * @param children all the nested features
+	 * @param optionalfeatures optional features to install
+	 * @return IFeatureReference[]
+	 */
+	private IIncludedFeatureReference[] childrenToConfigure(IIncludedFeatureReference[] children, IFeatureReference[] optionalfeatures) {
+
+		List childrenToInstall = new ArrayList();
+		for (int i = 0; i < children.length; i++) {
+			IIncludedFeatureReference optionalFeatureToConfigure = children[i];
+			if (!optionalFeatureToConfigure.isOptional()) {
+				childrenToInstall.add(optionalFeatureToConfigure);
+			} else {
+				for (int j = 0; j < optionalfeatures.length; j++) {
+					// must compare feature as optionalFeatures are from the install site
+					// where children are on the local site
+					try {
+						IFeature installedChildren = optionalfeatures[j].getFeature(null);
+						if (installedChildren.equals(optionalFeatureToConfigure.getFeature(null))) {
+							childrenToInstall.add(optionalFeatureToConfigure);
+							break;
+						}
+					} catch (CoreException e) {
+						UpdateCore.warn("", e); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+
+		IIncludedFeatureReference[] result = new IIncludedFeatureReference[childrenToInstall.size()];
+		if (childrenToInstall.size() > 0) {
+			childrenToInstall.toArray(result);
+		}
+
+		return result;
+	}
+
+	/*
+	 * @see IConfiguredSite#unconfigure(IFeature)
+	 */
+	public boolean unconfigure(IFeature feature) throws CoreException {
+		// the first call sould disable without checking for enable parent
+		return unconfigure(feature, true, false);
+	}
+
+	private boolean unconfigure(IFeature feature, boolean includePatches, boolean verifyEnableParent) throws CoreException {
+		IFeatureReference featureReference = getSite().getFeatureReference(feature);
+
+		if (featureReference == null) {
+			UpdateCore.warn("Unable to retrieve Feature Reference for feature" + feature); //$NON-NLS-1$
+			return false;
+		}
+
+		ConfigurationPolicy configPolicy = getConfigurationPolicy();
+		if (configPolicy == null)
+			return false;
+
+		// verify no enable parent
+		if (verifyEnableParent && !validateNoConfiguredParents(feature)) {
+			UpdateCore.warn("The feature " + feature.getVersionedIdentifier() + " to disable is needed by another enable feature"); //$NON-NLS-1$ //$NON-NLS-2$
+			return false;
+		}
+
+		boolean sucessfullyUnconfigured = false;
+		try {
+			sucessfullyUnconfigured = configPolicy.unconfigure(featureReference, true, true);
+		} catch (CoreException e) {
+			URL url = featureReference.getURL();
+			String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
+			UpdateCore.warn("Unable to unconfigure" + urlString, e); //$NON-NLS-1$
+			throw e;
+		}
+		if (sucessfullyUnconfigured) {
+			// 2.0.2: unconfigure patches that reference this feature.
+			// A patch is a feature that contains an import
+			// statement with patch="true" and an id/version
+			// that matches an already installed and configured
+			// feature. When patched feature is unconfigured,
+			// all the patches that reference it must be 
+			// unconfigured as well
+			// (in contrast, patched features can be
+			// configured without the patches).
+			if (includePatches)
+				unconfigurePatches(feature);
+
+			// top down approach, same configuredSite
+			IIncludedFeatureReference[] childrenRef = feature.getIncludedFeatureReferences();
+			for (int i = 0; i < childrenRef.length; i++) {
+				try {
+					IFeature child = childrenRef[i].getFeature(null); // disable the exact feature
+					unconfigure(child, includePatches, true); // check for parent as we should be the only parent.
+				} catch (CoreException e) {
+					// skip any bad children
+					UpdateCore.warn("Unable to unconfigure child feature: " + childrenRef[i] + " " + e); //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
+
+			// notify listeners
+			Object[] siteListeners = listeners.getListeners();
+			for (int i = 0; i < siteListeners.length; i++) {
+				IConfiguredSiteChangedListener listener = ((IConfiguredSiteChangedListener) siteListeners[i]);
+				listener.featureUnconfigured(feature);
+			}
+
+			return true;
+		} else {
+			URL url = featureReference.getURL();
+			String urlString = (url != null) ? url.toExternalForm() : "<no feature reference url>"; //$NON-NLS-1$
+			UpdateCore.warn("Unable to unconfigure:" + urlString); //$NON-NLS-1$
+			return false;
+		}
+	}
+
+	/*
+	 * Look for features that have an import reference
+	 * that points to this feature and where patch=true.
+	 * Unconfigure all the matching patches, but
+	 * do not do the same lookup for them
+	 * because patches cannot have patches themselves.
+	 */
+
+	private void unconfigurePatches(IFeature feature) {
+		IFeatureReference[] frefs = getConfiguredFeatures();
+		for (int i = 0; i < frefs.length; i++) {
+			IFeatureReference fref = frefs[i];
+			try {
+				IFeature candidate = fref.getFeature(null);
+				if (candidate.equals(feature))
+					continue;
+
+				if (UpdateUtils.isPatch(feature, candidate))
+					unconfigure(candidate, false, false);
+			} catch (CoreException e) {
+				UpdateCore.warn("", e); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/*
+	 * @see IConfiguredSite#getConfiguredFeatures()
+	 */
+	public IFeatureReference[] getConfiguredFeatures() {
+		if (isEnabled())
+			return getRawConfiguredFeatures();
+		else
+			return new ISiteFeatureReference[0];
+	}
+
+	/*
+	 * @see IConfiguredSite#getConfiguredFeatures()
+	 */
+	private IFeatureReference[] getRawConfiguredFeatures() {
+		ConfigurationPolicy configPolicy = getConfigurationPolicy();
+		if (configPolicy == null)
+			return new ISiteFeatureReference[0];
+
+		return configPolicy.getConfiguredFeatures();
+	}
+
+	/*
+	 * adds configured and unconfigured feature references
+	 */
+	public IFeatureReference[] getFeatureReferences() {
+
+		ConfigurationPolicy configPolicy = getConfigurationPolicy();
+		if (configPolicy == null)
+			return new ISiteFeatureReference[0];
+
+		IFeatureReference[] configuredFeatures = getConfiguredFeatures();
+		int confLen = configuredFeatures.length;
+		IFeatureReference[] unconfiguredFeatures = configPolicy.getUnconfiguredFeatures();
+		int unconfLen = unconfiguredFeatures.length;
+
+		IFeatureReference[] result = new IFeatureReference[confLen + unconfLen];
+		if (confLen > 0) {
+			System.arraycopy(configuredFeatures, 0, result, 0, confLen);
+		}
+		if (unconfLen > 0) {
+			System.arraycopy(unconfiguredFeatures, 0, result, confLen, unconfLen);
+		}
+
+		return result;
+	}
+
+	/*
+	 * Configure and unconfigure appropriate feature to
+	 * become 'like' currentConfiguration which is the configuration
+	 * the user wants to revert to.
+	 * 
+	 * All features from currentConfiguration should be configured
+	 */
+	public void revertTo(IConfiguredSite oldConfiguration, IProgressMonitor monitor, IProblemHandler handler) throws CoreException, InterruptedException {
+
+		ConfiguredSite oldConfiguredSite = (ConfiguredSite) oldConfiguration;
+
+		// retrieve the feature that were configured
+		IFeatureReference[] configuredFeatures = oldConfiguredSite.validConfiguredFeatures(handler);
+
+		for (int i = 0; i < configuredFeatures.length; i++) {
+			getConfigurationPolicy().configure(configuredFeatures[i], true, true);
+		}
+
+		// calculate all the features we have to unconfigure from the current state to this state
+		// in the history. 				
+		List featureToUnconfigure = oldConfiguredSite.calculateUnconfiguredFeatures(configuredFeatures);
+
+		// for each unconfigured feature check if it still exists
+		// if so add as unconfigured
+		Iterator iter = featureToUnconfigure.iterator();
+		while (iter.hasNext()) {
+			IFeatureReference element = (IFeatureReference) iter.next();
+			try {
+				// do not log activity
+				getConfigurationPolicy().unconfigure(element, true, true);
+			} catch (CoreException e) {
+				// log no feature to unconfigure
+				String url = element.getURL().toString();
+				ISite site = element.getSite();
+				String siteString = (site != null) ? site.getURL().toExternalForm() : Messages.ConfiguredSite_NoSite; 
+				UpdateCore.warn(NLS.bind(Messages.ConfiguredSite_CannotFindFeatureToUnconfigure, (new String[] { url, siteString })), e); 
+			}
+		}
+		//} // end USER_EXCLUDE
+	}
+
+	/*
+	 * We have to keep our configured feature
+	 * check if they are all valid
+	 * Return the valid configured features
+	 */
+	private IFeatureReference[] validConfiguredFeatures(IProblemHandler handler) throws InterruptedException {
+
+		IFeatureReference[] configuredFeatures = getConfiguredFeatures();
+		if (configuredFeatures != null) {
+			for (int i = 0; i < configuredFeatures.length; i++) {
+				IFeature feature = null;
+
+				// attempt to access the feature
+				try {
+					feature = configuredFeatures[i].getFeature(null);
+				} catch (CoreException e) {
+					// notify we cannot find the feature
+					UpdateCore.warn(null, e);
+					String featureString = configuredFeatures[i].getURL().toExternalForm();
+					if (!handler.reportProblem(NLS.bind(Messages.ConfiguredSite_CannotFindFeatureToConfigure, (new String[] { featureString })))) {
+						throw new InterruptedException();
+					}
+				}
+
+				// verify all the plugins still exist
+				if (feature != null) {
+					// get plugin identifier
+					List sitePluginIdentifiers = new ArrayList();
+					ISite site = feature.getSite();
+					IPluginEntry[] sitePluginEntries = null;
+
+					if (site != null) {
+						sitePluginEntries = site.getPluginEntries();
+						for (int index = 0; index < sitePluginEntries.length; index++) {
+							IPluginEntry entry = sitePluginEntries[index];
+							sitePluginIdentifiers.add(entry.getVersionedIdentifier());
+						}
+					}
+
+					if (sitePluginEntries.length > 0) {
+						IPluginEntry[] featurePluginEntries = feature.getPluginEntries();
+						for (int index = 0; index < featurePluginEntries.length; index++) {
+							IPluginEntry currentFeaturePluginEntry = featurePluginEntries[index];
+							if (!contains(currentFeaturePluginEntry.getVersionedIdentifier(), sitePluginIdentifiers)) {
+								// the plugin defined by the feature
+								// doesn't seem to exist on the site
+								String msg = "Error verifying existence of plugin:" + currentFeaturePluginEntry.getVersionedIdentifier().toString(); //$NON-NLS-1$
+								UpdateCore.log(msg, new Exception());
+
+								String siteString = (site != null) ? site.getURL().toExternalForm() : Messages.ConfiguredSite_NoSite;	
+								String errorLabel = NLS.bind(Messages.ConfiguredSite_CannotFindPluginEntry, (new String[] { currentFeaturePluginEntry.getVersionedIdentifier().toString(), siteString }));
+								if (handler == null) {
+									throw new InterruptedException(errorLabel);
+								}
+								if (!handler.reportProblem(errorLabel)) {
+									throw new InterruptedException();
+								}
+							} // end if not found in site
+						} // end for
+					}
+				}
+			} // end for configured feature
+		}
+		return configuredFeatures;
+	}
+
+	/*
+	 * We are in the process of calculating the delta between what was configured in the current
+	 * configuration that is not configured now
+	 * 
+	 * we have to figure out what feature have been unconfigured for the whole
+	 * history between current and us... 
+	 * 
+	 * is it as simple as  get all configured, and unconfigured,
+	 * the do the delta with what should be configured
+	 * 
+	 */
+	private List calculateUnconfiguredFeatures(IFeatureReference[] configuredFeatures) throws CoreException {
+
+		Set featureToUnconfigureSet = new HashSet();
+
+		// loop for all history
+		// try to see if the configured site existed
+		// if it does, get the unconfigured features 
+		// and the configured one
+		IInstallConfiguration[] history = SiteManager.getLocalSite().getConfigurationHistory();
+
+		for (int i = 0; i < history.length; i++) {
+			IInstallConfiguration element = history[i];
+			IConfiguredSite[] configSites = element.getConfiguredSites();
+			for (int j = 0; j < configSites.length; j++) {
+				ConfiguredSite configSite = (ConfiguredSite) configSites[j];
+				if (configSite.getSite().equals(getSite())) {
+					featureToUnconfigureSet.addAll(Arrays.asList(configSite.getConfigurationPolicy().getUnconfiguredFeatures()));
+					featureToUnconfigureSet.addAll(Arrays.asList(configSite.getConfigurationPolicy().getConfiguredFeatures()));
+				}
+			}
+		}
+
+		// remove the unconfigured feature we found that are now to be configured 
+		// (they may have been unconfigured in the past, but the revert makes them configured)
+		List featureToUnconfigureList = remove(configuredFeatures, featureToUnconfigureSet);
+
+		return featureToUnconfigureList;
+	}
+
+	/*
+	 * Utilities: Remove an array of feature references
+	 * from a list
+	 */
+	private List remove(IFeatureReference[] featureRefs, Set set) {
+		List result = new ArrayList();
+
+		if (set == null)
+			return result;
+
+		// if an element of the list is NOT found in the array,
+		// add it to the result list			
+		Iterator iter = set.iterator();
+		while (iter.hasNext()) {
+			IFeatureReference element = (IFeatureReference) iter.next();
+			boolean found = false;
+			for (int i = 0; i < featureRefs.length; i++) {
+				if (element.equals(featureRefs[i])) {
+					found = true;
+				}
+			}
+
+			if (!found)
+				result.add(element);
+		}
+		return result;
+	}
+
+	/*
+	 * I have issues when running list.contain(versionedIdentifier)
+	 * The code runs the Object.equals instead of the VersionedIdentifier.equals
+	 */
+	private boolean contains(VersionedIdentifier id, List list) {
+		boolean found = false;
+		if (list != null && !list.isEmpty()) {
+			Iterator iter = list.iterator();
+			while (iter.hasNext() && !found) {
+				VersionedIdentifier element = (VersionedIdentifier) iter.next();
+				if (element.equals(id)) {
+					found = true;
+				}
+			}
+		}
+		return found;
+	}
+
+	/*
+	 * 
+	 */
+	public ConfigurationPolicy getConfigurationPolicy() {
+		return (ConfigurationPolicy) getConfigurationPolicyModel();
+	}
+
+	/*
+	 * 
+	 */
+	public ISite getSite() {
+		return (ISite) getSiteModel();
+	}
+
+	/*
+	 * 
+	 */
+	public IInstallConfiguration getInstallConfiguration() {
+		return (IInstallConfiguration) getInstallConfigurationModel();
+	}
+
+	/*
+	 * 
+	 */
+	public IStatus getBrokenStatus(IFeature feature) {
+
+		IStatus featureStatus = createStatus(IStatus.OK, IFeature.STATUS_HAPPY, "", null); //$NON-NLS-1$
+
+		// check the Plugins of all the features
+		// every plugin of the feature must be on the site
+		IPluginEntry[] siteEntries = getSite().getPluginEntries();
+		IPluginEntry[] featuresEntries = feature.getPluginEntries();
+		IPluginEntry[] result = UpdateManagerUtils.diff(featuresEntries, siteEntries);
+		if (result != null && (result.length != 0)) {
+			String msg = Messages.SiteLocal_FeatureUnHappy; 
+			MultiStatus multi = new MultiStatus(featureStatus.getPlugin(), IFeature.STATUS_UNHAPPY, msg, null);
+
+			for (int k = 0; k < result.length; k++) {
+				VersionedIdentifier id = result[k].getVersionedIdentifier();
+				Object[] values = new String[] { "", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+				if (id != null) {
+					values = new Object[] { id.getIdentifier(), id.getVersion()};
+				}
+				String msg1 = NLS.bind(Messages.ConfiguredSite_MissingPluginsBrokenFeature, values);
+				UpdateCore.warn(msg1);
+				IStatus status = createStatus(IStatus.ERROR, IFeature.STATUS_UNHAPPY, msg1, null);
+				multi.add(status);
+			}
+			return multi;
+		}
+
+		// check os, arch, and ws
+
+		String msg = Messages.SiteLocal_FeatureHappy; 
+		return createStatus(IStatus.OK, IFeature.STATUS_HAPPY, msg, null);
+	}
+
+	/*
+	 * 
+	 */
+	public boolean isConfigured(IFeature feature) {
+		if (!isEnabled())
+			return false;
+
+		if (getConfigurationPolicy() == null)
+			return false;
+		IFeatureReference featureReference = getSite().getFeatureReference(feature);
+		if (featureReference == null) {
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_WARNINGS)
+				UpdateCore.warn("Unable to retrieve featureReference for feature:" + feature); //$NON-NLS-1$
+			return false;
+		}
+		return getConfigurationPolicy().isConfigured(featureReference);
+	}
+
+	/**
+	 * @see Object#toString()
+	 */
+	public String toString() {
+		if (getSite() == null)
+			return "No Site"; //$NON-NLS-1$
+		if (getSite().getURL() == null)
+			return "No URL"; //$NON-NLS-1$
+		return getSite().getURL().toExternalForm();
+	}
+
+	/**
+	 * @see IConfiguredSite#verifyUpdatableStatus()
+	 */
+	public IStatus verifyUpdatableStatus() {
+
+		if (verifyStatus != null)
+			return verifyStatus;
+
+		URL siteURL = getSite().getURL();
+		if (siteURL == null) {
+			verifyStatus = createStatus(IStatus.ERROR, Messages.ConfiguredSite_SiteURLNull, null); 
+			return verifyStatus;
+		}
+
+		if (!"file".equalsIgnoreCase(siteURL.getProtocol())) { //$NON-NLS-1$
+			verifyStatus = createStatus(IStatus.ERROR, Messages.ConfiguredSite_NonLocalSite, null); 
+			return verifyStatus;
+		}
+
+		String siteLocation = siteURL.getFile();
+		File file = new File(siteLocation);
+
+		// get the product name of the private marker
+		// if there is no private marker, check if the site is contained in another site
+		// if there is a marker and this is a different product, return false
+		// otherwise don't check if we are contained in another site
+		String productName = getProductName(file);
+		if (productName != null) {
+			if (!productName.equals(getProductIdentifier("id", getProductFile()))) { //$NON-NLS-1$
+				verifyStatus = createStatus(IStatus.ERROR, NLS.bind(Messages.ConfiguredSite_NotSameProductId, (new String[] { productName })), null);
+				return verifyStatus;
+			}
+		} else {
+			File container = getSiteContaining(file);
+			// allow the install location to pass even though it looks like this
+			// site is contained in another site
+			if (container != null && !siteLocation.equals(Platform.getInstallLocation().getURL().getFile())) {
+				verifyStatus = createStatus(IStatus.ERROR, NLS.bind(Messages.ConfiguredSite_ContainedInAnotherSite, (new String[] { container.getAbsolutePath() })), null);
+				return verifyStatus;
+			}
+		}
+
+		if (!canWrite(file)) {
+			verifyStatus = createStatus(IStatus.ERROR, Messages.ConfiguredSite_ReadOnlySite, null); 
+			return verifyStatus;
+		}
+
+		verifyStatus = createStatus(IStatus.OK, "", null); //$NON-NLS-1$
+		setUpdatable(true);
+		return verifyStatus;
+	}
+
+	/*
+	 * Verify we can write on the file system
+	 */
+    public static boolean canWrite(File file) {
+        if (file.canWrite() == false)
+            return false;
+
+        if (!file.isDirectory())
+            return false;
+
+        File fileTest = null;
+        try {
+        	// we use the .dll suffix to properly test on Vista virtual directories
+        	// on Vista you are not allowed to write executable files on virtual directories like "Program Files"
+            fileTest = File.createTempFile("writtableArea", ".dll", file); //$NON-NLS-1$ //$NON-NLS-2$
+        } catch (IOException e) {
+            //If an exception occurred while trying to create the file, it means that it is not writable
+            return false;
+        } finally {
+            if (fileTest != null)
+                fileTest.delete();
+        }
+        return true;
+    }
+
+	/*
+	 * Check if the directory contains a marker
+	 * if not ask all directory children to check
+	 * if one validates the condition, returns the marker
+	 */
+	private static File getSiteContaining(File file) {
+
+		if (file == null)
+			return null;
+
+		UpdateCore.warn("IsContained: Checking for markers at:" + file); //$NON-NLS-1$
+		if (file.exists() && file.isDirectory()) {
+			File productFile = new File(file, PRODUCT_SITE_MARKER);
+			File extensionFile = new File(file, EXTENSION_SITE_MARKER);
+			if (productFile.exists() || extensionFile.exists())
+				return file;
+//			// do not check if a marker exists in the current but start from the parent
+//			// the current is analyze by getProductname()
+//			if (file.getParentFile() != null) {
+//				File privateFile = new File(file.getParentFile(), PRIVATE_SITE_MARKER);
+//				if (privateFile.exists())
+//					return file.getParentFile();
+//			}
+		}
+		return getSiteContaining(file.getParentFile());
+	}
+
+	/*
+	 * Returns the name of the product if the identifier of the private Site markup is not
+	 * the same as the identifier of the product the workbench was started with.
+	 * If the product is the same, return null.
+	 */
+	private static String getProductName(File file) {
+
+		if (file == null)
+			return null;
+
+		File markerFile = new File(file, EXTENSION_SITE_MARKER );
+		if (!markerFile.exists()) {
+			return null;
+		}
+
+		File productFile = getProductFile();
+		String productId = null;
+		String privateId = null;
+		if (productFile != null) {
+			productId = getProductIdentifier("id", productFile); //$NON-NLS-1$
+			privateId = getProductIdentifier("id", markerFile); //$NON-NLS-1$
+			if (productId == null) {
+				UpdateCore.warn("Product ID is null at:" + productFile); //$NON-NLS-1$
+				return null;
+			}
+			if (!productId.equalsIgnoreCase(privateId)) {
+				UpdateCore.warn("Product id at" + productFile + " Different than:" + markerFile); //$NON-NLS-1$ //$NON-NLS-2$
+				String name = getProductIdentifier("name", markerFile); //$NON-NLS-1$
+				String version = getProductIdentifier("version", markerFile); //$NON-NLS-1$
+				String markerID = (name == null) ? version : name + ":" + version; //$NON-NLS-1$
+				if (markerID == null)
+					markerID = ""; //$NON-NLS-1$
+				return markerID;
+			} else {
+				return privateId;
+			}
+		} else {
+			UpdateCore.warn("Product Marker doesn't exist:" + productFile); //$NON-NLS-1$
+		}
+
+		return null;
+	}
+
+	/*
+	 * Returns the identifier of the product from the property file
+	 */
+	private static String getProductIdentifier(String identifier, File propertyFile) {
+		String result = null;
+		if (identifier == null)
+			return result;
+		InputStream in = null;
+		try {
+			in = new FileInputStream(propertyFile);
+			PropertyResourceBundle bundle = new PropertyResourceBundle(in);
+			result = bundle.getString(identifier);
+		} catch (IOException e) {
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_INSTALL)
+				UpdateCore.debug("Exception reading property file:" + propertyFile); //$NON-NLS-1$
+		} catch (MissingResourceException e) {
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_INSTALL)
+				UpdateCore.debug("Exception reading '" + identifier + "' from property file:" + propertyFile); //$NON-NLS-1$ //$NON-NLS-2$
+		} finally {
+			if (in != null)
+				try {
+					in.close();
+				} catch (IOException e1) {
+				}
+		}
+		return result;
+	}
+
+	/*
+	 * Returns the identifier of the product from the property file
+	 */
+	private static File getProductFile() {
+
+		String productInstallDirectory = ConfiguratorUtils.getInstallURL().getFile();
+		if (productInstallDirectory != null) {
+			File productFile = new File(productInstallDirectory, PRODUCT_SITE_MARKER);
+			if (productFile.exists()) {
+				return productFile;
+			} else {
+				UpdateCore.warn("Product marker doesn't exist:" + productFile); //$NON-NLS-1$
+			}
+		} else {
+			UpdateCore.warn("Cannot retrieve install URL from BootLoader"); //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	/*
+	 * 
+	 */
+	/*package*/
+	boolean createPrivateSiteMarker() {
+		URL siteURL = getSite().getURL();
+		if (siteURL == null) {
+			UpdateCore.warn("Unable to create marker. The Site url is null."); //$NON-NLS-1$
+			return false;
+		}
+
+		if (!"file".equalsIgnoreCase(siteURL.getProtocol())) { //$NON-NLS-1$
+			UpdateCore.warn("Unable to create private marker. The Site is not on the local file system."); //$NON-NLS-1$
+			return false;
+		}
+
+		String siteLocation = siteURL.getFile();
+		File productFile = getProductFile();
+		boolean success = false;
+		if (productFile != null) {
+			String productId = getProductIdentifier("id", productFile); //$NON-NLS-1$
+			String productName = getProductIdentifier("name", productFile); //$NON-NLS-1$
+			String productVer = getProductIdentifier("version", productFile); //$NON-NLS-1$
+			if (productId != null) {
+				File file = new File(siteLocation, EXTENSION_SITE_MARKER);
+				if (!file.exists()) {
+					OutputStream out = null;
+					OutputStreamWriter outWriter = null;
+					try {
+						out = new FileOutputStream(file);
+						outWriter = new OutputStreamWriter(out, "UTF8"); //$NON-NLS-1$
+						outWriter.write("id=" + productId+"\n"); //$NON-NLS-1$ //$NON-NLS-2$
+						if (productName != null)
+							outWriter.write("name=" + productName+"\n"); //$NON-NLS-1$ //$NON-NLS-2$
+						if (productVer != null)
+							outWriter.write("version=" + productVer+"\n"); //$NON-NLS-1$ //$NON-NLS-2$
+						success = true;
+						justCreated = true;
+					} catch (Exception e) {
+						UpdateCore.warn("Unable to create private Marker at:" + file, e); //$NON-NLS-1$
+					} finally {
+						try {
+							if (outWriter != null)
+								outWriter.close();
+						} catch (IOException e1) {
+						}
+						try {
+							if (out != null)
+								out.close();
+						} catch (IOException e2) {
+						}
+					}
+				}
+			}
+		}
+		return success;
+	}
+
+
+	/*
+	 * Returns true if the directory of the Site contains
+	 * .eclipseextension
+	 */
+	public boolean isExtensionSite() {
+		return containsMarker(EXTENSION_SITE_MARKER);
+	}
+
+	/*
+	 * Returns true if the directory of the Site contains
+	 * .eclipseextension
+	 */
+	public boolean isProductSite() {
+		return containsMarker(PRODUCT_SITE_MARKER);
+	}
+
+	/*
+	 * Returns true if the directory of the Site contains
+	 * .eclipseextension
+	 */
+	public boolean isPrivateSite() {
+		return isExtensionSite();
+	}
+
+	/*
+	 * 
+	 */
+	private boolean containsMarker(String marker) {
+		ISite site = getSite();
+		if (site == null) {
+			UpdateCore.warn("Contains Markers:The site is null"); //$NON-NLS-1$
+			return false;
+		}
+
+		URL url = site.getURL();
+		if (url == null) {
+			UpdateCore.warn("Contains Markers:Site URL is null"); //$NON-NLS-1$
+			return false;
+		}
+		if (!"file".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
+			UpdateCore.warn("Contains Markers:Non file protocol"); //$NON-NLS-1$
+			return false;
+		}
+		File file = new File(url.getFile());
+		if (!file.exists()) {
+			UpdateCore.warn("Contains Markers:The site doesn't exist:" + file); //$NON-NLS-1$
+			return false;
+		}
+		File extension = new File(file, marker);
+		if (!extension.exists()) {
+			UpdateCore.warn("Contains Markers:The extensionfile does not exist:" + extension); //$NON-NLS-1$
+			return false;
+		}
+		return true;
+	}
+
+	/*
+	 * Returns true if the Site is already natively linked
+	 */
+	public boolean isNativelyLinked() throws CoreException {
+		String platformString = getPlatformURLString();
+		if (platformString == null) {
+			UpdateCore.warn("Unable to retrieve platformString"); //$NON-NLS-1$
+			return false;
+		}
+
+		URL siteURL = null;
+		try {
+			// check if the site exists and is updateable
+			// update configSite
+			URL urlToCheck = new URL(platformString);
+			IPlatformConfiguration runtimeConfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+			IPlatformConfiguration.ISiteEntry entry = runtimeConfig.findConfiguredSite(urlToCheck);
+			if (entry != null) {
+				return entry.isNativelyLinked();
+			} else {
+				UpdateCore.warn("Unable to retrieve site:" + platformString + " from platform."); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+
+			// check by comparing URLs
+			IPlatformConfiguration.ISiteEntry[] sites = runtimeConfig.getConfiguredSites();
+			for (int i = 0; i < sites.length; i++) {
+				siteURL = sites[i].getURL();
+				URL resolvedURL = FileLocator.resolve(siteURL);
+				if (UpdateManagerUtils.sameURL(resolvedURL, urlToCheck))
+					return true;
+			}
+		} catch (MalformedURLException e) {
+			String msg = NLS.bind(Messages.ConfiguredSite_UnableResolveURL, (new String[] { platformString }));
+			throw Utilities.newCoreException(msg, e);
+		} catch (IOException e) {
+			String msg = NLS.bind(Messages.ConfiguredSite_UnableToAccessSite, (new Object[] { siteURL }));
+			throw Utilities.newCoreException(msg, e);
+		}
+
+		return false;
+	}
+
+	/*
+	* we have to check that no configured/enable parent include this feature
+	*/
+	private boolean validateNoConfiguredParents(IFeature feature) throws CoreException {
+		if (feature == null) {
+			UpdateCore.warn("ConfigurationPolicy: validate Feature is null"); //$NON-NLS-1$
+			return true;
+		}
+
+		IFeatureReference[] parents = UpdateManagerUtils.getParentFeatures(feature, getConfiguredFeatures(), false);
+		return (parents.length == 0);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ContentConsumer.java
new file mode 100644
index 0000000..5278a7c
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ContentConsumer.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+
+import org.eclipse.update.core.*;
+
+/**
+ * A default implementation for IFeatureContentConsumer
+ * </p>
+ * @since 2.0
+ */
+
+public abstract class ContentConsumer implements IContentConsumer {
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/CoreExceptionWithRootCause.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/CoreExceptionWithRootCause.java
new file mode 100644
index 0000000..d822959
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/CoreExceptionWithRootCause.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+public class CoreExceptionWithRootCause extends CoreException {
+
+	private static final long serialVersionUID = 6832993239926767403L;
+	
+	private Throwable e = null;
+	
+	public CoreExceptionWithRootCause(IStatus status) {
+		super(status);
+	}
+
+	public void setRootException(Throwable e) {
+		this.e = e;	
+	}
+
+	public Throwable getRootException() {
+		return e;
+	}
+
+	
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DefaultInstallHandler.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DefaultInstallHandler.java
new file mode 100644
index 0000000..5029b04
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DefaultInstallHandler.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+
+import java.io.*;
+import java.util.jar.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.JarContentReference.*;
+import org.eclipse.update.core.model.*;
+
+/**
+ * Default Implementation of InstallHandler
+ */
+public class DefaultInstallHandler extends BaseInstallHandler {
+
+	/*
+	 * @see IInstallHandler#nonPluginDataDownloaded(INonPluginEntry[], IVerificationListener)
+	 */
+	public void nonPluginDataDownloaded(
+		INonPluginEntry[] nonPluginData,
+		IVerificationListener listener)
+		throws CoreException {
+
+		// verify non-plugin archives. The DefaultInstallHandler assumes
+		// the verifier associated with the feature is able to verify the
+		// data archives.
+		if (nonPluginData == null || nonPluginData.length == 0)
+			return;
+
+		this.nonPluginEntries = nonPluginData;
+		IFeatureContentProvider provider = this.feature.getFeatureContentProvider();
+		IVerifier verifier = provider.getVerifier();
+		if (verifier == null)
+			return;
+
+		for (int i = 0; i < this.nonPluginEntries.length; i++) {
+			ContentReference[] archives =
+				provider.getNonPluginEntryArchiveReferences(nonPluginEntries[i], this.monitor);
+			IVerificationResult result;
+			for (int j = 0; j < archives.length; j++) {
+
+				// see if the data entry is a jar
+				ContentReference archive = archives[j];
+				if (!(archives[j] instanceof JarContentReference)
+					&& archives[j].getIdentifier().endsWith(".jar")) { //$NON-NLS-1$
+					try {
+						archive =
+							new JarContentReference(archives[j].getIdentifier(), archives[j].asFile());
+					} catch (IOException e) {
+					}
+				}
+
+				result = verifier.verify(this.feature, archive, false, this.monitor);
+				if (result != null)
+					promptForVerification(result, listener);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#completeInstall(IFeatureContentConsumer)
+	 */
+	public void completeInstall(IFeatureContentConsumer consumer)
+		throws CoreException {
+
+		// plugins have been installed. Check to see if we have any
+		// non-plugin entries that need to be handled.
+		if (this.nonPluginEntries == null || this.nonPluginEntries.length == 0)
+			return;
+
+		// install non-plugin archives
+		IFeatureContentProvider provider = this.feature.getFeatureContentProvider();
+		for (int i = 0; i < this.nonPluginEntries.length; i++) {
+			ContentReference[] archive =
+				provider.getNonPluginEntryArchiveReferences(nonPluginEntries[i], this.monitor);
+			IContentConsumer nonPluginConsumer = consumer.open(nonPluginEntries[i]);
+			for (int j = 0; j < archive.length; j++) {
+				String id = archive[j].getIdentifier();
+				if (id.endsWith(".jar")) { //$NON-NLS-1$
+					// the non-plugin archive is a jar. Unpack it into
+					// a directory constructed using the archive id
+					try {
+						final String prefix = id.substring(0, id.length() - 4) + "/"; //$NON-NLS-1$
+						JarContentReference jarRef = new JarContentReference("", archive[j].asFile()); //$NON-NLS-1$
+						ContentSelector selector = new ContentSelector() {
+							public String defineIdentifier(JarEntry entry) {
+								if (entry == null)
+									return null;
+								else
+									return prefix + entry.getName();
+							}
+						};
+						ContentReference[] entries = jarRef.peek(selector, this.monitor);
+						for (int k = 0; k < entries.length; k++) {
+							nonPluginConsumer.store(entries[k], this.monitor);
+						}
+					} catch (IOException e) {
+						throw Utilities
+							.newCoreException(NLS.bind(Messages.JarVerificationService_CancelInstall, (new String[] { id })),
+						e);
+					}
+
+				} else {
+					// the non-plugin archive is not a jar. Install it asis.
+					nonPluginConsumer.store(archive[j], this.monitor);
+				}
+			}
+			nonPluginConsumer.close();
+		}
+	}
+
+	/*
+	 * 
+	 */
+	private void promptForVerification(
+		IVerificationResult verificationResult,
+		IVerificationListener listener)
+		throws CoreException {
+
+		if (listener == null)
+			return;
+		int result = listener.prompt(verificationResult);
+
+		if (result == IVerificationListener.CHOICE_ABORT) {
+			Exception e = verificationResult.getVerificationException();
+			throw new InstallAbortedException(Messages.JarVerificationService_CancelInstall,e); 
+		}
+		if (result == IVerificationListener.CHOICE_ERROR) {
+			throw Utilities
+				.newCoreException(Messages.JarVerificationService_UnsucessfulVerification, 
+			verificationResult.getVerificationException());
+		}
+
+		return;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DeltaInstallHandler.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DeltaInstallHandler.java
new file mode 100644
index 0000000..d92d735
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DeltaInstallHandler.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.core;
+
+import org.eclipse.core.runtime.IStatus;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.update.core.BaseInstallHandler;
+import org.eclipse.update.core.ContentReference;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureContentConsumer;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.PluginEntry;
+import org.eclipse.update.core.Site;
+import org.eclipse.update.internal.operations.UpdateUtils;
+
+/**
+ * Install handler for partial plugin delivery: copy delta content from old plugin into the new one.
+ * The new plugin should only contain files that have changed.
+ */
+public class DeltaInstallHandler extends BaseInstallHandler {
+	private final static String PLUGIN_XML = "plugin.xml"; //$NON-NLS-1$
+	private final static String FRAGMENT_XML = "fragment.xml"; //$NON-NLS-1$
+	private final static String META_MANIFEST = "META-INF/MANIFEST.MF"; //$NON-NLS-1$
+
+	protected IFeature oldFeature;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#completeInstall(org.eclipse.update.core.IFeatureContentConsumer)
+	 */
+	public void completeInstall(IFeatureContentConsumer consumer)
+		throws CoreException {
+		try {
+			if (pluginEntries == null)
+				return;
+
+			if (!feature.isPatch()) {
+				// Get the old feature
+				IFeature[] oldFeatures = UpdateUtils
+						.getInstalledFeatures(feature);
+				if (oldFeatures.length == 0)
+					return;
+				oldFeature = oldFeatures[0];
+			} else {
+				oldFeature = UpdateUtils.getPatchedFeature(feature);
+				if (oldFeature == null) {
+					return;
+				}
+			}
+			
+			IPluginEntry[] oldPlugins = oldFeature.getPluginEntries();
+			for (int i = 0; i < pluginEntries.length; i++) {
+				IPluginEntry newPlugin = pluginEntries[i];
+				IPluginEntry oldPlugin =
+					getPluginEntry(
+						oldPlugins,
+						newPlugin.getVersionedIdentifier().getIdentifier());
+				if (oldPlugin == null)
+					continue;
+				try {
+					overlayPlugin(oldPlugin, newPlugin, consumer);
+				} catch (IOException e) {
+					throw new CoreException(
+						new Status(
+							IStatus.ERROR,
+							UpdateUtils.getPluginId(),
+							1,
+							"", //$NON-NLS-1$
+							e));
+				}
+			}
+		} finally {
+			//if (contentConsumer != null)
+			//	contentConsumer.close();
+		}
+	}
+
+	protected IPluginEntry getPluginEntry(IPluginEntry[] plugins, String id) {
+		for (int i = 0; i < plugins.length; i++)
+			if (plugins[i].getVersionedIdentifier().getIdentifier().equals(id))
+				return plugins[i];
+		return null;
+	}
+
+	protected boolean referenceExists(
+		ContentReference[] references,
+		ContentReference ref) {
+		String id = ref.getIdentifier();
+		if (id == null)
+			return false;
+
+		for (int i = 0; i < references.length; i++)
+			if (id.equals(references[i].getIdentifier()))
+				return true;
+		return false;
+	}
+
+	protected void overlayPlugin(
+		IPluginEntry oldPlugin,
+		IPluginEntry newPlugin,
+		IFeatureContentConsumer consumer)
+		throws CoreException, IOException {
+		if(newPlugin instanceof PluginEntry && !((PluginEntry)newPlugin).isUnpack()){
+			// partial plug-ins (in patches) must always be unpacked
+			return;
+		}
+		
+		// copy the content of the old plugin over the new one, but only
+		// those files that do not exist on the target
+		ContentReference[] oldReferences =
+			oldFeature
+				.getFeatureContentProvider()
+				.getPluginEntryContentReferences(
+				oldPlugin,
+				null);
+		ContentReference[] newReferences =
+			feature
+				.getFeatureContentProvider()
+				.getPluginEntryContentReferences(
+				newPlugin,
+				null);
+
+		URL newURL = new URL(consumer.getFeature().getSite().getURL(),
+				Site.DEFAULT_PLUGIN_PATH
+						+ newPlugin.getVersionedIdentifier().toString());
+		String pluginPath = newURL.getFile();
+		for (int i = 0; i < oldReferences.length; i++) {
+			if (isPluginManifest(oldReferences[i])
+				|| referenceExists(newReferences, oldReferences[i]))
+				continue;
+
+			InputStream input = null;
+			try {
+				input = oldReferences[i].getInputStream();
+				File targetFile =
+					new File(pluginPath, oldReferences[i].getIdentifier());
+				UpdateManagerUtils.copyToLocal(
+					input,
+					targetFile.getAbsolutePath(),
+					null);
+				UpdateManagerUtils.checkPermissions(
+					oldReferences[i],
+					pluginPath);
+				// 20305
+			} catch (IOException e) {
+				continue;
+			} finally {
+				if(input != null){
+					try{
+						input.close();
+					} catch (IOException ioe) {
+					}
+				}
+			}
+		}
+	}
+
+	protected boolean isPluginManifest(ContentReference ref) {
+		String id = ref.getIdentifier();
+		return PLUGIN_XML.equals(id) || FRAGMENT_XML.equals(id) || META_MANIFEST.equals(id);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/Digest.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/Digest.java
new file mode 100644
index 0000000..27e1616
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/Digest.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.JarContentReference;
+import org.eclipse.update.core.model.FeatureModel;
+import org.xml.sax.SAXException;
+
+public class Digest {
+	
+	private URL source;
+	private File localSource;
+	private JarFile digestJar;
+	private InputStream inputStream;
+	
+
+	public Digest(URL source){
+		this.source = source;
+	}
+	
+	public FeatureModel[] parseDigest() throws IOException, CoreException, SAXException {
+		DigestContentProvider digestContentProvider = new DigestContentProvider(source);
+		localSource = digestContentProvider.asLocalReference(new JarContentReference( null, source), null).asFile();
+		digestJar = new JarFile(localSource);
+		
+		ZipEntry digestEntry = digestJar.getEntry("digest.xml"); //$NON-NLS-1$
+		
+		if (digestEntry != null) {
+			inputStream = digestJar.getInputStream(digestEntry);
+			DigestParser digest = new DigestParser();
+			digest.init(new LiteFeatureFactory());
+			return digest.parse(inputStream);
+		} else {
+			throw new CoreException(null);
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DigestContentProvider.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DigestContentProvider.java
new file mode 100644
index 0000000..ec848aa
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DigestContentProvider.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.ContentReference;
+import org.eclipse.update.core.FeatureContentProvider;
+import org.eclipse.update.core.INonPluginEntry;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.IVerifier;
+import org.eclipse.update.core.InstallMonitor;
+
+public class DigestContentProvider extends FeatureContentProvider {
+
+	public DigestContentProvider(URL base) {
+		super(base);
+		// TODO Auto-generated constructor stub
+	}
+	
+	
+	public ContentReference asLocalReference( ContentReference ref,
+			InstallMonitor monitor) throws IOException, CoreException {
+		return super.asLocalReference(ref, monitor);
+	}
+
+	public ContentReference[] getArchiveReferences(InstallMonitor monitor)
+			throws CoreException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public ContentReference[] getFeatureEntryArchiveReferences(
+			InstallMonitor monitor) throws CoreException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public ContentReference[] getFeatureEntryContentReferences(
+			InstallMonitor monitor) throws CoreException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public ContentReference getFeatureManifestReference(InstallMonitor monitor)
+			throws CoreException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public ContentReference[] getNonPluginEntryArchiveReferences(
+			INonPluginEntry nonPluginEntry, InstallMonitor monitor)
+			throws CoreException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public ContentReference[] getPluginEntryArchiveReferences(
+			IPluginEntry pluginEntry, InstallMonitor monitor)
+			throws CoreException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public ContentReference[] getPluginEntryContentReferences(
+			IPluginEntry pluginEntry, InstallMonitor monitor)
+			throws CoreException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public IVerifier getVerifier() throws CoreException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DigestParser.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DigestParser.java
new file mode 100644
index 0000000..ca0782b
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/DigestParser.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.update.core.model.FeatureModelFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class DigestParser extends DefaultHandler {
+
+	private InternalFeatureParser featureParser;
+	
+	private ArrayList featureModels;
+
+	private SAXParser parser;
+
+	private FeatureModelFactory factory;
+
+	private String location;
+	
+	private final static SAXParserFactory parserFactory =
+		SAXParserFactory.newInstance();
+	
+	public DigestParser() {
+		super();
+		featureParser = new InternalFeatureParser();
+		try {
+			parserFactory.setNamespaceAware(true);
+			this.parser = parserFactory.newSAXParser();
+		} catch (ParserConfigurationException e) {
+			UpdateCore.log(e);
+		} catch (SAXException e) {
+			UpdateCore.log(e);
+		}
+	}
+
+	public void init(FeatureModelFactory factory) {
+		init(factory, null);
+	}
+    
+    /**
+     * @param factory
+     * @param location
+     * @since 3.1
+     */
+    public void init(FeatureModelFactory factory, String location) {
+    	
+    	this.factory = factory;
+    	this.location = location;
+    	factory = new LiteFeatureFactory();
+    	featureModels = new ArrayList();
+    	featureParser.internalInit(factory, location);
+    }
+
+	/**
+	 * Parses the specified input steam and constructs a feature model.
+	 * The input stream is not closed as part of this operation.
+	 * 
+	 * @param in input stream
+	 * @return feature model
+	 * @exception SAXException
+	 * @exception IOException
+	 * @since 2.0
+	 */
+	public LiteFeature[] parse(InputStream in) throws SAXException, IOException {
+		
+		parser.parse(new InputSource(in), this);	
+		return (LiteFeature[])featureModels.toArray( new LiteFeature[featureModels.size()]);
+	}
+
+
+	/**
+	 * Returns all status objects accumulated by the parser.
+	 *
+	 * @return multi-status containing accumulated status, or <code>null</code>.
+	 * @since 2.0
+	 */
+	public MultiStatus getStatus() {
+		return featureParser.getStatus();
+	}
+
+	/**
+	 * Handle start of element tags
+	 * @see DefaultHandler#startElement(String, String, String, Attributes)
+	 * @since 2.0
+	 */
+	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+		if(localName.equals("digest")) //$NON-NLS-1$
+			return;
+		if(localName.equals("feature")) //$NON-NLS-1$
+			featureParser.internalInit(factory, location);
+		
+		featureParser.startElement(uri, localName, qName, attributes);
+	}
+
+	/**
+	 * Handle end of element tags
+	 * @see DefaultHandler#endElement(String, String, String)
+	 * @since 2.0
+	 */
+	public void endElement(String uri, String localName, String qName) {
+		if(localName.equals("digest")) //$NON-NLS-1$
+			return;
+		featureParser.endElement(uri, localName, qName);
+		if(localName.equals("feature")) { //$NON-NLS-1$
+			try {
+				featureModels.add(featureParser.getFeatureModel());
+			} catch (SAXException e) {
+				e.printStackTrace();
+			} 
+		}
+	}
+	
+
+	/**
+	 * Handle character text
+	 * @see DefaultHandler#characters(char[], int, int)
+	 * @since 2.0
+	 */
+	public void characters(char[] ch, int start, int length) {
+		featureParser.characters(ch, start, length);
+	}
+
+	/**
+	 * Handle errors
+	 * @see DefaultHandler#error(SAXParseException)
+	 * @since 2.0
+	 */
+	public void error(SAXParseException ex) {
+		featureParser.error(ex);
+	}
+
+	/**
+	 * Handle fatal errors
+	 * @see DefaultHandler#fatalError(SAXParseException)
+	 * @exception SAXException
+	 * @since 2.0
+	 */
+	public void fatalError(SAXParseException ex) throws SAXException {
+		featureParser.fatalError(ex);
+	}
+
+	/**
+	 * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
+	 */
+	public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
+		featureParser.ignorableWhitespace(arg0, arg1, arg2);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/EmptyDirectoryException.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/EmptyDirectoryException.java
new file mode 100644
index 0000000..732e174
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/EmptyDirectoryException.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+public class EmptyDirectoryException extends CoreException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -762930667883265228L;
+
+	public EmptyDirectoryException(IStatus status) {
+		super(status);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ErrorRecoveryLog.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ErrorRecoveryLog.java
new file mode 100644
index 0000000..d87764b
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ErrorRecoveryLog.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.core.Utilities;
+
+
+/**
+ * Manages the error/recover log file
+ */
+public class ErrorRecoveryLog {
+	private static final String ERROR_RECOVERY_LOG = "error_recovery.log"; //$NON-NLS-1$
+	private static final String LOG_ENTRY_KEY = "LogEntry."; //$NON-NLS-1$
+	private static final String RETURN_CARRIAGE = "\r\n"; //$NON-NLS-1$
+	private static final String END_OF_FILE = "eof=eof"; //$NON-NLS-1$
+
+	//
+	public static final String START_INSTALL_LOG = 	"START_INSTALL_LOG"; //$NON-NLS-1$
+	public static final String PLUGIN_ENTRY = 		"PLUGIN"; //$NON-NLS-1$
+	public static final String FRAGMENT_ENTRY = 		"FRAGMENT";	 //$NON-NLS-1$
+	public static final String BUNDLE_MANIFEST_ENTRY = 		"BUNDLE_MANIFEST";	 //$NON-NLS-1$
+	public static final String BUNDLE_JAR_ENTRY = 			"BUNDLE";	 //$NON-NLS-1$
+	public static final String FEATURE_ENTRY = 		"FEATURE"; //$NON-NLS-1$2
+	public static final String ALL_INSTALLED = 		"ALL_FEATURES_INSTALLED"; //$NON-NLS-1$
+	public static final String RENAME_ENTRY = 		"RENAME"; //$NON-NLS-1$
+	public static final String END_INSTALL_LOG = 	"END_INSTALL_LOG"; //$NON-NLS-1$
+	public static final String START_REMOVE_LOG = 	"REMOVE_LOG"; //$NON-NLS-1$
+	public static final String END_ABOUT_REMOVE =	"END_ABOUT_TO_REMOVE"; //$NON-NLS-1$
+	public static final String DELETE_ENTRY = 		"DELETE"; //$NON-NLS-1$
+	public static final String END_REMOVE_LOG = 		"END_REMOVE_LOG"; //$NON-NLS-1$
+
+	private static ErrorRecoveryLog inst;
+	private FileWriter out;
+	private int index;
+	private List paths;
+	
+	private boolean open = false;
+	private int nbOfOpen = 0;
+	
+
+	/**
+	 * Constructor for ErrorRecoveryLog.
+	 */
+	private ErrorRecoveryLog() {
+		super();
+	}
+
+	/**
+	 * Singleton
+	 */
+	public static ErrorRecoveryLog getLog() {
+		if (inst == null){
+			inst = new ErrorRecoveryLog();
+		}
+		return inst;
+	}
+
+	/**
+	 * get a unique identifer for the file, ensure uniqueness up to now
+	 */
+	public static String getLocalRandomIdentifier(String path) {
+		
+		if (path==null) return null;
+		
+		// verify if it will be a directory without creating the file
+		// as it doesn't exist yet
+		if (path.endsWith(File.separator) || path.endsWith("/")) //$NON-NLS-1$
+			return path;
+		File file = new File(path);
+		String newName =
+			UpdateManagerUtils.getLocalRandomIdentifier(file.getName(), new Date());
+		while (new File(file.getParentFile(), newName).exists()) {
+			newName =
+				UpdateManagerUtils.getLocalRandomIdentifier(file.getName(), new Date());
+		}
+		File newFile = new File(file.getParentFile(),newName);
+		return newFile.getAbsolutePath();
+	}
+
+	/**
+	 * returns the log file 
+	 * We do not check if the file exists
+	 */
+	public File getRecoveryLogFile() {
+		IPlatformConfiguration configuration =
+			ConfiguratorUtils.getCurrentPlatformConfiguration();
+		URL location = configuration.getConfigurationLocation();
+		String locationString = location.getFile();
+		File platformConfiguration = new File(locationString);
+		if (!platformConfiguration.isDirectory()) platformConfiguration = platformConfiguration.getParentFile();
+		return new File(platformConfiguration, ERROR_RECOVERY_LOG);
+	}
+
+
+	/**
+	 * Open the log
+	 */
+	public void open(String logEntry) throws CoreException {
+		if (open) {
+			nbOfOpen++;			
+			UpdateCore.warn("Open nested Error/Recovery log #"+nbOfOpen+":"+logEntry);				 //$NON-NLS-1$ //$NON-NLS-2$
+			return;
+		}
+		
+		File logFile = null;		
+		try {
+			logFile = getRecoveryLogFile();
+			out = new FileWriter(logFile);
+			index = 0;
+			paths=null;
+			open=true;
+			nbOfOpen=0;
+			UpdateCore.warn("Start new Error/Recovery log #"+nbOfOpen+":"+logEntry);							 //$NON-NLS-1$ //$NON-NLS-2$
+		} catch (IOException e) {
+			throw Utilities.newCoreException(
+				NLS.bind(Messages.UpdateManagerUtils_UnableToLog, (new Object[] { logFile })),
+				e);
+		}
+		
+		append(logEntry);
+	}
+
+	/**
+	 * Append the string to the log and flush
+	 */
+	public void append(String logEntry) throws CoreException {
+		File logFile = null;
+		try {
+			if (!open) {
+				UpdateCore.warn("Internal Error: The Error/Recovery log is not open:"+logEntry);				 //$NON-NLS-1$
+				return;
+			}
+
+			StringBuffer buffer = new StringBuffer(LOG_ENTRY_KEY);
+			buffer.append(index);
+			buffer.append("="); //$NON-NLS-1$
+			buffer.append(logEntry);
+			buffer.append(RETURN_CARRIAGE);
+
+			out.write(buffer.toString());
+			out.flush();
+			index++;
+		} catch (IOException e) {
+			throw Utilities.newCoreException(
+				NLS.bind(Messages.UpdateManagerUtils_UnableToLog, (new Object[] { logFile })),
+				e);
+		}
+	}
+
+	/**
+	 * Append the string to the log and flush
+	 */
+	public void appendPath(String logEntry, String path) throws CoreException {
+		if (path == null)
+			return;
+		StringBuffer buffer = new StringBuffer(logEntry);
+		buffer.append(" "); //$NON-NLS-1$
+		buffer.append(path);
+		append(buffer.toString());
+		
+		addPath(path);
+	}
+
+	/**
+	 * Close any open recovery log
+	 */
+	public void close(String logEntry) throws CoreException {
+		
+		if (nbOfOpen>0){
+			UpdateCore.warn("Close nested Error/Recovery log #"+nbOfOpen+":"+logEntry);			 //$NON-NLS-1$ //$NON-NLS-2$
+			nbOfOpen--;			
+			return;
+		}			
+		
+		UpdateCore.warn("Close Error/Recovery log #"+nbOfOpen+":"+logEntry); //$NON-NLS-1$ //$NON-NLS-2$
+		append(logEntry);
+		if (out != null) {
+			try {
+				out.write(END_OF_FILE);
+				out.flush();
+				out.close();
+			} catch (IOException e) { //eat the exception
+			} finally {
+				out = null;
+				open=false;
+			}
+		}
+	}
+
+	/**
+	 * Delete the file from the file system
+	 */
+	public void delete() {
+		//File logFile = getRecoveryLogFile();
+		getRecoveryLogFile();
+		//if (logFile.exists())
+			//logFile.delete();	
+	}
+
+	/**
+	 * 
+	 */
+	private void addPath(String path){
+		if (paths==null) paths = new ArrayList();
+		paths.add(path);
+	}
+	
+	/*
+	 * creates a Status
+	 */
+	private IStatus createStatus(int statusSeverity, String msg, Exception e){
+		String id =
+			UpdateCore.getPlugin().getBundle().getSymbolicName();
+	
+		StringBuffer completeString = new StringBuffer(""); //$NON-NLS-1$
+		if (msg!=null)
+			completeString.append(msg);
+		if (e!=null){
+			completeString.append("\r\n["); //$NON-NLS-1$
+			completeString.append(e.toString());
+			completeString.append("]\r\n"); //$NON-NLS-1$
+		}
+		return new Status(statusSeverity, id, IStatus.OK, completeString.toString(), e);
+	}	
+	
+	/**
+	 * return a multi status, 
+	 * the children are the file that couldn't be removed
+	 */
+	public IStatus removeFromFileSystem(File file) {
+		
+		IStatus mainStatus = createStatus(IStatus.OK,"",null); //$NON-NLS-1$
+		MultiStatus multi = new MultiStatus(mainStatus.getPlugin(),mainStatus.getCode(),"",null);		 //$NON-NLS-1$
+		
+		if (!file.exists()){
+			multi.add(createStatus(IStatus.ERROR,Messages.ErrorRecoveryLog_noFiletoRemove+file,null)); 
+			return multi;
+		}
+			
+		if (file.isDirectory()) {
+			String[] files = file.list();
+			if (files != null) // be careful since file.list() can return null
+				for (int i = 0; i < files.length; ++i){
+					multi.addAll(removeFromFileSystem(new File(file, files[i])));
+				}
+		}
+		
+		if (!file.delete()) {
+			String msg = "Unable to remove file" +file.getAbsolutePath(); //$NON-NLS-1$ 
+			multi.add(createStatus(IStatus.ERROR,msg,null));
+		}
+		return multi;
+	}	
+	
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ExtendedSite.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ExtendedSite.java
new file mode 100644
index 0000000..b010bab
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ExtendedSite.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.update.core.IURLEntry;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.eclipse.update.internal.model.SiteWithTimestamp;
+
+public class ExtendedSite extends SiteWithTimestamp /*Site*/ {
+	
+	private boolean digestExist;
+	private String[] availableLocals;
+	private String digestURL;
+	private LiteFeature[] liteFeatures;
+	private LiteFeature[] allLiteFeatures;
+	private IURLEntry[] associateSites;
+	private boolean pack200 = false;
+	private IURLEntry selectedMirror;
+	
+	
+	public String getDigestURL() {
+		return digestURL;
+	}
+	public void setDigestURL(String digestURL) {
+		this.digestURL = digestURL;
+	}
+
+	public String[] getAvailableLocals() {
+		return availableLocals;
+	}
+	public void setAvailableLocals(String[] availableLocals) {
+		this.availableLocals = availableLocals;
+	}
+	public boolean isDigestExist() {
+		return digestExist;
+	}
+	public void setDigestExist(boolean digestExist) {
+		this.digestExist = digestExist;
+	}
+	public LiteFeature[] getLiteFeatures() {
+		if (getCurrentConfiguredSite()!=null)
+			return filterFeatures(getNonFilteredLiteFeatures());
+		else 
+			return getNonFilteredLiteFeatures();
+	}
+	public void setLiteFeatures(LiteFeature[] liteFeatures) {
+		
+		if ((liteFeatures == null) || (liteFeatures.length == 0))
+			return;
+		this.allLiteFeatures = liteFeatures;
+		List temp = new ArrayList();
+		for(int i = 0; i < allLiteFeatures.length ; i++) {
+			if (getFeatureReference(allLiteFeatures[i]) != null) {
+				temp.add(allLiteFeatures[i]);
+			}
+		}
+		if (!temp.isEmpty()) {
+			this.liteFeatures = (LiteFeature[])temp.toArray( new LiteFeature[temp.size()]);
+		}
+	}
+	
+	public LiteFeature getLiteFeature(VersionedIdentifier vid) {
+		if (allLiteFeatures == null)
+			return null;
+		
+		for(int i = 0; i < allLiteFeatures.length ; i++) {
+			if (vid.equals(allLiteFeatures[i].getVersionedIdentifier())) {
+				return allLiteFeatures[i];
+			}
+		}
+		return null;
+	}
+	
+	public LiteFeature[] getNonFilteredLiteFeatures() {
+		return liteFeatures;
+	}
+	public void setNonFilteredLiteFeatures(LiteFeature[] liteFeatures) {
+		this.liteFeatures = liteFeatures;
+	}
+	
+	
+	/**
+	 * Get whether or not this site may contain jars packed with pack200.
+	 * The packed version of foo.jar, is expected to be foo.jar.pack.gz
+	 * @return
+	 */
+	public boolean supportsPack200() {
+		return pack200;
+	}
+	
+	/**
+	 * Set whether or not this site may contain jars packed with pack200
+	 * The packed version of foo.jar is expected to be foo.jar.pack.gz
+	 * @param pack
+	 */
+	public void setSupportsPack200(boolean pack){
+		pack200 = pack;
+	}
+	
+	/*
+	 * Method filterFeatures.
+	 * Also implemented in Feature
+	 *  
+	 * @param list
+	 * @return List
+	 */
+	private LiteFeature[] filterFeatures(LiteFeature[] allIncluded) {
+		List list = new ArrayList();
+		if (allIncluded!=null){
+			for (int i = 0; i < allIncluded.length; i++) {
+				LiteFeature included = allIncluded[i];
+				if (UpdateManagerUtils.isValidEnvironment(included))
+					list.add(included);
+				else{
+					if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_WARNINGS){
+						UpdateCore.warn("Filtered out feature reference:"+included); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+		
+		LiteFeature[] result = new LiteFeature[list.size()];
+		if (!list.isEmpty()){
+			list.toArray(result);
+		}
+		
+		return result;	
+	}
+	public IURLEntry[] getAssociateSites() {
+		return associateSites;
+	}
+	public void setAssociateSites(IURLEntry[] associateSites) {
+		this.associateSites = associateSites;
+	}
+	
+	public IURLEntry getSelectedMirror() {
+		return selectedMirror;
+	}
+	
+	public void setSelectedMirror(IURLEntry selectedMirror) {
+		this.selectedMirror = selectedMirror;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ExtendedSiteURLFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ExtendedSiteURLFactory.java
new file mode 100644
index 0000000..bea3981
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ExtendedSiteURLFactory.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.update.core.model.SiteModel;
+
+public class ExtendedSiteURLFactory extends SiteURLFactory {
+	
+	public SiteModel createSiteMapModel() {
+		return new ExtendedSite();
+	}
+
+	
+    //public SiteFeatureReferenceModel createFeatureReferenceModel() {
+    //    return new UpdateSiteLiteFeatureReference();
+    //}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FatalIOException.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FatalIOException.java
new file mode 100644
index 0000000..b82ee06
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FatalIOException.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.IOException;
+
+public class FatalIOException extends IOException {
+	private static final long serialVersionUID = 7690318087505479039L;
+
+	public FatalIOException(String string) {
+		super(string);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureContentConsumer.java
new file mode 100644
index 0000000..278de69
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureContentConsumer.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+
+/**
+ * A default implementation for IFeatureContentConsumer
+ * </p>
+ * @since 2.0
+ */
+
+public abstract class FeatureContentConsumer extends ModelObject
+	implements IFeatureContentConsumer {
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureDownloadException.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureDownloadException.java
new file mode 100644
index 0000000..cef1d61
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureDownloadException.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.core.runtime.*;
+
+/**
+ * Exception thrown when IOException during downloading features
+ * 
+ * @since 3.0
+ */
+public class FeatureDownloadException extends CoreException {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+	 * Construct the exception indicating enclosing CoreException
+	 * 
+	 * @since 3.0
+	 */
+	public FeatureDownloadException(String msg, Exception e) {
+		super(
+			new Status(
+				IStatus.INFO,
+				"org.eclipse.update.core", //$NON-NLS-1$
+				IStatus.OK,
+				msg,
+				e));
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureEntryWrapper.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureEntryWrapper.java
new file mode 100644
index 0000000..da1eca5
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureEntryWrapper.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.core.runtime.IProduct;
+import org.eclipse.update.internal.configurator.FeatureEntry;
+import org.osgi.framework.Bundle;
+
+/**
+ * Class used to wrapper feature entry objects. This class is necessary
+ * to remove the depedancy of the org.eclipse.update.configurator on 
+ * the org.eclipse.core.runtime bundle.
+ *
+ * @since 3.2
+ */
+public class FeatureEntryWrapper implements IProduct {
+
+	private FeatureEntry entry;
+
+	/*
+	 * Constructor for the class.
+	 */
+	public FeatureEntryWrapper(FeatureEntry entry) {
+		super();
+		this.entry = entry;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProduct#getApplication()
+	 */
+	public String getApplication() {
+		return entry.getApplication();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProduct#getName()
+	 */
+	public String getName() {
+		return entry.getName();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProduct#getDescription()
+	 */
+	public String getDescription() {
+		return entry.getDescription();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProduct#getId()
+	 */
+	public String getId() {
+		return entry.getId();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProduct#getProperty(java.lang.String)
+	 */
+	public String getProperty(String key) {
+		return entry.getProperty(key);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProduct#getDefiningBundle()
+	 */
+	public Bundle getDefiningBundle() {
+		return entry.getDefiningBundle();
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureExecutableContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureExecutableContentConsumer.java
new file mode 100644
index 0000000..8226d87
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureExecutableContentConsumer.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+ 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.update.core.ContentReference;
+import org.eclipse.update.core.IContentConsumer;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureContentConsumer;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.INonPluginEntry;
+import org.eclipse.update.core.IPluginEntry;
+
+/**
+ * ContentConsumer Implementation for a FeatureExecutable
+ */
+
+public class FeatureExecutableContentConsumer extends FeatureContentConsumer {
+
+	private IFeature feature;
+	private boolean closed= false;
+	private boolean aborted= false;	
+	private ISiteContentConsumer contentConsumer;
+	private IFeatureContentConsumer parent = null;
+	private List /* of IFeatureContentCOnsumer */ children;
+
+	/*
+	 * @see IContentConsumer#open(INonPluginEntry)
+	 */
+	public IContentConsumer open(INonPluginEntry nonPluginEntry)
+		throws CoreException {
+		ContentConsumer cons = new NonPluginEntryContentConsumer(
+			getContentConsumer().open(nonPluginEntry));
+		return cons;
+	}
+
+	/*
+	 * @see IContentConsumer#open(IPluginEntry)
+	 */
+	public IContentConsumer open(IPluginEntry pluginEntry) throws CoreException {
+		ContentConsumer cons = new PluginEntryContentConsumer(getContentConsumer().open(pluginEntry));
+		return cons;		
+	}
+
+	/*
+	 * @see IContentConsumer#addChild(IFeature)
+	 */
+	public void addChild(IFeature child) throws CoreException {
+		IFeatureContentConsumer childConsumer = child.getFeatureContentConsumer();
+		childConsumer.setParent(this);
+		if (children==null) children = new ArrayList();
+		children.add(childConsumer);
+		return;
+	}
+
+
+	/*
+	 * @see IFeatureContentConsumer#store(ContentReference, IProgressMonitor)
+	 */
+	public void store(ContentReference contentReference, IProgressMonitor monitor)
+		throws CoreException {
+		getContentConsumer().store(contentReference, monitor);
+	}
+
+	/*
+	 * @see IFeatureContentConsumer#close()
+	 */
+	public IFeatureReference close() throws CoreException {
+		
+		if (!closed && getParent()!=null){
+			closed=true;
+			return null;
+		}
+		
+		// parent consumer, log we are about to rename
+		// log files have been downloaded
+		if (getParent()==null){
+			ErrorRecoveryLog.getLog().append(ErrorRecoveryLog.ALL_INSTALLED);
+		}
+		
+		IFeatureReference ref= null;
+		if (contentConsumer != null)
+			ref = contentConsumer.close();
+		
+		// close nested feature
+		IFeatureContentConsumer[] children = getChildren();
+		for (int i = 0; i < children.length; i++) {
+			children[i].close();
+		}
+							
+		return ref;
+	}
+
+	/*
+	 * @see IFeatureContentConsumer#setFeature(IFeature)
+	 */
+	public void setFeature(IFeature feature) {
+		this.feature= feature;
+	}
+
+	/*
+	 * Sets the parent 
+	 */
+	public void setParent(IFeatureContentConsumer featureContentConsumer) {
+		this.parent= featureContentConsumer;
+	}
+
+	/*
+	 * returns the Content Consumer for the feature
+	 * 
+	 * Right now we are the only one to implement SiteContentConsumer
+	 * Need to be exposed as API post v2.0
+	 */
+	private ISiteContentConsumer getContentConsumer() throws CoreException {
+		if (contentConsumer == null)
+			if (feature.getSite() instanceof SiteFile) {
+				SiteFile site= (SiteFile) feature.getSite();
+				contentConsumer= site.createSiteContentConsumer(feature);
+			} else {
+				throw new UnsupportedOperationException();
+			}
+		return contentConsumer;
+	}
+
+	/*
+	 * @see IFeatureContentConsumer#abort()
+	 */
+	public void abort() throws CoreException {
+
+		if (aborted) return;
+		
+		IFeatureContentConsumer[] children = getChildren();
+		for (int i = 0; i < children.length; i++) {
+			try {
+			children[i].abort();
+			} catch (Exception e){
+				//do Nothing
+			}
+		}
+
+		// do not close plugin and non plugin content consumer
+		// the contentConsumer will abort them
+		// we do not need to abort the NonPluginEntryContentConsumer and PluginEntryContentConsume
+
+		//implement the cleanup
+		if (contentConsumer!=null)
+			contentConsumer.abort();
+		
+		aborted = true;
+	}
+
+	/*
+	 * @see IFeatureContentConsumer#getFeature()
+	 */
+	public IFeature getFeature(){
+		return feature;
+	}
+
+	/*
+	 * @see IFeatureContentConsumer#getParent()
+	 */
+	public IFeatureContentConsumer getParent(){
+		return parent;
+	}
+
+	/*
+	 * @see IFeatureContentConsumer#getChildren()
+	 */
+	public IFeatureContentConsumer[] getChildren(){
+		if (children==null || children.size() == 0)
+			return new IFeatureContentConsumer[0];
+
+		return (IFeatureContentConsumer[]) children.toArray(arrayTypeFor(children));
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureExecutableContentProvider.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureExecutableContentProvider.java
new file mode 100644
index 0000000..0bf4c71
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureExecutableContentProvider.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+
+import java.io.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+
+/**
+ * Default implementation of a Executable Feature Content Provider
+ */
+
+public class FeatureExecutableContentProvider extends FeatureContentProvider {
+
+	/*
+	 * Constructor 
+	 */
+	public FeatureExecutableContentProvider(URL url) {
+		super(url);
+	}
+
+	/*
+	 * Return the path for a pluginEntry
+	 */
+	private String getPath(IPluginEntry pluginEntry)
+		throws IOException, CoreException {
+
+		// get the URL of the Archive file that contains the plugin entry
+		ISiteContentProvider provider = getFeature().getSite().getSiteContentProvider();
+		URL fileURL = provider.getArchiveReference(getPathID(pluginEntry));
+		String result = fileURL.getFile();
+
+		if (!result.endsWith(".jar") && !result.endsWith("/") && !result.endsWith(File.separator)) //$NON-NLS-1$ //$NON-NLS-2$
+			result += File.separator;
+		File pluginPath = new File(result);
+		if (!pluginPath.exists())
+			throw new IOException(
+				NLS.bind(Messages.FeatureExecutableContentProvider_FileDoesNotExist, (new String[] { result })));
+
+		return result;
+	}
+
+	/*
+	 * Returns the path for the Feature
+	 */
+	private String getFeaturePath() throws IOException {
+		String result = getFeature().getURL().getFile();
+
+		// return the list of all subdirectories
+		if (!(result.endsWith(File.separator) || result.endsWith("/"))) //$NON-NLS-1$
+			result += File.separator;
+		File pluginDir = new File(result);
+		if (!pluginDir.exists())
+			throw new IOException(
+				NLS.bind(Messages.FeatureExecutableContentProvider_FileDoesNotExist, (new String[] { result })));
+
+		return result;
+	}
+
+	/*
+	 * Returns all the files under the directory
+	 * Recursive call
+	 */
+	private List getFiles(File dir) throws IOException {
+		List result = new ArrayList();
+
+		if (!dir.isDirectory()) {
+			String msg =
+				NLS.bind(Messages.FeatureExecutableContentProvider_InvalidDirectory, (new String[] { dir.getAbsolutePath() }));
+
+			throw new IOException(msg);
+
+		}
+
+		File[] files = dir.listFiles();
+		if (files != null)
+			for (int i = 0; i < files.length; ++i) {
+				if (files[i].isDirectory()) {
+					result.addAll(getFiles(files[i]));
+				} else {
+					result.add(files[i]);
+				}
+			}
+
+		return result;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getVerifier()
+	 */
+	public IVerifier getVerifier() throws CoreException {
+		return null;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getFeatureManifestReference()
+	 */
+	public ContentReference getFeatureManifestReference(InstallMonitor monitor)
+		throws CoreException {
+		ContentReference result = null;
+		try {
+			result = new ContentReference(Feature.FEATURE_XML, new URL(getURL(), Feature.FEATURE_XML));
+
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException(
+				NLS.bind(Messages.FeatureExecutableContentProvider_UnableToCreateURLFor, (new String[] { getURL().toExternalForm() + " " + Feature.FEATURE_XML })), //$NON-NLS-1$
+				e);
+		}
+		return result;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getArchiveReferences()
+	 */
+	public ContentReference[] getArchiveReferences(InstallMonitor monitor)
+		throws CoreException {
+		// executable feature does not contain archives
+		return new ContentReference[0];
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getPluginEntryArchiveReferences(IPluginEntry)
+	 */
+	public ContentReference[] getPluginEntryArchiveReferences(
+		IPluginEntry pluginEntry,
+		InstallMonitor monitor)
+		throws CoreException {
+		ContentReference[] result = new ContentReference[1];
+		String archiveID = getPathID(pluginEntry);
+		try {
+			File archiveFile = new File(getPath(pluginEntry));
+			if(!archiveFile.isDirectory() && archiveFile.getName().endsWith(".jar")){ //$NON-NLS-1$
+				result[0] = new JarContentReference(archiveID, archiveFile);				
+			} else {
+				result[0] =
+					new ContentReference(archiveID, archiveFile);
+			}
+		} catch (IOException e) {
+			throw Utilities.newCoreException(
+					NLS.bind(Messages.FeatureExecutableContentProvider_UnableToRetrievePluginEntry, (new String[] { pluginEntry.getVersionedIdentifier().toString() })),
+					e);
+		}
+		return result;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getNonPluginEntryArchiveReferences(INonPluginEntry)
+	 */
+	public ContentReference[] getNonPluginEntryArchiveReferences(
+		INonPluginEntry nonPluginEntry,
+		InstallMonitor monitor)
+		throws CoreException {
+
+		ContentReference[] result = new ContentReference[1];
+		URL fileURL;
+
+		//try {
+		// get the URL of the Archive file that contains the plugin entry
+		ISiteContentProvider provider = getFeature().getSite().getSiteContentProvider();
+		fileURL = provider.getArchiveReference(getPathID(nonPluginEntry));
+
+		String fileString = fileURL.getFile();
+		File nonPluginData = new File(fileString);
+		if (!nonPluginData.exists())
+			throw Utilities.newCoreException(
+				NLS.bind(Messages.FeatureExecutableContentProvider_FileDoesNotExist, (new String[] { fileString })), 
+				null); 
+
+		try {
+			result[0] =
+				new ContentReference(nonPluginEntry.getIdentifier(), nonPluginData.toURL());
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException(
+				NLS.bind(Messages.FeatureExecutableContentProvider_UnableToRetrieveNonPluginEntry, (new String[] { nonPluginEntry.getIdentifier().toString() })),
+				e);
+		}
+		return result;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getFeatureEntryArchiveReferences()
+	 */
+	public ContentReference[] getFeatureEntryArchiveReferences(InstallMonitor monitor)
+		throws CoreException {
+		ContentReference[] contentReferences = new ContentReference[1];
+		contentReferences[0] = new ContentReference(null, getURL());
+		return contentReferences;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getFeatureEntryArchivesContentReferences()
+	 */
+	public ContentReference[] getFeatureEntryContentReferences(InstallMonitor monitor)
+		throws CoreException {
+		ContentReference[] result = new ContentReference[0];
+		try {
+			File featureDir = new File(getFeaturePath());
+			List files = getFiles(featureDir);
+			result = new ContentReference[files.size()];
+			for (int i = 0; i < result.length; i++) {
+				File currentFile = (File) files.get(i);
+				result[i] = new ContentReference(currentFile.getName(), currentFile.toURL());
+			}
+		} catch (IOException e) {
+			throw Utilities.newCoreException(
+				NLS.bind(Messages.FeatureExecutableContentProvider_UnableToRetrieveFeatureEntry, (new String[] { getFeature().getVersionedIdentifier().toString() })),
+				e);
+		}
+		return result;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getPluginEntryContentReferences(IPluginEntry)
+	 */
+	public ContentReference[] getPluginEntryContentReferences(
+		IPluginEntry pluginEntry,
+		InstallMonitor monitor)
+		throws CoreException {
+
+		ContentReference[] references = getPluginEntryArchiveReferences(pluginEntry, monitor);
+		ContentReference[] result = new ContentReference[0];
+
+		try {
+			if (references[0] instanceof JarContentReference) {
+				result = ((JarContentReference)references[0]).peek(null, monitor);
+			} else {
+				// return the list of all subdirectories
+				File pluginDir = new File(getPath(pluginEntry));
+				URL pluginURL = pluginDir.toURL();
+				List files = getFiles(pluginDir);
+				result = new ContentReference[files.size()];
+				for (int i = 0; i < result.length; i++) {
+					File currentFile = (File) files.get(i);
+					String relativeString = UpdateManagerUtils.getURLAsString(pluginURL, currentFile.toURL());
+					result[i] = new ContentReference(relativeString, currentFile.toURL());
+				}
+			}
+		} catch (IOException e) {
+			throw Utilities.newCoreException(
+				Messages.FeatureExecutableContentProvider_UnableToRetriveArchiveContentRef
+					+ pluginEntry.getVersionedIdentifier().toString(),
+				e);
+		}
+		
+		//[20866] we did not preserve executable bit
+		validatePermissions(result);
+		
+		return result;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureExecutableFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureExecutableFactory.java
new file mode 100644
index 0000000..170a688
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureExecutableFactory.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.BaseFeatureFactory;
+import org.eclipse.update.core.Feature;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureContentConsumer;
+import org.eclipse.update.core.IFeatureContentProvider;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.model.FeatureModel;
+import org.eclipse.update.internal.core.connection.ConnectionFactory;
+
+/**
+ * FeatureFactory for Executable Features
+ */
+public class FeatureExecutableFactory extends BaseFeatureFactory {
+
+	/*
+	 * @see IFeatureFactory#createFeature(URL,ISite,IProgressMonitor)
+	 */
+	public IFeature createFeature(URL url, ISite site, IProgressMonitor monitor) throws CoreException {
+
+		TargetFeature feature = null;
+		InputStream featureStream = null;
+		if (monitor == null)
+			monitor = new NullProgressMonitor();
+
+		if (url == null)
+			return createFeature(site);
+
+		// the URL should point to a directory
+		url = validate(url);
+
+		try {
+			IFeatureContentProvider contentProvider = new FeatureExecutableContentProvider(url);
+//			// PERF: Do not create FeatureContentConsumer
+// bug 79893
+			IFeatureContentConsumer contentConsumer =new FeatureExecutableContentConsumer();
+
+			URL nonResolvedURL = contentProvider.getFeatureManifestReference(null).asURL();
+			URL resolvedURL = URLEncoder.encode(nonResolvedURL);
+			featureStream = ConnectionFactory.get(resolvedURL).getInputStream();
+
+			feature = (TargetFeature) this.parseFeature(featureStream, resolvedURL.toExternalForm());
+			monitor.worked(1);
+			feature.setSite(site);
+
+			feature.setFeatureContentProvider(contentProvider);
+//			// PERF: FeatureContentConsumer
+// bug 79893
+			feature.setContentConsumer(contentConsumer);
+
+			feature.resolve(url, url);
+			feature.markReadOnly();
+		} catch (CoreException e) {
+			throw e;
+		} catch (Exception e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.FeatureFactory_CreatingError, (new String[] { url.toExternalForm() })), e);
+		} finally {
+			try {
+				if (featureStream != null)
+					featureStream.close();
+			} catch (IOException e) {
+			}
+		}
+		return feature;
+	}
+
+	/*
+	 * @see FeatureModelFactory#createFeatureModel()
+	 */
+	public FeatureModel createFeatureModel() {
+		return new TargetFeature();
+	}
+
+	/*
+	 * Creates an empty feature on the site 
+	 */
+	private IFeature createFeature(ISite site) throws CoreException {
+		TargetFeature feature = null;
+
+		IFeatureContentProvider contentProvider = new FeatureExecutableContentProvider(null);
+		IFeatureContentConsumer contentConsumer = new FeatureExecutableContentConsumer();
+		feature = (TargetFeature) createFeatureModel();
+		feature.setSite(site);
+		feature.setFeatureContentProvider(contentProvider);
+		feature.setContentConsumer(contentConsumer);
+
+		// do not mark read only yet...	
+		return feature;
+	}
+
+	/*
+	 * validates a URL as a directory URL
+	 */
+	private URL validate(URL url) throws CoreException {
+
+		if (url == null)
+			throw Utilities.newCoreException(Messages.FeatureExecutableFactory_NullURL, null); 
+
+		if (!(url.getFile().endsWith("/") || url.getFile().endsWith(File.separator) || url.getFile().endsWith(Feature.FEATURE_XML))) { //$NON-NLS-1$
+			try {
+				String path = url.getFile() + "/"; //$NON-NLS-1$
+				url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
+			} catch (MalformedURLException e) {
+				throw Utilities.newCoreException(NLS.bind(Messages.FeatureExecutableFactory_CannotCreateURL, (new String[] { url.toExternalForm() })), e);
+			}
+		}
+		return url;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedContentProvider.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedContentProvider.java
new file mode 100644
index 0000000..03fc180
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedContentProvider.java
@@ -0,0 +1,466 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.update.core.FeatureContentProvider;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.signedcontent.SignedContentFactory;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.jarprocessor.JarProcessor;
+import org.eclipse.update.internal.jarprocessor.Utils;
+import org.eclipse.update.internal.security.JarVerifier;
+import org.eclipse.update.internal.verifier.CertVerifier;
+
+/**
+ * Content Provider of a Feature Package
+ */
+public class FeaturePackagedContentProvider extends FeatureContentProvider {
+
+	private ContentReference localManifest = null;
+	private ContentReference[] localFeatureFiles = new ContentReference[0];
+	private IVerifier jarVerifier = null;
+	private ExtendedSite siteModel = null;
+	private boolean continueOnError;
+	/*
+	 * filter for file with .jar
+	 */
+	public static final FilenameFilter filter = new FilenameFilter() {
+		public boolean accept(File dir, String name) {
+			return name.endsWith(FeatureContentProvider.JAR_EXTENSION);
+		}
+	};
+
+	/*
+	 * Constructor
+	 */
+	public FeaturePackagedContentProvider(URL url, ISite site) {
+		super(url);
+		if (site instanceof ExtendedSite) {
+			this.siteModel = (ExtendedSite) site;
+		}
+	}
+	
+	/*
+	 * Returns a new verifier for each top-level install
+	 * (if the verifier has a parent, return the verifier
+	 * otherwise reinitialize)
+	 */
+	public IVerifier getVerifier() throws CoreException {
+		SignedContentFactory factory = UpdateCore.getPlugin().getSignedContentFactory();
+		if (jarVerifier == null || jarVerifier.getParent() == null) {
+			if (factory != null)
+				jarVerifier = new CertVerifier(UpdateCore.getPlugin().getSignedContentFactory());
+			else
+				jarVerifier = new JarVerifier();
+			return jarVerifier;
+		}
+
+		// re-init will be done if the parent changes
+		return jarVerifier;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getFeatureManifestReference()
+	 */
+	public ContentReference getFeatureManifestReference(InstallMonitor monitor) throws CoreException {
+
+		// check to see if we already have local copy of the manifest
+		if (localManifest != null)
+			return localManifest;
+		ContentReference[] featureArchiveReference = getFeatureEntryArchiveReferences(monitor);
+		JarContentReference featureJarReference = null;
+		try {
+
+			// force feature archive to local.
+			// This content provider always assumes exactly 1 archive file (index [0])		
+			featureJarReference = (JarContentReference) asLocalReference(featureArchiveReference[0], null);
+			// we need to unpack archive locally for UI browser references to be resolved correctly
+			localFeatureFiles = featureJarReference.unpack(getWorkingDirectory(), null, monitor);
+		} catch (IOException e) {
+			throw errorRetrieving(Feature.FEATURE_XML, featureJarReference, e); 
+		}
+
+		// find the manifest in the unpacked feature files
+		for (int i = 0; i < localFeatureFiles.length; i++) {
+			if (localFeatureFiles[i].getIdentifier().equals(Feature.FEATURE_XML)) {
+				localManifest = localFeatureFiles[i];
+				// cache reference to manifest
+				return localManifest;
+			}
+		}
+
+		// the manifest has not been found
+		String[] values = new String[] { Feature.FEATURE_XML, getURL().toExternalForm()};
+		throw Utilities.newCoreException(NLS.bind(Messages.FeaturePackagedContentProvider_NoManifestFile, values), new Exception()); 
+
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getArchiveReferences()
+	 */
+	public ContentReference[] getArchiveReferences(InstallMonitor monitor) throws CoreException {
+
+		IPluginEntry[] entries = getFeature().getPluginEntries();
+		INonPluginEntry[] nonEntries = getFeature().getNonPluginEntries();
+		List listAllContentRef = new ArrayList();
+		ContentReference[] allContentRef = new ContentReference[0];
+
+		// feature
+		listAllContentRef.addAll(Arrays.asList(getFeatureEntryArchiveReferences(monitor)));
+
+		// plugins
+		for (int i = 0; i < entries.length; i++) {
+			listAllContentRef.addAll(Arrays.asList(getPluginEntryArchiveReferences(entries[i], monitor)));
+		}
+
+		// non plugins
+		for (int i = 0; i < nonEntries.length; i++) {
+			listAllContentRef.addAll(Arrays.asList(getNonPluginEntryArchiveReferences(nonEntries[i], monitor)));
+		}
+
+		// transform List in Array
+		if (listAllContentRef.size() > 0) {
+			allContentRef = new ContentReference[listAllContentRef.size()];
+			listAllContentRef.toArray(allContentRef);
+		}
+
+		return allContentRef;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getFeatureEntryArchiveReferences()
+	 */
+	public ContentReference[] getFeatureEntryArchiveReferences(InstallMonitor monitor) throws CoreException {
+
+		//1 jar file <-> 1 feature
+		// we will return the JAR file 
+		ContentReference[] references = new ContentReference[1];
+		ContentReference currentReference = null;
+		String archiveID = null;
+
+		try {
+			archiveID = (getFeature() != null) ? getFeature().getVersionedIdentifier().toString() : "";	//$NON-NLS-1$
+			currentReference = new JarContentReference(archiveID, getURL());
+			currentReference = asLocalReference(currentReference, monitor);
+			references[0] = currentReference;
+		} catch (IOException e) {
+			references[0] = continueOnErrorOrRethrow(archiveID, e); 
+		}		
+		return references;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getPluginEntryArchiveReferences(IPluginEntry)
+	 */
+	public ContentReference[] getPluginEntryArchiveReferences(IPluginEntry pluginEntry, InstallMonitor monitor) throws CoreException {
+
+		// 1 plugin <-> 1 jar
+		// we return the JAR file	
+		ContentReference[] references = new ContentReference[1];
+		String archiveID = getPathID(pluginEntry);
+		ISite site = (getFeature() == null) ? null : getFeature().getSite();
+		ISiteContentProvider siteContentProvider = (site == null) ? null : site.getSiteContentProvider();
+		URL url = (siteContentProvider == null) ? null : siteContentProvider.getArchiveReference(archiveID);
+
+		try {
+			references[0] = retrieveLocalJar(new JarContentReference(archiveID, url), monitor);
+		} catch (IOException e) {
+			references[0] = continueOnErrorOrRethrow(archiveID, e);
+		}
+		return references;
+	}
+
+	private ContentReference retrieveLocalJar(JarContentReference reference, InstallMonitor monitor) throws IOException, CoreException {
+		//If the site does not support pack200, just get the jar as normal
+		if(siteModel == null || !siteModel.supportsPack200() || !JarProcessor.canPerformUnpack()) {
+			ContentReference contentReference = null;
+			try {
+				contentReference = asLocalReference(reference, monitor);
+			}
+			catch (FileNotFoundException e) {
+				contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+			}
+			catch (IOException e) {
+				contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+			}
+			catch (CoreException e) {
+				contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+			}
+			return contentReference;
+		}
+		
+		ContentReference packedRef = null;
+		String key = reference.toString();
+		Object jarLock = LockManager.getLock(key);
+		synchronized (jarLock) {
+			//do we have this jar already?
+			File localFile = Utilities.lookupLocalFile(key);
+			if (localFile != null) {
+				// check if the cached file is still valid (no newer version on server)
+				if (UpdateManagerUtils.isSameTimestamp(reference.asURL(), localFile.lastModified())) {
+					LockManager.returnLock(key);
+					return reference.createContentReference(reference.getIdentifier(), localFile);
+				}
+			}
+
+			try {
+				//don't have jar, check for pack.gz
+				URL packGZURL = new URL(reference.asURL().toExternalForm() + ".pack.gz"); //$NON-NLS-1$
+				packedRef = asLocalReference(new JarContentReference(reference.getIdentifier(), packGZURL), monitor);
+			} catch (IOException e) {
+				//no pack.gz
+			} catch (CoreException e){
+				//no pack.gz
+			}
+		}
+		
+		if (packedRef == null) {
+			//no pack.gz on server, get normal jar
+			ContentReference contentReference = null;
+			try {
+				contentReference = asLocalReference(reference, monitor);
+			}
+			catch (FileNotFoundException e) {
+				contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+			}
+			catch (IOException e) {
+				contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+			}
+			catch (CoreException e) {
+				contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+			}
+			return contentReference;
+		}
+
+		boolean success = false;
+		synchronized (jarLock) {
+			String packed = packedRef.toString();
+			Object packedLock = LockManager.getLock(packed);
+			synchronized (packedLock) {
+				try {
+					File tempFile = packedRef.asFile();
+					long timeStamp = tempFile.lastModified();
+	
+					JarProcessor processor = JarProcessor.getUnpackProcessor(null);
+					processor.setWorkingDirectory(tempFile.getParent());
+	
+					File packedFile = new File(tempFile.toString() + Utils.PACKED_SUFFIX);
+					tempFile.renameTo(packedFile);
+					
+					if (monitor != null) {
+						monitor.saveState();
+						monitor.subTask(Messages.JarContentReference_Unpacking + " " + reference.getIdentifier() + Utils.PACKED_SUFFIX);  //$NON-NLS-1$
+						monitor.showCopyDetails(false);
+					}
+					//unpacking the jar will strip the ".pack.gz" and leave us back with the original filename
+					try {
+						processor.processJar(packedFile);
+					} catch (Throwable e) {
+						//something is wrong unpacking
+					}
+	
+					if(tempFile.exists() && tempFile.length() > 0){
+						success = true;
+						tempFile.setLastModified(timeStamp);
+						Utilities.mapLocalFile(key, tempFile);
+						UpdateCore.getPlugin().getUpdateSession().markVisited(reference.asURL());
+					}
+				} finally {
+					LockManager.returnLock(packed);
+					LockManager.returnLock(key);
+					if(monitor != null)
+						monitor.restoreState();
+				}
+			}
+		}
+		if(!success){
+			//Something went wrong with the unpack, get the normal jar.
+			ContentReference contentReference = null;
+			try {
+				contentReference = asLocalReference(reference, monitor);
+			}
+			catch (FileNotFoundException e) {
+				contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+			}
+			catch (IOException e) {
+				contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+			}
+			catch (CoreException e) {
+				contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
+			}
+			return contentReference;
+		}
+		return packedRef;
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getNonPluginEntryArchiveReferences(INonPluginEntry)
+	 */
+	public ContentReference[] getNonPluginEntryArchiveReferences(INonPluginEntry nonPluginEntry, InstallMonitor monitor) throws CoreException {
+
+		// archive = feature/<id>_<ver>/<file>
+		String archiveID = Site.DEFAULT_FEATURE_PATH + ((getFeature() != null) ? getFeature().getVersionedIdentifier().toString() : ""); //$NON-NLS-1$
+		archiveID += "/" + nonPluginEntry.getIdentifier(); //$NON-NLS-1$
+
+		ContentReference[] references = new ContentReference[1];
+		ContentReference currentReference = null;
+
+		try {
+			ISite site = (getFeature() == null) ? null : getFeature().getSite();
+			ISiteContentProvider siteContentProvider = (site == null) ? null : site.getSiteContentProvider();
+			URL url = (siteContentProvider == null) ? null : siteContentProvider.getArchiveReference(archiveID);
+
+			currentReference = new ContentReference(nonPluginEntry.getIdentifier(), url);
+			currentReference = asLocalReference(currentReference, monitor);
+			references[0] = currentReference;
+
+		} catch (IOException e) {
+			references[0] = continueOnErrorOrRethrow(archiveID, e);
+		}
+
+		return references;
+	}
+
+
+	/*
+	 * @see IFeatureContentProvider#getFeatureEntryContentReferences()
+	 */
+	public ContentReference[] getFeatureEntryContentReferences(InstallMonitor monitor) throws CoreException {
+
+		return localFeatureFiles; // return cached feature references
+		// Note: assumes this content provider is always called first to
+		//       get the feature manifest. This forces the feature files
+		//       to be unpacked and caches the references
+	}
+
+	/*
+	 * @see IFeatureContentProvider#getPluginEntryContentReferences(IPluginEntry)
+	 */
+	public ContentReference[] getPluginEntryContentReferences(IPluginEntry pluginEntry, InstallMonitor monitor) throws CoreException {
+
+		ContentReference[] references = getPluginEntryArchiveReferences(pluginEntry, monitor);
+		ContentReference[] pluginReferences = new ContentReference[0];
+
+		try {
+			if (references[0] instanceof JarContentReference) {
+				JarContentReference localRef = (JarContentReference) asLocalReference(references[0], monitor);
+				pluginReferences = localRef.peek(null, monitor);
+			} else {
+				// return the list of all subdirectories
+				List files = getFiles(references[0].asFile());
+				pluginReferences = new ContentReference[files.size()];
+				for (int i = 0; i < pluginReferences.length; i++) {
+					File currentFile = (File) files.get(i);
+					pluginReferences[i] = new ContentReference(null, currentFile.toURL());
+				}
+			}
+
+			//[20866] we did not preserve executable bit
+			validatePermissions(pluginReferences);
+
+		} catch (IOException e) {
+			throw errorRetrieving(pluginEntry.getVersionedIdentifier().toString(), references[0], e);
+		}
+		return pluginReferences;
+	}
+
+	/*
+	 * return all the files under the directory
+	 */
+	private List getFiles(File dir) throws IOException {
+		List result = new ArrayList();
+
+		if (!dir.isDirectory())
+			throw new IOException(NLS.bind(Messages.FeaturePackagedContentProvider_InvalidDirectory, (new String[] { dir.getPath() })));
+
+		File[] files = dir.listFiles();
+		if (files != null) // be careful since it can be null
+			for (int i = 0; i < files.length; ++i) {
+				if (files[i].isDirectory()) {
+					result.addAll(getFiles(files[i]));
+				} else {
+					result.add(files[i]);
+				}
+			}
+		return result;
+	}
+
+	/*
+	 * 
+	 */
+	private CoreException errorRetrieving(String obj, ContentReference archive, Exception e) {
+
+		String[] values = new String[] { obj };
+
+		return Utilities.newCoreException(NLS.bind(Messages.FeaturePackagedContentProvider_ErrorRetrieving, values), e);	 	
+
+	}
+
+
+	public void setContinueOnError(boolean continueOnError) {
+		this.continueOnError = continueOnError;
+	}
+	
+	/** 
+	 * This method is used for when a core exception is detected, so, if its decided to rethrow, then 
+	 * a core exception odes not have to be recreated. 
+	 * 
+	 * @param archiveID id of the archive file
+	 * @param CoreException 
+	 * @return NullReference if its decided not to continue
+	 * @throws CoreException
+	 */
+	/*private ContentReference continueOrErrorOrRethrow(String archiveID, CoreException coreException) throws CoreException {
+		ContentReference reference = null;
+
+		if (continueOnError) {
+			// this ContentReference without a file or URL is purely a
+			// "missing jar" reference.
+			reference = new NullContentReference(archiveID);
+
+			String msg = "    ContinueOnError: The following ID was not found, so was skipped, and is not on miror site: " + archiveID; //$NON-NLS-1$
+			String id = UpdateCore.getPlugin().getBundle().getSymbolicName();
+			IStatus status = new Status(IStatus.WARNING, id , 0, msg, null);
+			UpdateCore.log(status);
+			
+		}
+		else {
+			throw coreException;
+		}
+		return reference;
+	}*/
+	
+	private ContentReference continueOnErrorOrRethrow(String archiveID, Exception e) throws CoreException {
+		ContentReference reference = null;
+
+		if (continueOnError) { 
+			// this ContentReference without a file or URL is purely a
+			// "missing jar" reference.
+			reference = new NullContentReference(archiveID);
+			
+			String msg = "    ContinueOnError: The following ID was not found, so was skipped, and is not on miror site: " + archiveID; //$NON-NLS-1$
+			String id = UpdateCore.getPlugin().getBundle().getSymbolicName();
+			IStatus status = new Status(IStatus.WARNING, id , 0, msg, null);
+			UpdateCore.log(status);	
+			
+		}
+		else {
+			throw errorRetrieving(archiveID, reference, e);
+		}
+		return reference;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedFactory.java
new file mode 100644
index 0000000..fc55651
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedFactory.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+import java.io.*;
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+
+/**
+ * Factory for Feature Packaged
+ */
+public class FeaturePackagedFactory extends BaseFeatureFactory {
+
+	/*
+	 * @see IFeatureFactory#createFeature(URL,ISite,IProgressMonitor)
+	 */
+	public IFeature createFeature(URL url,ISite site, IProgressMonitor monitor) throws CoreException {
+		Feature feature = null;
+		InputStream featureStream = null;
+		if (monitor == null)
+			monitor = new NullProgressMonitor();
+		monitor.beginTask(null,2);
+		monitor.worked(1);
+			
+					
+		try {	
+			IFeatureContentProvider contentProvider = new FeaturePackagedContentProvider(url, site);	
+			ContentReference manifest = contentProvider.getFeatureManifestReference(null/*IProgressMonitor*/);
+			featureStream = manifest.getInputStream();
+			feature = (Feature)parseFeature(featureStream);
+			monitor.worked(1);
+	
+			// if there is no update URL for the Feature
+			// use the Site URL
+			if (feature.getUpdateSiteEntry()==null){
+				URLEntryModel entryModel = createURLEntryModel();
+				URL siteUrl = site.getURL();
+				if (siteUrl!=null){
+					entryModel.setURLString(siteUrl.toExternalForm());
+					entryModel.resolve(siteUrl,null);
+					feature.setUpdateSiteEntryModel(entryModel);
+				}
+			}	
+			feature.setFeatureContentProvider(contentProvider);
+			feature.setSite(site);						
+			URL baseUrl = null;
+			try {
+				baseUrl = new URL(manifest.asURL(),"."); // make sure we have URL to feature directory //$NON-NLS-1$
+			} catch(MalformedURLException e) {	
+			}
+			feature.resolve(baseUrl, baseUrl);
+			feature.markReadOnly();			
+		}  catch (CoreException e){
+			throw e;
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw Utilities.newCoreException(NLS.bind(Messages.FeatureFactory_CreatingError, (new String[] { url.toExternalForm() })), e);
+		}finally {
+			try {
+				if (featureStream!=null)	
+					featureStream.close();
+			} catch (IOException e) {
+			}
+		}
+		return feature;
+	}
+    
+    public IncludedFeatureReferenceModel createIncludedFeatureReferenceModel() {
+     return new UpdateSiteIncludedFeatureReference();
+    }
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePlugin.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePlugin.java
new file mode 100644
index 0000000..f002ed7
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePlugin.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+import org.eclipse.update.core.*;
+/**
+ * An IPluginEntry - IFeature pair.
+ * The IFeature is a featue or a patch wich delivered the plugin
+ */
+public class FeaturePlugin {
+	private IPluginEntry pluginEntry;
+	private IFeature feature;
+	public FeaturePlugin(IPluginEntry entry, IFeature feature) {
+		pluginEntry = entry;
+		this.feature = feature;
+	}
+	public IPluginEntry getEntry() {
+		return pluginEntry;
+	}
+	public IFeature getFeature() {
+		return feature;
+	}
+	/**
+	 * Plugins are equal if their IDs and versions are the same.
+	 */
+	public boolean equals(Object o) {
+		if (o instanceof FeaturePlugin) {
+			FeaturePlugin p = (FeaturePlugin) o;
+			return getEntry().getVersionedIdentifier().equals(p.getEntry().getVersionedIdentifier());
+		}
+		return false;
+	}
+	public int hashCode() {
+		return getEntry().getVersionedIdentifier().hashCode();
+	}
+	public String toString() {
+		return pluginEntry + " in " + feature; //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureTypeFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureTypeFactory.java
new file mode 100644
index 0000000..56aeac4
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeatureTypeFactory.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+
+/**
+ * Manages FeatureFactory extension point
+ */
+public final class FeatureTypeFactory {
+
+	private static FeatureTypeFactory inst;
+	private Map factories;
+
+	private static final String SIMPLE_EXTENSION_ID = "featureTypes";	//$NON-NLS-1$	
+
+	/*
+	 * hide constructor
+	 */
+	private FeatureTypeFactory() {
+	}
+
+	/*
+	 * Singleton pattern
+	 */
+	public static FeatureTypeFactory getInstance() {
+		if (inst == null)
+			inst = new FeatureTypeFactory();
+		return inst;
+	}
+
+	/*
+	 * return the factory for the associated type
+	 */
+	public IFeatureFactory getFactory(String type) throws CoreException {
+		//
+		Object instance = getFactories().get(type);
+		if (instance == null) {
+			instance = createFactoryFor(type);
+			getFactories().put(type, instance);
+		}
+		return (IFeatureFactory) instance;
+	}
+
+	/*
+	 * creates a factory for the associated type and cache it 
+	 */
+	private IFeatureFactory createFactoryFor(String type) throws CoreException {
+		IFeatureFactory result = null;
+
+		String pluginID =
+			UpdateCore.getPlugin().getBundle().getSymbolicName();
+		IExtensionRegistry registry = Platform.getExtensionRegistry();
+		IConfigurationElement[] elements =
+			registry.getConfigurationElementsFor(pluginID, SIMPLE_EXTENSION_ID, type);
+
+		if (elements == null || elements.length == 0) {
+			throw Utilities.newCoreException(
+					NLS.bind(Messages.FeatureTypeFactory_UnableToFindFeatureFactory, (new String[] { type })),
+					null);
+		} 
+
+		IConfigurationElement element = elements[0];
+		result = (IFeatureFactory) element.createExecutableExtension("class");	//$NON-NLS-1$
+		return result;
+	}
+
+	/*
+	 * 
+	 */
+	private Map getFactories() {
+		if (factories == null)
+			factories = new HashMap();
+		return factories;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FileFragment.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FileFragment.java
new file mode 100644
index 0000000..309250f
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FileFragment.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.core;
+
+import java.io.*;
+
+
+public class FileFragment{
+	private File file;
+	private long bytes;
+	public FileFragment(File file, long size){
+		this.file=file;
+		this.bytes=size;
+	}
+	public File getFile(){
+		return file;
+	}
+	public long getSize(){
+		return bytes;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FragmentEntry.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FragmentEntry.java
new file mode 100644
index 0000000..2a7511f
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/FragmentEntry.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+
+/**
+ * This class is used to retrieve the fragments associated with a plugin.
+ */
+public class FragmentEntry {
+	
+	private String pluginId;
+	private String pluginVersion;
+	private String name; 
+	private String location;
+	
+	public FragmentEntry(String id, String version, String name, String location) {
+		this.pluginId = id;
+		this.pluginVersion = version;
+		this.name = name;
+		this.location = location;
+	}
+
+	/**
+	 * @return the plugin translatable name
+	 */
+	public String getName() {
+		return name;
+	}
+	
+	/**
+	 * @return the location of the plugin
+	 */
+	public String getLocation() {
+		return location;
+	}
+	
+	/**
+	 * Returns the plug-in identifier for this entry.
+	 * 
+	 * @return the plug-in identifier, or <code>null</code>
+	 */
+	public String getPluginIdentifier() {
+		return pluginId;
+	}
+
+	/**
+	 * Returns the plug-in version for this entry.
+	 * 
+	 * @return the plug-in version, or <code>null</code>
+	 */
+	public String getPluginVersion() {
+		return pluginVersion;
+	}
+
+	/**
+	 * @see Object#toString()
+	 */
+	public String toString() {
+		String msg = (getPluginIdentifier()!=null)?getPluginIdentifier().toString():""; //$NON-NLS-1$
+		msg += getPluginVersion()!=null?" "+getPluginVersion().toString():""; //$NON-NLS-1$ //$NON-NLS-2$
+		return msg;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ISiteContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ISiteContentConsumer.java
new file mode 100644
index 0000000..ac8ba7d
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ISiteContentConsumer.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+ 
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+ 
+ /**
+  * A site content consumer manages the storage or archives, plugins and
+  * feature inside an <code> ISite</code>
+  */
+ 
+public interface ISiteContentConsumer {
+
+	/**
+	 * Stores a content reference into the SiteContentConsumer
+	 * @param contentReference the content reference to store
+	 * @param monitor the progress monitor
+	 * @throws CoreException if an error occurs storing the content reference
+	 * @since 2.0 
+	 */
+	public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException;
+
+	/**
+	 * opens a Non plugin Entry for storage
+	 * @return the new FeatureContentConsumer for this <code>INonPluginEntry</code>
+	 * @throws CoreException if the opens is done on a FeatureContentConsumer parent other than an IFeature.
+	 * @since 2.0 
+	 */
+	public IContentConsumer open(INonPluginEntry nonPluginEntry) throws CoreException;
+
+	/**
+	 * opens a Non plugin Entry for storage
+	 * @return the new FeatureContentConsumer for this <code>IPluginEntry</code>
+	 * @throws CoreException if the opens is done on a FeatureContentConsumer parent other than an IFeature.
+	 * @since 2.0 
+	 */
+	public IContentConsumer open(IPluginEntry pluginEntry) throws CoreException;
+	
+	/**
+	 * closes the opened SiteContentConsumer
+	 * @throws CoreException
+	 * @since 2.0 
+	 */
+	public IFeatureReference close() throws CoreException ;	
+	
+
+	/**
+	 * aborts the opened SiteContentConsumer
+	 * @throws CoreException
+	 * @since 2.0 
+	 */
+	public void abort() throws CoreException;		
+	
+}
+
+
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallConfiguration.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallConfiguration.java
new file mode 100644
index 0000000..c0801dd
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallConfiguration.java
@@ -0,0 +1,974 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.update.internal.model.SiteLocalModel;
+
+import org.eclipse.core.runtime.ListenerList;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.IActivity;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.configuration.IInstallConfigurationChangedListener;
+import org.eclipse.update.configuration.IProblemHandler;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.core.FeatureContentProvider;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteContentProvider;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.core.Site;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.eclipse.update.core.model.SiteModel;
+import org.eclipse.update.internal.configurator.ConfigurationActivator;
+import org.eclipse.update.internal.configurator.FeatureEntry;
+import org.eclipse.update.internal.configurator.PlatformConfiguration;
+import org.eclipse.update.internal.configurator.PluginEntry;
+import org.eclipse.update.internal.configurator.SiteEntry;
+import org.eclipse.update.internal.model.ConfigurationActivityModel;
+import org.eclipse.update.internal.model.ConfiguredSiteModel;
+import org.eclipse.update.internal.model.InstallConfigurationModel;
+import org.osgi.framework.Bundle;
+
+/**
+ * Manages ConfiguredSites
+ *
+ */
+
+public class InstallConfiguration extends InstallConfigurationModel implements IInstallConfiguration {
+	private static boolean isWindows = System.getProperty("os.name").startsWith("Win"); //$NON-NLS-1$ //$NON-NLS-2$
+	private ListenerList listeners = new ListenerList(ListenerList.IDENTITY);
+
+	/*
+	 * default constructor.
+	 */
+	public InstallConfiguration() {
+	}
+
+	/*
+	 * Copy constructor 
+	 * @since 3.0
+	 */
+	public InstallConfiguration(IInstallConfiguration config) throws MalformedURLException, CoreException {
+		this(config, null, null);
+	}
+	
+	/*
+	 * copy constructor
+	 */
+	public InstallConfiguration(IInstallConfiguration config, URL newLocation, String label) throws CoreException, MalformedURLException {
+		// set current date and timeline as caller can call setDate if the
+		// date on the URL string has to be the same
+		Date now = new Date();
+		setCreationDate(now);
+		setCurrent(false);
+		
+		if (newLocation == null) {
+			String newFileName = UpdateManagerUtils.getLocalRandomIdentifier(SiteLocalModel.CONFIG_FILE, now);
+			newLocation = UpdateManagerUtils.getURL(((LocalSite)SiteManager.getLocalSite()).getLocationURL(), newFileName, null);
+		}
+		setLocationURLString(newLocation.toExternalForm());
+		
+		if (label == null)
+			label = Utilities.format(now);
+		setLabel(label);
+
+		// do not copy list of listeners nor activities
+		// make a copy of the siteConfiguration object
+		if (config != null) {
+			IConfiguredSite[] csites = config.getConfiguredSites();
+			if (csites != null) {
+				for (int i = 0; i < csites.length; i++) {
+					ConfiguredSite configSite = new ConfiguredSite(csites[i]);
+					addConfigurationSiteModel(configSite);
+				}
+			}
+		}
+
+		resolve(newLocation, null);
+		// no need to parse file, all data are initialized
+		initialized = true;
+	}
+	
+
+	/*
+	 * Returns the list of configured sites or an empty array
+	 */
+	public IConfiguredSite[] getConfiguredSites() {
+		ConfiguredSiteModel[] result = getConfigurationSitesModel();
+		if (result.length == 0)
+			return new IConfiguredSite[0];
+		else
+			return (IConfiguredSite[]) result;
+	}
+
+	/*
+	 * Returns the default site policy
+	 */
+	private int getDefaultPolicy() {
+		return PlatformConfiguration.getDefaultPolicy();
+	}
+
+	/**
+	 * Creates a Configuration Site and a new Site
+	 * The policy is from <code> org.eclipse.core.boot.IPlatformConfiguration</code>
+	 */
+	public IConfiguredSite createConfiguredSite(File file) throws CoreException {
+
+		if (!file.getName().equals("eclipse")) { //$NON-NLS-1$
+			file = new File(file, "eclipse"); //$NON-NLS-1$
+			file.mkdirs();
+		}
+		
+		if (isDuplicateSite(file))
+			throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_location_exists, (new String[] { file.getPath() })),null);
+		ISite site = InternalSiteManager.createSite(file);
+
+		//create a config site around the site
+		// even if the site == null
+		BaseSiteLocalFactory factory = new BaseSiteLocalFactory();
+		ConfiguredSite configSite = (ConfiguredSite) factory.createConfigurationSiteModel((SiteModel) site, getDefaultPolicy());
+
+		if (configSite.isNativelyLinked()) {
+			throw Utilities.newCoreException(Messages.InstallConfiguration_AlreadyNativelyLinked, null); 
+		}
+		
+		if (configSite.isProductSite()) {
+			throw Utilities.newCoreException(Messages.InstallConfiguration_AlreadyProductSite, null); 
+		}
+		
+		if (site != null) {
+			configSite.setPlatformURLString(site.getURL().toExternalForm());
+
+			// obtain the list of plugins
+			IPlatformConfiguration runtimeConfiguration = ConfiguratorUtils.getCurrentPlatformConfiguration();
+			ConfigurationPolicy configurationPolicy = configSite.getConfigurationPolicy();
+			String[] pluginPath = new String[0];
+			if (configurationPolicy.getPolicy() == IPlatformConfiguration.ISitePolicy.USER_INCLUDE)
+				pluginPath = configurationPolicy.getPluginPath(site);
+
+			// create new Site in configuration
+			IPlatformConfiguration.ISitePolicy sitePolicy = runtimeConfiguration.createSitePolicy(configurationPolicy.getPolicy(), pluginPath);
+
+			// change runtime
+			IPlatformConfiguration.ISiteEntry siteEntry = runtimeConfiguration.createSiteEntry(site.getURL(), sitePolicy);
+			runtimeConfiguration.configureSite(siteEntry);
+
+			// if the privatre marker doesn't already exist create it
+			configSite.createPrivateSiteMarker();
+			((SiteModel)site).setConfiguredSiteModel(configSite);
+		}
+		// configure all features as enable
+		configure(configSite);
+		
+		return configSite;
+	}
+
+	/**
+	 * Creates a Configuration Site and a new Site as a private link site
+	 * The policy is from <code> org.eclipse.core.boot.IPlatformConfiguration</code>
+	 */
+	public IConfiguredSite createLinkedConfiguredSite(File file) throws CoreException {
+		return createConfiguredSite(file);
+//		if (isDuplicateSite(file))
+//			throw Utilities.newCoreException(UpdateUtils.getFormattedMessage("InstallConfiguration.location.exists", file.getPath()),null);
+//		
+//		ISite site = InternalSiteManager.createSite(file);
+//
+//		//create a config site around the site
+//		// even if the site == null
+//		BaseSiteLocalFactory factory = new BaseSiteLocalFactory();
+//		ConfiguredSite configSite = (ConfiguredSite) factory.createConfigurationSiteModel((SiteModel) site, getDefaultPolicy());
+//
+//		if (!configSite.isExtensionSite()) {
+//			String msg = Policy.bind("InstallConfiguration.NotAnExtensionSite");
+//			throw Utilities.newCoreException(msg, null);
+//		}
+//
+//		if (configSite.isNativelyLinked()) {
+//			throw Utilities.newCoreException("InstallConfiguration.AlreadyNativelyLinked", null);
+//		}
+//
+//		if (site != null) {
+//			configSite.setPlatformURLString(site.getURL().toExternalForm());
+//
+//			// obtain the list of plugins
+//			IPlatformConfiguration runtimeConfiguration = ConfiguratorUtils.getCurrentPlatformConfiguration();
+//			ConfigurationPolicy configurationPolicy = configSite.getConfigurationPolicy();
+//			String[] pluginPath = new String[0];
+//			if (configurationPolicy.getPolicy() == IPlatformConfiguration.ISitePolicy.USER_INCLUDE)
+//				pluginPath = configurationPolicy.getPluginPath(site);
+//
+//			// create new Site in configuration
+//			IPlatformConfiguration.ISitePolicy sitePolicy = runtimeConfiguration.createSitePolicy(configurationPolicy.getPolicy(), pluginPath);
+//
+//			// change runtime
+//			IPlatformConfiguration.ISiteEntry siteEntry = runtimeConfiguration.createSiteEntry(site.getURL(), sitePolicy);
+//			runtimeConfiguration.configureSite(siteEntry);
+//
+//		}
+//
+//		// configure all features as enable
+//		configure(configSite);
+//
+//		return configSite;
+	}
+
+	/*
+	 *Configure all features as Enable Check we only enable highest version
+	 */
+	private void configure(ConfiguredSite linkedSite) throws CoreException {
+		ISite site = linkedSite.getSite();
+		ISiteFeatureReference[] newFeaturesRef = site.getFeatureReferences();
+
+		for (int i = 0; i < newFeaturesRef.length; i++) {
+			// TRACE
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) {
+				String reconciliationType = "enable (optimistic)"; //$NON-NLS-1$
+				UpdateCore.debug("New Linked Site:New Feature: " + newFeaturesRef[i].getURL() + " as " + reconciliationType); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			ConfigurationPolicy policy = linkedSite.getConfigurationPolicy();
+			policy.configure(newFeaturesRef[i], true, false);
+		}
+		SiteReconciler.checkConfiguredFeatures(linkedSite);
+	}
+
+	/*
+	 *
+	 */
+	public void addConfiguredSite(IConfiguredSite site) {
+		if (!isCurrent() && isReadOnly())
+			return;
+
+		ConfigurationActivity activity = new ConfigurationActivity(IActivity.ACTION_SITE_INSTALL);
+		activity.setLabel(site.getSite().getURL().toExternalForm());
+		activity.setDate(new Date());
+		ConfiguredSiteModel configSiteModel = (ConfiguredSiteModel) site;
+		addConfigurationSiteModel(configSiteModel);
+		configSiteModel.setInstallConfigurationModel(this);
+
+		// notify listeners
+		Object[] configurationListeners = listeners.getListeners();
+		for (int i = 0; i < configurationListeners.length; i++) {
+			IInstallConfigurationChangedListener listener = ((IInstallConfigurationChangedListener) configurationListeners[i]);
+			listener.installSiteAdded(site);
+		}
+
+		// everything done ok
+		activity.setStatus(IActivity.STATUS_OK);
+		this.addActivity(activity);
+	}
+
+	/**
+	 * Method addActivity.
+	 * @param activity
+	 */
+	public void addActivity(IActivity activity) {
+		addActivityModel((ConfigurationActivityModel)activity);
+	}
+
+	/*
+	 *
+	 */
+	public void removeConfiguredSite(IConfiguredSite site) {
+		if (!isCurrent() && isReadOnly())
+			return;
+
+		if (removeConfigurationSiteModel((ConfiguredSiteModel) site)) {
+			// notify listeners
+			Object[] configurationListeners = listeners.getListeners();
+			for (int i = 0; i < configurationListeners.length; i++) {
+				IInstallConfigurationChangedListener listener = ((IInstallConfigurationChangedListener) configurationListeners[i]);
+				listener.installSiteRemoved(site);
+			}
+			
+			//activity
+			ConfigurationActivity activity = new ConfigurationActivity(IActivity.ACTION_SITE_REMOVE);
+			activity.setLabel(site.getSite().getURL().toExternalForm());
+			activity.setDate(new Date());
+			activity.setStatus(IActivity.STATUS_OK);
+			this.addActivity(activity);
+		}
+	}
+
+	/*
+	 * @see IInstallConfiguration#addInstallConfigurationChangedListener(IInstallConfigurationChangedListener)
+	 */
+	public void addInstallConfigurationChangedListener(IInstallConfigurationChangedListener listener) {
+		listeners.add(listener);
+	}
+
+	/*
+	 * @see IInstallConfiguration#removeInstallConfigurationChangedListener(IInstallConfigurationChangedListener)
+	 */
+	public void removeInstallConfigurationChangedListener(IInstallConfigurationChangedListener listener) {
+		listeners.remove(listener);
+	}
+
+
+	/*
+	 * Deletes the configuration from its URL/location
+	 */
+	public void remove() {
+		// save the configuration
+		if ("file".equalsIgnoreCase(getURL().getProtocol())) { //$NON-NLS-1$
+			// the location points to a file
+			File file = new File(getURL().getFile());
+			UpdateManagerUtils.removeFromFileSystem(file);
+		}
+	}
+
+	/**
+	 * Saves the configuration into its URL/location
+	 * and changes the platform configuration.
+	 * The runtime site entries from platform.xml are updated as required
+	 * (cannot recreate these because must preserve other runtime state) [18520]
+	 * @return true if restart is needed
+	 */
+	public boolean save() throws CoreException {
+		
+		// Write info  into platform for the next runtime
+		IPlatformConfiguration runtimeConfiguration = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		ConfiguredSiteModel[] configurationSites = getConfigurationSitesModel();
+
+		// clean configured Entries from platform runtime
+		IPlatformConfiguration.IFeatureEntry[] configuredFeatureEntries = runtimeConfiguration.getConfiguredFeatureEntries();
+		for (int i = 0; i < configuredFeatureEntries.length; i++) {
+			runtimeConfiguration.unconfigureFeatureEntry(configuredFeatureEntries[i]);
+		}
+
+		// [19958] remember sites currently configured by runtime (use
+		// temp configuration object rather than a straight list to ensure
+		// correct lookup)
+		IPlatformConfiguration tempConfig = null;
+		try {
+			tempConfig = ConfiguratorUtils.getPlatformConfiguration(null);
+			IPlatformConfiguration.ISiteEntry[] tmpSites = runtimeConfiguration.getConfiguredSites();
+			for (int i = 0; i < tmpSites.length; i++) {
+				tempConfig.configureSite(tmpSites[i]);
+			}
+		} catch (IOException e) {
+			// assume no currently configured sites
+		}
+
+		//check sites
+		checkSites(configurationSites, runtimeConfiguration);
+
+		// Save the plugin path, primary feature and platform
+		for (int i = 0; i < configurationSites.length; i++) {
+			ConfiguredSite cSite = ((ConfiguredSite) configurationSites[i]);
+			ConfigurationPolicy configurationPolicy = cSite.getConfigurationPolicy();
+
+			savePluginPath(cSite, runtimeConfiguration, tempConfig);
+
+			// IF primary feature URL or platform feature URL that we need to pass to runtime config
+			// is part of platform:base:, write it as platform:base: URL
+			IFeatureReference[] configuredFeaturesRef = configurationPolicy.getConfiguredFeatures();
+			for (int j = 0; j < configuredFeaturesRef.length; j++) {
+				IFeature feature = null;
+				try {
+					feature = configuredFeaturesRef[j].getFeature(null);
+				} catch (CoreException e) {
+					UpdateCore.warn(null, e);
+				}
+				saveFeatureEntry(cSite, feature, runtimeConfiguration);
+			}
+		}
+
+		// [19958] remove any extra site entries from runtime configuration
+		// (site entries that no longer exist in this configuration)
+		if (tempConfig != null) {
+			IPlatformConfiguration.ISiteEntry[] tmpSites = tempConfig.getConfiguredSites();
+			for (int i = 0; i < tmpSites.length; i++) {
+				runtimeConfiguration.unconfigureSite(tmpSites[i]);
+			}
+		}
+
+		try {
+			runtimeConfiguration.save();
+			// log configuration and activities
+			this.date = new Date(runtimeConfiguration.getChangeStamp());
+			if ("file".equalsIgnoreCase(getURL().getProtocol())) //$NON-NLS-1$
+				UpdateCore.log(this);
+			resetActivities();
+			return isRestartNeeded(runtimeConfiguration);
+		} catch (IOException e) {
+			CoreException exc = Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_UnableToSavePlatformConfiguration, (new String[] { runtimeConfiguration.getConfigurationLocation().toExternalForm() })), e);
+			UpdateCore.warn("",exc); //$NON-NLS-1$
+		}
+		return true;
+	}
+
+	/*
+	 * Write the plugin path for each site
+	 * Do not check if the site already existed before [16696].
+	 * Reuse any runtime site objects in platform.cfg (to preserve state) [18520].
+	 */
+	private void savePluginPath(ConfiguredSite cSite, IPlatformConfiguration runtimeConfiguration, IPlatformConfiguration tempConfig) // [19958]
+	throws CoreException {
+
+		ConfigurationPolicy configurationPolicy = cSite.getConfigurationPolicy();
+
+		// create a ISitePolicy (policy, pluginPath)
+		// for the site
+		String[] pluginPath = configurationPolicy.getPluginPath(cSite.getSite());
+		IPlatformConfiguration.ISitePolicy sitePolicy = runtimeConfiguration.createSitePolicy(configurationPolicy.getPolicy(), pluginPath);
+
+		// get the URL of the site that matches the one platform.cfg gave us
+		URL urlToCheck = null;
+		try {
+			urlToCheck = new URL(cSite.getPlatformURLString());
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_UnableToCreateURL, (new String[] { cSite.getPlatformURLString() })), e);
+		} catch (ClassCastException e) {
+			throw Utilities.newCoreException(Messages.InstallConfiguration_UnableToCast, e);	
+		}
+
+		// update runtime configuration [18520]
+		// Note: we must not blindly replace the site entries because they
+		//       contain additional runtime state that needs to be preserved.
+		IPlatformConfiguration.ISiteEntry siteEntry = runtimeConfiguration.findConfiguredSite(urlToCheck);
+		if (siteEntry == null)
+			siteEntry = runtimeConfiguration.createSiteEntry(urlToCheck, sitePolicy);
+		else {
+			siteEntry.setSitePolicy(sitePolicy);
+			((SiteEntry)siteEntry).refreshPlugins();
+			if (tempConfig != null) // [19958] remove reused entries from list
+				tempConfig.unconfigureSite(siteEntry);
+		}
+		((SiteEntry)siteEntry).setEnabled(cSite.isEnabled());
+		runtimeConfiguration.configureSite(siteEntry, true /*replace if exists*/);
+	}
+
+	/*
+	 * Save the Feature entry
+	 * The feature can be a primary feature and/or a platform feature
+	 */
+	private void saveFeatureEntry(ConfiguredSite cSite, IFeature feature, IPlatformConfiguration runtimeConfiguration) throws CoreException {
+		if (feature == null)
+			return;
+
+		// get the URL of the plugin that corresponds to the feature (pluginid = featureid)
+		String id = feature.getVersionedIdentifier().getIdentifier();
+		IPluginEntry[] entries = feature.getPluginEntries();
+		URL url = null;
+		IPluginEntry featurePlugin = null;
+		for (int k = 0; k < entries.length; k++) {
+			if (id.equalsIgnoreCase(entries[k].getVersionedIdentifier().getIdentifier())) {
+				url = getRuntimeConfigurationURL(entries[k], cSite);
+				featurePlugin = entries[k];
+				break;
+			}
+		}
+		String pluginVersion = null;
+		if (featurePlugin != null)
+			pluginVersion = featurePlugin.getVersionedIdentifier().getVersion().toString();
+
+        // Find the site
+        SiteEntry siteEntry = null;
+        try {
+            URL featureUrl = new URL(cSite.getPlatformURLString());
+            siteEntry = (SiteEntry)runtimeConfiguration.findConfiguredSite(featureUrl);
+        } catch (MalformedURLException e) {
+            throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_UnableToCreateURL, (new String[] { cSite.getPlatformURLString() })), e);
+        } catch (ClassCastException e) {
+            throw Utilities.newCoreException(Messages.InstallConfiguration_UnableToCast, e);    
+        }
+
+        // if the URL doesn't exist throw a CoreException
+        if (siteEntry == null) {
+            throw new CoreException(
+                    new Status(IStatus.ERROR, UpdateCore.getPlugin().getBundle().getSymbolicName(),
+                            NLS.bind(Messages.InstallConfiguration_unableToFindSite, (new String[] { cSite.getSite().getURL().toExternalForm(), runtimeConfiguration.getConfigurationLocation().toExternalForm() }))));
+        }
+
+		// write the primary features
+		if (feature.isPrimary()) {
+			// get any fragments for the feature plugin
+			ArrayList list = new ArrayList();
+			if (url != null)
+				list.add(url);
+			if (featurePlugin != null) {
+				URL[] fragments = getRuntimeFragmentURLs(featurePlugin);
+				list.addAll(Arrays.asList(fragments));
+			}
+			URL[] roots = (URL[]) list.toArray(new URL[0]);
+			String pluginIdentifier = feature.getPrimaryPluginID();
+
+			// save information in runtime platform state
+			String version = feature.getVersionedIdentifier().getVersion().toString();
+			String application = feature.getApplication();
+			FeatureEntry featureEntry = (FeatureEntry)runtimeConfiguration.createFeatureEntry(id, version, pluginIdentifier, pluginVersion, true, application, roots);
+			featureEntry.setURL(getFeatureRelativeURL(feature));
+			siteEntry.addFeatureEntry(featureEntry);
+		} else {
+			// write non-primary feature entries
+			String version = feature.getVersionedIdentifier().getVersion().toString();
+			String pluginIdentifier = feature.getPrimaryPluginID();
+			FeatureEntry featureEntry = (FeatureEntry)runtimeConfiguration.createFeatureEntry(id, version, pluginIdentifier, pluginVersion, false, null, null);
+			featureEntry.setURL(getFeatureRelativeURL(feature));
+			siteEntry.addFeatureEntry(featureEntry);
+		}
+
+		// write the platform features (features that contain special platform plugins)
+		IPluginEntry[] platformPlugins = getPlatformPlugins(feature, runtimeConfiguration);
+		for (int k = 0; k < platformPlugins.length; k++) {
+			id = platformPlugins[k].getVersionedIdentifier().getIdentifier();
+			url = getRuntimeConfigurationURL(platformPlugins[k], cSite);
+			if (url != null) {
+				runtimeConfiguration.setBootstrapPluginLocation(id, url);
+			}
+		}
+	}
+
+	/*
+	 * Log if we are about to create a site that didn't exist before
+	 * in platform.cfg [16696].
+	 */
+	private void checkSites(ConfiguredSiteModel[] configurationSites, IPlatformConfiguration runtimeConfiguration) throws CoreException {
+
+		// check all the sites we are about to write already existed
+		// they should have existed either because they were created by
+		// updateManager or because we read them from platform.cfg
+		for (int i = 0; i < configurationSites.length; i++) {
+			// get the URL of the site that matches the one platform.cfg gave us
+			URL urlToCheck = null;
+			try {
+				urlToCheck = new URL(configurationSites[i].getPlatformURLString());
+			} catch (MalformedURLException e) {
+				UpdateCore.warn(NLS.bind(Messages.InstallConfiguration_UnableToCreateURL, (new String[] { configurationSites[i].getPlatformURLString() })), e);
+			} catch (ClassCastException e) {
+				UpdateCore.warn(Messages.InstallConfiguration_UnableToCast, e);
+			}
+
+			// if the URL doesn't exits log it
+			IPlatformConfiguration.ISiteEntry siteEntry = runtimeConfiguration.findConfiguredSite(urlToCheck);
+			if (siteEntry == null) {
+				UpdateCore.warn(NLS.bind(Messages.InstallConfiguration_unableToFindSite, (new String[] { urlToCheck.toExternalForm(), runtimeConfiguration.getConfigurationLocation().toExternalForm() }))); 
+			}
+		}
+	}
+
+
+	/*
+	 * reverts this configuration to the match the new one
+	 *
+	 * Compare the oldSites with the currentOne. the old state is the state we want to revert to.
+	 *
+	 * If a site was in old state, but not in the currentOne, keep it in the hash.
+	 * If a site is in the currentOne but was not in the old state, unconfigure all features and add it in the hash
+	 * If a site was in baoth state, calculate the 'delta' and re-set it in the hash map
+	 *
+	 * At the end, set the configured site from the new sites hash map
+	 *
+	 */
+	public void revertTo(IInstallConfiguration configuration, IProgressMonitor monitor, IProblemHandler handler) throws CoreException, InterruptedException {
+
+		IConfiguredSite[] oldConfigSites = configuration.getConfiguredSites();
+		IConfiguredSite[] nowConfigSites = this.getConfiguredSites();
+
+		// create a hashtable of the *old* and *new* sites
+		Map oldSitesMap = new Hashtable(0);
+		Map newSitesMap = new Hashtable(0);
+		for (int i = 0; i < oldConfigSites.length; i++) {
+			IConfiguredSite element = oldConfigSites[i];
+			oldSitesMap.put(element.getSite().getURL().toExternalForm(), element);
+			newSitesMap.put(element.getSite().getURL().toExternalForm(), element);
+		}
+		// create list of all the sites that map the *old* sites
+		// we want the intersection between the old sites and the current sites
+		if (nowConfigSites != null) {
+			String key = null;
+
+			for (int i = 0; i < nowConfigSites.length; i++) {
+				key = nowConfigSites[i].getSite().getURL().toExternalForm();
+				IConfiguredSite oldSite = (IConfiguredSite) oldSitesMap.get(key);
+				if (oldSite != null) {
+					// the Site existed before, calculate the delta between its current state and the
+					// state we are reverting to and put it back into the map
+					 ((ConfiguredSite) nowConfigSites[i]).revertTo(oldSite, monitor, handler);
+				} else {
+					// the site didn't exist in the InstallConfiguration we are reverting to
+					// unconfigure everything from this site so it is still present
+					ISiteFeatureReference[] featuresToUnconfigure = nowConfigSites[i].getSite().getFeatureReferences();
+					for (int j = 0; j < featuresToUnconfigure.length; j++) {
+						IFeature featureToUnconfigure = null;
+						try {
+							featureToUnconfigure = featuresToUnconfigure[j].getFeature(null);
+						} catch (CoreException e) {
+							UpdateCore.warn(null, e);
+						}
+						if (featureToUnconfigure != null)
+							nowConfigSites[i].unconfigure(featureToUnconfigure);
+					}
+				}
+				newSitesMap.put(key,nowConfigSites[i]);
+			}
+
+			// the new configuration has the exact same sites as the old configuration
+			// the old configuration in the Map are either as-is because they don't exist
+			// in the current one, or they are the delta from the current one to the old one
+			Collection sites = newSitesMap.values();
+			if (sites != null && !sites.isEmpty()) {
+				ConfiguredSiteModel[] sitesModel = new ConfiguredSiteModel[sites.size()];
+				sites.toArray(sitesModel);
+				setConfigurationSiteModel(sitesModel);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallConfiguration#getActivities()
+	 */
+	public IActivity[] getActivities() {
+		if (getActivityModel().length == 0)
+			return new IActivity[0];
+		return (IActivity[]) getActivityModel();
+	}
+
+	/*
+	 * returns the list of platform plugins of the feature or an empty list
+	 * if the feature doesn't contain any platform plugins
+	 */
+	private IPluginEntry[] getPlatformPlugins(IFeature feature, IPlatformConfiguration runtimeConfiguration) {
+		Map featurePlatformPlugins = new HashMap();
+		String[] platformPluginID = runtimeConfiguration.getBootstrapPluginIdentifiers();
+		IPluginEntry[] featurePlugins = feature.getPluginEntries();
+
+		for (int i = 0; i < platformPluginID.length; i++) {
+			String featurePluginId = null;
+			for (int j = 0; j < featurePlugins.length; j++) {
+				featurePluginId = featurePlugins[j].getVersionedIdentifier().getIdentifier();
+				if (platformPluginID[i].equals(featurePluginId)) {
+					featurePlatformPlugins.put(platformPluginID[i], featurePlugins[j]);
+				}
+			}
+		}
+
+		Collection values = featurePlatformPlugins.values();
+		if (values == null || values.size() == 0)
+			return new IPluginEntry[0];
+
+		IPluginEntry[] result = new IPluginEntry[values.size()];
+		Iterator iter = values.iterator();
+		int index = 0;
+		while (iter.hasNext()) {
+			result[index] = ((IPluginEntry) iter.next());
+			index++;
+		}
+		return result;
+	}
+
+	/*
+	 * returns the URL of the pluginEntry on the site
+	 * Transform the URL to use platform: protocol if needed
+	 * return null if the URL to write is not valid
+	 */
+	private URL getRuntimeConfigurationURL(IPluginEntry entry, ConfiguredSite cSite) throws CoreException {
+
+		String rootString = cSite.getPlatformURLString();
+		String pluginPathID = getPathID(entry);
+		try {
+			ISiteContentProvider siteContentProvider = cSite.getSite().getSiteContentProvider();
+			URL pluginEntryfullURL = siteContentProvider.getArchiveReference(pluginPathID);
+
+			//
+			if (!rootString.startsWith("platform")) { //$NON-NLS-1$
+				// DEBUG:
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION)
+					UpdateCore.debug("getRuntimeConfiguration Plugin Entry Full URL:" + pluginEntryfullURL + " Platform String:" + rootString + " [NON PLATFORM URL]."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				return pluginEntryfullURL;
+			}
+
+			//URL pluginEntryRootURL = Platform.resolve(new URL(rootString));
+			// Do not resolve [16507], just use platform:base/ as a root
+			// rootString = platform:base
+			// pluginRoot = /home/a
+			// pluginFull = /home/a/c/boot.jar
+			// relative = platform:/base/c/boot.jar
+			URL pluginEntryRootURL = cSite.getSite().getURL();
+			String relativeString = UpdateManagerUtils.getURLAsString(pluginEntryRootURL, pluginEntryfullURL);
+			URL result = new URL(new URL(rootString), relativeString);
+
+			// DEBUG:
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION)
+				UpdateCore.debug("getRuntimeConfiguration plugin Entry Full URL:" + pluginEntryfullURL + " Platform String:" + rootString + " Site URL:" + pluginEntryRootURL + " Relative:" + relativeString); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+			// verify we are about to write a valid file URL
+			// check with fullURL as it is not resolved to platform:base/
+			if (pluginEntryfullURL != null) {
+				if ("file".equals(pluginEntryfullURL.getProtocol())) { //$NON-NLS-1$
+					String fileString = pluginEntryfullURL.getFile();
+					if (!new File(fileString).exists()) {
+						UpdateCore.warn("The URL:" + result + " doesn't point to a valid platform plugin.The URL will not be written in the platform configuration", new Exception()); //$NON-NLS-1$ //$NON-NLS-2$
+						return null;
+					}
+				}
+			}
+
+			return result;
+		} catch (IOException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_UnableToCreateURL, (new String[] { rootString })), e);
+		}
+	}
+
+	/*
+	 * Return URLs for any fragments that are associated with the specified plugin entry
+	 */
+	private URL[] getRuntimeFragmentURLs(IPluginEntry entry) throws CoreException {
+
+		// get the identifier associated with the entry
+		VersionedIdentifier vid = entry.getVersionedIdentifier();
+
+		// get the plugin descriptor from the registry
+		Bundle bundle = Platform.getBundle(vid.getIdentifier());
+		ArrayList list = new ArrayList();
+		if (bundle != null && bundle.getState() != Bundle.UNINSTALLED && bundle.getState() != Bundle.INSTALLED) {
+			FragmentEntry[] fragments = UpdateManagerUtils.getFragments(bundle);
+			for (int i = 0; fragments != null && i < fragments.length; i++) {
+				String location = fragments[i].getLocation();
+				try {
+					URL locationURL = new URL(location);
+					locationURL = FileLocator.toFileURL(FileLocator.resolve(locationURL));
+					list.add(asInstallRelativeURL(locationURL));
+				} catch (IOException e) {
+					// skip bad fragments
+				}
+			}
+		}
+		return (URL[]) list.toArray(new URL[0]);
+	}
+
+	/**
+	 * Returns the path identifier for a plugin entry.
+	 * <code>plugins/&lt;pluginId>_&lt;pluginVersion>.jar</code>
+	 * @return the path identifier
+	 */
+	private String getPathID(IPluginEntry entry) {
+		return Site.DEFAULT_PLUGIN_PATH + entry.getVersionedIdentifier().toString() + FeatureContentProvider.JAR_EXTENSION;
+	}
+
+	/**
+	 * Try to recast URL as platform:/base/
+	 */
+	private URL asInstallRelativeURL(URL url) {
+		// get location of install
+		URL install = ConfiguratorUtils.getInstallURL();
+
+		// try to determine if supplied URL can be recast as install-relative
+		if (install.getProtocol().equals(url.getProtocol())) {
+			if (install.getProtocol().equals("file")) { //$NON-NLS-1$
+				String installS = new File(install.getFile()).getAbsolutePath().replace(File.separatorChar, '/');
+				if (!installS.endsWith("/")) //$NON-NLS-1$
+					installS += "/"; //$NON-NLS-1$
+				String urlS = new File(url.getFile()).getAbsolutePath().replace(File.separatorChar, '/');
+				if (!urlS.endsWith("/")) //$NON-NLS-1$
+					urlS += "/"; //$NON-NLS-1$
+				int ix = installS.lastIndexOf("/"); //$NON-NLS-1$
+				if (ix != -1) {
+					installS = installS.substring(0, ix + 1);
+					if (urlS.startsWith(installS)) {
+						try {
+							return new URL("platform:/base/" + urlS.substring(installS.length())); //$NON-NLS-1$
+						} catch (MalformedURLException e) {
+						}
+					}
+				}
+			}
+		}
+		return url;
+	}
+	
+	private boolean isDuplicateSite(File siteDirectory) {
+		IConfiguredSite[] sites = getConfiguredSites();
+		URL fileURL;
+		try {
+			fileURL = siteDirectory.toURL();
+		} catch (MalformedURLException e) {
+			return false;
+		}
+		for (int i = 0; i < sites.length; i++) {
+			URL url = sites[i].getSite().getURL();
+			if (UpdateManagerUtils.sameURL(fileURL, url))
+				return true;
+		}
+		return false;
+	}
+	
+	/*
+	 * Returns the feature url relative to the site.
+	 */
+	private String getFeatureRelativeURL(IFeature feature) {
+		String url = feature.getURL().toExternalForm();
+		String siteURL = feature.getSite().getURL().toExternalForm();
+		// TODO fix this. toURL() returns file:/d:/eclipse/etc... wheareas the 
+		// platform.asLocalURL() returns file:d:/eclipse/etc... (no leading / )
+//		if (url.startsWith("file:/") && Platform.getOS().equals("win32"))
+//			url = "file:" + url.substring(6);
+		
+		if (url.startsWith(siteURL))
+			return url.substring(siteURL.length());
+		else
+			return url;
+	}
+	
+	/**
+	 * @return true if restart is needed
+	 */
+	private boolean isRestartNeeded(IPlatformConfiguration runtimeConfig) {
+
+		// First, create a map for faster lookups
+		Set newPluginsSet = null;
+		if (runtimeConfig instanceof PlatformConfiguration) {
+			newPluginsSet = ((PlatformConfiguration)runtimeConfig).getPluginPaths();
+			// On windows, we will be doing case insensitive search as well, so lower it now
+			if (isWindows) {
+				String[] newPluginsSetArray = (String[])newPluginsSet.toArray( new String[newPluginsSet.size()]);
+				for (int i = 0; i < newPluginsSetArray.length; i++) {
+					newPluginsSet.add(newPluginsSetArray[i].toLowerCase());
+				}
+			}
+		} else {
+			URL[] newBundlePaths = runtimeConfig.getPluginPath();
+			newPluginsSet = new HashSet(newBundlePaths.length);
+			for (int i=0; i<newBundlePaths.length; i++) {
+				
+				String pluginLocation = newBundlePaths[i].getFile();
+				newPluginsSet.add(pluginLocation);
+				// On windows, we will be doing case insensitive search as well, so lower it now
+				if (isWindows)
+					newPluginsSet.add(pluginLocation.toLowerCase());
+			}
+		}
+		
+		
+		
+		Bundle[] oldBundles = UpdateCore.getPlugin().getBundleContext().getBundles();
+
+		int offset = ConfigurationActivator.UPDATE_PREFIX.length();
+		for (int i=0; i<oldBundles.length; i++) {
+			if (oldBundles[i].getBundleId() == 0)
+				continue; // skip the system bundle
+			String oldBundleLocation = oldBundles[i].getLocation();
+			// Don't worry about bundles we did not install
+			if (!oldBundleLocation.startsWith(ConfigurationActivator.UPDATE_PREFIX))
+				continue;
+			oldBundleLocation = oldBundleLocation.substring(offset);
+			
+			if (newPluginsSet.contains(oldBundleLocation))
+				continue;
+			if (isWindows && newPluginsSet.contains(oldBundleLocation.toLowerCase()))
+				continue;
+			
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION)
+				UpdateCore.debug("Bundle " + oldBundleLocation + " has been removed"); //$NON-NLS-1$ //$NON-NLS-2$
+			return true;
+		}
+		
+		if (runtimeConfig instanceof PlatformConfiguration) {
+			return areThereNewVersionOfOldPlugins( ((PlatformConfiguration)runtimeConfig).getPlugins(), oldBundles);
+		}
+
+		return false;
+	}
+	
+	/**
+	 * The method should only be called if all old plug-ins exist in the new
+	 * configuration. Determines if a new version was added to any plugin ID, so
+	 * more versions are enabled for any given plug-in id then in old
+	 * configuration.
+	 * 
+	 * @param newConfigurationPlugins
+	 * @param oldConfigurationBundles
+	 * @return
+	 */
+	private boolean areThereNewVersionOfOldPlugins(PluginEntry[] newConfigurationPlugins, Bundle[] oldConfigurationBundles) {
+
+		
+		for ( int i = 0; i < oldConfigurationBundles.length; i++) {
+			if (oldConfigurationBundles[i].getBundleId() == 0)
+				continue; // skip the system bundle
+			if ( getNumberOfPlugins(oldConfigurationBundles[i].getSymbolicName(), oldConfigurationBundles) != getNumberOfPlugins(oldConfigurationBundles[i].getSymbolicName(), newConfigurationPlugins)) {
+				return true;
+			}
+		}
+		return false;				
+	}
+
+	private int getNumberOfPlugins(String symbolicName, PluginEntry[] newConfigurationPlugins) {
+		
+		int numberOfPlugins = 0;
+		
+		for ( int i = 0; i < newConfigurationPlugins.length; i++) {
+			if ( symbolicName.equals(newConfigurationPlugins[i].getPluginIdentifier())) {
+				numberOfPlugins++;
+			}
+		}
+		
+		return numberOfPlugins;
+	}
+
+	private int getNumberOfPlugins(String symbolicName, Bundle[] oldConfigurationBundles) {
+
+		int numberOfPlugins = 0;
+		
+		for ( int i = 0; i < oldConfigurationBundles.length; i++) {
+			if ( symbolicName.equals(oldConfigurationBundles[i].getSymbolicName())) {
+				numberOfPlugins++;
+			}
+		}
+		
+		return numberOfPlugins;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (!(obj instanceof InstallConfiguration))
+			return false;
+		
+		InstallConfiguration config = (InstallConfiguration)obj;
+	
+		return getCreationDate().equals(config.getCreationDate()) && 
+				getLabel().equals(config.getLabel()) &&
+				getLocationURLString().equals(config.getLocationURLString());
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallHandlerProxy.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallHandlerProxy.java
new file mode 100644
index 0000000..0b47f34
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallHandlerProxy.java
@@ -0,0 +1,613 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.ContentReference;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureContentConsumer;
+import org.eclipse.update.core.IInstallHandler;
+import org.eclipse.update.core.IInstallHandlerEntry;
+import org.eclipse.update.core.IInstallHandlerWithFilter;
+import org.eclipse.update.core.INonPluginEntry;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.IVerificationListener;
+import org.eclipse.update.core.InstallMonitor;
+import org.eclipse.update.core.Utilities;
+import org.osgi.framework.Bundle;
+
+public class InstallHandlerProxy implements IInstallHandlerWithFilter {
+
+	private IFeature feature = null;
+	private int type;
+	private IInstallHandler handler = null;
+	private IStatus savedStatus = null;
+	private boolean DEBUG = false;
+
+	private static final String EXT_PLUGIN = "org.eclipse.update.core"; //$NON-NLS-1$
+	private static final String UI_PLUGIN = "org.eclipse.ui"; //$NON-NLS-1$
+	private static final String EXT_POINT = "installHandlers"; //$NON-NLS-1$
+	private Method nonPluginDataAcceptor = null;
+
+	/**
+	 * A class loader that combines a the org.eclipse.update.core plugin class loader with the
+	 * org.eclipse.ui class loader (only when UI is active).
+	 */
+	private static class InstallHandlerClassLoader extends URLClassLoader {
+		private Bundle updateCore;
+		private Bundle eclipseUI;
+
+		public InstallHandlerClassLoader(URL[] classpath) {
+			super(classpath);
+			updateCore = Platform.getBundle(EXT_PLUGIN);
+			eclipseUI = Platform.getBundle(UI_PLUGIN);
+			if (eclipseUI != null && eclipseUI.getState() != Bundle.ACTIVE) 
+				eclipseUI = null;
+		}
+
+		public Class loadClass(String className) throws ClassNotFoundException {
+			// First check update core plugin loader, then the eclipse ui plugin loader
+			Class c = null;
+			try {
+				c = updateCore.loadClass(className);
+			} catch (ClassNotFoundException e) {
+				try {
+					if(eclipseUI != null)
+						c = eclipseUI.loadClass(className);
+				} catch (ClassNotFoundException e2) {
+				} finally {
+				}
+			} finally {
+			}
+			if (c != null)
+				return c;
+			else
+				return super.loadClass(className);
+		}
+
+		public URL getResource(String resName) {
+			// First check update core plugin loader, then the eclipse ui plugin loader
+			URL u = updateCore.getResource(resName);
+			if(u == null && eclipseUI != null)
+				u = eclipseUI.getResource(resName);
+				
+			if (u != null)
+				return u;
+			else
+				return super.getResource(resName);
+		}
+	}
+	
+	public InstallHandlerProxy(
+		int type,
+		IFeature feature,
+		IInstallHandlerEntry entry,
+		InstallMonitor monitor)
+		throws CoreException {
+
+		initialize(type, feature, entry, monitor);
+	}
+
+	/*
+	 * @see IInstallHandler#initialize
+	 */
+	public void initialize(
+		int type,
+		IFeature feature,
+		IInstallHandlerEntry entry,
+		InstallMonitor monitor)
+		throws CoreException {
+
+		DEBUG = UpdateCore.DEBUG_SHOW_IHANDLER;
+		// validate arguments
+		if (feature == null)
+			throw new IllegalArgumentException();
+		this.feature = feature;
+		this.type = type;
+
+		//  check if we have a handler entry specified in the feature.xml
+		if (entry == null) {
+			if (DEBUG)
+				debug("not specified"); //$NON-NLS-1$
+			return; // no handler entry
+		}
+
+		String library = entry.getLibrary();
+		String handlerName = entry.getHandlerName();
+		if (handlerName == null || handlerName.trim().equals("")) { //$NON-NLS-1$
+			if (DEBUG)
+				debug("not specified"); //$NON-NLS-1$
+			return; // no handler class spacified in entry
+		}
+		if (DEBUG) {
+			debug("handler=" + handlerName); //$NON-NLS-1$
+			debug("path=   " + library); //$NON-NLS-1$
+		}
+
+		// get handler instance
+		try {
+			if (library == null || library.trim().equals("")) //$NON-NLS-1$
+				this.handler = getGlobalHandler(handlerName);
+			else
+				this.handler = getLocalHandler(library, handlerName);
+			if (this.handler == null)
+				return;
+			handler.initialize(type, feature, entry, monitor);
+		} catch (ClassNotFoundException e) {
+			handleExceptionInInit(
+				NLS.bind(Messages.InstallHandler_notFound, (new String[] { feature.getLabel() })),
+				e);
+
+		} catch (ClassCastException e) {
+			handleExceptionInInit(
+				NLS.bind(Messages.InstallHandler_invalidHandler, (new String[] { feature.getLabel() })),
+				e);
+		} catch (CoreException e) {
+			handleExceptionInInit(null, e);
+		} catch (Exception e) {
+			handleExceptionInInit(
+				NLS.bind(Messages.InstallHandler_unableToCreateHandler, (new String[] { feature.getLabel() })),
+				e);
+		}
+
+	}
+
+	/*
+	 * @see IInstallHandler#installInitiated
+	 */
+	public void installInitiated() throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling installInitiated()"); //$NON-NLS-1$
+				handler.installInitiated();
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#allPluginsDownloaded
+	 */
+	public void pluginsDownloaded(IPluginEntry[] plugins) throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling pluginsDownloaded()"); //$NON-NLS-1$
+				handler.pluginsDownloaded(plugins);
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#allPluginsInstalled
+	 */
+	public void completeInstall(IFeatureContentConsumer consumer)
+		throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling completeInstall()"); //$NON-NLS-1$
+				handler.completeInstall(consumer);
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#allDataDownloaded
+	 */
+	public void nonPluginDataDownloaded(
+		INonPluginEntry[] nonPluginData,
+		IVerificationListener listener)
+		throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling nonPluginDataDownloaded()"); //$NON-NLS-1$
+				handler.nonPluginDataDownloaded(nonPluginData, listener);
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#installCompleted
+	 */
+	public void installCompleted(boolean success) throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling installCompleted()"); //$NON-NLS-1$
+				handler.installCompleted(success);
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#configureInitiated
+	 */
+	public void configureInitiated() throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling configureInitiated()"); //$NON-NLS-1$
+				handler.configureInitiated();
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#completeConfigure
+	 */
+	public void completeConfigure() throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling completeConfigure()"); //$NON-NLS-1$
+				handler.completeConfigure();
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#configureCompleted
+	 */
+	public void configureCompleted(boolean success) throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling configureCompleted()"); //$NON-NLS-1$
+				handler.configureCompleted(success);
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#unconfigureInitiated
+	 */
+	public void unconfigureInitiated() throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling unconfigureInitiated()"); //$NON-NLS-1$
+				handler.unconfigureInitiated();
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#completeUnconfigure
+	 */
+	public void completeUnconfigure() throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling completeUnconfigure()"); //$NON-NLS-1$
+				handler.completeUnconfigure();
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#unconfigureCompleted
+	 */
+	public void unconfigureCompleted(boolean success) throws CoreException {
+		if (handler == null) {
+			if (savedStatus == null)
+				return;
+			else
+				throw new CoreException(savedStatus); // delayed exception
+		} else {
+			try {
+				if (DEBUG)
+					debug("calling unconfigureCompleted()"); //$NON-NLS-1$
+				handler.unconfigureCompleted(success);
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+			if (savedStatus != null)
+				throw new CoreException(savedStatus); // delayed exception
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#uninstallInitiated
+	 */
+	public void uninstallInitiated() throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling uninstallInitiated()"); //$NON-NLS-1$
+				handler.uninstallInitiated();
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#completeUninstall
+	 */
+	public void completeUninstall() throws CoreException {
+		if (handler == null)
+			return;
+		else {
+			try {
+				if (DEBUG)
+					debug("calling completeUninstall()"); //$NON-NLS-1$
+				handler.completeUninstall();
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+		}
+	}
+
+	/*
+	 * @see IInstallHandler#uninstallCompleted
+	 */
+	public void uninstallCompleted(boolean success) throws CoreException {
+		if (handler == null) {
+			if (savedStatus == null)
+				return;
+			else
+				throw new CoreException(savedStatus); // delayed exception
+		} else {
+			try {
+				if (DEBUG)
+					debug("calling uninstallCompleted()"); //$NON-NLS-1$
+				handler.uninstallCompleted(success);
+			} catch (Throwable e) {
+				handleExceptionInCall(e, feature);
+			}
+			if (savedStatus != null)
+				throw new CoreException(savedStatus); // delayed exception
+		}
+	}
+
+	/*
+	 * common exception handling for initialization
+	 */
+	private void handleExceptionInInit(String s, Exception e)
+		throws CoreException {
+
+		CoreException ce;
+		if (e instanceof CoreException)
+			ce = (CoreException) e;
+		else
+			ce = Utilities.newCoreException(s, e);
+
+		if (isUndoAction()) {
+			// for "undo" operations, deactivate handler and log error
+			String id =
+				UpdateCore.getPlugin().getBundle().getSymbolicName();
+			IStatus status =
+				new Status(IStatus.ERROR, id, 0, "InstallHandler.deactivated", ce);	//$NON-NLS-1$
+			UpdateCore.getPlugin().getLog().log(status);
+			handler = null; // disable subsequent handler calls
+			savedStatus = status;
+		} else
+			// for "do" operations, hurl ...
+			throw ce;
+	}
+
+	/*
+	 * common exception handling for calls to install handler
+	 */
+	private void handleExceptionInCall(Throwable e, IFeature feature)
+		throws CoreException {
+
+		CoreException ce;
+		if (e instanceof CoreException)
+			ce = (CoreException) e;
+		else
+			ce =
+				Utilities.newCoreException(
+					NLS.bind(Messages.InstallHandler_callException, (new String[] { feature.getLabel() })),
+					e);
+		
+		if (isUndoAction()) {
+			// for "undo" operations, deactivate handler and log error
+			String id =
+				UpdateCore.getPlugin().getBundle().getSymbolicName();
+			IStatus status =
+				new Status(IStatus.ERROR, id, 0, "InstallHandler.deactivated", ce);	//$NON-NLS-1$
+			UpdateCore.getPlugin().getLog().log(status);
+			handler = null; // disable subsequent handler calls
+			savedStatus = status;
+		} else
+			// for "do" operations, hurl ...
+			throw ce;
+	}
+
+	/*
+	 * Indicates whether we are doing (install, configure) or 
+	 * undoing (uninstall, unconfigure)
+	 */
+	private boolean isUndoAction() {
+		if (this.type == IInstallHandler.HANDLER_ACTION_INSTALL
+			|| this.type == IInstallHandler.HANDLER_ACTION_CONFIGURE)
+			return false; // causes exception to be thrown and action aborted
+		else
+			return true; // causes exception to be logged and action continues
+	}
+
+	/*
+	 * get an instance of handler downloaded as part of the feature
+	 */
+	private IInstallHandler getLocalHandler(String libs, String name)
+		throws IOException, CoreException, ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+		// Get baseline URL for handler (relative to feature.xml). For
+		// features being installed from a server (eg. http protocol)
+		// the URL will most likely be to a local file copy containing the
+		// unpacked feature jar.
+		ContentReference baseRef =
+			feature.getFeatureContentProvider().getFeatureManifestReference(null);
+		URL base = null;
+		if (baseRef != null)
+			base = baseRef.asURL();
+		if (base == null)
+			throw Utilities.newCoreException(
+				NLS.bind(Messages.InstallHandler_unableToCreateHandler, (new String[] { this.feature.getLabel() })),
+				null);
+
+
+		// determine loader class path
+		StringTokenizer libraries = new StringTokenizer(libs, ","); //$NON-NLS-1$
+		URL[] cp = new URL[libraries.countTokens()];
+		for( int token = 0; token < cp.length; token++) {
+			cp[token] = new URL(base, libraries.nextToken());
+		}
+		if (this.type == IInstallHandler.HANDLER_ACTION_UNINSTALL) {
+			// check if we are doing uninstall
+			// ... need to make temp copy of library (being removed)
+			URL[] jars = new URL[cp.length];
+			for( int jar = 0; jar < cp.length; jar++) {
+				File tempLib = File.createTempFile("tmp" + jar, ".jar"); //$NON-NLS-1$ //$NON-NLS-2$
+				tempLib.deleteOnExit();
+				FileOutputStream fos = null;
+				InputStream is = null;
+				try {
+					fos = new FileOutputStream(tempLib);
+					is = new FileInputStream(cp[jar].getPath());
+					Utilities.copy(is, fos, null);
+				} finally {
+					if (fos != null)
+						try {
+							fos.close();
+						} catch (Exception e) {
+						}
+					if (is != null)
+						try {
+							is.close();
+						} catch (Exception e) {
+						}
+				}
+				jars[jar] = tempLib.toURL();
+			}
+			cp = jars;
+		}
+
+		// create class loader, load and instantiate handler
+		ClassLoader loader = new InstallHandlerClassLoader(cp);
+		Class clazz = loader.loadClass(name);
+		IInstallHandler handler = (IInstallHandler) clazz.newInstance();
+		return handler;
+	}
+
+	/*
+	 * get instance of global handler registered via extension point
+	 */
+	private IInstallHandler getGlobalHandler(String name) throws Exception {
+
+		IExtensionRegistry reg = Platform.getExtensionRegistry();
+		IConfigurationElement[] handlerExtension =
+			reg.getConfigurationElementsFor(EXT_PLUGIN, EXT_POINT, name);
+		if (handlerExtension == null || handlerExtension.length <= 0)
+			throw Utilities.newCoreException(
+				NLS.bind(Messages.InstallHandler_unableToCreateHandler, (new String[] { this.feature.getLabel() })),
+				null);
+
+		return (IInstallHandler) handlerExtension[0].createExecutableExtension("class"); //$NON-NLS-1$
+	}
+	
+	private void debug(String s) {
+		String pfx = (feature==null) ? "" : feature.getVersionedIdentifier().toString(); //$NON-NLS-1$
+		System.out.println("InstallHandler["+pfx+"]: " + s); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	public boolean acceptNonPluginData(INonPluginEntry data) {
+		Boolean result = new Boolean(true);
+		if (handler != null){
+			if (DEBUG)
+				debug("calling acceptNonPluginData()"); //$NON-NLS-1$
+			if(handler instanceof IInstallHandlerWithFilter)
+				return ((IInstallHandlerWithFilter)handler).acceptNonPluginData(data);
+			else{ //support upgrade from legacy versions
+				if(getNonPluginDataAcceptor() != null){
+					try{
+						Object[] param = {data};
+						result = (Boolean)getNonPluginDataAcceptor().invoke(handler,param);
+					}catch(Exception e){
+						//todo
+					}
+				}
+			}
+		}
+		return result.booleanValue();
+	}
+	private Method getNonPluginDataAcceptor(){
+		if(nonPluginDataAcceptor == null){
+			try{
+				Class[] types = {INonPluginEntry.class};
+				nonPluginDataAcceptor = handler.getClass().getMethod("acceptNonPluginData",types); //$NON-NLS-1$
+			}catch(NoSuchMethodException nsme){
+			}
+		}
+		return nonPluginDataAcceptor;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallLogParser.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallLogParser.java
new file mode 100644
index 0000000..495d38c
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallLogParser.java
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.core;
+
+import java.io.*;
+import java.net.*;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.operations.*;
+
+
+/**
+ * Parses the installation log and creates installation configuration objects
+ */
+public class InstallLogParser {
+	private IPath logPath;
+	private BufferedReader buffRead;
+	private InstallConfiguration currentConfiguration;
+	private HashMap installConfigMap;
+	private Comparator comparator;
+	
+	private static final String FEATURE_INSTALL = "feature-install"; //$NON-NLS-1$
+	private static final String FEATURE_REMOVE = "feature-remove"; //$NON-NLS-1$
+	private static final String SITE_INSTALL = "site-install"; //$NON-NLS-1$
+	private static final String SITE_REMOVE = "site-remove"; //$NON-NLS-1$
+	private static final String UNCONFIGURE = "feature-disable"; //$NON-NLS-1$
+	private static final String CONFIGURE = "feature-enable"; //$NON-NLS-1$
+	private static final String REVERT = "revert"; //$NON-NLS-1$
+	private static final String RECONCILIATION = "reconciliation"; //$NON-NLS-1$
+	private static final String PRESERVED = "preserve-configuration"; //$NON-NLS-1$	
+	
+	private static final String ACTIVITY = "!ACTIVITY"; //$NON-NLS-1$
+	
+	public static final String SUCCESS = "success"; //$NON-NLS-1$
+	public static final String FAILURE = "failure"; //$NON-NLS-1$
+
+	
+	public InstallLogParser(){
+		String loc = ConfiguratorUtils.getCurrentPlatformConfiguration().getConfigurationLocation().getFile();
+		logPath = new Path(loc).removeLastSegments(1).append("install.log");  //$NON-NLS-1$
+		installConfigMap = new HashMap();
+		try {
+			InstallConfiguration[] configs = (InstallConfiguration[])SiteManager.getLocalSite().getConfigurationHistory();
+			for (int i=0;i<configs.length; i++){
+				if (!configs[i].isCurrent())
+					installConfigMap.put(new Long(configs[i].getCreationDate().getTime()), configs[i]);
+			}
+			// Need to make a copy of the current config instead
+			InstallConfiguration config = getConfigCopy((InstallConfiguration)SiteManager.getLocalSite().getCurrentConfiguration());
+			installConfigMap.put(new Long(config.getCreationDate().getTime()), config);
+			
+		} catch (CoreException e) {
+			UpdateCore.log(e);
+		} catch (MalformedURLException e){
+			UpdateCore.log(e);
+		}
+		comparator = new Comparator(){
+			public int compare(Object e1, Object e2) {
+				Date date1 = ((InstallConfiguration)e1).getCreationDate();
+				Date date2 = ((InstallConfiguration)e2).getCreationDate();
+				return date1.before(date2) ? 1 : -1;
+			}
+		};
+	}
+	private InstallConfiguration getConfigCopy(InstallConfiguration origConfig) throws CoreException, MalformedURLException{
+		InstallConfiguration config = new InstallConfiguration(origConfig, origConfig.getURL(), origConfig.getLabel() );
+		config.setCreationDate(origConfig.getCreationDate());
+		return config;
+	}
+	public void parseInstallationLog(){
+		try {
+			openLog();
+			parseLog();
+		} catch (CoreException e) {
+			UpdateUtils.logException(e);
+		} finally {
+			closeLog();
+		}
+	}
+	
+	private void openLog() throws CoreException {
+		try {
+		    // throws FileNotFoundException, IOException
+		    InputStream is = new FileInputStream(logPath.toOSString());
+		    // throws UnsupportedEncodingException
+		    InputStreamReader isr = new InputStreamReader(is,"UTF-8"); //$NON-NLS-1$
+		    buffRead = new BufferedReader(isr);
+		} catch (Exception e) {
+			throwCoreException(e);
+		}
+	}
+	
+	private void throwCoreException(Throwable e) throws CoreException {
+		throw new CoreException(
+			new Status(
+				IStatus.ERROR,
+				UpdateUtils.getPluginId(),
+				IStatus.ERROR,
+				Messages.InstallLogParser_errors, 
+				e));
+	}
+	
+	private void parseLog() throws CoreException {
+		// 		.install-log template
+		//		!CONFIGURATION <configuration-date>
+		//		!ACTIVITY <date> <target> <action> <status>
+
+		try {
+			String type, status, action;
+			StringTokenizer htmlCode;
+
+			while (buffRead.ready()) {
+
+				htmlCode = new StringTokenizer(buffRead.readLine());
+				while (!(htmlCode.hasMoreElements())) {
+					if (!buffRead.ready())
+						return;
+					htmlCode = new StringTokenizer(buffRead.readLine());
+				}
+
+				type = htmlCode.nextToken().trim();
+
+				if (type.equals(ACTIVITY)) {
+					String time = htmlCode.nextToken();
+					String date;
+					StringBuffer target = new StringBuffer();
+					date = htmlCode.nextToken(".");  //$NON-NLS-1$
+					htmlCode.nextToken(" ");  //$NON-NLS-1$
+					while (htmlCode.countTokens() > 2){
+						target.append(" "); //$NON-NLS-1$
+						target.append(htmlCode.nextToken());
+					}
+					
+					action = htmlCode.nextToken();
+					status = htmlCode.nextToken();
+					createActivity(action, time, date, status, target.toString(), currentConfiguration);
+				}  else {
+					String time = htmlCode.nextToken();
+					StringBuffer date;
+					date = new StringBuffer();
+					while (htmlCode.countTokens() > 0){
+						if (date.length() != 0)
+							date.append(" "); //$NON-NLS-1$
+						date.append(htmlCode.nextToken());
+					}
+					currentConfiguration = (InstallConfiguration)installConfigMap.get(new Long(time));
+				}
+			}
+		} catch (Exception e) {
+			throwCoreException(e);
+		}
+	}
+	
+	private void closeLog() {
+		try {
+			if (buffRead != null)
+				buffRead.close();
+		} catch (IOException e) {
+		} finally {
+			buffRead = null;
+		}
+	}
+	private IActivity createActivity(String action, String time, String date, String status, String target, InstallConfiguration config){
+		ConfigurationActivity a = new ConfigurationActivity();
+
+		int code = 0;
+		if (FEATURE_INSTALL.equals(action))
+			code = IActivity.ACTION_FEATURE_INSTALL;
+		else if (FEATURE_REMOVE.equals(action))
+			code = IActivity.ACTION_FEATURE_REMOVE;
+		else if (SITE_INSTALL.equals(action))
+			code = IActivity.ACTION_SITE_INSTALL;
+		else if (SITE_REMOVE.equals(action))
+			code = IActivity.ACTION_SITE_REMOVE;
+		else if (UNCONFIGURE.equals(action))
+			code = IActivity.ACTION_UNCONFIGURE;
+		else if (CONFIGURE.equals(action))
+			code = IActivity.ACTION_CONFIGURE;
+		else if (REVERT.equals(action))
+			code = IActivity.ACTION_REVERT;
+		else if (RECONCILIATION.equals(action))
+			code = IActivity.ACTION_RECONCILIATION;
+		else if (PRESERVED.equals(action))
+			code = IActivity.ACTION_ADD_PRESERVED;
+		
+		a.setAction(code);
+		try {
+			long activityTime = Long.parseLong(time);
+			a.setDate(new Date(activityTime));
+		} catch (NumberFormatException e) {
+			//PAL foundation
+			//a.setDate(new Date(date));
+			try {
+				a.setDate(new SimpleDateFormat().parse(date));
+			} catch (ParseException e1) {
+				//ignore
+			}
+		}
+		a.setStatus(SUCCESS.equals(status) ? IActivity.STATUS_OK : IActivity.STATUS_NOK);
+		a.setLabel(target);
+		a.setInstallConfigurationModel(config);
+		
+		if (config != null && !configContainsActivity(config, a)){
+			config.addActivity(a);
+		}
+		
+		return a;
+	}
+	
+	private boolean configContainsActivity(InstallConfiguration c, IActivity a){
+		IActivity[] activities = c.getActivities();
+		for (int i = 0 ; i<activities.length; i++){
+			if (a.equals(activities[i]))
+				return true;
+		}
+		return false;
+	}
+
+	public InstallConfiguration[] getConfigurations(){
+		Collection configSet = installConfigMap.values();
+		InstallConfiguration[] configs = (InstallConfiguration[]) configSet.toArray(new InstallConfiguration[configSet.size()]);
+		Arrays.sort(configs, comparator);
+		return configs;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallRegistry.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallRegistry.java
new file mode 100644
index 0000000..94e73e9
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallRegistry.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.core.*;
+
+/**
+ * Keeps track of all the features and plugins installed by Update mgr
+ * so they can be uninstalled later.
+ * The info is persisted in the .config/registry file and each entry has a key=key where
+ * for feature this key is feature_<id>_<version> and for plugins
+ * key is plugin_<id>_<version>. Normally, getVersionedIdentifier() will
+ * return <id>_<version>. Eg: feature_org.eclipse.platform_3.0.0
+ * 
+ */
+public class InstallRegistry extends Properties {
+
+    private static final long serialVersionUID = 1L;
+    private File file = null;
+	private final static String REGISTRY = "registry"; //$NON-NLS-1$
+	private static InstallRegistry instance;
+	
+	// plugins installed in this eclipse session
+	private HashMap justInstalledPlugins = new HashMap();
+	
+	/**
+	 * Creates empty Properties.
+	 */
+	private InstallRegistry() {
+		super();
+		String configFile =
+			ConfiguratorUtils
+				.getCurrentPlatformConfiguration()
+				.getConfigurationLocation()
+				.getFile();
+		file = new File(configFile);
+		file = file.getParentFile();
+		file = new File(file, REGISTRY);
+		restore();
+	}
+
+	/**
+	 * Singleton
+	 */
+	public static InstallRegistry getInstance() {
+		if (instance == null)
+			instance = new InstallRegistry();
+		return instance;
+	}
+
+	/**
+	 * Restores contents of the Properties from a file.
+	 * @return true if persistant data was read in
+	 */
+	public boolean restore() {
+		InputStream in = null;
+		boolean loaded = false;
+		clear();
+		// Test if we have a contribution file to start with
+		// If this is a clean start, then we will not have a 
+		// contribution file. return false.
+		if (!file.exists())
+			return loaded;
+		try {
+			in = new FileInputStream(file);
+			super.load(in);
+			loaded = true;
+		} catch (IOException e) {
+			UpdateCore.log(e);
+		} finally {
+			if (in != null)
+				try {
+					in.close();
+				} catch (IOException e) {
+				}
+		}
+		return loaded;
+	}
+	/**
+	 * Saves contents of the table to a file.
+	 * @return true if operation was successful
+	 */
+	public synchronized boolean save() {
+		OutputStream out = null;
+		boolean ret = false;
+		try {
+			out = new FileOutputStream(file);
+			super.store(out, "This is a generated file; do not edit."); //$NON-NLS-1$
+			ret = true;
+		} catch (IOException e) {
+			UpdateCore.log(e);
+		} finally {
+			try {
+				if (out != null) {
+					out.close();
+				}
+			} catch (IOException e) {
+			}
+		}
+		return ret;
+	}
+	
+	/**
+	 * Registers an installed feature so it can be uninstalled later.
+	 * @param feature feature to register.
+	 */
+	public static synchronized void registerFeature(IFeature feature) {
+		String name = "feature_"+feature.getVersionedIdentifier(); //$NON-NLS-1$
+		if (InstallRegistry.getInstance().get(name) == null) {
+			InstallRegistry.getInstance().put(name, name);
+			// we save after each registration
+			InstallRegistry.getInstance().save();
+		}
+	}
+	
+	/**
+	 * Registers an installed feature so it can be uninstalled later.
+	 * @param pluginEntry plugin to register.
+	 */
+	public static synchronized void registerPlugin(IPluginEntry pluginEntry) {
+		String name = "plugin_"+pluginEntry.getVersionedIdentifier(); //$NON-NLS-1$
+		if (InstallRegistry.getInstance().get(name) == null) {
+			InstallRegistry.getInstance().put(name, name);
+			// we save after each registration
+			InstallRegistry.getInstance().save();
+		}
+		
+		// add plugin to the list of just installed plugins .
+		InstallRegistry.getInstance().justInstalledPlugins.put(name,name);
+	}
+	
+	/**
+	 * Removes specified feature from registry
+	 *
+	 */
+	public static synchronized void unregisterFeature(IFeature feature) {
+		String name = "feature_"+feature.getVersionedIdentifier(); //$NON-NLS-1$
+		InstallRegistry.getInstance().remove(name);
+	}
+	
+	/**
+	 * Removes specified plugin from registry
+	 *
+	 */
+	public static synchronized void unregisterPlugin(IPluginEntry pluginEntry) {
+		String name = "plugin_"+pluginEntry.getVersionedIdentifier(); //$NON-NLS-1$
+		InstallRegistry.getInstance().remove(name);
+		
+		// remove the plugin from the list of just installed plugins (if needed).
+		InstallRegistry.getInstance().justInstalledPlugins.remove(name);
+	}
+	
+	/**
+	 * Returns true if the plugin was installed during this eclipse session
+	 * @param pluginEntry
+	 * @return
+	 */
+	public boolean isPluginJustInstalled(IPluginEntry pluginEntry) {
+		String name = "plugin_"+pluginEntry.getVersionedIdentifier(); //$NON-NLS-1$
+		return InstallRegistry.getInstance().justInstalledPlugins.get(name) != null;
+	}
+	
+	/**
+	 * This method is only needed for the update JUnit tests.
+	 *
+	 */
+	public static void cleanup() {
+		InstallRegistry.getInstance().justInstalledPlugins.clear();
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InternalSiteManager.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InternalSiteManager.java
new file mode 100644
index 0000000..f016501
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InternalSiteManager.java
@@ -0,0 +1,396 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.ILocalSite;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFactory;
+import org.eclipse.update.core.ISiteFactoryExtension;
+import org.eclipse.update.core.JarContentReference;
+import org.eclipse.update.core.Site;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.model.InvalidSiteTypeException;
+import org.eclipse.update.internal.core.connection.ConnectionFactory;
+import org.eclipse.update.internal.core.connection.IResponse;
+import org.eclipse.update.internal.model.ITimestamp;
+
+/**
+ * 
+ */
+public class InternalSiteManager {
+
+	public static ILocalSite localSite;
+
+	public static final String DEFAULT_SITE_TYPE = SiteURLContentProvider.SITE_TYPE;
+	private static final String DEFAULT_EXECUTABLE_SITE_TYPE = SiteFileContentProvider.SITE_TYPE;
+
+	private static Map estimates;
+
+	// cache found sites
+	private static Map sites = new HashMap();
+	// cache http updated url
+	private static Map httpSitesUpdatedUrls = new HashMap();
+	// cache timestamps
+	private static Map siteTimestamps = new HashMap();
+	public static boolean globalUseCache = true;
+
+	// true if an exception occured creating localSite
+	// so we cache it and don't attempt to create it again
+	private static CoreException exceptionOccured = null;
+
+	/*
+	 * @see SiteManager#getLocalSite()
+	 */
+	public static ILocalSite getLocalSite() throws CoreException {
+		return internalGetLocalSite();
+	}
+
+	/*
+	 * Internal call if optimistic reconciliation needed
+	 */
+	private static ILocalSite internalGetLocalSite() throws CoreException {
+
+		// if an exception occured while retrieving the Site
+		// rethrow it
+		if (exceptionOccured != null)
+			throw exceptionOccured;
+
+		if (localSite == null) {
+			try {
+				localSite = LocalSite.internalGetLocalSite();
+			} catch (CoreException e) {
+				exceptionOccured = e;
+				throw e;
+			}
+		}
+		return localSite;
+	}
+	
+	private static boolean isValidCachedSite(URL siteURL) {
+		if (!sites.containsKey(siteURL.toExternalForm()))
+			return false;
+			
+		Long timestamp = (Long)siteTimestamps.get(siteURL);
+		if (timestamp == null)
+			return false;
+		long localLastModified = timestamp.longValue();
+		
+		return UpdateManagerUtils.isSameTimestamp(siteURL, localLastModified);
+	}
+
+	/*
+	 * @see ILocalSite#getSite(URL)
+	 */
+	public static ISite getSite(URL siteURL, boolean useCache, IProgressMonitor monitor) throws CoreException {
+		ISite site = null;
+		if (monitor==null) monitor = new NullProgressMonitor();
+
+		if (siteURL == null)
+			return null;
+
+		// use cache if set up globally (globalUseCache=true)
+		// and passed as parameter (useCache=true)
+		if (httpSitesUpdatedUrls.containsKey(siteURL.toExternalForm())) {
+			siteURL = (URL)httpSitesUpdatedUrls.get(siteURL.toExternalForm());
+		}
+		String siteURLString = siteURL.toExternalForm();
+		if ((useCache && globalUseCache) && isValidCachedSite(siteURL)) {
+			site = (ISite) sites.get(siteURLString);
+			UpdateCore.getPlugin().getUpdateSession().markVisited(site.getURL());
+			return site;
+		}
+		
+		// try adding "eclipse" to the site url, in case this is an extension site
+		if ("file".equals(siteURL.getProtocol()) ) { //$NON-NLS-1$
+			File f = new File(siteURL.getFile());
+			if (f.isDirectory() && !"eclipse".equals(f.getName())) { //$NON-NLS-1$
+				f = new File(f, "eclipse"); //$NON-NLS-1$
+				try {
+					if ((useCache && globalUseCache) && isValidCachedSite(f.toURL())) {
+						site = (ISite) sites.get(f.toURL().toExternalForm());
+						return site;
+					}
+				} catch (MalformedURLException e) {
+				}	
+			}
+		}
+
+		// consider file protocol also if the URL points to a directory
+		// and no site.xml exist
+		// if the user points to a file, consider DEFAULT_SITE_TYPE
+		// site.xml will have to specify the type
+		boolean fileProtocol = "file".equalsIgnoreCase(siteURL.getProtocol()); //$NON-NLS-1$
+		boolean directoryExists = false;
+		if (fileProtocol) {
+			File dir;
+			dir = new File(siteURL.getFile());
+			if (dir != null && dir.isDirectory()) {
+				if (!(new File(dir, Site.SITE_XML).exists()))
+					directoryExists = true;
+			}
+		}
+
+		//PERF: if file: <path>/ and directory exists then consider executable
+		monitor.beginTask(Messages.InternalSiteManager_ConnectingToSite, 8); 
+		if (fileProtocol && directoryExists) {
+			site = attemptCreateSite(DEFAULT_EXECUTABLE_SITE_TYPE, siteURL, monitor);
+			monitor.worked(4); // only one attempt
+		} else {
+			try {
+				monitor.worked(3);
+				site = attemptCreateSite(DEFAULT_SITE_TYPE, siteURL, monitor);
+				monitor.worked(1);
+			} catch (CoreException preservedException) {
+				if (!monitor.isCanceled()) {
+					// attempt a retry is the protocol is file, with executbale type
+					if (!fileProtocol)
+						throw preservedException;
+
+					try {
+						site = attemptCreateSite(DEFAULT_EXECUTABLE_SITE_TYPE, siteURL, monitor);
+					} catch (CoreException retryException) {
+						IStatus firstStatus = preservedException.getStatus();
+						MultiStatus multi = new MultiStatus(firstStatus.getPlugin(), IStatus.OK, Messages.InternalSiteManager_FailedRetryAccessingSite, retryException); 
+						multi.addAll(firstStatus);
+						throw preservedException;
+					}
+				}
+			}
+		}
+
+		if (site != null) {
+			sites.put(site.getURL().toExternalForm(), site);
+			UpdateCore.getPlugin().getUpdateSession().markVisited(site.getURL());
+			if (site instanceof ITimestamp) {
+				siteTimestamps.put(site.getURL(), new Long(((ITimestamp)site).getTimestamp().getTime()));
+			} else {
+				try {
+					IResponse response = ConnectionFactory.get(URLEncoder.encode(siteURL));
+					siteTimestamps.put(siteURL, new Long(response.getLastModified()));
+				} catch (MalformedURLException e) {
+				} catch (IOException e) {
+				}
+			}
+		}
+
+		//flush the JarFile we may hold on to
+		// we keep the temp not to create them again
+		JarContentReference.shutdown(); // make sure we are not leaving jars open for this site
+
+		//flush mapping of downloaded JAR files
+		// FIXME : provide better cache flushing after 2.1
+		// FIXED: everything downloaded is cached and timestamped.
+		//        Timestamps are compared to lastModifed on the server
+		//        and we download only when there is a differenc
+		// Utilities.flushLocalFile();
+
+		return site;
+	}
+
+	/*
+	 * Attempt to create a site
+	 * if the site guessed is not the type found,
+	 * attempt to create a type with the type found in the site.xml
+	 */
+	private static ISite attemptCreateSite(String guessedTypeSite, URL siteURL, IProgressMonitor monitor) throws CoreException {
+		if (monitor == null) monitor = new NullProgressMonitor();
+		ISite site = null;
+
+		try {
+			monitor.worked(1);
+			site = createSite(guessedTypeSite, siteURL, monitor);
+			monitor.worked(1); // if no error, occurs the retry branch doesn't need to be executed
+		} catch (InvalidSiteTypeException e) {
+			if (monitor.isCanceled()) return null;
+
+			// the type in the site.xml is not the one expected	
+			// attempt to use this type instead	
+			//DEBUG:
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_TYPE) {
+				UpdateCore.debug("The Site :" + siteURL.toExternalForm() + " is a different type than the guessed type based on the protocol. new Type:" + e.getNewType());	//$NON-NLS-1$ //$NON-NLS-2$ 
+			}
+
+			try {
+				if (e.getNewType() == null)
+					throw e;
+				site = createSite(e.getNewType(), siteURL, monitor);
+			} catch (InvalidSiteTypeException e1) {
+				throw Utilities.newCoreException(NLS.bind(Messages.InternalSiteManager_UnableToCreateSiteWithType, (new String[] { e.getNewType(), siteURL.toExternalForm() })), e1); 
+			}
+		}
+
+		return site;
+	}
+
+	/*
+	 * create an instance of a class that implements ISite
+	 * 
+	 * the URL can be of the following form
+	 * 1 protocol://...../
+	 * 2 protocol://.....
+	 * 3 protocol://..../site.xml
+	 * 4 protocol://...#...
+	 * 
+	 * 1 If the file of the file of teh url ends with '/', attempt to open the stream.
+	 * if it fails, add site.xml and attempt to open the stream
+	 * 
+	 * 2 attempt to open the stream
+	 * 	fail
+	 * 		add '/site.xml' and attempt to open the stream
+	 * 	sucess
+	 * 		attempt to parse, if it fails, add '/site.xml' and attempt to open the stream
+	 * 
+	 * 3 open the stream
+	 * 
+	 * 4 open the stream	
+	 */
+	private static ISite createSite(String siteType, URL url, IProgressMonitor monitor) throws CoreException, InvalidSiteTypeException {
+		
+		if (monitor == null) monitor = new NullProgressMonitor();
+		//ISite site = null;
+		ISiteFactory factory = SiteTypeFactory.getInstance().getFactory(siteType);
+		URL fixedUrl;
+		
+		// see if we need to (and can) fix url by adding site.xml to it
+		try {
+			if ( (url.getRef() != null) || (url.getFile().endsWith(Site.SITE_XML) || (url.getProtocol().equalsIgnoreCase("file")))) { //$NON-NLS-1$
+			 	fixedUrl = url;
+			} else if (url.getFile().endsWith("/")) { //$NON-NLS-1$
+				fixedUrl = new URL(url, Site.SITE_XML);
+			} else {
+				fixedUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile() + "/" + Site.SITE_XML);	//$NON-NLS-1$
+			}
+		} catch (MalformedURLException mue) {
+			fixedUrl = url;
+		}
+		
+		try {
+			try { 
+				monitor.worked(1);
+				return createSite( factory, fixedUrl, url, monitor);
+			} catch (CoreException ce) {
+				if (monitor.isCanceled()) 
+					return null;
+			
+				if (!fixedUrl.equals(url)) {
+					// try with original url
+					 return createSite( factory, url, url, monitor);
+				} else if (url.getProtocol().equalsIgnoreCase("file") && ! url.getFile().endsWith(Site.SITE_XML)){ //$NON-NLS-1$
+					try {
+						if (url.getFile().endsWith("/")) { //$NON-NLS-1$
+							return createSite(factory, new URL(url,
+									Site.SITE_XML), url, monitor);
+						} else {
+							return createSite(factory, new URL(url
+									.getProtocol(), url.getHost(), url
+									.getPort(), url.getFile()
+									+ "/" + Site.SITE_XML), url, monitor); //$NON-NLS-1$							
+						}
+					} catch (MalformedURLException mue) {
+						throw ce;
+					}
+				} else {
+					throw ce;
+				}
+			}
+		} catch(CoreException ce) {
+			throw Utilities.newCoreException(NLS.bind(Messages.InternalSiteManager_UnableToAccessURL, (new String[] { url.toExternalForm() })), ce);
+		}
+	}
+	
+	private static ISite createSite(ISiteFactory factory, URL url, URL originalUrl, IProgressMonitor monitor) throws CoreException, InvalidSiteTypeException {
+		
+		ISite site;
+			
+		site = createSite(factory, url, monitor);
+		httpSitesUpdatedUrls.put(originalUrl.toExternalForm(), url);	
+		
+		return site;
+	}
+	
+	private static ISite createSite(ISiteFactory factory, URL url, IProgressMonitor monitor) throws CoreException, InvalidSiteTypeException {
+		if (factory instanceof ISiteFactoryExtension)
+			return ((ISiteFactoryExtension)factory).createSite(url, monitor);
+		else
+			return factory.createSite(url);
+	}
+
+	/*
+	 * Creates a new site on the file system
+	 * This is the only Site we can create.
+	 * 
+	 * @param siteLocation
+	 * @throws CoreException
+	 */
+	public static ISite createSite(File siteLocation) throws CoreException {
+		ISite site = null;
+		if (siteLocation != null) {
+			try {
+				URL siteURL = siteLocation.toURL();
+				site = getSite(siteURL, false, null);
+			} catch (MalformedURLException e) {
+				throw Utilities.newCoreException(NLS.bind(Messages.InternalSiteManager_UnableToCreateURL, (new String[] { siteLocation.getAbsolutePath() })), e);
+			}
+		}
+		return site;
+	}
+
+
+	/**
+	 * Method downloaded.
+	 * @param downloadSize size downloaded in bytes
+	 * @param time time in seconds
+	 * @param url
+	 */
+	public static void downloaded(long downloadSize, long time, URL url) {
+		if (downloadSize <= 0 || time < 0)
+			return;
+		String host = url.getHost();
+		long sizeByTime = (time == 0) ? 0 : downloadSize / time;
+		Long value = new Long(sizeByTime);
+		if (estimates == null) {
+			estimates = new HashMap();
+		} else {
+			Long previous = (Long) estimates.get(host);
+			if (previous != null) {
+				value = new Long((previous.longValue() + sizeByTime) / 2);
+			}
+		}
+		estimates.put(host, value);
+	}
+	/**
+	 * Method getEstimatedTransferRate rate bytes/seconds.
+	 * @param host
+	 * @return long
+	 */
+	public static long getEstimatedTransferRate(String host) {
+		if (estimates == null)
+			return 0;
+		Long value = (Long) estimates.get(host);
+		if (value == null)
+			return 0;
+		return value.longValue();
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/JarDeltaInstallHandler.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/JarDeltaInstallHandler.java
new file mode 100644
index 0000000..d1a7e34
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/JarDeltaInstallHandler.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.core;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.IFeatureContentConsumer;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.PluginEntry;
+import org.eclipse.update.core.Site;
+
+public class JarDeltaInstallHandler extends DeltaInstallHandler {
+
+	
+	protected void overlayPlugin(
+			IPluginEntry oldPlugin,
+			IPluginEntry newPlugin,
+			IFeatureContentConsumer consumer)
+			throws CoreException, IOException {
+		
+			if(newPlugin instanceof PluginEntry && ((PluginEntry)newPlugin).isUnpack()){
+				// partial plug-ins (in patches) must always be unpacked
+				super.overlayPlugin(oldPlugin, newPlugin, consumer);
+			}
+			
+			URL oldURI = null;
+			try {
+				oldURI = new URL(consumer.getFeature().getSite().getURL().getPath() + 
+									 Site.DEFAULT_PLUGIN_PATH + 
+									 oldPlugin.getVersionedIdentifier().toString());
+			} catch (MalformedURLException e) {
+				throw new IOException(e.getMessage());
+			}
+			File oldJarFile = new File(oldURI.toExternalForm());
+			JarFile oldJar = new JarFile(oldJarFile);
+			
+			URL newURI = null;
+			try {
+				newURI = new URL(consumer.getFeature().getSite().getURL().getPath() + 
+								 Site.DEFAULT_PLUGIN_PATH + 
+								 newPlugin.getVersionedIdentifier().toString());
+			} catch (MalformedURLException e) {
+				throw new IOException(e.getMessage());
+			}
+			File newJarFile = new File(newURI.toExternalForm());
+			JarFile newJar = new JarFile(newJarFile);
+
+			String tempFileName = oldURI + "-" + (new Date()).getTime(); //$NON-NLS-1$
+			File tempFile = new File(tempFileName);
+			FileOutputStream fos = new FileOutputStream(tempFile);
+			JarOutputStream jos = new JarOutputStream( fos);
+			
+			addToJar(jos, newJar);
+			addToJar(jos, oldJar);
+			
+			jos.closeEntry();
+			jos.finish();
+			fos.close();
+			newJar.close();
+			oldJar.close();
+			
+			newJarFile = new File(newURI.toExternalForm());
+			newJarFile.delete();
+			
+			newJarFile.createNewFile();
+
+			copyFile(tempFile, newJarFile);
+	}
+	
+	public static void copyFile(File src, File dst) throws IOException {
+		InputStream in=null;
+		OutputStream out=null;
+		try {
+			in = new BufferedInputStream(new FileInputStream(src));
+			out = new BufferedOutputStream(new FileOutputStream(dst));		
+			byte[] buffer = new byte[4096];
+			int len;
+			while ((len=in.read(buffer)) != -1) {
+				out.write(buffer, 0, len);
+			}
+		} finally {
+			if (in != null)
+				try {
+					in.close();
+				} catch (IOException e) {
+				}
+			if (out != null)
+				try {
+					out.close();
+				} catch (IOException e) {
+				}
+		}
+	}
+
+	public static void addToJar(JarOutputStream jos, JarFile jf) throws IOException {
+		Enumeration e = jf.entries();
+		
+		while(e.hasMoreElements()) {
+			
+			ZipEntry je = (ZipEntry)e.nextElement();
+			InputStream io = jf.getInputStream(je);
+			
+			byte b[] = new byte[4096];
+			int read = 0;
+			try {
+				jos.putNextEntry(je);
+				while( ( read = io.read(b, 0, 4096)) != -1) {
+					jos.write(b, 0, read);
+				}
+			} catch (ZipException ze) {
+				//ze.printStackTrace();
+				throw ze;
+			}		
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LiteFeature.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LiteFeature.java
new file mode 100644
index 0000000..25ac09f
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LiteFeature.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.update.core.Feature;
+
+public class LiteFeature extends Feature {
+	
+	private boolean fullFeature = true;
+
+	public boolean isFullFeature() {
+		return fullFeature;
+	}
+
+	public void setFullFeature(boolean fullFeature) {
+		this.fullFeature = fullFeature;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LiteFeatureFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LiteFeatureFactory.java
new file mode 100644
index 0000000..0f0a9ee
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LiteFeatureFactory.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.update.core.BaseFeatureFactory;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.model.FeatureModel;
+
+public class LiteFeatureFactory extends BaseFeatureFactory {
+
+	public LiteFeatureFactory() {
+		super();
+	}
+
+	public IFeature createFeature(URL url, ISite site, IProgressMonitor monitor)
+			throws CoreException {
+		
+		return null;
+	}
+
+	public FeatureModel createFeatureModel() {
+		return new LiteFeature();
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LocalSite.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LocalSite.java
new file mode 100644
index 0000000..c41697d
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LocalSite.java
@@ -0,0 +1,374 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.core.runtime.ListenerList;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Date;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.IActivity;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.configuration.ILocalSite;
+import org.eclipse.update.configuration.ILocalSiteChangedListener;
+import org.eclipse.update.configuration.IProblemHandler;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.internal.model.InstallConfigurationModel;
+import org.eclipse.update.internal.model.SiteLocalModel;
+import org.eclipse.update.internal.model.SiteLocalParser;
+
+/**
+ * This class manages the configurations.
+ */
+
+public class LocalSite extends SiteLocalModel implements ILocalSite{
+
+	private ListenerList listeners = new ListenerList(ListenerList.IDENTITY);
+	private SiteStatusAnalyzer siteStatusAnalyzer;
+	private boolean isTransient = false;
+
+	/*
+	 * Have new features been found during reconciliation
+	 */
+	public static boolean newFeaturesFound = false;
+
+	/*
+	 * initialize the configurations from the persistent model.
+	 * Set the reconciliation as non optimistic
+	 */
+	public static ILocalSite getLocalSite() throws CoreException {
+		return internalGetLocalSite();
+	}
+
+	/*
+	 *Internal call is reconciliation needs to be optimistic
+	 */
+	public static ILocalSite internalGetLocalSite() throws CoreException {
+	
+		LocalSite localSite = new LocalSite();
+	
+		// obtain platform configuration
+		IPlatformConfiguration currentPlatformConfiguration = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		localSite.isTransient(currentPlatformConfiguration.isTransient());
+	
+		try {
+			URL configXML = currentPlatformConfiguration.getConfigurationLocation();
+			localSite.setLocationURLString(configXML.toExternalForm());
+			localSite.resolve(configXML, null);
+	
+			// Attempt to read previous state
+			parseLocalSiteFile(currentPlatformConfiguration, localSite);
+
+		} catch (MalformedURLException exception) {
+			throw Utilities.newCoreException(NLS.bind(Messages.SiteLocal_UnableToCreateURLFor, (new String[] { localSite.getLocationURLString() + " & " + CONFIG_FILE })), exception); //$NON-NLS-1$
+		}
+	
+		return localSite;
+	}
+
+	/**
+	 * Create the localSite object
+	 */
+	private static boolean parseLocalSiteFile(IPlatformConfiguration platformConfig, LocalSite localSite ) throws CoreException, MalformedURLException {
+
+		//attempt to parse the LocalSite.xml	
+//		URL resolvedURL = URLEncoder.encode(configXML);
+		try {
+//			InputStream in = UpdateCore.getPlugin().get(resolvedURL).getInputStream();
+			new SiteLocalParser(platformConfig, localSite);
+			return true;
+		} catch (Exception exception) {
+			return false;
+		}
+	}
+
+	/**
+	 * 
+	 */
+	protected LocalSite() {
+	}
+
+	/**
+	 * adds a new configuration to the LocalSite
+	 *  the newly added configuration is teh current one
+	 */
+	public void addConfiguration(IInstallConfiguration config) {
+		if (config != null) {
+			addConfigurationModel((InstallConfigurationModel) config);
+
+			trimHistoryToCapacity();
+
+			// set configuration as current		
+			if (getCurrentConfigurationModel() != null)
+				getCurrentConfigurationModel().setCurrent(false);
+			if (config instanceof InstallConfiguration)
+				 ((InstallConfiguration) config).setCurrent(true);
+
+			setCurrentConfigurationModel((InstallConfigurationModel) config);
+			((InstallConfigurationModel) config).markReadOnly();
+
+			// notify listeners
+			Object[] siteLocalListeners = listeners.getListeners();
+			for (int i = 0; i < siteLocalListeners.length; i++) {
+				((ILocalSiteChangedListener) siteLocalListeners[i]).currentInstallConfigurationChanged(config);
+			}
+		}
+
+	}
+
+	/*
+	 * 
+	 */
+	private void trimHistoryToCapacity() {
+		// check if we have to remove a configuration
+		// the first added is #0
+		while (getConfigurationHistory().length > getMaximumHistoryCount() &&
+				getConfigurationHistory().length > 1) {
+			// do not remove the first element in history, this is the original config
+			InstallConfigurationModel removedConfig = getConfigurationHistoryModel()[1];
+			if (removeConfigurationModel(removedConfig)) {
+
+				// DEBUG:
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION) {
+					UpdateCore.debug("Removed configuration :" + removedConfig.getLabel()); //$NON-NLS-1$
+				}
+
+				// notify listeners
+				Object[] siteLocalListeners = listeners.getListeners();
+				for (int i = 0; i < siteLocalListeners.length; i++) {
+					((ILocalSiteChangedListener) siteLocalListeners[i]).installConfigurationRemoved((IInstallConfiguration) removedConfig);
+				}
+
+				//remove files
+				URL url = removedConfig.getURL();
+				UpdateManagerUtils.removeFromFileSystem(new File(url.getFile()));
+			}
+		}
+	}
+	/*
+	 * @see ILocalSite#addLocalSiteChangedListener(ILocalSiteChangedListener)
+	 */
+	public void addLocalSiteChangedListener(ILocalSiteChangedListener listener) {
+		listeners.add(listener);
+	}
+
+	/*
+	 * @see ILocalSite#removeLocalSiteChangedListener(ILocalSiteChangedListener)
+	 */
+	public void removeLocalSiteChangedListener(ILocalSiteChangedListener listener) {
+		listeners.add(listener);
+	}
+
+	/**
+	 * Saves the site into the config file.
+	 * @return true if changes restart is needed
+	 */
+	public boolean save() throws CoreException {
+
+		// Save the current configuration as
+		// the other are already saved
+		// and set runtim info for next startup
+		return ((InstallConfiguration) getCurrentConfiguration()).save();
+	}
+	
+//	/**
+//	 * Method createNewInstallConfiguration.
+//	 * @return IInstallConfiguration
+//	 */
+//	private IInstallConfiguration createNewInstallConfiguration() throws CoreException {
+//		InstallConfiguration newInstallConfig = createConfigurationSite(null);
+//		newInstallConfig.setTimeline(newInstallConfig.getCreationDate().getTime());
+//		return newInstallConfig;
+//	}
+
+
+	/**
+	 * @since 2.0
+	 * @deprecated This method should not be used. The current install configuration is to be used.
+	 */
+	public IInstallConfiguration cloneCurrentConfiguration() throws CoreException {
+		try {
+			return new InstallConfiguration(getCurrentConfiguration());
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException(Messages.SiteLocal_cloneConfig, e); 
+		}
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public void revertTo(IInstallConfiguration configuration, IProgressMonitor monitor, IProblemHandler handler) throws CoreException {
+
+		// create the activity 
+		//Start UOW ?
+		ConfigurationActivity activity = new ConfigurationActivity(IActivity.ACTION_REVERT);
+		activity.setLabel(configuration.getLabel());
+		activity.setDate(new Date());
+		IInstallConfiguration newConfiguration = null;
+
+		try {
+			// create a configuration
+			newConfiguration = cloneCurrentConfiguration();
+			newConfiguration.setLabel(configuration.getLabel());
+
+			// add to the stack which will set up as current
+			addConfiguration(newConfiguration);
+
+			// process delta
+			// the Configured featuresConfigured are the same as the old configuration
+			// the unconfigured featuresConfigured are the rest...
+			 ((InstallConfiguration) newConfiguration).revertTo(configuration, monitor, handler);
+
+			// everything done ok
+			activity.setStatus(IActivity.STATUS_OK);
+		} catch (CoreException e) {
+			// error
+			activity.setStatus(IActivity.STATUS_NOK);
+			throw e;
+		} catch (InterruptedException e) {
+			//user decided not to revert, do nothing
+			// because we didn't add the configuration to the history
+		} finally {
+			if (newConfiguration != null)
+				 ((InstallConfiguration) newConfiguration).addActivity(activity);
+		}
+
+	}
+
+	/**
+	 * @since 2.0
+	 * @deprecated
+	 */
+	public IInstallConfiguration addToPreservedConfigurations(IInstallConfiguration configuration) throws CoreException {
+		return null;
+	}
+
+	/*
+	 * @see ILocalSite#getPreservedConfigurationFor(IInstallConfiguration)
+	 */
+	public IInstallConfiguration findPreservedConfigurationFor(IInstallConfiguration configuration) {
+
+		// based on time stamp for now
+		InstallConfigurationModel preservedConfig = null;
+		if (configuration != null) {
+			InstallConfigurationModel[] preservedConfigurations = getPreservedConfigurationsModel();
+			if (preservedConfigurations != null) {
+				for (int indexPreserved = 0; indexPreserved < preservedConfigurations.length; indexPreserved++) {
+					if (configuration.getCreationDate().equals(preservedConfigurations[indexPreserved].getCreationDate())) {
+						preservedConfig = preservedConfigurations[indexPreserved];
+						break;
+					}
+				}
+			}
+		}
+
+		return (IInstallConfiguration) preservedConfig;
+	}
+
+	/*
+	 * @see ILocalSite#getCurrentConfiguration()
+	 * LocalSiteModel#getCurrentConfigurationModel() may return null if
+	 * we just parsed LocalSite.xml
+	 */
+	public IInstallConfiguration getCurrentConfiguration() {
+		if (getCurrentConfigurationModel() == null) {
+			int index = 0;
+			if ((index = getConfigurationHistoryModel().length) == 0) {
+				return null;
+			} else {
+				InstallConfigurationModel config = getConfigurationHistoryModel()[index - 1];
+				config.setCurrent(true);
+				setCurrentConfigurationModel(config);
+			}
+		}
+		return (IInstallConfiguration) getCurrentConfigurationModel();
+	}
+
+	/*
+	 * @see ILocalSite#getPreservedConfigurations()
+	 */
+	public IInstallConfiguration[] getPreservedConfigurations() {
+		if (getPreservedConfigurationsModel().length == 0)
+			return new IInstallConfiguration[0];
+		return (IInstallConfiguration[]) getPreservedConfigurationsModel();
+	}
+
+	/*
+	 * @see ILocalSite#removeFromPreservedConfigurations(IInstallConfiguration)
+	 */
+	public void removeFromPreservedConfigurations(IInstallConfiguration configuration) {
+		if (removePreservedConfigurationModel((InstallConfigurationModel) configuration))
+			 ((InstallConfiguration) configuration).remove();
+	}
+
+	/*
+	 * @see ILocalSite#getConfigurationHistory()
+	 */
+	public IInstallConfiguration[] getConfigurationHistory() {
+		if (getConfigurationHistoryModel().length == 0)
+			return new IInstallConfiguration[0];
+		return (IInstallConfiguration[]) getConfigurationHistoryModel();
+	}
+
+
+	/**
+	 * Gets the isTransient.
+	 * @return Returns a boolean
+	 */
+	public boolean isTransient() {
+		return isTransient;
+	}
+
+	/**
+	 * Sets the isTransient.
+	 * @param isTransient The isTransient to set
+	 */
+	private void isTransient(boolean isTransient) {
+		this.isTransient = isTransient;
+	}
+
+	/*
+	 * 
+	 */
+	private SiteStatusAnalyzer getSiteStatusAnalyzer() {
+		if (siteStatusAnalyzer == null)
+			siteStatusAnalyzer = new SiteStatusAnalyzer(this);
+		return siteStatusAnalyzer;
+	}
+
+	/*
+	 *  check if the Plugins of the feature are on the plugin path
+	 *  If all the plugins are on the plugin path, and the version match and there is no other version -> HAPPY
+	 *  If all the plugins are on the plugin path, and the version match and there is other version -> AMBIGUOUS
+	 *  If some of the plugins are on the plugin path, but not all -> UNHAPPY
+	 * 	Check on all ConfiguredSites
+	 */
+	public IStatus getFeatureStatus(IFeature feature) throws CoreException {
+		return getSiteStatusAnalyzer().getFeatureStatus(feature);
+	} 
+	/**
+	 * @see org.eclipse.update.internal.model.SiteLocalModel#setMaximumHistoryCount(int)
+	 */
+	public void setMaximumHistoryCount(int history) {
+		super.setMaximumHistoryCount(history);
+		trimHistoryToCapacity();
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LockManager.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LockManager.java
new file mode 100644
index 0000000..f1abe5d
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/LockManager.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.util.Hashtable;
+
+/**
+ * @author aniefer
+ *
+ */
+public class LockManager {
+	// lock
+	private final static Object lock = new Object();
+
+	// hashtable of locks
+	private static Hashtable locks = new Hashtable();
+	
+	public static Object getLock(String key) {
+		synchronized (lock) {
+			if (locks.get(key) == null)
+				locks.put(key, key);
+			return locks.get(key);
+		}
+	}
+	
+	public static void returnLock(String key) {
+		synchronized (lock) {
+			locks.remove(key);
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/Messages.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/Messages.java
new file mode 100644
index 0000000..bee325b
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/Messages.java
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class Messages extends NLS {
+
+	private static final String BUNDLE_NAME = "org.eclipse.update.internal.core.messages";//$NON-NLS-1$
+
+	private Messages() {
+		// Do not instantiate
+	}
+
+	public static String BaseSiteFactory_CannotRetriveParentDirectory;
+	public static String ContentReference_UnableToCreateInputStream;
+	public static String ContentReference_UnableToReturnReferenceAsFile;
+	public static String ContentReference_UnableToReturnReferenceAsURL;
+	public static String ContentReference_HttpNok;
+	public static String ContentReference_FileDoesNotExist;
+	public static String Feature_SiteAlreadySet;
+	public static String Feature_TaskInstallFeatureFiles;
+	public static String Feature_TaskInstallPluginFiles;
+	public static String Feature_NoContentProvider;
+	public static String Feature_NoFeatureContentConsumer;
+	public static String Feature_NoURL;
+	public static String Feature_FeatureVersionToString;
+	public static String Feature_InstallationCancelled;
+	public static String Feature_UnableToInitializeFeatureReference;
+	public static String FeatureContentProvider_Downloading;
+	public static String FeatureContentProvider_UnableToRetrieve;
+	public static String FeatureContentProvider_UnableToCreate;
+	public static String FeatureContentProvider_ExceptionDownloading;
+	public static String InstallHandler_unableToCreateHandler;
+	public static String InstallHandler_notFound;
+	public static String InstallHandler_invalidHandler;
+	public static String InstallHandler_callException;
+	public static String InstallHandler_error;
+	public static String InstallMonitor_DownloadSize;
+	public static String InstallMonitor_DownloadSizeLong;
+	public static String ProductProvider;
+	public static String JarContentReference_Unpacking;
+	public static String Site_CannotFindCategory;
+	public static String Site_NoCategories;
+	public static String Site_NoContentProvider;
+	public static String VersionedIdentifier_IdOrVersionNull;
+	public static String SiteFile_CannotRemovePlugin;
+	public static String SiteFile_CannotRemoveFeature;
+	public static String SiteFile_UnableToCreateURL;
+	public static String SiteFile_Removing;
+	public static String SiteFileFactory_UnableToCreateURL;
+	public static String SiteFileFactory_UnableToAccessSite;
+	public static String SiteFileFactory_DirectoryDoesNotExist;
+	public static String DefaultFeatureParser_location;
+	public static String DefaultFeatureParser_NoFeatureTag;
+	public static String DefaultFeatureParser_WrongParsingStack;
+	public static String DefaultFeatureParser_UnknownElement;
+	public static String DefaultFeatureParser_TooManyURLtag;
+	public static String DefaultFeatureParser_UnknownStartState;
+	public static String DefaultFeatureParser_IdOrVersionInvalid;
+	public static String DefaultFeatureParser_MissingId;
+	public static String DefaultFeatureParser_ParsingStackBackToInitialState;
+	public static String DefaultFeatureParser_ElementAlreadySet;
+	public static String DefaultFeatureParser_StateIncludeWrongElement;
+	public static String DefaultFeatureParser_RequireStateWithoutImportElement;
+	public static String DefaultFeatureParser_MissingPatchVersion;
+	public static String DefaultFeatureParser_wrongMatchForPatch;
+	public static String DefaultFeatureParser_patchWithPlugin;
+	public static String DefaultFeatureParser_MultiplePatchImports;
+	public static String DefaultFeatureParser_UnknownEndState;
+	public static String DefaultFeatureParser_ErrorParsing;
+	public static String DefaultFeatureParser_ErrorlineColumnMessage;
+	public static String DefaultFeatureParser_ErrorParsingFeature;
+	public static String DefaultFeatureParser_UnknownState;
+	public static String DefaultFeatureParser_NoLicenseText;
+	public static String DefaultFeatureParser_PluginAndFeatureId;
+	public static String SiteContentProvider_ErrorCreatingURLForArchiveID;
+	public static String DefaultSiteParser_NoSiteTag;
+	public static String DefaultSiteParser_WrongParsingStack;
+	public static String DefaultSiteParser_UnknownElement;
+	public static String DefaultSiteParser_UnknownStartState;
+	public static String DefaultSiteParser_Missing;
+	public static String DefaultSiteParser_ParsingStackBackToInitialState;
+	public static String DefaultSiteParser_ElementAlreadySet;
+	public static String DefaultSiteParser_UnknownEndState;
+	public static String DefaultSiteParser_ErrorParsing;
+	public static String DefaultSiteParser_ErrorlineColumnMessage;
+	public static String DefaultSiteParser_ErrorParsingSite;
+	public static String DefaultSiteParser_UnknownState;
+	public static String DefaultSiteParser_InvalidXMLStream;
+	public static String ModelObject_ModelReadOnly;
+	public static String SiteModelObject_ErrorParsingSiteStream;
+	public static String SiteModelObject_ErrorAccessingSiteStream;
+	public static String InstallConfiguration_ErrorDuringFileAccess;
+	public static String InstallConfigurationParser_FeatureReferenceNoURL;
+	public static String FeatureExecutableContentProvider_FileDoesNotExist;
+	public static String FeatureExecutableContentProvider_InvalidDirectory;
+	public static String FeatureExecutableContentProvider_UnableToCreateURLFor;
+	public static String FeatureExecutableContentProvider_UnableToRetrieveNonPluginEntry;
+	public static String FeatureExecutableContentProvider_UnableToRetrieveFeatureEntry;
+	public static String FeatureExecutableContentProvider_UnableToRetrievePluginEntry;
+	public static String ConfiguredSite_NonInstallableSite;
+	public static String ConfiguredSite_NullFeatureToInstall;
+	public static String ConfiguredSite_NonUninstallableSite;
+	public static String ConfiguredSite_NoSite;
+	public static String ConfiguredSite_CannotFindFeatureToUnconfigure;
+	public static String ConfiguredSite_CannotFindFeatureToConfigure;
+	public static String ConfiguredSite_CannotFindPluginEntry;
+	public static String ConfiguredSite_MissingPluginsBrokenFeature;
+	public static String ConfiguredSite_UnableToRemoveConfiguredFeature;
+	public static String ConfiguredSite_UnableToFindFeature;
+	public static String ConfiguredSite_SiteURLNull;
+	public static String ConfiguredSite_NonLocalSite;
+	public static String ConfiguredSite_NotSameProductId;
+	public static String ConfiguredSite_ContainedInAnotherSite;
+	public static String ConfiguredSite_ReadOnlySite;
+	public static String ConfiguredSite_UnableResolveURL;
+	public static String ConfiguredSite_UnableToAccessSite;
+	public static String FeatureFactory_CreatingError;
+	public static String FeatureModelFactory_ErrorAccesingFeatureStream;
+	public static String FeatureExecutableFactory_NullURL;
+	public static String FeatureExecutableFactory_CannotCreateURL;
+	public static String FeaturePackagedContentProvider_NoManifestFile;
+	public static String FeaturePackagedContentProvider_InvalidDirectory;
+	public static String FeaturePackagedContentProvider_ErrorRetrieving;
+	public static String FeatureReference_UnableToResolveURL;
+	public static String FeatureTypeFactory_UnableToFindFeatureFactory;
+	public static String InstallConfiguration_UnableToCreateURL;
+	public static String InstallConfiguration_UnableToCast;
+	public static String InstallConfiguration_UnableToSavePlatformConfiguration;
+	public static String InstallConfiguration_AlreadyNativelyLinked;
+	public static String InstallConfiguration_AlreadyProductSite;
+	public static String InstallConfiguration_unableToFindSite;
+	public static String InternalSiteManager_UnableToCreateSiteWithType;
+	public static String InternalSiteManager_UnableToAccessURL;
+	public static String InternalSiteManager_UnableToCreateURL;
+	public static String InternalSiteManager_FailedRetryAccessingSite;
+	public static String InternalSiteManager_ConnectingToSite;
+	public static String GlobalConsumer_ErrorCreatingFile;
+	public static String SiteFileContentConsumer_UnableToCreateURL;
+	public static String SiteFileContentConsumer_UnableToCreateURLForFile;
+	public static String SiteFileContentConsumer_unableToDelete;
+	public static String ContentConsumer_UnableToRename;
+	public static String SiteFileFactory_UnableToObtainParentDirectory;
+	public static String SiteFileFactory_FileDoesNotExist;
+	public static String SiteFileFactory_UnableToCreateURLForFile;
+	public static String SiteFileFactory_ErrorParsingFile;
+	public static String SiteFileFactory_ErrorAccessing;
+	public static String SiteTypeFactory_UnableToFindSiteFactory;
+	public static String UpdateManagerUtils_UnableToRemoveFile;
+	public static String UpdateManagerUtils_FileAlreadyExists;
+	public static String SiteLocal_UnableToCreateURLFor;
+	public static String SiteLocal_UnableToDetermineFeatureStatusSiteNull;
+	public static String SiteLocal_TwoVersionSamePlugin1;
+	public static String SiteLocal_TwoVersionSamePlugin2;
+	public static String SiteLocal_FeatureUnHappy;
+	public static String SiteLocal_FeatureHappy;
+	public static String SiteLocal_FeatureAmbiguous;
+	public static String SiteLocal_NestedFeatureUnHappy;
+	public static String SiteLocal_NestedFeatureUnavailable;
+	public static String SiteLocal_NoPluginVersion;
+	public static String SiteLocal_UnableToDetermineFeatureStatusConfiguredSiteNull;
+	public static String SiteLocal_FeatureDisable;
+	public static String SiteLocal_FeatureStatusUnknown;
+	public static String SiteLocal_NestedFeatureDisable;
+	public static String SiteURLFactory_UnableToCreateURL;
+	public static String SiteURLFactory_UnableToAccessSiteStream;
+	public static String JarVerifier_Verify;
+	public static String JarVerifier_UnableToFindEncryption;
+	public static String JarVerifier_UnableToLoadCertificate;
+	public static String JarVerifier_UnableToFindProviderForKeystore;
+	public static String JarVerifier_KeyStoreNotLoaded;
+	public static String JarVerifier_UnableToAccessJar;
+	public static String JarVerifier_InvalidFile;
+	public static String JarVerifier_InvalidJar;
+	public static String JarVerificationResult_ValidBetween;
+	public static String JarVerificationResult_ExpiredCertificate;
+	public static String JarVerificationResult_CertificateNotYetValid;
+	public static String JarVerificationResult_CertificateValid;
+	public static String JarVerificationService_UnsucessfulVerification;
+	public static String JarVerificationService_CancelInstall;
+	public static String UpdateManagerUtils_UnableToLog;
+	public static String ConnectionThreadManager_tooManyConnections;
+	public static String ConnectionThreadManager_unresponsiveURL;
+	public static String IncludedFeatureReference_featureUninstalled;
+	public static String ActivityConstraints_warning;
+	public static String ActivityConstraints_rootMessage;
+	public static String ActivityConstraints_rootMessageInitial;
+	public static String ActivityConstraints_beforeMessage;
+	public static String ActivityConstraints_afterMessage;
+	public static String ActivityConstraints_platform;
+	public static String ActivityConstraints_primary;
+	public static String ActivityConstaints_prereq_plugin;
+	public static String ActivityConstaints_prereq_feature;
+	public static String ActivityConstraints_prereq;
+	public static String ActivityConstraints_prereqPerfect;
+	public static String ActivityConstraints_prereqEquivalent;
+	public static String ActivityConstraints_prereqCompatible;
+	public static String ActivityConstraints_prereqGreaterOrEqual;
+	public static String ActivityConstraints_os;
+	public static String ActivityConstraints_ws;
+	public static String ActivityConstraints_arch;
+	public static String ActivityConstraints_cycle;
+	public static String ActivityConstraints_childMessage;
+	public static String ActivityConstraints_optionalChild;
+	public static String ActivityConstraints_exclusive;
+	public static String ActivityConstraints_noLicense;
+	public static String ActivityConstraints_readOnly;
+	public static String ActivityConstraints_platformModified;
+	public static String DuplicateConflictsDialog_conflict;
+	public static String OperationsManager_error_old;
+	public static String OperationsManager_installing;
+	public static String OperationsManager_error_uninstall;
+	public static String Search_networkProblems;
+	public static String InstallConfiguration_location_exists;
+	public static String InstallLogParser_errors;
+	public static String SiteLocal_cloneConfig;
+	public static String UpdateManagerUtils_inputStreamEnded;
+	public static String UpdateSearchRequest_loadingPolicy;
+	public static String UpdateManagerUtils_copy;
+	public static String UpdatePolicy_parsePolicy;
+	public static String UpdatePolicy_policyExpected;
+	public static String UpdateSearchRequest_searching;
+	public static String UpdateSearchRequest_contacting;
+	public static String UpdateSearchRequest_checking;
+	public static String UpdatePolicy_invalidURL;
+	public static String UpdatePolicy_nameNoNull;
+	public static String UpdatePolicy_UpdatePolicy;
+	public static String SiteFile_featureNotRemoved;
+	public static String SiteFile_pluginNotRemoved;
+	public static String ErrorRecoveryLog_noFiletoRemove;
+	public static String UpdatesSearchCategory_errorSearchingForUpdates;
+    public static String UninstallCommand_featureNotInstalledByUM;
+	public static String Standalone_siteConfigured;
+	public static String Standalone_noSite;
+	public static String Standalone_noSite3;
+	public static String Standalone_noConfiguredSite;
+	public static String Standalone_installing;
+	public static String Standalone_notFoundOrNewer;
+	public static String Standalone_duplicate;
+	public static String Standalone_installed;
+	public static String Standalone_cannotInstall;
+	public static String Standalone_noFeatures1;
+	public static String Standalone_noFeatures2;
+	public static String Standalone_noFeatures3;
+	public static String Standalone_noFeatures4;
+	public static String Standalone_noConfigSiteForFeature;
+	public static String Standalone_invalidCmd;
+	public static String Standalone_connection;
+	public static String Standalone_searching;
+	public static String Standalone_cmdFailed;
+	public static String Standalone_cmdFailedNoLog;
+	public static String Standalone_cmdCompleteWithErrors;
+	public static String Standalone_cmdOK;
+	public static String Standalone_updating;
+	public static String Standalone_noUpdate;
+	public static String Standalone_updated;
+	
+	public static String SiteFilePluginContentConsumer_unableToDelete;
+	public static String SiteFilePackedPluginContentConsumer_unableToDelete;	
+	
+	public static String HttpResponse_rangeExpected;
+	public static String HttpResponse_wrongRange;
+	public static String DefaultSiteParser_mirrors;
+	public static String FeatureExecutableContentProvider_UnableToRetriveArchiveContentRef;
+	
+	public static String JarProcessor_unpackNotFound;
+	public static String JarProcessor_noPackUnpack;
+	public static String JarProcessor_packNotFound;
+	
+	public static String SiteOptimizer_inputNotSpecified;
+	public static String SiteOptimizer_inputFileNotFound;
+	public static String SiteCategory_other_label;
+	public static String SiteCategory_other_description;
+
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	public static String InstallCommand_site;
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/NonPluginEntryContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/NonPluginEntryContentConsumer.java
new file mode 100644
index 0000000..e040188
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/NonPluginEntryContentConsumer.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+
+/**
+ * ContentConsumer for a non plugin entry of a feature
+ */
+
+public class NonPluginEntryContentConsumer extends ContentConsumer {
+
+	private boolean closed = false;
+
+	private IContentConsumer contentConsumer;
+		
+	/*
+	 * Constructor
+	 */
+	public NonPluginEntryContentConsumer(IContentConsumer contentConsumer){
+		this.contentConsumer = contentConsumer;
+	}
+
+	/*
+	 * @see ContentConsumer#store(ContentReference, IProgressMonitor)
+	 */
+	public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException {
+		if (!closed){
+			contentConsumer.store( contentReference,monitor);
+		} else {
+			UpdateCore.warn("Attempt to store in a closed NonPluginEntryContentConsumer",new Exception()); //$NON-NLS-1$
+		}
+	}
+
+	/*
+	 * @see ContentConsumer#close()
+	 */
+	public void close() throws CoreException  {
+		if (!closed){
+			closed = true;
+			contentConsumer.close();
+		} else {
+			UpdateCore.warn("Attempt to close a closed NonPluginEntryContentConsumer",new Exception()); //$NON-NLS-1$
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/NullContentReference.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/NullContentReference.java
new file mode 100644
index 0000000..963fa1d
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/NullContentReference.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.update.core.ContentReference;
+
+/**
+ * NullContentReference implements a general access wrapper 
+ * to feature and site content -- but, for which, there is no 
+ * content actually found. This way, it can "keep" the ID that was 
+ * requested, and still hold a place in lists and arrays, without a 
+ * change to other program logic. It does, how ever require the internal
+ * algorithms to be more careful about assumptions made ... for example, 
+ * just because asFile is null, it does not follow that asURL will not be null. 
+ * <p>
+ * This class may not be instantiated or subclassed by clients. 
+ * </p>
+ * @see org.eclipse.update.core.ContentReference
+ * @see org.eclipse.update.core.JarContentReference
+ * @see org.eclipse.update.core.JarEntryContentReference
+ */
+public class NullContentReference extends ContentReference {
+
+
+	/**
+	 * Contructor for the "missing jar" case. 
+	 * 
+	 * @param id
+	 */
+	public NullContentReference(String id) {
+		super(id, (File) null);
+	}
+	/**
+	 * A factory method to create a content reference of
+	 * the same type.
+	 * 
+	 * @param id "symbolic" path identifier
+	 */
+	public ContentReference createContentReference(String id, File file) {
+		return new NullContentReference(id);
+	}
+
+	/**
+	 * Overrides super class implementation to avoid throwing a FileNotFound exception.
+	 * 
+	 * @return null
+	 */
+	public InputStream getInputStream() throws IOException {
+		return null;
+	}
+	/**
+	 * Overrides super class implementation to avoid throwing a FileNotFound exception.
+	 * 
+	 * @return null
+	 */
+	public File asFile() throws IOException {
+		return null; 
+	}
+
+	/**
+	 * Overrides super class implementation to avoid throwing URL exceptions.
+	 * 
+	 * @return null
+	 */
+	public URL asURL() throws IOException {
+		return null;
+	}
+
+	/**
+	 * Return string representation of this reference.
+	 * 
+	 * @return string representation
+	 */
+	public String toString() {
+			return "Missing archive file: " + '(' + getIdentifier() + ')'; //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/PatchedFeature.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/PatchedFeature.java
new file mode 100644
index 0000000..bc9dae9
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/PatchedFeature.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+/**
+ * Feature and corresponding patch features
+ */
+public class PatchedFeature {
+	private IFeatureReference feature;
+	private Collection patches = new HashSet();
+	/**
+	 *  
+	 */
+	public PatchedFeature(IFeatureReference feature) {
+		super();
+		this.feature = feature;
+	}
+	public void addPatch(IFeatureReference patch) {
+		patches.add(patch);
+	}
+	/**
+	 * @return Returns the feature.
+	 */
+	public IFeatureReference getFeature() {
+		return feature;
+	}
+	/**
+	 * @return Returns the patches.
+	 */
+	public IFeatureReference[] getPatches() {
+		return (IFeatureReference[]) patches.toArray(new IFeatureReference[patches.size()]);
+	}
+	/**
+	 * @return Returns the feature and the patches.
+	 */
+	public IFeatureReference[] getFeatureAndPatches() {
+		IFeatureReference[] features = new IFeatureReference[patches.size() + 1];
+		features[0] = feature;
+		System.arraycopy(getPatches(), 0, features, 1, patches.size());
+		return features;
+	}
+	/**
+	 * Obtains all plugins from the feature and its patches. Each plugin will
+	 * have unique ID.
+	 * If there are multiple version of plugin with same ID among the feature
+	 * and its patches, highest version plugins are chosen.
+	 * 
+	 * @return FeaturePlugin[]
+	 */
+	public FeaturePlugin[] getPlugins() {
+		// Use a map of PatchedPluigns by plugin ID
+		// to collect one version of each plugin
+		Map plugins = new HashMap();
+		IFeatureReference[] featureRefs = getFeatureAndPatches();
+		// for each (feature or any patch)
+		for (int i = 0; i < featureRefs.length; i++) {
+			try {
+				IFeature feature = featureRefs[i].getFeature(null);
+				if (feature == null) {
+					UpdateCore.warn("Null Feature", new Exception()); //$NON-NLS-1$
+					continue;
+				}
+				// get plugin entries
+				IPluginEntry[] entries = feature.getPluginEntries();
+				for (int entr = 0; entr < entries.length; entr++) {
+					String pluginId = entries[entr].getVersionedIdentifier().getIdentifier();
+					PluginVersionIdentifier pluginVersion = entries[entr].getVersionedIdentifier().getVersion();
+					// check if map contains >= version of same plugin
+					FeaturePlugin existingPlugin = (FeaturePlugin) plugins.get(pluginId);
+					if (existingPlugin != null && existingPlugin.getEntry().getVersionedIdentifier().getVersion().isGreaterOrEqualTo(pluginVersion)) {
+						// same or newer plugin already collected
+						continue;
+					} else {
+						plugins.put(pluginId, new FeaturePlugin(entries[entr], feature));
+					}
+				}
+			} catch (CoreException e) {
+				UpdateCore.warn(null, e);
+			}
+		}
+		return (FeaturePlugin[]) plugins.values().toArray(new FeaturePlugin[plugins.size()]);
+	}
+	public String toString() {
+		StringBuffer str = new StringBuffer(feature.toString());
+		IFeatureReference[] patches = getFeatureAndPatches();
+		for (int i = 0; i < patches.length; i++) {
+			str.append(" +patch=" + patches[i].toString() + " "); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		return str.toString();
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/PluginEntryContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/PluginEntryContentConsumer.java
new file mode 100644
index 0000000..a549ee5
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/PluginEntryContentConsumer.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+
+/**
+ * ContentConsumer for a plugin entry of a feature
+ */
+
+public class PluginEntryContentConsumer extends ContentConsumer {
+
+	private boolean closed = false;
+
+	private IContentConsumer contentConsumer;
+		
+	/*
+	 * Constructor
+	 */
+	public PluginEntryContentConsumer(IContentConsumer contentConsumer){
+		this.contentConsumer = contentConsumer;
+	}
+
+	/*
+	 * @see ContentConsumer#store(ContentReference, IProgressMonitor)
+	 */
+	public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException {
+		if (!closed){
+			contentConsumer.store(contentReference,monitor);
+		} else {
+			UpdateCore.warn("Attempt to store in a closed PluginEntryContentConsumer",new Exception()); //$NON-NLS-1$
+		}
+	}
+
+	/*
+	 * @see ContentConsumer#close()
+	 */
+	public void close() throws CoreException {
+		if (!closed){
+			closed = true;
+			contentConsumer.close();
+		} else {
+			UpdateCore.warn("Attempt to close a closed PluginEntryContentConsumer",new Exception()); //$NON-NLS-1$
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ProductProvider.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ProductProvider.java
new file mode 100644
index 0000000..da84d80
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/ProductProvider.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.internal.configurator.FeatureEntry;
+
+/**
+ * Maps primary features to IProduct
+ */
+public class ProductProvider implements IProductProvider {
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProductProvider#getProducts()
+	 */
+	public IProduct[] getProducts() {
+		IPlatformConfiguration configuration = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		if (configuration == null)
+			return new IProduct[0];
+		IPlatformConfiguration.IFeatureEntry[] features = configuration.getConfiguredFeatureEntries();
+		ArrayList primaryFeatures = new ArrayList();
+		for (int i = 0; i < features.length; i++)
+			if (features[i].canBePrimary() && (features[i] instanceof FeatureEntry))
+				primaryFeatures.add(new FeatureEntryWrapper((FeatureEntry) features[i]));
+		// TODO handle unmanaged plugins later
+		return (IProduct[]) primaryFeatures.toArray(new IProduct[primaryFeatures.size()]);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.IProductProvider#getName()
+	 */
+	public String getName() {
+		return Messages.ProductProvider;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteContentConsumer.java
new file mode 100644
index 0000000..3c121cd
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteContentConsumer.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+
+import org.eclipse.update.core.*;
+
+/**
+ * A default implementation for IFeatureContentConsumer
+ * </p>
+ * @since 2.0
+ */
+
+public abstract class SiteContentConsumer implements ISiteContentConsumer {
+	
+	private ISite site;
+	
+	/*
+	 * @see ISiteContentConsumer#setSite(ISite)
+	 */
+	/**
+	 * Sets the site.
+	 * @param site The site to set
+	 */
+	public void setSite(ISite site) {
+		this.site = site;
+	}
+
+	/**
+	 * Gets the site.
+	 * @return Returns a ISite
+	 */
+	public ISite getSite() {
+		return site;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFile.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFile.java
new file mode 100644
index 0000000..29c6f31
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFile.java
@@ -0,0 +1,424 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.ContentReference;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureContentConsumer;
+import org.eclipse.update.core.IFeatureFactory;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IInstallHandler;
+import org.eclipse.update.core.INonPluginEntry;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.core.IVerificationListener;
+import org.eclipse.update.core.IVerifier;
+import org.eclipse.update.core.InstallMonitor;
+import org.eclipse.update.core.Site;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.model.ContentEntryModel;
+import org.eclipse.update.core.model.FeatureModel;
+import org.eclipse.update.core.model.FeatureReferenceModel;
+import org.eclipse.update.core.model.InstallAbortedException;
+import org.eclipse.update.internal.operations.UpdateUtils;
+
+
+/**
+ * Site on the File System
+ */
+public class SiteFile extends Site {
+
+	/**
+	 * plugin entries 
+	 */
+	private List pluginEntries = new ArrayList(0);
+
+	/**
+	 * 
+	 */
+	public ISiteContentConsumer createSiteContentConsumer(IFeature targetFeature) throws CoreException {
+		SiteFileContentConsumer consumer = new SiteFileContentConsumer(targetFeature);
+		consumer.setSite(this);
+		return consumer;
+	}
+
+	/**
+	 */
+	public String getDefaultPackagedFeatureType() {
+		return DEFAULT_INSTALLED_FEATURE_TYPE;
+	}
+
+	/*
+	 * @see ISite#install(IFeature, IVerifier, IProgressMonitor)
+	 */
+	public IFeatureReference install(IFeature sourceFeature, IVerificationListener verificationListener, IProgressMonitor progress) throws CoreException {
+		return install(sourceFeature,null,verificationListener,progress);
+	}
+
+	/*
+	 * @see ISite#install(IFeature, IVerifier, IProgressMonitor)
+	 */
+	public IFeatureReference install(IFeature sourceFeature, IFeatureReference[] optionalfeatures, IVerificationListener verificationListener, IProgressMonitor progress) throws CoreException {
+
+		if (sourceFeature == null)
+			return null;
+
+		// make sure we have an InstallMonitor		
+		InstallMonitor monitor;
+		if (progress == null)
+			monitor = null;
+		else if (progress instanceof InstallMonitor)
+			monitor = (InstallMonitor) progress;
+		else
+			monitor = new InstallMonitor(progress);
+
+		// create new executable feature and install source content into it
+		IFeature localFeature = createExecutableFeature(sourceFeature);
+
+		IFeatureReference localFeatureReference = null;
+		localFeatureReference = sourceFeature.install(localFeature, optionalfeatures, verificationListener, monitor);
+
+		return localFeatureReference;
+	}
+
+	/*
+	 * @see ISite#install(IFeature,IFeatureContentConsumer, IVerifier,IVerificationLIstener, IProgressMonitor)
+	 */
+	public IFeatureReference install(IFeature sourceFeature, IFeatureReference[] optionalfeatures, IFeatureContentConsumer parentContentConsumer, IVerifier parentVerifier, IVerificationListener verificationListener, IProgressMonitor progress)
+		throws InstallAbortedException, CoreException {
+
+		if (sourceFeature == null)
+			return null;
+
+		// make sure we have an InstallMonitor		
+		InstallMonitor monitor;
+		if (progress == null)
+			monitor = null;
+		else if (progress instanceof InstallMonitor)
+			monitor = (InstallMonitor) progress;
+		else
+			monitor = new InstallMonitor(progress);
+
+		// create new executable feature and install source content into it
+		IFeature localFeature = createExecutableFeature(sourceFeature);
+		parentContentConsumer.addChild(localFeature);
+
+		// set the verifier
+		IVerifier vr = sourceFeature.getFeatureContentProvider().getVerifier();
+		if (vr != null)
+			vr.setParent(parentVerifier);
+
+		IFeatureReference localFeatureReference = null;
+		localFeatureReference = sourceFeature.install(localFeature, optionalfeatures, verificationListener, monitor);
+
+		return localFeatureReference;
+	}
+
+	/*
+	 * @see ISite#remove(IFeature, IProgressMonitor)
+	 */
+	public void remove(IFeature feature, IProgressMonitor progress) throws CoreException {
+
+		if (feature == null) {
+			UpdateCore.warn("Feature to remove is null"); //$NON-NLS-1$
+			return;
+		}
+		
+		ErrorRecoveryLog recoveryLog = ErrorRecoveryLog.getLog();
+
+		// make sure we have an InstallMonitor		
+		InstallMonitor monitor;
+		if (progress == null)
+			monitor = null;
+		else if (progress instanceof InstallMonitor)
+			monitor = (InstallMonitor) progress;
+		else
+			monitor = new InstallMonitor(progress);
+
+		// Setup optional install handler
+		InstallHandlerProxy handler = new InstallHandlerProxy(IInstallHandler.HANDLER_ACTION_UNINSTALL, feature, feature.getInstallHandlerEntry(), monitor);
+		boolean success = false;
+		Throwable originalException = null;
+
+		try {
+
+			// start log
+			recoveryLog.open(ErrorRecoveryLog.START_REMOVE_LOG);
+
+			// log files have been downloaded
+			recoveryLog.append(ErrorRecoveryLog.END_ABOUT_REMOVE);
+
+			handler.uninstallInitiated();
+
+			// remove the feature and the plugins if they are not used and not activated
+			// get the plugins from the feature
+			IPluginEntry[] pluginsToRemove = getPluginEntriesOnlyReferencedBy(feature);
+
+			if (monitor != null) {
+				monitor.beginTask(Messages.SiteFile_Removing + feature.getLabel(), pluginsToRemove.length + 1);	
+			}
+
+			// remove feature reference from the site
+			ISiteFeatureReference[] featureReferences = getFeatureReferences();
+			if (featureReferences != null) {
+				for (int indexRef = 0; indexRef < featureReferences.length; indexRef++) {
+					IFeatureReference element = featureReferences[indexRef];
+					if (element.getVersionedIdentifier().equals(feature.getVersionedIdentifier())) {
+						removeFeatureReferenceModel((FeatureReferenceModel) element);
+						break;
+					}
+				}
+			}
+
+			if (InstallRegistry.getInstance().get("feature_"+feature.getVersionedIdentifier()) == null) { //$NON-NLS-1$
+				UpdateCore.log(NLS.bind(Messages.SiteFile_featureNotRemoved, (new String[] { feature.getVersionedIdentifier().toString() })), null);
+			} else {
+				// remove the feature content
+				ContentReference[] references = feature.getFeatureContentProvider().getFeatureEntryArchiveReferences(monitor);
+				for (int i = 0; i < references.length; i++) {
+					try {
+						UpdateManagerUtils.removeFromFileSystem(references[i].asFile());
+						if (monitor != null)
+							monitor.worked(1);
+					} catch (IOException e) {
+						throw Utilities.newCoreException(NLS.bind(Messages.SiteFile_CannotRemoveFeature, (new String[] { feature.getVersionedIdentifier().getIdentifier(), getURL().toExternalForm() })), e);
+					}
+				}
+				InstallRegistry.unregisterFeature(feature);
+			}
+
+			//finds the contentReferences for an IPluginEntry
+			// and remove it
+			for (int i = 0; i < pluginsToRemove.length; i++) {
+				remove(feature, pluginsToRemove[i], monitor);
+			}
+
+			// remove any children feature
+			IFeatureReference[] childrenRef = feature.getIncludedFeatureReferences();
+			for (int i = 0; i < childrenRef.length; i++) {
+				IFeature childFeature = null;
+				try {
+					childFeature = childrenRef[i].getFeature(null);
+				} catch (CoreException e) {
+					UpdateCore.warn("Unable to retrieve feature to remove for:" + childrenRef[i]); //$NON-NLS-1$
+				}
+                // do not remove nested feature if configured (i.e. used by another configured feature)
+				if (childFeature != null && !getCurrentConfiguredSite().isConfigured(childFeature))
+					remove(childrenRef[i].getFeature(null), monitor);
+			}
+
+			// remove the feature from the site cache
+			removeFeatureFromCache(feature.getURL());
+			
+			handler.completeUninstall();
+
+			success = true;
+		} catch (Throwable t) {
+			originalException = t;
+		} finally {
+			Throwable newException = null;
+			try {
+				if (success) {
+					// close the log
+					recoveryLog.close(ErrorRecoveryLog.END_REMOVE_LOG);
+					recoveryLog.delete();
+				} else {
+					recoveryLog.close(ErrorRecoveryLog.END_REMOVE_LOG);
+				}
+				handler.uninstallCompleted(success);
+			} catch (Throwable t) {
+				newException = t;
+			}
+			if (originalException != null) // original exception wins
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallHandler_error, (new String[] { feature.getLabel() })), originalException);
+			if (newException != null)
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallHandler_error, (new String[] { feature.getLabel() })), newException);
+		}
+	}
+
+	/**
+	 * returns the download size
+	 * of the feature to be installed on the site.
+	 * If the site is <code>null</code> returns the maximum size
+	 * 
+	 * If one plug-in entry has an unknown size.
+	 * then the download size is unknown.
+	 * 
+	 */
+	public long getDownloadSizeFor(IFeature feature) {
+		long result = 0;
+		//[132029]
+		//IPluginEntry[] entriesToInstall = feature.getPluginEntries();
+		//IPluginEntry[] siteEntries = this.getPluginEntries();
+		//entriesToInstall = UpdateManagerUtils.diff(entriesToInstall, siteEntries);
+		//[18355]
+		//INonPluginEntry[] nonPluginEntriesToInstall = feature.getNonPluginEntries();
+
+		try {
+			//[132029]
+			//result = feature.getFeatureContentProvider().getDownloadSizeFor(entriesToInstall, nonPluginEntriesToInstall);
+			IFeatureReference[] children = feature.getIncludedFeatureReferences();
+			IFeature currentFeature = null;
+			for (int i = 0; i < children.length; i++) {
+				currentFeature = UpdateUtils.getIncludedFeature(feature, children[i]);
+				if (currentFeature != null) {
+					result += getDownloadSizeFor(currentFeature);
+					if(result == ContentEntryModel.UNKNOWN_SIZE)
+						return result;
+				}
+			}
+
+			IPluginEntry[] entriesToInstall = feature.getPluginEntries();
+			IPluginEntry[] siteEntries = this.getPluginEntries();
+			entriesToInstall = UpdateManagerUtils.diff(entriesToInstall, siteEntries);
+			//[18355]
+			   INonPluginEntry[] nonPluginEntriesToInstall = feature.getNonPluginEntries();
+
+			 result += feature.getFeatureContentProvider().getDownloadSizeFor(entriesToInstall, nonPluginEntriesToInstall);
+		} catch (CoreException e) {
+			UpdateCore.warn(null, e);
+			result = ContentEntryModel.UNKNOWN_SIZE;
+		}
+		return result;
+	}
+
+	/**
+	 * returns the download size
+	 * of the feature to be installed on the site.
+	 * If the site is <code>null</code> returns the maximum size
+	 * 
+	 * If one plug-in entry has an unknown size.
+	 * then the download size is unknown.
+	 * 
+	 * @see ISite#getDownloadSizeFor(IFeature)
+	 * 
+	 */
+	public long getInstallSizeFor(IFeature feature) {
+		long result = 0;
+
+		try {
+			List pluginsToInstall = new ArrayList();
+
+			// get all the plugins [17304]
+			pluginsToInstall.addAll(Arrays.asList(feature.getPluginEntries()));
+			IFeatureReference[] children = feature.getIncludedFeatureReferences();
+			IFeature currentFeature = null;
+			for (int i = 0; i < children.length; i++) {
+				currentFeature = UpdateUtils.getIncludedFeature(feature, children[i]);
+				if (currentFeature != null) {
+					//[132029]
+					//pluginsToInstall.addAll(Arrays.asList(currentFeature.getPluginEntries()));
+					result += getInstallSizeFor(currentFeature);
+					if (result == ContentEntryModel.UNKNOWN_SIZE)
+						return result;
+				}
+			}
+
+			IPluginEntry[] entriesToInstall = new IPluginEntry[0];
+			if (pluginsToInstall.size() > 0) {
+				entriesToInstall = new IPluginEntry[pluginsToInstall.size()];
+				pluginsToInstall.toArray(entriesToInstall);
+			}
+
+			IPluginEntry[] siteEntries = this.getPluginEntries();
+			entriesToInstall = UpdateManagerUtils.diff(entriesToInstall, siteEntries);
+
+			//[18355]
+			INonPluginEntry[] nonPluginEntriesToInstall = feature.getNonPluginEntries();
+			
+			//[132029]
+			//result = feature.getFeatureContentProvider().getInstallSizeFor(entriesToInstall, nonPluginEntriesToInstall);
+			result += feature.getFeatureContentProvider().getInstallSizeFor(entriesToInstall, nonPluginEntriesToInstall);
+		} catch (CoreException e) {
+			UpdateCore.warn(null, e);
+			result = ContentEntryModel.UNKNOWN_SIZE;
+		}
+
+		return result;
+	}
+
+	/**
+	 * Adds a plugin entry 
+	 * Either from parsing the file system or 
+	 * installing a feature
+	 * 
+	 * We cannot figure out the list of plugins by reading the Site.xml as
+	 * the archives tag are optionals
+	 */
+	public void addPluginEntry(IPluginEntry pluginEntry) {
+		pluginEntries.add(pluginEntry);
+	}
+
+	public IPluginEntry[] getPluginEntries() {
+		IPluginEntry[] result = new IPluginEntry[0];
+		if (!(pluginEntries == null || pluginEntries.isEmpty())) {
+			result = new IPluginEntry[pluginEntries.size()];
+			pluginEntries.toArray(result);
+		}
+		return result;
+	}
+
+
+	public int getPluginEntryCount() {
+		return getPluginEntries().length;
+	}
+
+	/**
+	 * 
+	 */
+	private IFeature createExecutableFeature(IFeature sourceFeature) throws CoreException {
+		IFeature result = null;
+		IFeatureFactory factory = FeatureTypeFactory.getInstance().getFactory(DEFAULT_INSTALLED_FEATURE_TYPE);
+		result = factory.createFeature(/*URL*/null, this, null);
+
+		// at least set the version identifier to be the same
+		 ((FeatureModel) result).setFeatureIdentifier(sourceFeature.getVersionedIdentifier().getIdentifier());
+		((FeatureModel) result).setFeatureVersion(sourceFeature.getVersionedIdentifier().getVersion().toString());
+		return result;
+	}
+
+	/**
+	 * 
+	 */
+	private void remove(IFeature feature, IPluginEntry pluginEntry, InstallMonitor monitor) throws CoreException {
+
+		if (pluginEntry == null)
+			return;
+			
+		if (InstallRegistry.getInstance().get("plugin_"+pluginEntry.getVersionedIdentifier()) == null) { //$NON-NLS-1$
+			UpdateCore.log(NLS.bind(Messages.SiteFile_pluginNotRemoved, (new String[] { pluginEntry.getVersionedIdentifier().toString() })), null);
+			return; 
+		}
+
+		ContentReference[] references = feature.getFeatureContentProvider().getPluginEntryArchiveReferences(pluginEntry, monitor);
+		for (int i = 0; i < references.length; i++) {
+			try {
+				UpdateManagerUtils.removeFromFileSystem(references[i].asFile());
+				if (monitor != null)
+					monitor.worked(1);
+			} catch (IOException e) {
+				throw Utilities.newCoreException(NLS.bind(Messages.SiteFile_CannotRemovePlugin, (new String[] { pluginEntry.getVersionedIdentifier().toString(), getURL().toExternalForm() })), e);
+			}
+		}
+		pluginEntries.remove(pluginEntry);
+		InstallRegistry.unregisterPlugin(pluginEntry);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileContentConsumer.java
new file mode 100644
index 0000000..d1e4139
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileContentConsumer.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.update.core.FeatureContentProvider;
+
+import java.io.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+
+/**
+ * ContentConsummer for a SiteFile
+ */
+public class SiteFileContentConsumer extends SiteContentConsumer {
+
+	private IFeature feature;
+	private boolean closed = false;
+
+	// recovery
+	private String oldPath;
+	private String newPath;
+
+	//  for abort
+	private List /* of SiteFilePluginContentConsumer */
+	contentConsumers;
+	private List /*of path as String */
+	installedFiles;
+	
+	// PERF: new instance variable
+	private SiteFileFactory archiveFactory = new SiteFileFactory();
+
+	/*
+	 * Constructor 
+	 */
+	public SiteFileContentConsumer(IFeature feature) {
+		this.feature = feature;
+		installedFiles = new ArrayList();
+	}
+
+	/*
+	 * Returns the path in which the Feature will be installed
+	 */
+	private String getFeaturePath() throws CoreException {
+		String featurePath = null;
+		try {
+			VersionedIdentifier featureIdentifier = feature.getVersionedIdentifier();
+			String path = Site.DEFAULT_INSTALLED_FEATURE_PATH + featureIdentifier.toString() + File.separator;
+			URL newURL = new URL(getSite().getURL(), path);
+			featurePath = newURL.getFile();
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException(Messages.SiteFileContentConsumer_UnableToCreateURL + e.getMessage(), e);	
+		}
+		return featurePath;
+	}
+
+	/*
+	 * @see ISiteContentConsumer#open(INonPluginEntry)
+	 */
+	public IContentConsumer open(INonPluginEntry nonPluginEntry) throws CoreException {
+		return new SiteFileNonPluginContentConsumer(getFeaturePath());
+	}
+
+	/*
+	 * @see ISiteContentConsumer#open(IPluginEntry)
+	 */
+	public IContentConsumer open(IPluginEntry pluginEntry) throws CoreException {
+		ContentConsumer cons;
+		if(pluginEntry instanceof PluginEntryModel && !((PluginEntryModel)pluginEntry).isUnpack()){
+			// plugin can run from a jar
+			 cons = new SiteFilePackedPluginContentConsumer(pluginEntry, getSite());
+		} else{
+			// plugin must be unpacked
+			cons = new SiteFilePluginContentConsumer(pluginEntry, getSite());
+		}
+		addContentConsumers(cons);
+		return cons;
+	}
+
+	/*
+	 * @see ISiteContentConsumer#store(ContentReference, IProgressMonitor)
+	 */
+	public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException {
+
+		if (closed) {
+			UpdateCore.warn("Attempt to store in a closed SiteFileContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+
+		InputStream inStream = null;
+		String featurePath = getFeaturePath();
+		String contentKey = contentReference.getIdentifier();
+		featurePath += contentKey;
+
+		// error recovery
+		if (featurePath.endsWith("\\"+Feature.FEATURE_XML) || featurePath.endsWith("/"+Feature.FEATURE_XML)) { //$NON-NLS-1$ //$NON-NLS-2$
+			oldPath = featurePath.replace(File.separatorChar, '/');
+			File localFile = new File(oldPath);
+			if (localFile.exists()) {
+				throw Utilities.newCoreException(NLS.bind(Messages.UpdateManagerUtils_FileAlreadyExists, (new Object[] { localFile })), null);
+			}
+			featurePath = ErrorRecoveryLog.getLocalRandomIdentifier(featurePath);
+			newPath = featurePath;
+			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.FEATURE_ENTRY, featurePath);
+		}
+
+		try {
+			inStream = contentReference.getInputStream();
+			UpdateManagerUtils.copyToLocal(inStream, featurePath, null);
+			UpdateManagerUtils.checkPermissions(contentReference, featurePath); // 20305
+			installedFiles.add(featurePath);
+		} catch (IOException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.GlobalConsumer_ErrorCreatingFile, (new String[] { featurePath })), e);
+		} finally {
+			if (inStream != null) {
+				try {
+					// close stream
+					inStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+
+	}
+
+	/*
+	 * @see ISiteContentConsumer#close()
+	 */
+	public IFeatureReference close() throws CoreException {
+
+		if (closed)
+			UpdateCore.warn("Attempt to close a closed SiteFileContentConsumer", new Exception()); //$NON-NLS-1$
+
+		// create a new Feature reference to be added to the site
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(getSite());
+		File file = null;
+
+		try {
+			file = new File(getFeaturePath());
+			ref.setURL(file.toURL());
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.SiteFileContentConsumer_UnableToCreateURLForFile, (new String[] { file.getAbsolutePath() })), e);
+		}
+
+		//rename file back 
+		if (newPath != null) {
+			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.RENAME_ENTRY, newPath);
+			boolean sucess = false;
+			File fileToRename = new File(newPath);
+			if (fileToRename.exists()) {
+				File renamedFile = new File(oldPath);
+				if (renamedFile.exists()) {
+					UpdateManagerUtils.removeFromFileSystem(renamedFile);
+					UpdateCore.warn("Removing already existing file:" + oldPath); //$NON-NLS-1$
+				}
+				sucess = fileToRename.renameTo(renamedFile);
+			}
+			if (!sucess) {
+				String msg = NLS.bind(Messages.ContentConsumer_UnableToRename, (new String[] { newPath, oldPath }));
+				throw Utilities.newCoreException(msg, new Exception(msg));
+			}
+		}
+
+		// close plugin and non plugin content consumer
+		if (contentConsumers != null) {
+			Iterator iter = contentConsumers.iterator();
+			while (iter.hasNext()) {
+				ContentConsumer element = (ContentConsumer) iter.next();
+				element.close();
+			}
+		}
+		contentConsumers = null;
+
+		if (ref != null) {
+			// the feature MUST have renamed the plugins at that point
+			// (by closing the PluginContentConsumer)
+			commitPlugins(ref);
+			ref.markReadOnly();
+		}
+
+		closed = true;
+		return ref;
+	}
+
+	/*
+	 * @see ISiteContentConsumer#abort()
+	 */
+	public void abort() throws CoreException {
+
+		if (closed) {
+			UpdateCore.warn("Attempt to abort a closed SiteFileContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+
+		//abort all plugins content consumer opened
+		if (contentConsumers != null) {
+			Iterator iter = contentConsumers.iterator();
+			while (iter.hasNext()) {
+				Object element = iter.next();
+				if (element instanceof  SiteFilePluginContentConsumer) {
+					((SiteFilePluginContentConsumer)element).abort();
+				} else if (element instanceof  SiteFilePackedPluginContentConsumer){
+					((SiteFilePackedPluginContentConsumer)element).abort();
+				}
+				
+			}
+		}
+		contentConsumers = null;
+		boolean sucess = true;
+
+		//Remove feature.xml first if it exists
+		if (oldPath != null) {
+			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.DELETE_ENTRY, oldPath);
+			File fileToDelete = new File(oldPath);
+			if (fileToDelete.exists()) {
+				sucess = fileToDelete.delete();
+			}
+		}
+
+		if (!sucess) {
+			String msg = NLS.bind(Messages.SiteFileContentConsumer_unableToDelete, (new String[] { oldPath })); 
+			UpdateCore.log(msg, null);
+		} else {
+			// remove the feature files;
+			Iterator iter = installedFiles.iterator();
+			File featureFile = null;
+			while (iter.hasNext()) {
+				String path = (String) iter.next();
+				featureFile = new File(path);
+				UpdateManagerUtils.removeFromFileSystem(featureFile);
+			}
+
+			// remove the feature directory if empty
+			String featurePath = getFeaturePath();
+			UpdateManagerUtils.removeEmptyDirectoriesFromFileSystem(new File(featurePath));
+		}
+		closed = true;
+		return;
+	}
+
+	/*
+	 * commit the plugins installed as archive on the site
+	 * (creates the map between the plugin id and the location of the plugin)
+	 */
+	private void commitPlugins(IFeatureReference localFeatureReference) throws CoreException {
+	
+		// get the feature
+		 ((SiteFile) getSite()).addFeatureReferenceModel((SiteFeatureReferenceModel) localFeatureReference);
+		IFeature localFeature = null;
+		try {
+			localFeature = localFeatureReference.getFeature(null);
+		} catch (CoreException e) {
+			UpdateCore.warn(null, e);
+			return;
+		}
+	
+		if (localFeature == null)
+			return;
+	
+		// add the installed plugins directories as archives entry
+		ArchiveReferenceModel archive = null;
+		IPluginEntry[] pluginEntries = localFeature.getPluginEntries();
+		for (int i = 0; i < pluginEntries.length; i++) {
+			String versionId = pluginEntries[i].getVersionedIdentifier().toString();
+			String pluginID = Site.DEFAULT_PLUGIN_PATH + versionId + FeatureContentProvider.JAR_EXTENSION;
+			archive = archiveFactory.createArchiveReferenceModel();
+			archive.setPath(pluginID);
+			try {
+				URL url = null;
+				if (pluginEntries[i] instanceof PluginEntryModel
+						&& !((PluginEntryModel) pluginEntries[i]).isUnpack()) {
+					url = new URL(getSite().getURL(), Site.DEFAULT_PLUGIN_PATH	+ versionId + ".jar"); //$NON-NLS-1$
+				} else {
+					url = new URL(getSite().getURL(), Site.DEFAULT_PLUGIN_PATH	+ versionId + File.separator);
+				}
+				archive.setURLString(url.toExternalForm());
+				archive.resolve(url, null);
+				((SiteFile) getSite()).addArchiveReferenceModel(archive);
+			} catch (MalformedURLException e) {
+	
+				String urlString = (getSite().getURL() != null) ? getSite().getURL().toExternalForm() : "";	//$NON-NLS-1$
+				urlString += Site.DEFAULT_PLUGIN_PATH + pluginEntries[i].toString();
+				throw Utilities.newCoreException(NLS.bind(Messages.SiteFile_UnableToCreateURL, (new String[] { urlString })), e);
+			}
+		}
+		return;
+	}
+
+	/*
+	 * Adds a SiteFilePluginContentConsumer to the list
+	 */
+	private void addContentConsumers(ContentConsumer cons) {
+		if (contentConsumers == null)
+			contentConsumers = new ArrayList();
+		contentConsumers.add(cons);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileContentProvider.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileContentProvider.java
new file mode 100644
index 0000000..09ce8c2
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileContentProvider.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.net.URL;
+
+import org.eclipse.update.core.SiteContentProvider;
+
+/**
+ * Site on the File System
+ */
+public class SiteFileContentProvider extends SiteContentProvider {
+	
+	public static final String SITE_TYPE = "org.eclipse.update.core.file";	 //$NON-NLS-1$
+
+	/**
+	 * Constructor for FileSite
+	 */
+	public SiteFileContentProvider(URL url) {
+		super(url);
+	}
+}
+
+
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileFactory.java
new file mode 100644
index 0000000..24dc5ca
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileFactory.java
@@ -0,0 +1,446 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.update.core.FeatureContentProvider;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.BaseSiteFactory;
+import org.eclipse.update.core.ContentReference;
+import org.eclipse.update.core.Feature;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.JarContentReference;
+import org.eclipse.update.core.PluginEntry;
+import org.eclipse.update.core.Site;
+import org.eclipse.update.core.SiteContentProvider;
+import org.eclipse.update.core.SiteFeatureReferenceModel;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.model.ArchiveReferenceModel;
+import org.eclipse.update.core.model.InvalidSiteTypeException;
+import org.eclipse.update.core.model.SiteModel;
+import org.eclipse.update.core.model.SiteModelFactory;
+import org.eclipse.update.internal.model.BundleManifest;
+import org.eclipse.update.internal.model.DefaultPluginParser;
+import org.xml.sax.SAXException;
+
+public class SiteFileFactory extends BaseSiteFactory {
+
+	// private when parsing file system
+	private SiteFile site;
+
+	/*
+	 * @see ISiteFactory#createSite(URL,boolean)
+	 */
+	public ISite createSite(URL url) throws CoreException, InvalidSiteTypeException {
+
+		Site site = null;
+		InputStream siteStream = null;
+		SiteModelFactory factory = this;
+
+		try {
+			// if url points to a directory
+			// attempt to parse site.xml
+			String path = url.getFile();
+			File siteLocation = new File(path);
+			if (siteLocation.isDirectory()) {
+				url = siteLocation.toURL();
+				File siteXMLFile = new File(siteLocation, Site.SITE_XML);
+				if (siteXMLFile.exists()) {
+					siteStream = new FileInputStream(siteXMLFile);
+					site = (Site) factory.parseSite(siteStream);
+				} else {
+					// parse siteLocation
+					site = parseSite(siteLocation);
+				}
+			} else {
+				// we are not pointing to a directory
+				// attempt to parse the file
+				try {
+					URL resolvedURL = URLEncoder.encode(url);
+					siteStream = openStream(resolvedURL);
+					site = (Site) factory.parseSite(siteStream);
+				} catch (IOException e) {
+
+					// attempt to parse parent directory
+					File file = new File(url.getFile());
+					File parentDirectory = file.getParentFile();
+
+					// do not create directory if it doesn't exist	[18318]
+					// instead hrow error					
+					if (parentDirectory != null && !parentDirectory.exists())
+						throw Utilities.newCoreException(NLS.bind(Messages.SiteFileFactory_DirectoryDoesNotExist, (new String[] {file.getAbsolutePath()})), null);
+
+					if (parentDirectory == null || !parentDirectory.isDirectory())
+						throw Utilities.newCoreException(NLS.bind(Messages.SiteFileFactory_UnableToObtainParentDirectory, (new String[] {file.getAbsolutePath()})), null);
+
+					site = parseSite(parentDirectory);
+
+				}
+			}
+
+			SiteContentProvider contentProvider = new SiteFileContentProvider(url);
+			site.setSiteContentProvider(contentProvider);
+			contentProvider.setSite(site);
+			site.resolve(url, url);
+
+			// Do not set read only as may install in it
+			//site.markReadOnly();
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.SiteFileFactory_UnableToCreateURL, (new String[] {url == null ? "" : url.toExternalForm()})), e); //$NON-NLS-1$
+		} catch (IOException e) {
+			throw Utilities.newCoreException(Messages.SiteFileFactory_UnableToAccessSite, ISite.SITE_ACCESS_EXCEPTION, e);
+		} finally {
+			try {
+				if (siteStream != null)
+					siteStream.close();
+			} catch (IOException e) {
+			}
+		}
+		return site;
+	}
+
+	/**
+	 * Method parseSite.
+	 */
+	private Site parseSite(File directory) throws CoreException {
+
+		this.site = (SiteFile) createSiteMapModel();
+
+		if (!directory.exists())
+			throw Utilities.newCoreException(NLS.bind(Messages.SiteFileFactory_FileDoesNotExist, (new String[] {directory.getAbsolutePath()})), null);
+
+		File pluginPath = new File(directory, Site.DEFAULT_PLUGIN_PATH);
+
+		//PACKAGED
+		try {
+			parsePackagedFeature(directory); // in case it contains JAR files
+		} catch (EmptyDirectoryException ede) {
+			UpdateCore.log(ede.getStatus());
+		}
+
+		try {
+			parsePackagedPlugins(pluginPath);
+		} catch (EmptyDirectoryException ede) {
+			UpdateCore.log(ede.getStatus());
+		}
+
+		// INSTALLED
+		try {
+			parseInstalledFeature(directory);
+		} catch (EmptyDirectoryException ede) {
+			UpdateCore.log(ede.getStatus());
+		}
+
+		try {
+			parseInstalledPlugins(pluginPath);
+		} catch (EmptyDirectoryException ede) {
+			UpdateCore.log(ede.getStatus());
+		}
+
+		return site;
+
+	}
+
+	/**
+	 * Method parseFeature.
+	 * @throws CoreException
+	 */
+	private void parseInstalledFeature(File directory) throws CoreException {
+
+		File featureDir = new File(directory, Site.DEFAULT_INSTALLED_FEATURE_PATH);
+		if (featureDir.exists()) {
+			String[] dir;
+			SiteFeatureReferenceModel featureRef;
+			URL featureURL;
+			File currentFeatureDir;
+			String newFilePath = null;
+
+			try {
+				// handle the installed featuresConfigured under featuresConfigured subdirectory
+				dir = featureDir.list();
+				if (dir == null) {
+					throw new EmptyDirectoryException(new Status(IStatus.WARNING, UpdateCore.getPlugin().getBundle().getSymbolicName(), IStatus.OK, directory.getName() + File.separator + directory.getName() + "directory is empty", null)); //$NON-NLS-1$
+				}
+				for (int index = 0; index < dir.length; index++) {
+
+					// the URL must ends with '/' for the bundle to be resolved
+					newFilePath = dir[index] + (dir[index].endsWith("/") ? "/" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+					currentFeatureDir = new File(featureDir, newFilePath);
+					// check if feature.xml exists
+					File featureXMLFile = new File(currentFeatureDir, Feature.FEATURE_XML);
+					if (!featureXMLFile.exists()) {
+						UpdateCore.warn("Unable to find feature.xml in directory:" + currentFeatureDir); //$NON-NLS-1$
+					} else {
+						// PERF: remove code
+						//SiteFileFactory archiveFactory = new SiteFileFactory();
+						featureURL = currentFeatureDir.toURL();
+						featureRef = createFeatureReferenceModel();
+						featureRef.setSiteModel(site);
+						featureRef.setURLString(featureURL.toExternalForm());
+						featureRef.setType(ISite.DEFAULT_INSTALLED_FEATURE_TYPE);
+						((Site) site).addFeatureReferenceModel(featureRef);
+					}
+				}
+			} catch (MalformedURLException e) {
+				throw Utilities.newCoreException(NLS.bind(Messages.SiteFileFactory_UnableToCreateURLForFile, (new String[] {newFilePath})), e);
+			}
+		}
+	}
+
+	/**
+	* Method parseFeature.
+	* @throws CoreException
+	*/
+	private void parsePackagedFeature(File directory) throws CoreException {
+
+		// FEATURES
+		File featureDir = new File(directory, Site.DEFAULT_FEATURE_PATH);
+		if (featureDir.exists()) {
+			String[] dir;
+			SiteFeatureReferenceModel featureRef;
+			URL featureURL;
+			File currentFeatureFile;
+			String newFilePath = null;
+
+			try {
+				// only list JAR files
+				dir = featureDir.list(FeaturePackagedContentProvider.filter);
+				if (dir == null) {
+					throw new EmptyDirectoryException(new Status(IStatus.WARNING, UpdateCore.getPlugin().getBundle().getSymbolicName(), IStatus.OK, directory.getName() + File.separator + directory.getName() + "directory is empty", null)); //$NON-NLS-1$
+				}
+
+				for (int index = 0; index < dir.length; index++) {
+
+					// check if the JAR file contains a feature.xml
+					currentFeatureFile = new File(featureDir, dir[index]);
+					JarContentReference ref = new JarContentReference("", currentFeatureFile); //$NON-NLS-1$
+					ContentReference result = null;
+					try {
+						result = ref.peek(Feature.FEATURE_XML, null, null);
+					} catch (IOException e) {
+						UpdateCore.warn("Exception retrieving feature.xml in file:" + currentFeatureFile, e); //$NON-NLS-1$
+					}
+					if (result == null) {
+						UpdateCore.warn("Unable to find feature.xml in file:" + currentFeatureFile); //$NON-NLS-1$
+					} else {
+						featureURL = currentFeatureFile.toURL();
+						// PERF: remove code
+						//SiteFileFactory archiveFactory = new SiteFileFactory();
+						featureRef = createFeatureReferenceModel();
+						featureRef.setSiteModel(site);
+						featureRef.setURLString(featureURL.toExternalForm());
+						featureRef.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+						site.addFeatureReferenceModel(featureRef);
+					}
+				}
+			} catch (MalformedURLException e) {
+				throw Utilities.newCoreException(NLS.bind(Messages.SiteFileFactory_UnableToCreateURLForFile, (new String[] {newFilePath})), e);
+			}
+		}
+	}
+
+	/**
+	 * Method parsePlugins.
+	 * 
+	 * look into each plugin/fragment directory, crack the plugin.xml open (or
+	 * fragment.xml ???) get id and version, calculate URL...
+	 * 
+	 * @throws CoreException
+	 */
+	private void parseInstalledPlugins(File pluginsDir) throws CoreException {
+		if (!pluginsDir.exists() || !pluginsDir.isDirectory()) {
+			return;
+		}
+		File[] dirs = pluginsDir.listFiles(new FileFilter() {
+			public boolean accept(File f) {
+				return f.isDirectory();
+			}
+		});
+		DefaultPluginParser parser = new DefaultPluginParser();
+
+		if (dirs == null) {
+			throw new EmptyDirectoryException(new Status(IStatus.WARNING, UpdateCore.getPlugin().getBundle().getSymbolicName(), IStatus.OK, pluginsDir.getName() + File.separator + pluginsDir.getName() + "directory is empty", null)); //$NON-NLS-1$
+		}
+		for (int i = 0; i < dirs.length; i++) {
+			File pluginFile = new File(dirs[i], "META-INF/MANIFEST.MF"); //$NON-NLS-1$
+			InputStream in = null;
+			try {
+				BundleManifest bundleManifest = new BundleManifest(pluginFile);
+				if (bundleManifest.exists()) {
+					PluginEntry entry = bundleManifest.getPluginEntry();
+					addParsedPlugin(entry, dirs[i]);
+				} else {
+					if (!(pluginFile = new File(dirs[i], "plugin.xml")) //$NON-NLS-1$
+							.exists()) {
+						pluginFile = new File(dirs[i], "fragment.xml"); //$NON-NLS-1$
+					}
+					if (pluginFile != null && pluginFile.exists() && !pluginFile.isDirectory()) {
+						in = new FileInputStream(pluginFile);
+						PluginEntry entry = parser.parse(in);
+						addParsedPlugin(entry, dirs[i]);
+					}
+				}
+			} catch (IOException e) {
+				String pluginFileString = (pluginFile == null) ? null : pluginFile.getAbsolutePath();
+				UpdateCore.log(Utilities.newCoreException(NLS.bind(Messages.SiteFileFactory_ErrorAccessing, (new String[] {pluginFileString})), e));
+			} catch (SAXException e) {
+				String pluginFileString = (pluginFile == null) ? null : pluginFile.getAbsolutePath();
+				UpdateCore.log(Utilities.newCoreException(NLS.bind(Messages.SiteFileFactory_ErrorParsingFile, (new String[] {pluginFileString})), e));
+			} finally {
+				if (in != null) {
+					try {
+						in.close();
+					} catch (IOException e) {
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * transform each Plugin and Fragment into an ArchiveReferenceModel
+	 * and a PluginEntry for the Site	 
+	 */
+	// PERF: removed intermediate Plugin object
+	private void addParsedPlugin(PluginEntry entry, File file) throws CoreException {
+
+		String location = null;
+		try {
+			if (entry != null) {
+
+				// create the plugin Entry
+				((Site) site).addPluginEntry(entry);
+
+				// Create the Site mapping ArchiveRef->PluginEntry
+				// the id of the archiveRef is plugins\<pluginid>_<ver>.jar as per the specs
+				// PERF: remove code
+				//SiteFileFactory archiveFactory = new SiteFileFactory();				
+				ArchiveReferenceModel archive = createArchiveReferenceModel();
+				String id = (entry.getVersionedIdentifier().toString());
+				String pluginID = Site.DEFAULT_PLUGIN_PATH + id + FeatureContentProvider.JAR_EXTENSION;
+				archive.setPath(pluginID);
+				location = file.toURL().toExternalForm();
+				archive.setURLString(location);
+				((Site) site).addArchiveReferenceModel(archive);
+
+				// TRACE				
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) {
+					UpdateCore.debug("Added archive to site:" + pluginID + " pointing to: " + location); //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.SiteFileFactory_UnableToCreateURLForFile, (new String[] {location})), e);
+		}
+	}
+
+	/**
+	 *  
+	 */
+	private void parsePackagedPlugins(File pluginDir) throws CoreException {
+		if (!pluginDir.exists()) {
+			return;
+		}
+		String[] dir = pluginDir.list(FeaturePackagedContentProvider.filter);
+
+		if (dir == null) {
+			throw new EmptyDirectoryException(new Status(IStatus.WARNING, UpdateCore.getPlugin().getBundle().getSymbolicName(), IStatus.OK, pluginDir.getName() + File.separator + pluginDir.getName() + "directory is empty", null)); //$NON-NLS-1$
+		}
+		for (int i = 0; i < dir.length; i++) {
+			ContentReference ref = null;
+			String refString = null;
+			InputStream in = null;
+			JarContentReference jarReference = null;
+			try {
+				File file = new File(pluginDir, dir[i]);
+				jarReference = new JarContentReference(null, file);
+				ref = jarReference.peek("META-INF/MANIFEST.MF", null, null); //$NON-NLS-1$
+				if (ref != null) {
+					in = ref.getInputStream();
+					BundleManifest manifest = new BundleManifest(in);
+					if (manifest.exists()) {
+
+						addParsedPlugin(manifest.getPluginEntry(), file);
+						continue;
+					}
+				}
+				ref = jarReference.peek("plugin.xml", null, null);//$NON-NLS-1$
+				if (ref == null) {
+					ref = jarReference.peek("fragment.xml", null, null); //$NON-NLS-1$
+				}
+				if (ref != null) {
+					in = ref.getInputStream();
+					PluginEntry entry = new DefaultPluginParser().parse(in);
+					addParsedPlugin(entry, file);
+				}
+			} catch (Exception e) {
+				try {
+					refString = (ref == null) ? null : ref.asURL().toExternalForm();
+				} catch (IOException ioe) {
+				}
+
+				String message;
+
+				if (e instanceof IOException) {
+					message = NLS.bind(Messages.SiteFileFactory_ErrorAccessing, (new String[] {refString}));
+				} else if (e instanceof SAXException) {
+					message = NLS.bind(Messages.SiteFileFactory_ErrorParsingFile, (new String[] {refString}));
+				} else {
+					message = NLS.bind(Messages.SiteFileFactory_ErrorAccessing, (new String[] {refString}));
+				}// end if
+
+				// Log exception, but do not throw to caller.
+				// Continue with processing remaining plug-ins
+				UpdateCore.log(message, e);
+			} finally {
+				if (in != null) {
+					try {
+						in.close();
+					} catch (IOException ce) {
+					}
+				}
+				if (jarReference != null) {
+					try {
+						jarReference.closeArchive();
+					} catch (IOException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				}
+			}
+		}
+	}
+
+	/*
+	 * @see SiteModelFactory#createSiteMapModel()
+	 */
+	public SiteModel createSiteMapModel() {
+		return new SiteFile();
+	}
+
+	/*
+	 * @see SiteModelFactory#canParseSiteType(String)
+	 */
+	public boolean canParseSiteType(String type) {
+		return (super.canParseSiteType(type) || SiteFileContentProvider.SITE_TYPE.equalsIgnoreCase(type));
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileNonPluginContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileNonPluginContentConsumer.java
new file mode 100644
index 0000000..7dbfd58
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFileNonPluginContentConsumer.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+import java.io.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+
+/**
+ * Plugin Content Consumer on a Site
+ */
+public class SiteFileNonPluginContentConsumer extends ContentConsumer {
+
+	private String path;
+	private boolean closed = false;
+
+	/*
+	 * Constructor 
+	 */
+	public SiteFileNonPluginContentConsumer(String featurePath) {
+		this.path = featurePath;
+	}
+
+	/*
+	 * @see ISiteContentConsumer#store(ContentReference, IProgressMonitor)
+	 */
+	public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException {
+
+		if (closed) {
+			UpdateCore.warn("Attempt to store in a closed SiteFileNonPluginContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+
+		InputStream inStream = null;
+		String featurePath = path;
+		String contentKey = contentReference.getIdentifier();
+		featurePath += contentKey;
+		try {
+			inStream = contentReference.getInputStream();
+			UpdateManagerUtils.copyToLocal(inStream, featurePath, null);
+			UpdateManagerUtils.checkPermissions(contentReference, featurePath); // 20305
+		} catch (IOException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.GlobalConsumer_ErrorCreatingFile, (new String[] { featurePath })), e);
+		} finally {
+			if (inStream != null) {
+				try {
+					// close stream
+					inStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+
+	}
+
+	/*
+	 * @see ISiteContentConsumer#close()
+	 */
+	public void close() {
+		if (closed) {
+			UpdateCore.warn("Attempt to close a closed SiteFileNonPluginContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+		closed = true;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFilePackedPluginContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFilePackedPluginContentConsumer.java
new file mode 100644
index 0000000..bf65225
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFilePackedPluginContentConsumer.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+import java.io.*;
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+
+/**
+ * Plugin Content Consumer on a Site
+ * for a plugin that will run from a jar
+ */
+public class SiteFilePackedPluginContentConsumer extends ContentConsumer {
+
+	private IPluginEntry pluginEntry;
+	private ISite site;
+	private boolean closed = false;
+	private String jarPath;
+	private String tempPath;
+
+	/*
+	 * Constructor
+	 */
+	public SiteFilePackedPluginContentConsumer(IPluginEntry pluginEntry, ISite site) {
+		this.pluginEntry = pluginEntry;
+		this.site = site;
+	}
+
+	/*
+	 * @see ISiteContentConsumer#store(ContentReference, IProgressMonitor)
+	 */
+	public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException {
+		InputStream inStream = null;
+
+		if (closed) {
+			UpdateCore.warn("Attempt to store in a closed SiteFilePluginContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+
+		try {
+			URL newURL = new URL(site.getURL(), Site.DEFAULT_PLUGIN_PATH + pluginEntry.getVersionedIdentifier().toString() + ".jar"); //$NON-NLS-1$
+			inStream = contentReference.getInputStream();
+			jarPath = newURL.getFile().replace(File.separatorChar, '/');
+			File jarFile = new File(jarPath);
+			if (jarFile.exists()) {
+				throw Utilities.newCoreException(NLS.bind(Messages.UpdateManagerUtils_FileAlreadyExists, (new Object[] { jarFile })), null);
+			}
+			// error recovery
+			tempPath= ErrorRecoveryLog.getLocalRandomIdentifier(jarPath+".tmp"); //$NON-NLS-1$
+				ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.BUNDLE_JAR_ENTRY, tempPath);
+			//
+			UpdateManagerUtils.copyToLocal(inStream, tempPath, null);
+		} catch (IOException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.GlobalConsumer_ErrorCreatingFile, (new String[] { tempPath })), e);
+		} finally {
+			if (inStream != null) {
+				try {
+					// close stream
+					inStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+	}
+
+	/*
+	 * @see ISiteContentConsumer#close() 
+	 */
+	public void close() throws CoreException {
+
+		if (closed) {
+			UpdateCore.warn("Attempt to close a closed SiteFilePluginContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+
+		if (tempPath != null) {
+			// rename file 
+			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.RENAME_ENTRY, tempPath);
+			File fileToRename = new File(tempPath);
+			boolean sucess = false;
+			if (fileToRename.exists()) {
+				File renamedFile = new File(jarPath);
+				sucess = fileToRename.renameTo(renamedFile);
+			}
+			if (!sucess) {
+				String msg = NLS.bind(Messages.ContentConsumer_UnableToRename, (new String[] { tempPath, jarPath }));
+				throw Utilities.newCoreException(msg, new Exception(msg));
+			}
+		}
+
+		if (site instanceof SiteFile)
+			 ((SiteFile) site).addPluginEntry(pluginEntry);
+		closed = true;
+	}
+
+	/*
+	 * 
+	 */
+	public void abort() throws CoreException {
+
+		if (closed) {
+			UpdateCore.warn("Attempt to abort a closed SiteFilePluginContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+
+		boolean sucess = true;
+
+		// delete plugin.jar
+		if (jarPath != null) {
+			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.DELETE_ENTRY, jarPath);
+			File fileToRemove = new File(jarPath);
+
+			if (fileToRemove.exists()) {
+				sucess = fileToRemove.delete();
+			}
+		}
+
+		if (!sucess) {
+			String msg = NLS.bind(Messages.SiteFilePackedPluginContentConsumer_unableToDelete, (new String[] { jarPath })); 
+			UpdateCore.log(msg, null);
+		}
+		closed = true;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFilePluginContentConsumer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFilePluginContentConsumer.java
new file mode 100644
index 0000000..3b3d047
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteFilePluginContentConsumer.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+
+/**
+ * Plugin Content Consumer on a Site
+ */
+public class SiteFilePluginContentConsumer extends ContentConsumer {
+
+	private IPluginEntry pluginEntry;
+	private ISite site;
+	private boolean closed = false;
+
+	// recovery
+	// temporary name to original name map
+	private Map renames = new HashMap(2);
+
+	// for abort
+	private List /*of path as String */
+	installedFiles;
+
+	/*
+	 * Constructor
+	 */
+	public SiteFilePluginContentConsumer(IPluginEntry pluginEntry, ISite site) {
+		this.pluginEntry = pluginEntry;
+		this.site = site;
+		installedFiles = new ArrayList();
+	}
+
+	/*
+	 * @see ISiteContentConsumer#store(ContentReference, IProgressMonitor)
+	 */
+	public void store(ContentReference contentReference, IProgressMonitor monitor) throws CoreException {
+		InputStream inStream = null;
+		String pluginPath = null;
+
+		if (closed) {
+			UpdateCore.warn("Attempt to store in a closed SiteFilePluginContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+
+		try {
+			URL newURL = new URL(site.getURL(), Site.DEFAULT_PLUGIN_PATH + pluginEntry.getVersionedIdentifier().toString());
+			pluginPath = newURL.getFile(); 
+			String contentKey = contentReference.getIdentifier();
+			inStream = contentReference.getInputStream();
+			pluginPath += pluginPath.endsWith(File.separator) ? contentKey : File.separator + contentKey;
+
+			// error recovery
+			String logEntry=null;
+			if ("plugin.xml".equals(contentKey)) { //$NON-NLS-1$
+				logEntry=ErrorRecoveryLog.PLUGIN_ENTRY;
+			} else if ("fragment.xml".equals(contentKey)) { //$NON-NLS-1$
+				logEntry=ErrorRecoveryLog.FRAGMENT_ENTRY;
+			} else if ("META-INF/MANIFEST.MF".equals(contentKey)) { //$NON-NLS-1$
+				logEntry=ErrorRecoveryLog.BUNDLE_MANIFEST_ENTRY;
+			}
+			if (logEntry!=null) {
+				String originalName = pluginPath.replace(File.separatorChar, '/');
+				File localFile = new File(originalName);
+				if (localFile.exists()) {
+					throw Utilities.newCoreException(NLS.bind(Messages.UpdateManagerUtils_FileAlreadyExists, (new Object[] { localFile })), null);
+				}
+				pluginPath = ErrorRecoveryLog.getLocalRandomIdentifier(pluginPath);
+				renames.put(pluginPath, originalName);
+				ErrorRecoveryLog.getLog().appendPath(logEntry, pluginPath);
+			}
+			//
+			UpdateManagerUtils.copyToLocal(inStream, pluginPath, null);
+			UpdateManagerUtils.checkPermissions(contentReference, pluginPath); // 20305
+			installedFiles.add(pluginPath);
+		} catch (IOException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.GlobalConsumer_ErrorCreatingFile, (new String[] { pluginPath })), e);
+		} finally {
+			if (inStream != null) {
+				try {
+					// close stream
+					inStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+	}
+
+	/*
+	 * @see ISiteContentConsumer#close() 
+	 */
+	public void close() throws CoreException {
+
+		if (closed) {
+			UpdateCore.warn("Attempt to close a closed SiteFilePluginContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+
+		for(Iterator it = renames.entrySet().iterator(); it.hasNext();){
+			// rename file 
+			Map.Entry entry = (Map.Entry)it.next();
+			String temporary = (String) entry.getKey();
+			String original = (String) entry.getValue();
+			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.RENAME_ENTRY, temporary);
+			File fileToRename = new File(temporary);
+			boolean sucess = false;
+			if (fileToRename.exists()) {
+				File renamedFile = new File(original);
+				sucess = fileToRename.renameTo(renamedFile);
+			}
+			if (!sucess) {
+				String msg = NLS.bind(Messages.ContentConsumer_UnableToRename, (new String[] { temporary, original }));
+				throw Utilities.newCoreException(msg, new Exception(msg));
+			}
+		}
+
+		if (site instanceof SiteFile)
+			 ((SiteFile) site).addPluginEntry(pluginEntry);
+		closed = true;
+	}
+
+	/*
+	 * 
+	 */
+	public void abort() throws CoreException {
+
+		if (closed) {
+			UpdateCore.warn("Attempt to abort a closed SiteFilePluginContentConsumer", new Exception()); //$NON-NLS-1$
+			return;
+		}
+
+		boolean success = true;
+		InstallRegistry.unregisterPlugin(pluginEntry);
+
+		// delete plugin manifests first
+		for(Iterator it = renames.values().iterator(); it.hasNext();){
+			String originalName = (String) it.next();
+
+			ErrorRecoveryLog.getLog().appendPath(ErrorRecoveryLog.DELETE_ENTRY, originalName);
+			File fileToRemove = new File(originalName);
+			if (fileToRemove.exists()) {
+				if(!fileToRemove.delete()){
+					String msg = NLS.bind(Messages.SiteFilePluginContentConsumer_unableToDelete, (new String[] { originalName })); 
+					UpdateCore.log(msg, null);	
+					success = false;
+				}
+			}
+		}
+
+		if (success) {
+			// remove the plugin files;
+			Iterator iter = installedFiles.iterator();
+			File featureFile = null;
+			while (iter.hasNext()) {
+				String path = (String) iter.next();
+				featureFile = new File(path);
+				UpdateManagerUtils.removeFromFileSystem(featureFile);
+			}
+
+			// remove the plugin directory if empty
+			try {
+				URL newURL = new URL(site.getURL(), Site.DEFAULT_PLUGIN_PATH + pluginEntry.getVersionedIdentifier().toString());
+				String pluginPath = newURL.getFile();
+				UpdateManagerUtils.removeEmptyDirectoriesFromFileSystem(new File(pluginPath));
+			} catch (MalformedURLException e) {
+				throw Utilities.newCoreException(e.getMessage(), e);
+			}
+		}
+		closed = true;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteReconciler.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteReconciler.java
new file mode 100644
index 0000000..7fdb7ff
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteReconciler.java
@@ -0,0 +1,347 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.util.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.ModelObject;
+
+/**
+ * This class manages the reconciliation.
+ */
+
+public class SiteReconciler extends ModelObject {
+
+	private SiteReconciler(LocalSite siteLocal) {
+		//never instantiated
+	}
+
+	/**
+	 * Validate the list of configured features eliminating extra
+	 * entries (if possible). Make sure we do not leave configured
+	 * nested features with "holes" (ie. unconfigured children)
+	 */
+	public static void checkConfiguredFeatures(IConfiguredSite configuredSite) {
+
+		// Note: if we hit errors in the various computation
+		// methods and throw a CoreException, we will not catch it
+		// in this method. Consequently we will not attempt to
+		// unconfigure any "extra" features because we would 
+		// likely get it wrong. The platform will run with extra features
+		// configured. The runtime will eliminate extra plugins based
+		// on runtime binding rules.
+
+		// determine "proposed" list of configured features
+		ConfiguredSite cSite = (ConfiguredSite) configuredSite;
+		// debug
+		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) {
+			UpdateCore.debug("Validate configuration of site " + cSite.getSite().getURL()); //$NON-NLS-1$
+		}
+		IFeatureReference[] configuredRefs = cSite.getConfiguredFeatures();
+		ArrayList allPossibleConfiguredFeatures = new ArrayList();
+		for (int i = 0; i < configuredRefs.length; i++) {
+			try {
+				IFeature feature = configuredRefs[i].getFeature(null);
+				allPossibleConfiguredFeatures.add(feature);
+				// debug
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) {
+					UpdateCore.debug("   configured feature " + feature.getVersionedIdentifier().toString()); //$NON-NLS-1$
+				}
+			} catch (CoreException e) {
+				UpdateCore.warn("", e); //$NON-NLS-1$
+			}
+		}
+
+		// find top level features
+		ArrayList topFeatures = computeTopFeatures(allPossibleConfiguredFeatures);
+
+		// find non efix top level features
+		ArrayList topNonEfixFeatures = getNonEfixFeatures(topFeatures);
+
+		// expand non efix top level features (compute full nesting structures).
+		ArrayList configuredFeatures = expandFeatures(topNonEfixFeatures, configuredSite);
+
+		// retrieve efixes that patch enable feature
+		// they must be kept enabled
+		if (topFeatures.size() != topNonEfixFeatures.size()) {
+			Map patches = getPatchesAsFeature(allPossibleConfiguredFeatures);
+			if (!patches.isEmpty()) {
+				// calculate efixes to enable
+				List efixesToEnable = getPatchesToEnable(patches, configuredFeatures);
+				// add efies to keep enable
+				//add them to the enable list
+				for (Iterator iter = efixesToEnable.iterator(); iter.hasNext();) {
+					IFeature element = (IFeature) iter.next();
+					ArrayList expandedEfix = new ArrayList();
+					expandEfixFeature(element, expandedEfix, configuredSite);
+					configuredFeatures.addAll(expandedEfix);
+				}
+			}
+		}
+
+		// compute extra features
+		ArrayList extras = diff(allPossibleConfiguredFeatures, configuredFeatures);
+
+		// unconfigure extra features
+		ConfigurationPolicy cPolicy = cSite.getConfigurationPolicy();
+		for (int i = 0; i < extras.size(); i++) {
+			IFeature feature = (IFeature) extras.get(i);
+			IFeatureReference ref = cSite.getSite().getFeatureReference(feature);
+			try {
+				cPolicy.unconfigure(ref, true, false);
+				// debug
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) {
+					UpdateCore.debug("Unconfiguring \"extra\" feature " + feature.getVersionedIdentifier().toString()); //$NON-NLS-1$
+				}
+			} catch (CoreException e) {
+				UpdateCore.warn("", e); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/*
+	 *  
+	 */
+	private static ArrayList computeTopFeatures(ArrayList features) {
+		/* map of Feature by VersionedIdentifier */
+		Map topFeatures = new HashMap(features.size());
+		// start with the features passed in
+		for (Iterator it = features.iterator(); it.hasNext();) {
+			IFeature f = ((IFeature) it.next());
+			topFeatures.put(f.getVersionedIdentifier(), f);
+		}
+		// remove all features that nest in some other feature
+		for (Iterator it = features.iterator(); it.hasNext();) {
+			try {
+				IIncludedFeatureReference[] children = ((IFeature) it.next()).getIncludedFeatureReferences();
+				for (int j = 0; j < children.length; j++) {
+					try {
+						topFeatures.remove(children[j].getVersionedIdentifier());
+					} catch (CoreException e1) {
+						if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_WARNINGS)
+							UpdateCore.warn("", e1); //$NON-NLS-1$
+					}
+				}
+			} catch (CoreException e) {
+				UpdateCore.warn("", e); //$NON-NLS-1$
+			}
+		}
+		ArrayList list = new ArrayList();
+		list.addAll(topFeatures.values());
+		// debug
+		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) {
+			UpdateCore.debug("Computed top-level features"); //$NON-NLS-1$
+			for (int i = 0; i < topFeatures.size(); i++) {
+				UpdateCore.debug("   " + ((IFeature) list.get(i)).getVersionedIdentifier().toString()); //$NON-NLS-1$
+			}
+		}
+		return list;
+	}
+
+	/*
+	 * 
+	 */
+	private static ArrayList expandFeatures(ArrayList features, IConfiguredSite configuredSite) {
+		ArrayList result = new ArrayList();
+
+		// expand all top level features
+		for (int i = 0; i < features.size(); i++) {
+			expandFeature((IFeature) features.get(i), result, configuredSite);
+		}
+
+		return result;
+	}
+
+	/*
+	 * 
+	 */
+	private static void expandFeature(IFeature feature, ArrayList features, IConfiguredSite configuredSite) {
+
+		// add feature
+		if (!features.contains(feature)) {
+			features.add(feature);
+			// debug
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) {
+				UpdateCore.debug("Retaining configured feature " + feature.getVersionedIdentifier().toString()); //$NON-NLS-1$
+			}
+		}
+
+		// add nested children to the list
+		IIncludedFeatureReference[] children = null;
+		try {
+			children = feature.getIncludedFeatureReferences();
+		} catch (CoreException e) {
+			UpdateCore.warn("", e); //$NON-NLS-1$
+			return;
+		}
+
+		for (int j = 0; j < children.length; j++) {
+			IFeature child = null;
+			try {
+				child = children[j].getFeature(null);
+			} catch (CoreException e) {
+				if (!UpdateManagerUtils.isOptional(children[j]))
+					UpdateCore.warn("", e); //$NON-NLS-1$
+				// 25202 do not return right now, the peer children may be ok
+			}
+			if (child != null)
+				expandFeature(child, features, configuredSite);
+		}
+	}
+
+	/*
+	 * 
+	 */
+	private static ArrayList diff(ArrayList left, ArrayList right) {
+		ArrayList result = new ArrayList();
+
+		// determine difference (left "minus" right)
+		for (int i = 0; i < left.size(); i++) {
+			IFeature feature = (IFeature) left.get(i);
+			if (!right.contains(feature))
+				result.add(feature);
+		}
+		return result;
+	}
+
+	/*
+	 * get the list of enabled patches
+	 */
+	private static Map getPatchesAsFeature(ArrayList allConfiguredFeatures) {
+		// get all efixes and the associated patched features
+		Map patches = new HashMap();
+		if (allConfiguredFeatures != null) {
+			Iterator iter = allConfiguredFeatures.iterator();
+			while (iter.hasNext()) {
+				List patchedFeaturesID = new ArrayList();
+				IFeature element = (IFeature) iter.next();
+				// add the patched feature identifiers
+				for (int i = 0; i < element.getImports().length; i++) {
+					if (element.getImports()[i].isPatch()) {
+						VersionedIdentifier id = element.getImports()[i].getVersionedIdentifier();
+						if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER)
+							UpdateCore.debug("Found patch " + element + " for feature identifier " + id); //$NON-NLS-1$ //$NON-NLS-2$
+						patchedFeaturesID.add(id);
+					}
+				}
+
+				if (!patchedFeaturesID.isEmpty()) {
+					patches.put(element, patchedFeaturesID);
+				}
+			}
+		}
+
+		return patches;
+	}
+
+	/*
+	 * retruns the list of pathes-feature who patch enabled features
+	 */
+	private static List getPatchesToEnable(Map efixes, ArrayList configuredFeatures) {
+
+		ArrayList enabledVersionedIdentifier = new ArrayList();
+		Iterator iter = configuredFeatures.iterator();
+		while (iter.hasNext()) {
+			IFeature element = (IFeature) iter.next();
+			enabledVersionedIdentifier.add(element.getVersionedIdentifier());
+		}
+
+		// loop through the patches
+		List result = new ArrayList();
+		iter = efixes.keySet().iterator();
+		while (iter.hasNext()) {
+			boolean toEnable = false;
+			IFeature efixFeature = (IFeature) iter.next();
+			List patchedFeatures = (List) efixes.get(efixFeature);
+			// loop through the 'patched features identifier' the for this patch
+			// see if it the patch patches at least one enable feature
+			Iterator patchedFeaturesIter = patchedFeatures.iterator();
+			while (patchedFeaturesIter.hasNext() && !toEnable) {
+				VersionedIdentifier patchedFeatureID = (VersionedIdentifier) patchedFeaturesIter.next();
+				if (enabledVersionedIdentifier.contains(patchedFeatureID)) {
+					toEnable = true;
+				}
+			}
+
+			if (!toEnable) {
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER)
+					UpdateCore.debug("The Patch " + efixFeature + " does not patch any enabled features: it will be disabled"); //$NON-NLS-1$ //$NON-NLS-2$
+			} else {
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER)
+					UpdateCore.debug("The patch " + efixFeature + " will be enabled."); //$NON-NLS-1$ //$NON-NLS-2$
+				result.add(efixFeature);
+			}
+		}
+		return result;
+	}
+
+	/*
+	 * returns the feature that are not patches
+	 */
+	private static ArrayList getNonEfixFeatures(ArrayList topFeatures) {
+		Map efixFeatures = getPatchesAsFeature(topFeatures);
+		Set keySet = efixFeatures.keySet();
+		if (keySet == null || keySet.isEmpty())
+			return topFeatures;
+
+		Iterator iter = topFeatures.iterator();
+		ArrayList result = new ArrayList();
+		while (iter.hasNext()) {
+			IFeature element = (IFeature) iter.next();
+			if (!keySet.contains(element)) {
+				result.add(element);
+			}
+		}
+		return result;
+	}
+
+	/*
+	 * only enable non-efix children recursively
+	 */
+	private static void expandEfixFeature(IFeature feature, ArrayList features, IConfiguredSite configuredSite) {
+
+		// add feature
+		if (!features.contains(feature)) {
+			features.add(feature);
+			// debug
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) {
+				UpdateCore.debug("Retaining configured feature " + feature.getVersionedIdentifier().toString()); //$NON-NLS-1$
+			}
+		}
+
+		// add nested children to the list
+		IIncludedFeatureReference[] children = null;
+		try {
+			children = feature.getIncludedFeatureReferences();
+		} catch (CoreException e) {
+			UpdateCore.warn("", e); //$NON-NLS-1$
+			return;
+		}
+
+		for (int j = 0; j < children.length; j++) {
+			IFeature child = null;
+			try {
+				child = children[j].getFeature(null);
+			} catch (CoreException e) {
+				if (!children[j].isOptional())
+					UpdateCore.warn("", e); //$NON-NLS-1$
+				// 25202 do not return right now, the peer children may be ok
+			}
+			if (child != null) {
+				if (!UpdateCore.isPatch(child))
+					expandEfixFeature(child, features, configuredSite);
+			}
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteStatusAnalyzer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteStatusAnalyzer.java
new file mode 100644
index 0000000..fcdbb1d
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteStatusAnalyzer.java
@@ -0,0 +1,463 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IImport;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * This class manages the configurations.
+ */
+
+public class SiteStatusAnalyzer {
+
+	private static final String SOURCE_BUNDLES_PATH = "org.eclipse.equinox.source/source.info"; //$NON-NLS-1$
+	private static final String ID = "org.eclipse.update.core"; //$NON-NLS-1$
+	private static List allConfiguredFeatures; /*VersionedIdentifier */
+	private LocalSite siteLocal;
+
+	// A list of versionedIdentifiers for source bundles; initialized on demand.
+	private List sourceBundles = null;
+
+	/**
+	 * 
+	 */
+	public SiteStatusAnalyzer(LocalSite siteLocal) {
+		this.siteLocal = siteLocal;
+	}
+
+	/*
+	 *  check if the Plugins of the feature are on the plugin path
+	 *  If all the plugins are on the plugin path, and the version match and there is no other version -> HAPPY
+	 *  If all the plugins are on the plugin path, and the version match and there is other version -> AMBIGUOUS
+	 *  If some of the plugins are on the plugin path, but not all -> UNHAPPY
+	 * 	Check on all ConfiguredSites
+	 */
+	private IStatus getStatus(IFeature feature) {
+
+		// validate site
+		ISite featureSite = feature.getSite();
+		if (featureSite == null) {
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION)
+				UpdateCore.debug("Cannot determine status of feature:" + feature.getLabel() + ". Site is NULL."); //$NON-NLS-1$ //$NON-NLS-2$
+			String msg = NLS.bind(Messages.SiteLocal_UnableToDetermineFeatureStatusSiteNull, (new Object[] {feature.getURL()}));
+			return createStatus(IStatus.ERROR, IFeature.STATUS_AMBIGUOUS, msg, null);
+		}
+
+		// validate configured site		
+		ConfiguredSite cSite = (ConfiguredSite) featureSite.getCurrentConfiguredSite();
+		if (cSite == null) {
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION)
+				UpdateCore.warn("Cannot determine status of feature: " + feature.getLabel() + ". Configured Site is NULL."); //$NON-NLS-1$ //$NON-NLS-2$
+			String msg = NLS.bind(Messages.SiteLocal_UnableToDetermineFeatureStatusConfiguredSiteNull, (new Object[] {feature.getURL()}));
+			return createStatus(IStatus.ERROR, IFeature.STATUS_AMBIGUOUS, msg, null);
+		}
+
+		// check if disable, if so return
+		IFeatureReference ref = cSite.getSite().getFeatureReference(feature);
+		if (ref != null) {
+			if (!cSite.getConfigurationPolicy().isConfigured(ref))
+				return createStatus(IStatus.OK, IFeature.STATUS_DISABLED, "", null); //$NON-NLS-1$
+		} else {
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION)
+				UpdateCore.warn("Unable to find reference for feature " + feature + " in site " + cSite.getSite().getURL()); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		// check if broken
+		IStatus status = cSite.getBrokenStatus(feature);
+		if (status.getSeverity() != IStatus.OK) {
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION)
+				UpdateCore.debug("Feature broken:" + feature.getLabel() + ".Site:" + cSite.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+			return status;
+		}
+
+		// check ambiguous against registry [17015]
+		IPluginEntry[] featuresEntries = feature.getPluginEntries();
+		return status(feature, featuresEntries);
+	}
+
+	/*
+	 *  check if the Plugins of the feature are on the plugin path
+	 *  If all the plugins are on the plugin path, and the version match and there is no other version -> HAPPY
+	 *  If all the plugins are on the plugin path, and the version match and there is other version -> AMBIGUOUS
+	 *  If some of the plugins are on the plugin path, but not all -> UNHAPPY
+	 * 	Check on all ConfiguredSites
+	 */
+	public IStatus getFeatureStatus(IFeature feature) throws CoreException {
+
+		IFeature childFeature = null;
+		IStatus childStatus;
+
+		IFeatureReference[] children = feature.getIncludedFeatureReferences();
+
+		// consider disable
+		// check the current feature
+		String msg = Messages.SiteLocal_FeatureDisable;
+		int code = IFeature.STATUS_DISABLED;
+		IStatus featureStatus = getStatus(feature);
+		MultiStatus multiTemp = new MultiStatus(featureStatus.getPlugin(), code, msg, null);
+		if (featureStatus.getSeverity() == IStatus.ERROR) {
+			if (featureStatus.isMultiStatus()) {
+				multiTemp.addAll(featureStatus);
+			} else {
+				multiTemp.add(featureStatus);
+			}
+		}
+		// preserve the worse code through the method (self assesment + children assessment)
+		if (featureStatus.getCode() > code)
+			code = featureStatus.getCode();
+
+		// do not check children if feature is disable
+		if (!(code == IFeature.STATUS_DISABLED)) {
+			for (int i = 0; i < children.length; i++) {
+				if (!UpdateManagerUtils.isOptional(children[i])) {
+					try {
+						childFeature = children[i].getFeature(null);
+					} catch (CoreException e) {
+						childFeature = null;
+						if (!UpdateManagerUtils.isOptional(children[i]))
+							UpdateCore.warn("Error retrieving feature:" + children[i]); //$NON-NLS-1$
+					}
+
+					if (childFeature == null) {
+						UpdateCore.warn("getFeatureStatus: Feature is null for:" + children[i]); //$NON-NLS-1$
+						// Unable to find children feature, broken
+						Object featureAsPrintableObject = children[i].getURL();
+						featureAsPrintableObject = children[i].getVersionedIdentifier();
+						String msg1 = NLS.bind(Messages.SiteLocal_NestedFeatureUnavailable, (new Object[] {featureAsPrintableObject}));
+						multiTemp.add(createStatus(IStatus.ERROR, IFeature.STATUS_UNHAPPY, msg1, null));
+						if (IFeature.STATUS_UNHAPPY > code)
+							code = IFeature.STATUS_UNHAPPY;
+					} else {
+						childStatus = getFeatureStatus(childFeature);
+						// do not add the status, add the children status as getFeatureStatus
+						// returns a multiStatus 
+						if (childStatus.getCode() == IFeature.STATUS_DISABLED) {
+							VersionedIdentifier versionID = childFeature.getVersionedIdentifier();
+							String featureVer = (versionID == null) ? "" : versionID.getVersion().toString(); //$NON-NLS-1$
+							String msg1 = NLS.bind(Messages.SiteLocal_NestedFeatureDisable, (new String[] {childFeature.getLabel(), featureVer}));
+							multiTemp.add(createStatus(IStatus.ERROR, childStatus.getCode(), msg1, null));
+							if (IFeature.STATUS_UNHAPPY > code)
+								code = IFeature.STATUS_UNHAPPY;
+						}
+						if (childStatus.getSeverity() != IStatus.OK) {
+							VersionedIdentifier versionID = childFeature.getVersionedIdentifier();
+							String featureVer = (versionID == null) ? "" : versionID.getVersion().toString(); //$NON-NLS-1$
+							String msg1 = NLS.bind(Messages.SiteLocal_NestedFeatureUnHappy, (new String[] {childFeature.getLabel(), featureVer}));
+							multiTemp.add(createStatus(IStatus.ERROR, childStatus.getCode(), msg1, null));
+							if (childStatus.getCode() > code)
+								code = childStatus.getCode();
+						}
+					}
+				}
+			}
+		}
+
+		// set message
+		switch (code) {
+			case IFeature.STATUS_HAPPY :
+				msg = Messages.SiteLocal_FeatureHappy;
+				break;
+			case IFeature.STATUS_UNHAPPY :
+				msg = Messages.SiteLocal_FeatureUnHappy;
+				break;
+			case IFeature.STATUS_AMBIGUOUS :
+				msg = Messages.SiteLocal_FeatureAmbiguous;
+				break;
+			case IFeature.STATUS_DISABLED :
+				msg = Messages.SiteLocal_FeatureDisable;
+				break;
+			default :
+				msg = Messages.SiteLocal_FeatureStatusUnknown;
+				break;
+		}
+		MultiStatus multi = new MultiStatus(featureStatus.getPlugin(), code, msg, null);
+		multi.addAll(multiTemp);
+		return multi;
+	}
+
+	/*
+	 * compute the status based on getStatus() rules 
+	 */
+	private IStatus status(IFeature pluginsOriginatorFeature, IPluginEntry[] featurePlugins) {
+		VersionedIdentifier featurePluginID;
+
+		String happyMSG = Messages.SiteLocal_FeatureHappy;
+		String ambiguousMSG = Messages.SiteLocal_FeatureAmbiguous;
+		IStatus featureStatus = createStatus(IStatus.OK, IFeature.STATUS_HAPPY, "", null); //$NON-NLS-1$
+		MultiStatus multi = new MultiStatus(featureStatus.getPlugin(), IFeature.STATUS_AMBIGUOUS, ambiguousMSG, null);
+		PackageAdmin pkgAdmin = UpdateCore.getPlugin().getPackageAdmin();
+
+		// is Ambigous if we find a plugin from the feature
+		// with a different version and not the one we are looking
+		for (int i = 0; i < featurePlugins.length; i++) {
+			MultiStatus tempmulti = new MultiStatus(featureStatus.getPlugin(), IFeature.STATUS_AMBIGUOUS, ambiguousMSG, null);
+			featurePluginID = featurePlugins[i].getVersionedIdentifier();
+			boolean found = false;
+
+			String singleVersionRange = '[' + featurePluginID.getVersion().toString() + ',' + featurePluginID.getVersion().toString() + ']';
+			Bundle[] bundles = pkgAdmin.getBundles(featurePluginID.getIdentifier(), singleVersionRange);
+			if (bundles != null && bundles.length == 1) {
+				found = true;
+				continue;
+			}
+
+			// Check if there is another feature with this plugin (but different version)
+			// log it
+			bundles = pkgAdmin.getBundles(featurePluginID.getIdentifier(), null);
+			for (int j = 0; bundles != null && j < bundles.length && !found; j++) {
+				String bundleVersion = (String) bundles[j].getHeaders().get(Constants.BUNDLE_VERSION);
+				IFeature feature = getFeatureForId(new VersionedIdentifier(bundles[j].getSymbolicName(), bundleVersion));
+				if ((feature != null) && (!isFeaturePatchOfThisFeature(pluginsOriginatorFeature, feature))) {
+					String msg = null;
+					String label = feature.getLabel();
+					String featureVersion = feature.getVersionedIdentifier().getVersion().toString();
+					Object[] values = new Object[] {bundles[j].getSymbolicName(), featurePluginID.getVersion(), bundleVersion, label, featureVersion};
+					msg = NLS.bind(Messages.SiteLocal_TwoVersionSamePlugin2, values);
+					UpdateCore.warn("Found another version of the same plugin on the path:" + bundles[j].getSymbolicName() + " " + bundleVersion); //$NON-NLS-1$ //$NON-NLS-2$
+					tempmulti.add(createStatus(IStatus.ERROR, IFeature.STATUS_AMBIGUOUS, msg, null));
+				} else {
+					found = true;
+				}
+
+			}
+
+			// check whether the plugin is a source bundle
+			// that has not been configured into the runtime
+			if (!found) {
+				loadSourceBundlesList();
+				for (Iterator iter = sourceBundles.iterator(); iter.hasNext();) {
+					VersionedIdentifier nextId = (VersionedIdentifier) iter.next();
+					if (featurePluginID.equals(nextId)) {
+						found = true;
+						break;
+					}
+				}
+			}
+
+			// if we haven't found the exact plugin, add the children
+			// of tempMulti (i,e the other we found) 
+			// if we have no children, we have a problem as a required plugin is not there at all
+			if (!found) {
+				if (tempmulti.getChildren().length > 0) {
+					multi.addAll(tempmulti);
+				} else {
+					if (multi.getCode() != IFeature.STATUS_UNHAPPY) {
+						String unhappyMSG = Messages.SiteLocal_FeatureUnHappy;
+						MultiStatus newMulti = new MultiStatus(featureStatus.getPlugin(), IFeature.STATUS_UNHAPPY, unhappyMSG, null);
+						newMulti.addAll(multi);
+						multi = newMulti;
+					}
+					String msg = NLS.bind(Messages.SiteLocal_NoPluginVersion, (new String[] {featurePluginID.getIdentifier()}));
+					multi.add(createStatus(IStatus.ERROR, IFeature.STATUS_UNHAPPY, msg, null));
+				}
+			}
+		}
+
+		if (!multi.isOK())
+			return multi;
+
+		// we return happy as we consider the isBroken verification has been done
+		return createStatus(IStatus.OK, IFeature.STATUS_HAPPY, happyMSG, null);
+	}
+
+	public static File toFile(URL url) {
+		try {
+			if (!"file".equalsIgnoreCase(url.getProtocol())) //$NON-NLS-1$
+				return null;
+			//assume all illegal characters have been properly encoded, so use URI class to unencode
+			return new File(new URI(url.toExternalForm()));
+		} catch (Exception e) {
+			//URL contains unencoded characters
+			return new File(url.getFile());
+		}
+	}
+
+	/**
+	 * 	Get the contents of the source bundles text file.
+	 */
+	private void loadSourceBundlesList() {
+		if (sourceBundles != null)
+			return;
+
+		sourceBundles = new ArrayList(32);
+		IPlatformConfiguration config = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		URL configLocation = config.getConfigurationLocation();
+		if (configLocation == null)
+			return;
+		// Drop off /org.eclipse.update/platform.xml
+		File configDir = toFile(configLocation);
+		configDir = configDir.getParentFile();
+		if (configDir == null)
+			return;
+		configDir = configDir.getParentFile();
+		if (configDir == null)
+			return;
+		File sourceBundlesFile = new File(configDir, SOURCE_BUNDLES_PATH);
+
+		try {
+			BufferedReader reader = new BufferedReader(new FileReader(sourceBundlesFile));
+			String line;
+			try {
+				while ((line = reader.readLine()) != null) {
+					if (line.startsWith("#"))
+						continue;
+					line = line.trim();// symbolicName,version,other ignored stuff
+					if (line.length() == 0)
+						continue;
+
+					StringTokenizer tok = new StringTokenizer(line, ",", true);
+					String symbolicName = tok.nextToken();
+					if (symbolicName.equals(","))
+						continue;
+					else
+						tok.nextToken(); // ,
+
+					String version = tok.nextToken();
+					if (version.equals(","))
+						continue;
+					else
+						tok.nextToken(); // ,
+
+					VersionedIdentifier sourceId = new VersionedIdentifier(symbolicName, version);
+					sourceBundles.add(sourceId);
+				}
+			} finally {
+				try {
+					reader.close();
+				} catch (IOException ex) {
+					// ignore
+				}
+			}
+		} catch (MalformedURLException e) {
+			UpdateCore.log(new Status(IStatus.ERROR, ID, "Error occurred while reading source bundle list.", e)); //$NON-NLS-1$
+		} catch (IOException e) {
+			UpdateCore.log(new Status(IStatus.ERROR, ID, "Error occurred while reading source bundle list.", e)); //$NON-NLS-1$
+		}
+	}
+
+	private boolean isFeaturePatchOfThisFeature(IFeature pluginsOriginatorFeature, IFeature feature) {
+
+		if (!feature.isPatch())
+			return false;
+
+		IImport[] featureImports = feature.getImports();
+
+		if (featureImports == null) {
+			return false;
+		}
+
+		for (int i = 0; i < featureImports.length; i++) {
+			if (featureImports[i].isPatch() && featureImports[i].getVersionedIdentifier().equals(pluginsOriginatorFeature.getVersionedIdentifier())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * creates a Status
+	 */
+	private IStatus createStatus(int statusSeverity, int statusCode, String msg, Exception e) {
+		String id = UpdateCore.getPlugin().getBundle().getSymbolicName();
+
+		StringBuffer completeString = new StringBuffer(""); //$NON-NLS-1$
+		if (msg != null)
+			completeString.append(msg);
+		if (e != null) {
+			completeString.append("\r\n["); //$NON-NLS-1$
+			completeString.append(e.toString());
+			completeString.append("]\r\n"); //$NON-NLS-1$
+		}
+		return new Status(statusSeverity, id, statusCode, completeString.toString(), e);
+	}
+
+	/*
+	 * returns all the configured fetaures
+	 */
+	private IFeature[] getAllConfiguredFeatures() {
+		if (allConfiguredFeatures == null) {
+
+			allConfiguredFeatures = new ArrayList();
+			IConfiguredSite[] allConfiguredSites = siteLocal.getCurrentConfiguration().getConfiguredSites();
+
+			for (int i = 0; i < allConfiguredSites.length; i++) {
+				IFeatureReference[] refs = allConfiguredSites[i].getConfiguredFeatures();
+				IFeature feature = null;
+				for (int j = 0; j < refs.length; j++) {
+					feature = null;
+					try {
+						feature = refs[j].getFeature(null);
+					} catch (CoreException e) {
+					}
+					if (feature != null) {
+						allConfiguredFeatures.add(feature);
+					}
+				}
+			}
+		}
+
+		IFeature[] features = new IFeature[allConfiguredFeatures.size()];
+		if (allConfiguredFeatures.size() > 0) {
+			allConfiguredFeatures.toArray(features);
+		}
+		return features;
+	}
+
+	/*
+	 * returns the Feature that declares this versionedIdentifier or null if none found
+	 */
+	private IFeature getFeatureForId(VersionedIdentifier id) {
+
+		if (id == null)
+			return null;
+
+		IFeature[] allFeatures = getAllConfiguredFeatures();
+		IFeature currentFeature = null;
+		IPluginEntry[] allPlugins = null;
+		IPluginEntry currentPlugin = null;
+		for (int i = 0; i < allFeatures.length; i++) {
+			currentFeature = allFeatures[i];
+			allPlugins = currentFeature.getPluginEntries();
+			for (int j = 0; j < allPlugins.length; j++) {
+				currentPlugin = allPlugins[j];
+				if (id.equals(currentPlugin.getVersionedIdentifier()))
+					return currentFeature;
+			}
+		}
+		return null;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteTypeFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteTypeFactory.java
new file mode 100644
index 0000000..5526f76
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteTypeFactory.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+
+/**
+ * 
+ */
+public final class SiteTypeFactory {
+	
+
+	/**
+	 * extension point ID
+	 */
+	public static final String SIMPLE_EXTENSION_ID = "siteTypes";	 //$NON-NLS-1$
+	
+
+	private static SiteTypeFactory inst;
+	
+	private Map factories;
+
+	/**
+	 * hide ctr 
+	 */
+	private SiteTypeFactory() {
+	}
+
+	public static SiteTypeFactory getInstance() {
+		if (inst == null)
+			inst = new SiteTypeFactory();
+		return inst;
+	}
+
+
+	/**
+	 * return the factory for the type
+	 */
+	public ISiteFactory getFactory(String type) throws CoreException {
+			//
+			Object instance = getFactories().get(type);
+			if (instance==null) {
+				instance = createFactoryFor(type);
+				getFactories().put(type,instance);
+			}
+			return (ISiteFactory) instance;
+	}
+
+	/**
+	 * 
+	 */
+	private ISiteFactory createFactoryFor(String type) throws CoreException {
+		ISiteFactory result = null;
+		
+		String pluginID = UpdateCore.getPlugin().getBundle().getSymbolicName();
+		IExtensionRegistry registry = Platform.getExtensionRegistry();
+		IConfigurationElement[] elements = registry.getConfigurationElementsFor(pluginID,SIMPLE_EXTENSION_ID,type);
+		if (elements==null || elements.length==0){
+			throw Utilities.newCoreException(NLS.bind(Messages.SiteTypeFactory_UnableToFindSiteFactory, (new String[] { type })),null);
+		} else {
+			IConfigurationElement element = elements[0];
+			result = (ISiteFactory)element.createExecutableExtension("class"); //$NON-NLS-1$
+		}
+		return result;
+	}
+
+	/**
+	 * Gets the actories.
+	 * @return Returns a Map
+	 */
+	private Map getFactories() {
+		if (factories==null) factories = new HashMap();
+			return factories;
+	}
+
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteURLContentProvider.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteURLContentProvider.java
new file mode 100644
index 0000000..a6070c9
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteURLContentProvider.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.net.URL;
+
+import org.eclipse.update.core.SiteContentProvider;
+
+/**
+ * 
+ */
+public class SiteURLContentProvider extends SiteContentProvider {
+	
+	public static final String SITE_TYPE = "org.eclipse.update.core.http"; //$NON-NLS-1$
+
+	/**
+	 * Constructor for HTTPSite
+	 */
+	public SiteURLContentProvider(URL url) {
+		super(url);
+	}
+}
+
+
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteURLFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteURLFactory.java
new file mode 100644
index 0000000..0540a85
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/SiteURLFactory.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Date;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.BaseSiteFactory;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFactoryExtension;
+import org.eclipse.update.core.Site;
+import org.eclipse.update.core.SiteFeatureReferenceModel;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.model.InvalidSiteTypeException;
+import org.eclipse.update.core.model.SiteModelFactory;
+import org.eclipse.update.internal.core.connection.ConnectionFactory;
+import org.eclipse.update.internal.core.connection.IResponse;
+import org.eclipse.update.internal.model.SiteWithTimestamp;
+
+/**
+ * An update site factory.
+ *
+ */
+public class SiteURLFactory extends BaseSiteFactory implements ISiteFactoryExtension {
+	
+	/*
+	 * For backward compatibility.
+	 */
+	public ISite createSite(URL url) throws CoreException, InvalidSiteTypeException {
+		return createSite(url, null);
+	}
+	/*
+	 * @see ISiteFactory#createSite(URL, boolean)
+	 * 
+	 * the URL can be of the following form
+	 * 1 protocol://...../
+	 * 2 protocol://.....
+	 * 3 protocol://..../site.xml
+	 * 
+	 * 1 If the file of the file of teh url ends with '/', attempt to open the stream.
+	 * if it fails, add site.xml and attempt to open the stream
+	 * 
+	 * 2 attempt to open the stream
+	 * 	fail
+	 * 		add '/site.xml' and attempt to open the stream
+	 * 	sucess
+	 * 		attempt to parse, if it fails, add '/site.xml' and attempt to open teh stream
+	 * 
+	 * 3 open the stream	 
+	 */
+	public ISite createSite(URL url, IProgressMonitor monitor) throws CoreException, InvalidSiteTypeException {
+		Site site = null;
+		InputStream siteStream = null;
+	
+		try {
+			SiteURLContentProvider contentProvider = new SiteURLContentProvider(url);
+	
+			URL resolvedURL = URLEncoder.encode(url);
+			IResponse response = ConnectionFactory.get(resolvedURL);
+			UpdateManagerUtils.checkConnectionResult(response, resolvedURL);
+			siteStream = response.getInputStream(monitor);
+			// the stream can be null if the user cancels the connection
+			if (siteStream==null) return null;
+
+			SiteModelFactory factory = this;
+			site = (Site) factory.parseSite(siteStream);
+			//System.out.println(site.getClass().getCanonicalName());
+			site.setSiteContentProvider(contentProvider);
+			contentProvider.setSite(site);
+			site.resolve(url, url);
+			site.markReadOnly();
+			/*SiteWithTimestamp siteWithTimestamp = new SiteWithTimestamp(site);
+			siteWithTimestamp.setTimestamp( new Date(response.getLastModified()));
+			site = siteWithTimestamp;*/
+			((SiteWithTimestamp)site).setTimestamp( new Date(response.getLastModified()));
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.SiteURLFactory_UnableToCreateURL, (new String[] { url == null ? "" : url.toExternalForm() })), e); //$NON-NLS-1$
+		} catch (IOException e) {
+			throw Utilities.newCoreException(NLS.bind(Messages.SiteURLFactory_UnableToAccessSiteStream, (new String[] { url == null ? "" : url.toExternalForm() })), ISite.SITE_ACCESS_EXCEPTION, e);	//$NON-NLS-1$
+		} finally {
+			if (siteStream != null) {
+				try {
+					siteStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+		return site;
+	}
+
+	/*
+	 * @see SiteModelFactory#canParseSiteType(String)
+	 */
+	public boolean canParseSiteType(String type) {
+		return (super.canParseSiteType(type) || SiteURLContentProvider.SITE_TYPE.equalsIgnoreCase(type));
+	}
+    /* (non-Javadoc)
+     * @see org.eclipse.update.core.BaseSiteFactory#createFeatureReferenceModel()
+     */
+    public SiteFeatureReferenceModel createFeatureReferenceModel() {
+        return new UpdateSiteFeatureReference();
+    }
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/TargetFeature.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/TargetFeature.java
new file mode 100644
index 0000000..6c789f1
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/TargetFeature.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.Feature;
+import org.eclipse.update.core.IFeatureContentConsumer;
+import org.eclipse.update.core.Utilities;
+
+/**
+ * 
+ */
+public class TargetFeature extends Feature {
+
+
+	/**
+	 * The content consumer of the DefaultFeature
+	 */
+	private IFeatureContentConsumer contentConsumer;
+	
+
+	/**
+	 * Constructor for TargetFeature.
+	 */
+	public TargetFeature() {
+		super();
+	}
+
+	/**
+	 * Sets the content Consumer
+	 */
+	public void setContentConsumer(IFeatureContentConsumer contentConsumer) {
+		this.contentConsumer = contentConsumer;
+		contentConsumer.setFeature(this);
+	}
+
+	/*
+	 * @see IFeature#getFeatureContentConsumer()
+	 */
+	public IFeatureContentConsumer getFeatureContentConsumer() throws CoreException {
+		if (this.contentConsumer == null) {
+			throw Utilities.newCoreException( NLS.bind(Messages.Feature_NoFeatureContentConsumer, (new String[] { getURL().toExternalForm() })), null);
+		}
+		return contentConsumer;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/URLEncoder.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/URLEncoder.java
new file mode 100644
index 0000000..3200a9f
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/URLEncoder.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *     James D Miles (IBM Corp.) - bug 191368, Policy URL doesn't support UTF-8 characters
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.Assert;
+/**
+ * Encodes a <code>URL</code> into an <code>ASCII</code> readable
+ * <code>URL</code> that is safe for transport. Encoded
+ * <code>URL</code>s can be decoded using the <code>URLDecoder</code>.
+ *
+ * @see URLDecoder
+ */
+public final class URLEncoder {
+	/**
+	 * Prevents instances from being created.
+	 */
+	private URLEncoder() {
+	}
+	/**
+	 * Encodes the given file and reference parts of a <code>URL</code> into
+	 * an <code>ASCII</code> readable <code>String</code> that is safe for
+	 * transport. Returns the result.
+	 *
+	 * @return the result of encoding the given file and reference parts of
+	 *         a <code>URL</code> into an <code>ASCII</code> readable
+	 *         <code>String</code> that is safe for transport
+	 */
+	public static String encode(String file, String query, String ref) {
+		StringBuffer buf = new StringBuffer();
+		StringTokenizer tokenizer = new StringTokenizer(file, "/", true); //$NON-NLS-1$
+
+		while (tokenizer.hasMoreTokens()) {
+			String token = tokenizer.nextToken();
+			if (token.equals("/")) { //$NON-NLS-1$
+				buf.append(token);
+			} else {
+				buf.append(encodeSegment(token));
+			}
+		}
+
+		if (query != null){
+			buf.append('?');
+			buf.append(query);
+		}
+
+		if (ref != null) {
+			buf.append('#');
+			buf.append(encodeSegment(ref));
+		}
+
+		return buf.toString();
+	}
+	/**
+	 * Encodes the given <code>URL</code> into an <code>ASCII</code>
+	 * readable <code>URL</code> that is safe for transport. Returns the
+	 * result.
+	 *
+	 * @return the result of encoding the given <code>URL</code> into an
+	 *         <code>ASCII</code> readable <code>URL</code> that is safe for
+	 *         transport
+	 */
+	public static URL encode(URL url) throws MalformedURLException {
+		// encode the path not the file as the URL may contain a query
+		String file = url.getPath();
+		String query = url.getQuery();
+		String ref = url.getRef();
+		String auth = url.getAuthority();
+		String host = url.getHost();
+		int port = url.getPort();
+		String userinfo = url.getUserInfo();
+
+		// do not encode if there is an authority, such as in
+		// ftp://user:password@host:port/path 
+		// because the URL constructor does not allow it
+		URL result = url;
+		if (auth == null || auth.equals("") || userinfo == null) // $NON-NLS-1$ $NON-NLS-2$  //$NON-NLS-1$
+			result =  new URL(url.getProtocol(), host, port, encode(file, query, ref));
+		return result;
+	}
+	private static String encodeSegment(String segment) {
+		
+		// if we find a '%' in the string, consider the URL to be already encoded
+		if (segment.indexOf('%')!=-1) return segment;
+		
+		StringBuffer result = new StringBuffer(segment.length());
+
+		for (int i = 0; i < segment.length(); ++i) {
+			char c = segment.charAt(i);
+			if (mustEncode(c)) {
+				byte[] bytes = null;
+				try {
+					bytes = new Character(c).toString().getBytes("UTF8"); //$NON-NLS-1$
+				} catch (UnsupportedEncodingException e) {
+					Assert.isTrue(false, e.getMessage());
+				}
+				for (int j = 0; j < bytes.length; ++j) {
+					result.append('%');
+					result.append(Integer.toHexString((bytes[j] >> 4) & 0x0F));
+					result.append(Integer.toHexString(bytes[j] & 0x0F));
+				}
+			} else {
+				result.append(c);
+			}
+		}
+
+		return result.toString();
+	}
+	
+	private static boolean mustEncode(char c) {
+		if (c >= 'a' && c <= 'z') {
+			return false;
+		}
+
+		if (c >= 'A' && c <= 'Z') {
+			return false;
+		}
+
+		if (c >= '0' && c <= '9') {
+			return false;
+		}
+
+		if (c >= '\'' && c <= '.') {
+			return false;
+		}
+
+		if (c == '!' || c == '$' || c == '_' || c == '[' || c == ']') {
+			return false;
+		}
+
+		// needed otherwise file:///c:/file/ becomes file:///C%3a/file/
+		if (c ==':'){
+			return false;
+		}
+		return true;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/URLKey.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/URLKey.java
new file mode 100644
index 0000000..75c76ad
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/URLKey.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+ 
+import java.net.*;
+
+
+
+/**
+ * 
+ * 
+ */
+public class URLKey {
+
+	private URL url;
+	
+	/**
+	 * Constructor for URLKey.
+	 */
+	public URLKey(URL url) {
+		super();
+		this.url = url;
+	}
+
+	/**
+	 * @see java.lang.Object#equals(Object)
+	 */
+	public boolean equals(Object obj) {
+			if (obj == null) {
+				return false;
+			}
+
+			if (this == obj) {
+				return true;
+			}
+
+			if (obj instanceof URLKey) {
+				return equals(((URLKey) obj).getURL());
+			}
+
+			if (!(obj instanceof URL)) {
+				return false;
+			}
+
+			URL url2 = (URL)obj;
+			if (url == url2) {
+				return true;
+			}
+
+			return UpdateManagerUtils.sameURL(url,url2);
+	}
+
+	/**
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode() {
+		return url.hashCode();
+	}
+
+	/**
+	 * Returns the url.
+	 * @return URL
+	 */
+	public URL getURL() {
+		return url;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateCore.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateCore.java
new file mode 100644
index 0000000..0707949
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateCore.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import org.eclipse.core.net.proxy.IProxyService;
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.signedcontent.SignedContentFactory;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.connection.ConnectionThreadManagerFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class UpdateCore extends Plugin {
+
+	// debug options
+	public static boolean DEBUG;
+	public static boolean DEBUG_SHOW_INSTALL;
+	public static boolean DEBUG_SHOW_PARSING;
+	public static boolean DEBUG_SHOW_WARNINGS;
+	public static boolean DEBUG_SHOW_CONFIGURATION;
+	public static boolean DEBUG_SHOW_TYPE;
+	public static boolean DEBUG_SHOW_WEB;
+	public static boolean DEBUG_SHOW_IHANDLER;
+	public static boolean DEBUG_SHOW_RECONCILER;
+		
+	private static final String PREFIX = "org.eclipse.update.core"; //$NON-NLS-1$
+	public static final String P_HISTORY_SIZE = PREFIX + ".historySize"; //$NON-NLS-1$
+	public static final String P_CHECK_SIGNATURE = PREFIX + ".checkSignature"; //$NON-NLS-1$
+	public static final String P_AUTOMATICALLY_CHOOSE_MIRROR =  PREFIX + ".automaticallyChooseMirror"; //$NON-NLS-1$
+	public static final String P_UPDATE_VERSIONS = PREFIX + ".updateVersions"; //$NON-NLS-1$
+	public static final String EQUIVALENT_VALUE = "equivalent"; //$NON-NLS-1$
+	public static final String COMPATIBLE_VALUE = "compatible"; //$NON-NLS-1$
+	
+	public static int DEFAULT_HISTORY = 100;//Integer.MAX_VALUE;
+	
+	//The shared instance.
+	private static UpdateCore plugin;
+
+	//log
+	private static UpdateManagerLogWriter log;
+	private static final String LOG_FILE="install.log"; //$NON-NLS-1$
+
+	// bundle data
+	private BundleContext context;
+	private ServiceTracker pkgAdminTracker;
+	private ServiceTracker verifierFactoryTracker;
+	private ServiceTracker proxyTracker;
+	
+	// Session
+	private UpdateSession updateSession = null;
+	/**
+	 * HTTP response code indicating success.
+	 */
+	public static final int HTTP_OK = 200;
+	
+	/**
+	 * The constructor.
+	 */
+	public UpdateCore() {
+		plugin = this;
+	}
+	
+
+	/**
+	 * Returns the shared instance.
+	 */
+	public static UpdateCore getPlugin() {
+		return plugin;
+	}
+	
+
+	private boolean getBooleanDebugOption(String flag, boolean dflt) {
+		String result = Platform.getDebugOption(flag);
+		if (result == null)
+			return dflt;
+		else
+			return result.trim().equalsIgnoreCase("true"); //$NON-NLS-1$
+	}
+
+	/**
+	 * dumps a String in the trace
+	 */
+	public static void debug(String s) {
+		StringBuffer msg = new StringBuffer();
+		msg.append(getPlugin().toString());
+		msg.append("^"); //$NON-NLS-1$
+		msg.append(Integer.toHexString(Thread.currentThread().hashCode()));
+		msg.append(" "); //$NON-NLS-1$
+		msg.append(s);
+		System.out.println(msg.toString());
+	}
+	
+	/**
+	 * Dumps a String in the log if WARNING is set to true
+	 */
+	public static void warn(String s) {
+		if (DEBUG && DEBUG_SHOW_WARNINGS) {
+			if (s!=null){
+				s="WARNING: "+s; //$NON-NLS-1$
+			}
+			log(s, null); 
+		}
+	}
+
+	/**
+	 * Dumps an exception in the log if WARNING is set to true
+	 * 
+	 * @param s log string
+	 * @param e exception to be logged
+	 * @since 2.0
+	 */
+	public static void warn(String s, Throwable e) {
+		if (DEBUG && DEBUG_SHOW_WARNINGS){
+			if (s!=null){
+				s="UPDATE MANAGER INFO: "+s; //$NON-NLS-1$
+			}
+			log(s,e);
+		}
+	}
+			
+	/**
+	 * Logs a status
+	 */
+	public static void log(IStatus status){
+		UpdateCore.getPlugin().getLog().log(status);		
+	}
+	
+	/**
+	 * Logs an error
+	 */
+	public static void log(Throwable e){		
+		log("",e); //$NON-NLS-1$
+	}	
+	
+	/**
+	 * Logs a string and an  error
+	 */
+	public static void log(String msg, Throwable e){
+		IStatus status = null;
+		if (e instanceof CoreException) 
+			status = ((CoreException)e).getStatus();
+		else 
+			status = Utilities.newCoreException(msg,e).getStatus();		
+		if (status!=null)
+			log(status);
+	}		
+	/*
+	 * Method log.
+	 * @param newConfiguration
+	 */
+	public static void log(IInstallConfiguration newConfiguration) {
+		if (log!=null)
+			log.log(newConfiguration);
+	}
+
+	/*
+	 * Get update log location relative to platform configuration
+	 */
+	private static File getInstallLogFile() throws IOException {
+		
+		IPlatformConfiguration config = ConfiguratorUtils.getCurrentPlatformConfiguration();		
+		URL configurationLocation = config.getConfigurationLocation();
+		if (configurationLocation==null){
+			warn("Unable to retrieve location for update manager log file"); //$NON-NLS-1$
+			return null;
+		}
+//		URL configLocation = Platform.resolve(configurationLocation);
+		File updateStateLocation = null;
+
+		if ("file".equalsIgnoreCase(configurationLocation.getProtocol())) { //$NON-NLS-1$
+			File path = new File(configurationLocation.getFile());
+			updateStateLocation = new File(path.getParentFile(), LOG_FILE);
+		}
+		return updateStateLocation;
+	}
+
+	/**
+	 * Sends the GET request to the server and returns the server's
+	 * response.
+	 *
+	 * @param url the URL to open on the server
+	 * @return the server's response
+	 * @throws IOException if an I/O error occurs. Reasons include:
+	 * <ul>
+	 * <li>The client is closed.
+	 * <li>The client could not connect to the server
+	 * <li>An I/O error occurs while communicating with the server
+	 * <ul>
+	 */
+
+	
+	/*
+	 * Returns true if the feature is a patch
+	 */
+	public static boolean isPatch(IFeature candidate) {
+		IImport[] imports = candidate.getImports();
+
+		for (int i = 0; i < imports.length; i++) {
+			IImport iimport = imports[i];
+			if (iimport.isPatch())
+				return true;
+		}
+		return false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		this.context = context;
+
+        DEBUG = getBooleanDebugOption("org.eclipse.update.core/debug", false); //$NON-NLS-1$
+
+		if (DEBUG) {
+			DEBUG_SHOW_WARNINGS = getBooleanDebugOption("org.eclipse.update.core/debug/warning", false); //$NON-NLS-1$
+			DEBUG_SHOW_PARSING = getBooleanDebugOption("org.eclipse.update.core/debug/parsing", false); //$NON-NLS-1$
+			DEBUG_SHOW_INSTALL = getBooleanDebugOption("org.eclipse.update.core/debug/install", false); //$NON-NLS-1$
+			DEBUG_SHOW_CONFIGURATION = getBooleanDebugOption("org.eclipse.update.core/debug/configuration", false); //$NON-NLS-1$
+			DEBUG_SHOW_TYPE = getBooleanDebugOption("org.eclipse.update.core/debug/type", false); //$NON-NLS-1$
+			DEBUG_SHOW_WEB = getBooleanDebugOption("org.eclipse.update.core/debug/web", false); //$NON-NLS-1$
+			DEBUG_SHOW_IHANDLER = getBooleanDebugOption("org.eclipse.update.core/debug/installhandler", false); //$NON-NLS-1$
+			DEBUG_SHOW_RECONCILER = getBooleanDebugOption("org.eclipse.update.core/debug/reconciler", false); //$NON-NLS-1$
+		}
+		
+		//
+		try {
+			File logFile = getInstallLogFile();
+			if (logFile!=null)
+				log = new UpdateManagerLogWriter(logFile);
+		} catch (IOException e){
+			warn("",e); //$NON-NLS-1$
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		super.stop(context);
+		
+		JarContentReference.shutdown(); // make sure we are not leaving jars open
+		Utilities.shutdown(); // cleanup temp area
+		if (log!=null)
+			log.shutdown();
+		
+		ConnectionThreadManagerFactory.getConnectionManager().shutdown();
+
+		
+		this.context = null;
+		if (pkgAdminTracker != null) {
+			pkgAdminTracker.close();
+			pkgAdminTracker = null;
+		}
+		if (verifierFactoryTracker != null) {
+			verifierFactoryTracker.close();
+			verifierFactoryTracker = null;
+		}
+		if (proxyTracker != null) {
+			proxyTracker.close();
+			proxyTracker = null;
+		}
+	}
+	
+	public BundleContext getBundleContext() {
+		return context;
+	}
+	
+	PackageAdmin getPackageAdmin() {
+		if (pkgAdminTracker == null) {
+			pkgAdminTracker = new ServiceTracker(context, PackageAdmin.class.getName(), null);
+			pkgAdminTracker.open();
+		}
+		return (PackageAdmin)pkgAdminTracker.getService();
+	}
+	
+	public IProxyService getProxyService() {
+		if (proxyTracker == null) {
+		    proxyTracker=new ServiceTracker(getBundle().getBundleContext(),
+		            IProxyService.class.getName(), null);
+		    proxyTracker.open();
+		}
+		return (IProxyService)proxyTracker.getService();
+	}
+
+
+	public SignedContentFactory getSignedContentFactory() {
+		if (verifierFactoryTracker == null) {
+			verifierFactoryTracker = new ServiceTracker(context, SignedContentFactory.class.getName(), null);
+			verifierFactoryTracker.open();
+		}
+		return (SignedContentFactory)verifierFactoryTracker.getService();
+	}
+	
+	public UpdateSession getUpdateSession() {
+		synchronized(UpdateSession.class) {
+			if (updateSession == null) {
+				updateSession = new UpdateSession();
+			}
+		}		
+		return updateSession;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateManagerLogWriter.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateManagerLogWriter.java
new file mode 100644
index 0000000..1daf0ca
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateManagerLogWriter.java
@@ -0,0 +1,301 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.update.configuration.IActivity;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+
+
+/**
+ * A log writer that writes update manager log entries.  
+ */
+public class UpdateManagerLogWriter {
+	private File logFile = null;
+	private Writer log = null;
+
+	private static final String CONFIGURATION = "!CONFIGURATION"; //$NON-NLS-1$
+	private static final String ACTIVITY = "!ACTIVITY"; //$NON-NLS-1$
+
+	private static final String SUCCESS = "success"; //$NON-NLS-1$
+	private static final String FAILURE = "failure"; //$NON-NLS-1$
+
+	private static final String FEATURE_INSTALL = "feature-install"; //$NON-NLS-1$
+	private static final String FEATURE_REMOVE = "feature-remove"; //$NON-NLS-1$
+	private static final String SITE_INSTALL = "site-install"; //$NON-NLS-1$
+	private static final String SITE_REMOVE = "site-remove"; //$NON-NLS-1$
+	private static final String UNCONFIGURE = "feature-disable"; //$NON-NLS-1$
+	private static final String CONFIGURE = "feature-enable"; //$NON-NLS-1$
+	private static final String REVERT = "revert"; //$NON-NLS-1$
+	private static final String RECONCILIATION = "reconciliation"; //$NON-NLS-1$
+	private static final String PRESERVED = "preserve-configuration"; //$NON-NLS-1$	
+	private static final String UNKNOWN = "unknown"; //$NON-NLS-1$	
+
+	private static final String LINE_SEPARATOR;
+
+	static {
+		String s = System.getProperty("line.separator"); //$NON-NLS-1$
+		LINE_SEPARATOR = s == null ? "\n" : s; //$NON-NLS-1$
+	}
+
+	/*
+	 * 
+	 */
+	public UpdateManagerLogWriter(File file) {
+		this.logFile = file;
+		UpdateCore.warn("UPDATE MANAGER LOG Location: "+file.getAbsolutePath()); //$NON-NLS-1$
+
+		// If the file does not exist, prime it with the sites in the exisiting config
+		if (!file.exists())
+			initLog();
+	}
+	
+	/*
+	 * Initializes the log with the original configuration
+	 */
+	private void initLog() {
+		try {
+			IPlatformConfiguration runtimeConfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+			IPlatformConfiguration.ISiteEntry[] sites = runtimeConfig.getConfiguredSites();
+			ConfigurationActivity[] activities = new ConfigurationActivity[sites.length];
+			for (int i=0; i<sites.length; i++) {
+				activities[i] = new ConfigurationActivity(IActivity.ACTION_SITE_INSTALL);
+				activities[i].setLabel(FileLocator.toFileURL(sites[i].getURL()).toExternalForm());
+				activities[i].setDate(new Date());
+				activities[i].setStatus(IActivity.STATUS_OK);
+			}
+			Date date = new Date(runtimeConfig.getChangeStamp());
+			safeWriteConfiguration(date, activities);
+		} catch (Exception e) {
+			// silently ignore errors
+		}
+	}
+
+	/*
+	 * 
+	 */
+	private void closeLogFile() throws IOException {
+		try {
+			if (log != null) {
+				log.flush();
+				log.close();
+			}
+		} finally {
+			log = null;
+		}
+	}
+	
+	/*
+	 * 
+	 */
+	public void log(IInstallConfiguration installConfig) {
+		safeWriteConfiguration(installConfig.getCreationDate(), installConfig.getActivities());
+	}
+	
+	
+	/*
+	 * 
+	 */
+	private void openLogFile() {
+		try {
+			log = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logFile.getAbsolutePath(), true), "UTF-8")); //$NON-NLS-1$
+		} catch (IOException e) {
+			// there was a problem opening the log file so log to the console
+			log = logForStream(System.err);
+		}
+	}
+	
+    /*
+     * 
+     */
+	private String getFormattedDate(Date date) {
+		try {
+			DateFormat formatter = new SimpleDateFormat("MMM dd, yyyy kk:mm:ss.SS"); //$NON-NLS-1$
+			return formatter.format(date);
+		} catch (Exception e) {
+			// If there were problems writing out the date, ignore and
+			// continue since that shouldn't stop us from losing the rest
+			// of the information
+		}
+		return Long.toString(System.currentTimeMillis());
+	}
+	
+	/*
+	 * 
+	 */
+	private Writer logForStream(OutputStream output) {
+		try {
+			return new BufferedWriter(new OutputStreamWriter(output, "UTF-8")); //$NON-NLS-1$
+		} catch (UnsupportedEncodingException e) {
+			return new BufferedWriter(new OutputStreamWriter(output));
+		}
+	}
+	
+	
+	/*
+	 * Shuts down the update manager log.
+	 */
+	public synchronized void shutdown() {
+		try {
+			if (logFile != null) {
+				closeLogFile();
+				logFile = null;
+			} else {
+				if (log != null) {
+					Writer old = log;
+					log = null;
+					old.flush();
+					old.close();
+				}
+			}
+		} catch (IOException e) {
+			//we've shutdown the log, so not much else we can do!
+			e.printStackTrace();
+		}
+	}
+
+	/*
+	 * 
+	 */
+	private synchronized void safeWriteConfiguration(Date date, IActivity[] activities) {
+		// thread safety: (Concurrency003)
+		if (logFile != null)
+			openLogFile();
+		if (log == null)
+			log = logForStream(System.err);
+		try {
+			try {
+				write(date, activities);
+			} finally {
+				if (logFile != null)
+					closeLogFile();
+				else
+					log.flush();
+			}
+		} catch (Exception e) {
+			System.err.println("An exception occurred while writing to the update manager log:"); //$NON-NLS-1$
+			e.printStackTrace(System.err);
+			System.err.println("Logging to the console instead."); //$NON-NLS-1$
+			//we failed to write, so dump log entry to console instead
+			try {
+				log = logForStream(System.err);
+				write(date, activities);
+				log.flush();
+			} catch (Exception e2) {
+				System.err.println("An exception occurred while logging to the console:"); //$NON-NLS-1$
+				e2.printStackTrace(System.err);
+			}
+		} finally {
+			log = null;
+		}
+	}
+	
+
+	/*
+	 * !CONFIGURATION <label>
+	 */
+	private void write(Date date, IActivity[] activities) throws IOException {
+		writeln();
+		write(CONFIGURATION);
+		writeSpace();	
+		write(String.valueOf(date.getTime()));
+		writeSpace();
+		write(date.toString());
+		writeln();
+		for (int i = 0; i < activities.length; i++) {
+			write(activities[i]);
+		}				
+	}
+
+	/*
+	 * !ACTIVITY <date> <target> <action> <status>
+	 */
+	private void write(IActivity activity) throws IOException {
+		write(ACTIVITY);
+		writeSpace();	
+		write(String.valueOf(activity.getDate().getTime()));
+		writeSpace();
+		write(getFormattedDate(activity.getDate()));
+		writeSpace();
+		write(activity.getLabel());
+		writeSpace();
+		write(getAction(activity.getAction()));
+		writeSpace();
+		write((activity.getStatus()==IActivity.STATUS_OK)?SUCCESS:FAILURE);
+		writeln();		
+	}
+
+	/*
+	 * 
+	 */
+	private String getAction(int i) {
+		switch (i) {
+			case IActivity.ACTION_FEATURE_INSTALL :
+				return FEATURE_INSTALL;
+			case IActivity.ACTION_FEATURE_REMOVE :
+				return FEATURE_REMOVE;
+			case IActivity.ACTION_SITE_INSTALL :
+				return SITE_INSTALL;
+			case IActivity.ACTION_SITE_REMOVE :
+				return SITE_REMOVE;
+			case IActivity.ACTION_UNCONFIGURE :
+				return UNCONFIGURE;
+			case IActivity.ACTION_CONFIGURE :
+				return CONFIGURE;
+			case IActivity.ACTION_REVERT :
+				return REVERT;
+			case IActivity.ACTION_RECONCILIATION :
+				return RECONCILIATION;
+			case IActivity.ACTION_ADD_PRESERVED :
+				return PRESERVED;
+							
+			default :
+				return UNKNOWN+" ["+i+"]"; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+
+
+	/*
+	 * 
+	 */
+	private void writeln() throws IOException {
+		write(LINE_SEPARATOR);
+	}
+	
+	/*
+	 * 
+	 */
+	private void write(String message) throws IOException {
+		if (message != null)
+			log.write(message);
+	}
+	
+	/*
+	 * 
+	 */
+	private void writeSpace() throws IOException {
+		write(" "); //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateManagerUtils.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateManagerUtils.java
new file mode 100644
index 0000000..d1e713a
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateManagerUtils.java
@@ -0,0 +1,964 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *     Chris Aniszczyk (IBM Corp.) - Fixed NPE
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.update.core.IUpdateConstants;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.InstallAbortedException;
+import org.eclipse.update.internal.core.connection.ConnectionFactory;
+import org.eclipse.update.internal.core.connection.IResponse;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * 
+ */
+public class UpdateManagerUtils {
+
+	private static boolean OS_UNIX = org.eclipse.osgi.service.environment.Constants.OS_HPUX
+			.equals(Platform.getOS())
+			|| org.eclipse.osgi.service.environment.Constants.OS_AIX
+					.equals(Platform.getOS())
+			|| org.eclipse.osgi.service.environment.Constants.OS_LINUX
+					.equals(Platform.getOS())
+			|| org.eclipse.osgi.service.environment.Constants.OS_SOLARIS
+					.equals(Platform.getOS())
+			|| org.eclipse.osgi.service.environment.Constants.OS_MACOSX
+					.equals(Platform.getOS());
+	private static FragmentEntry[] noFragments = new FragmentEntry[0];
+	private static Map table;
+
+	static {
+		table = new HashMap();
+		table.put("compatible", new Integer(IUpdateConstants.RULE_COMPATIBLE)); //$NON-NLS-1$
+		table.put("perfect", new Integer(IUpdateConstants.RULE_PERFECT)); //$NON-NLS-1$
+		table.put("equivalent", new Integer(IUpdateConstants.RULE_EQUIVALENT)); //$NON-NLS-1$
+		table.put("greaterOrEqual", new Integer(IUpdateConstants.RULE_GREATER_OR_EQUAL)); //$NON-NLS-1$
+	}
+
+	// manage URL to File
+	private static Map urlFileMap;
+
+	private static Map localFileFragmentMap;
+	private static Stack bufferPool;
+	private static final int BUFFER_SIZE = 4096; // 4kbytes
+	private static final int INCREMENT_SIZE = 10240; // 10kbytes
+	/**
+	 * return the urlString if it is a absolute URL
+	 * otherwise, return the default URL if the urlString is null
+	 * The defaultURL may point ot a file, create a file URL then
+	 * if the urlString or the default URL are relatives, prepend the rootURL to it
+	 */
+	public static URL getURL(URL rootURL, String urlString, String defaultURL) throws MalformedURLException {
+		URL url = null;
+
+		// if no URL , provide Default
+		if (urlString == null || urlString.trim().equals("")) { //$NON-NLS-1$
+
+			// no URL, no default, return right now...
+			if (defaultURL == null || defaultURL.trim().equals("")) //$NON-NLS-1$
+				return null;
+			else
+				urlString = defaultURL;
+		}
+
+		// URL can be relative or absolute	
+		if (urlString.startsWith("/") && urlString.length() > 1) //$NON-NLS-1$
+			urlString = urlString.substring(1);
+		try {
+			url = new URL(urlString);
+		} catch (MalformedURLException e) {
+			// the url is not an absolute URL
+			// try relative
+			url = new URL(rootURL, urlString);
+		}
+
+		return url;
+	}
+
+	/**
+	 * return a relative String to rootURL 
+	 * if url contains rootURL so
+	 * new URL(rootURL, resultString) == url
+	 * 
+	 */
+	public static String getURLAsString(URL rootURL, URL url) {
+		String result = null;
+
+		if (rootURL == null) {
+			return (url == null) ? null : url.toString();
+		}
+
+		// if no URL , return null
+		if (url != null) {
+
+			result = url.toExternalForm();
+
+			if (rootURL.getHost() != null && !rootURL.getHost().equals(url.getHost()))
+				return result;
+
+			if (rootURL.getProtocol() != null && !rootURL.getProtocol().equals(url.getProtocol()))
+				return result;
+
+			if (rootURL.getPort() != url.getPort())
+				return result;
+
+			String rootURLFileString = rootURL.getFile();
+			rootURLFileString = rootURLFileString.replace(File.separatorChar, '/');
+			if (!rootURLFileString.endsWith("/")) { //$NON-NLS-1$
+				int index = rootURLFileString.lastIndexOf('/');
+				if (index != -1) {
+					rootURLFileString = rootURLFileString.substring(0, index);
+				}
+			}
+			String urlFileString = url.getFile();
+
+			if (urlFileString.startsWith(rootURLFileString)) {
+				result = urlFileString.substring(rootURLFileString.length());
+				result = result.replace(File.separatorChar, '/');
+			} else {
+				// we need to check the following
+				// file:/C:/ and file:C:/
+				if ("file".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
+					File rootFile = new File(rootURLFileString);
+					File urlFile = new File(urlFileString);
+
+					File relativePath = urlFile;
+					while (relativePath != null && !rootFile.equals(relativePath.getParentFile())) {
+						relativePath = relativePath.getParentFile();
+					}
+
+					if (relativePath == null) {
+						UpdateCore.warn("Cannot calculate relative path"); //$NON-NLS-1$
+						return url.toString();
+					} else {
+						String relativeRootString = relativePath.getParentFile().getAbsolutePath();
+						String fullString = urlFile.getAbsolutePath();
+						if (!fullString.startsWith(relativeRootString)) {
+							UpdateCore.warn("Full path:" + fullString + " does not start with " + relativeRootString); //$NON-NLS-1$ //$NON-NLS-2$
+							return url.toString();
+						} else {
+							String returnString = fullString.substring(relativeRootString.length() + 1);
+							if (urlFile.isDirectory())
+								returnString += File.separator;
+							// we lost the last slash when tranforming in File
+							returnString = returnString.replace(File.separatorChar, '/');
+							return returnString;
+						}
+
+					}
+
+				} else {
+					result = url.toString();
+				}
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	 * returns a translated String
+	 */
+	public static String getResourceString(String infoURL, ResourceBundle bundle) {
+		String result = null;
+		if (infoURL != null) {
+			result = Platform.getResourceString(UpdateCore.getPlugin().getBundle(), infoURL, bundle);
+		}
+		return result;
+	}
+
+	/**
+	 * 
+	 */
+	public static URL copyToLocal(InputStream sourceContentReferenceStream, String localName, InstallMonitor monitor) throws MalformedURLException, IOException, InstallAbortedException {
+		URL result = null;
+		// create the Dir if they do not exist
+		// get the path from the File to resolve File.separator..
+		// do not use the String as it may contain URL like separator
+		File localFile = new File(localName);
+		int index = localFile.getPath().lastIndexOf(File.separator);
+		if (index != -1) {
+			File dir = new File(localFile.getPath().substring(0, index));
+			if (!dir.exists())
+				dir.mkdirs();
+		}
+
+		// transfer the content of the File
+		if (!localFile.isDirectory()) {
+			OutputStream localContentReferenceStream = new FileOutputStream(localFile);
+			try {
+				Utilities.copy(sourceContentReferenceStream, localContentReferenceStream, monitor);
+			} finally {
+				try {
+					localContentReferenceStream.close();
+				} catch (IOException e){}
+			}
+		}
+		result = localFile.toURL();
+		return result;
+	}
+
+	/*
+	 * [20305] need to slam permissions for executable libs on some
+	 * platforms. This is a temporary fix
+	 */
+	public static void checkPermissions(ContentReference ref, String filePath) {
+
+		if (ref.getPermission() != 0) {
+			UpdateCore.warn("Change permission for " + filePath + " to " + ref.getPermission()); //$NON-NLS-1$ //$NON-NLS-2$
+			// FIXME: change the code to use JNI
+		}
+
+		if (filePath != null && OS_UNIX && ref.getPermission() != 0) {
+			// add execute permission on shared libraries 20305
+			// do not remove write permission 20896
+			// chmod a+x *.sl
+			try {
+				Process pr = Runtime.getRuntime().exec(new String[] { "chmod", "a+x", filePath }); //$NON-NLS-1$ //$NON-NLS-2$
+				Thread chmodOutput = new StreamConsumer(pr.getInputStream());
+				chmodOutput.setName("chmod output reader"); //$NON-NLS-1$
+				chmodOutput.start();
+				Thread chmodError = new StreamConsumer(pr.getErrorStream());
+				chmodError.setName("chmod error reader"); //$NON-NLS-1$
+				chmodError.start();
+			} catch (IOException ioe) {
+			}
+
+		}
+	}
+
+	/**
+	 * Returns a random file name for the local system
+	 * attempt to conserve the extension if there is a '.' in the path
+	 * and no File.Seperator after the '.'
+	 * 
+	 * \a\b\c.txt -> c987659385.txt
+	 * c.txt -> c3854763.txt
+	 * c	-> c953867549
+	 */
+	public static String getLocalRandomIdentifier(String remotePath, Date date) {
+		int dotIndex = remotePath.lastIndexOf(".");	//$NON-NLS-1$
+		int fileIndex = remotePath.lastIndexOf(File.separator);
+		// if there is a separator after the dot
+		// do not consider it as an extension
+		String ext = (dotIndex != -1 && fileIndex < dotIndex) ? remotePath.substring(dotIndex) : ""; //$NON-NLS-1$
+		// the name is the string between the separator and the dot
+		// if there is no separator, it is the string up to the dot		
+		// if there is no dot, go to the end of the string 
+		if (fileIndex == -1)
+			fileIndex = 0;
+		if (dotIndex == -1)
+			dotIndex = remotePath.length();
+		// if I have a separator and no dot: /a/b/c -> c
+		// if my separator is the last /a/b/c/, fileIndex and dotIndex are the same, so it will return the default temp name
+		String name = (fileIndex < dotIndex) ? remotePath.substring(fileIndex, dotIndex) : "Eclipse_Update_TMP_"; //$NON-NLS-1$
+		String result = name + date.getTime() + ext;
+		return result;
+	}
+
+	/**
+	 * remove a file or directory from the file system.
+	 * used to clean up install
+	 */
+	public static void removeFromFileSystem(File file) {
+		if (!file.exists() || !file.canWrite())
+			return;
+
+		if (file.isDirectory()) {
+			String[] files = file.list();
+			if (files != null) // be careful since file.list() can return null
+				for (int i = 0; i < files.length; ++i)
+					removeFromFileSystem(new File(file, files[i]));
+		}
+
+		if (!file.delete()) {
+			String msg = NLS.bind(Messages.UpdateManagerUtils_UnableToRemoveFile, (new String[] { file.getAbsolutePath() }));
+			UpdateCore.log(msg, new Exception());
+		}
+	}
+
+	/**
+	 * remove all the empty directories recursively
+	 * used to clean up install
+	 */
+	public static void removeEmptyDirectoriesFromFileSystem(File file) {
+		if (!file.isDirectory())
+			return;
+
+		String[] files = file.list();
+		if (files != null) { // be careful since file.list() can return null
+			for (int i = 0; i < files.length; ++i) {
+				removeEmptyDirectoriesFromFileSystem(new File(file, files[i]));
+			}
+		}
+		if (!file.delete()) {
+			String msg = NLS.bind(Messages.UpdateManagerUtils_UnableToRemoveFile, (new String[] { file.getAbsolutePath() }));
+			UpdateCore.log(msg, new Exception());
+		}
+	}
+
+	/**
+	 * Returns the plugin entries that are in source array and
+	 * not in target array
+	 */
+	public static IPluginEntry[] diff(IPluginEntry[] sourceArray, IPluginEntry[] targetArray) { // No pluginEntry to Install, return Nothing to instal
+		if (sourceArray == null || sourceArray.length == 0) {
+			return new IPluginEntry[0];
+		} // No pluginEntry installed, Install them all
+		if (targetArray == null || targetArray.length == 0) {
+			return sourceArray;
+		} // if a IPluginEntry from sourceArray is NOT in
+		// targetArray, add it to the list
+		List list1 = Arrays.asList(targetArray);
+		List result = new ArrayList(0);
+		for (int i = 0; i < sourceArray.length; i++) {
+			if (!list1.contains(sourceArray[i]))
+				result.add(sourceArray[i]);
+		}
+
+		IPluginEntry[] resultEntry = new IPluginEntry[result.size()];
+		if (result.size() > 0)
+			result.toArray(resultEntry);
+		return resultEntry;
+	}
+
+	/**
+	 * 
+	 */
+	public static URL asDirectoryURL(URL url) throws MalformedURLException {
+		//url = URLEncoder.encode(url);
+		String path = url.getFile();
+		if (!path.endsWith("/")) { //$NON-NLS-1$
+			int index = path.lastIndexOf('/');
+			if (index != -1)
+				path = path.substring(0, index + 1);
+			// ignore any ref in original URL
+			url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
+		}
+		return url;
+	}
+
+	/*
+	 * Compares two URL for equality
+	 * Return false if one of them is null
+	 */
+	public static boolean sameURL(URL url1, URL url2) {
+
+		if (url1 == null || url2 == null)
+			return false;
+		if (url1 == url2)
+			return true;
+		if (url1.equals(url2))
+			return true;
+
+		// check if URL are file: URL as we may
+		// have 2 URL pointing to the same featureReference
+		// but with different representation
+		// (i.e. file:/C;/ and file:C:/)
+		if (!"file".equalsIgnoreCase(url1.getProtocol())) //$NON-NLS-1$
+			return false;
+		if (!"file".equalsIgnoreCase(url2.getProtocol())) //$NON-NLS-1$
+			return false;
+
+		File file1 = getFileFor(url1);//new File(url1.getFile());
+		File file2 = getFileFor(url2);
+
+		if (file1 == null)
+			return false;
+
+		return (file1.equals(file2));
+	}
+	
+	/*
+	 * Method getFileFor.
+	 * @param url1
+	 * @return File
+	 */
+	private static File getFileFor(URL url1) {
+		if (urlFileMap == null) urlFileMap = new HashMap();
+		if (urlFileMap.get(url1)!=null) return (File)urlFileMap.get(url1);
+		File newFile = new File(url1.getFile());
+		urlFileMap.put(url1,newFile);
+		return newFile; 
+	}
+
+	/*
+	 * returns the list of FeatureReference that are parent of 
+	 * the Feature or an empty array if no parent found.
+	 * @param onlyOptional if set to <code>true</code> only return parents that consider the feature optional
+	 * @param child
+	 * @param possiblesParent
+	 */
+	public static IFeatureReference[] getParentFeatures(IFeature childFeature, IFeatureReference[] possiblesParent, boolean onlyOptional) throws CoreException {
+
+		if (childFeature == null)
+			return new IFeatureReference[0];
+
+		List parentList = new ArrayList();
+		IIncludedFeatureReference[] children = null;
+		IFeature compareFeature = null;
+		for (int i = 0; i < possiblesParent.length; i++) {
+			try {
+				IFeature possibleParentFeature = possiblesParent[i].getFeature(null);
+				if (possibleParentFeature != null) {
+					children = possibleParentFeature.getIncludedFeatureReferences();
+					for (int j = 0; j < children.length; j++) {
+						try {
+							compareFeature = children[j].getFeature(null);
+						} catch (CoreException e) {
+							UpdateCore.warn("", e); //$NON-NLS-1$
+						}
+						if (childFeature.equals(compareFeature)) {
+							if (onlyOptional) {
+								if (UpdateManagerUtils.isOptional(children[j])) {
+									parentList.add(possiblesParent[i]);
+								} else {
+									UpdateCore.warn("Feature :" + children[j] + " not optional. Not included in parents list."); //$NON-NLS-1$ //$NON-NLS-2$
+								}
+							} else {
+								parentList.add(possiblesParent[i]);
+							}
+						}
+					}
+				}
+			} catch (CoreException e) {
+				UpdateCore.warn("", e); //$NON-NLS-1$
+			}
+		}
+
+		IFeatureReference[] parents = new IFeatureReference[0];
+		if (parentList.size() > 0) {
+			parents = new IFeatureReference[parentList.size()];
+			parentList.toArray(parents);
+		}
+		return parents;
+	}
+
+	/*
+	 * If the return code of the HTTP connection is not 200 (OK)
+	 * thow an IO exception
+	 * 
+	 */
+	public static void checkConnectionResult(IResponse response,URL url) throws IOException {
+		// did the server return an error code ?
+		int result = response.getStatusCode();
+
+		if (result != UpdateCore.HTTP_OK) { 
+			String serverMsg = response.getStatusMessage();
+			response.close();
+			throw new FatalIOException(NLS.bind(Messages.ContentReference_HttpNok, (new Object[] { new Integer(result), serverMsg, url })));						
+		}
+	}
+
+	public static class StreamConsumer extends Thread {
+		InputStream is;
+		byte[] buf;
+		public StreamConsumer(InputStream inputStream) {
+			super();
+			this.setDaemon(true);
+			this.is = inputStream;
+			buf = new byte[512];
+		}
+		public void run() {
+			try {
+				int n = 0;
+				while (n >= 0)
+					n = is.read(buf);
+			} catch (IOException ioe) {
+			}
+		}
+	}
+
+	/**
+	 * Return the optional children to install
+	 * The optional features to install may not all be direct children 
+	 * of the feature.
+	 * Also include non-optional features
+	 * 
+	 * @param children all the nested features
+	 * @param optionalfeatures optional features to install
+	 * @return IFeatureReference[]
+	 */
+	public static IFeatureReference[] optionalChildrenToInstall(IFeatureReference[] children, IFeatureReference[] optionalfeatures) {
+
+		List optionalChildrenToInstall = new ArrayList();
+		for (int i = 0; i < children.length; i++) {
+			IFeatureReference optionalFeature = children[i];
+			if (!UpdateManagerUtils.isOptional(optionalFeature)) {
+				optionalChildrenToInstall.add(optionalFeature);
+			} else {
+				for (int j = 0; j < optionalfeatures.length; j++) {
+					if (optionalFeature.equals(optionalfeatures[j])) {
+						optionalChildrenToInstall.add(optionalFeature);
+						break;
+					}
+				}
+			}
+		}
+
+		IFeatureReference[] result = new IFeatureReference[optionalChildrenToInstall.size()];
+		if (optionalChildrenToInstall.size() > 0) {
+			optionalChildrenToInstall.toArray(result);
+		}
+
+		return result;
+	}
+
+	/**
+	 * returns the mapping of matching rules
+	 * the default returns perfect
+	 * 
+	 * @since 2.0.2
+	 */
+	public static int getMatchingRule(String rule) {
+		if (rule == null)
+			return IUpdateConstants.RULE_COMPATIBLE;
+		final Integer integer = (Integer) table.get(rule);
+		if (integer == null)
+			return IUpdateConstants.RULE_PERFECT;
+		int ruleInt = integer.intValue();
+		if (ruleInt == IUpdateConstants.RULE_NONE)
+			return IUpdateConstants.RULE_PERFECT;
+		return ruleInt;
+	}
+	
+	/**
+	 * returns the mapping of matching id rules
+	 * the default returns perfect
+	 * 
+	 * @since 2.0.2
+	 */
+	public static int getMatchingIdRule(String rule) {
+		
+		if (rule == null)
+			return IUpdateConstants.RULE_COMPATIBLE;
+		if (rule!=null && rule.equalsIgnoreCase("prefix")) //$NON-NLS-1$
+			return IUpdateConstants.RULE_PREFIX;
+		return IUpdateConstants.RULE_PERFECT;
+	}
+	
+	/**
+	 * Method isOptional.
+	 * @param featureReference
+	 * @return boolean
+	 */
+	public static boolean isOptional(IFeatureReference featureReference) {
+		if (featureReference==null) return false;
+		if (featureReference instanceof IIncludedFeatureReference){
+			return ((IIncludedFeatureReference)featureReference).isOptional();
+		}
+		return false;
+	}
+
+	/**
+	 * 
+	 */
+	public static boolean isValidEnvironment(IPlatformEnvironment candidate) {
+		if (candidate==null) return false;
+		String os = candidate.getOS();
+		String ws = candidate.getWS();
+		String arch = candidate.getOSArch();
+		String nl = candidate.getNL();
+		if (os!=null && !isMatching(os, SiteManager.getOS())) return false;
+		if (ws!=null && !isMatching(ws, SiteManager.getWS())) return false;
+		if (arch!=null && !isMatching(arch, SiteManager.getOSArch())) return false;
+		if (nl!=null && !isMatchingLocale(nl, SiteManager.getNL())) return false;
+		return true;
+	}
+
+	/* Original code - commented out to provide a replacement as per bug 98387
+	
+	private static boolean isMatching(String candidateValues, String siteValues) {
+		if (siteValues==null) return false;
+		if ("*".equals(candidateValues)) return true; //$NON-NLS-1$
+		if ("".equals(candidateValues)) return true; //$NON-NLS-1$
+		siteValues = siteValues.toUpperCase();		
+		StringTokenizer stok = new StringTokenizer(candidateValues, ","); //$NON-NLS-1$
+		while (stok.hasMoreTokens()) {
+			String token = stok.nextToken().toUpperCase();
+			if (siteValues.indexOf(token)!=-1) return true;
+		}
+		return false;
+	}
+	*/
+	
+	/*
+	 * Fixed bug 98387
+	 */
+	
+	private static boolean isMatching(String candidateValues, String siteValues) {
+		if (siteValues==null) return false;
+		if ("*".equals(candidateValues)) return true; //$NON-NLS-1$
+		if ("".equals(candidateValues)) return true; //$NON-NLS-1$
+		StringTokenizer siteTokens = new StringTokenizer(siteValues, ",");  //$NON-NLS-1$
+		//$NON-NLS-1$	
+		while(siteTokens.hasMoreTokens()) {
+		    StringTokenizer candidateTokens = new StringTokenizer
+	                                       (candidateValues, ","); //$NON-NLS-1$
+			String siteValue = siteTokens.nextToken();
+			while (candidateTokens.hasMoreTokens()) {
+				if (siteValue.equalsIgnoreCase
+	                             (candidateTokens.nextToken())) return true;
+			}
+		}
+		return false;
+	}
+
+	
+	/**
+	 * 
+	 */	
+	private static boolean isMatchingLocale(String candidateValues, String locale) {
+		if (locale==null) return false;
+		if ("*".equals(candidateValues)) return true; //$NON-NLS-1$
+		if ("".equals(candidateValues)) return true; //$NON-NLS-1$
+		
+		locale = locale.toUpperCase();
+		candidateValues = candidateValues.toUpperCase();	
+		StringTokenizer stok = new StringTokenizer(candidateValues, ","); //$NON-NLS-1$
+		while (stok.hasMoreTokens()) {
+			String candidate = stok.nextToken();
+			if (locale.indexOf(candidate) == 0)
+				return true;
+			if (candidate.indexOf(locale) == 0)
+				return true;
+		}
+		return false;
+	}
+
+	
+	/*
+	 * 
+	 */
+	private static void appendEscapedChar(StringBuffer buffer, char c) {
+		String replacement = getReplacement(c);
+		if (replacement != null) {
+			buffer.append('&');
+			buffer.append(replacement);
+			buffer.append(';');
+		} else {
+			if ((c >= ' ' && c <= 0x7E) || c == '\n' || c == '\r' || c == '\t') {
+				buffer.append(c);
+			} else {
+				buffer.append("&#"); //$NON-NLS-1$
+				buffer.append(Integer.toString(c));
+				buffer.append(';');
+			}
+		}
+	}
+
+	/*
+	 * 
+	 */
+	public static String xmlSafe(String s) {
+		StringBuffer result = new StringBuffer(s.length() + 10);
+		for (int i = 0; i < s.length(); ++i)
+			appendEscapedChar(result, s.charAt(i));
+		return result.toString();
+	}
+	
+	/*
+	 * 
+	 */
+	private static String getReplacement(char c) {
+		// Encode special XML characters into the equivalent character references.
+		// These five are defined by default for all XML documents.
+		switch (c) {
+			case '<' :
+				return "lt"; //$NON-NLS-1$
+			case '>' :
+				return "gt"; //$NON-NLS-1$
+			case '"' :
+				return "quot"; //$NON-NLS-1$
+			case '\'' :
+				return "apos"; //$NON-NLS-1$
+			case '&' :
+				return "amp"; //$NON-NLS-1$
+		}
+		return null;
+	}
+	
+	public static boolean isSameTimestamp(URL url, long timestamp) {	
+		try {
+			if (UpdateCore.getPlugin().getUpdateSession().isVisited(url)) {
+				return true;
+			}
+			URL resolvedURL = URLEncoder.encode(url);
+			IResponse response = ConnectionFactory.get(resolvedURL);
+			long remoteLastModified = response.getLastModified();
+			// 2 seconds tolerance, as some OS's may round up the time stamp
+			// to the closest second. For safety, we make it 2 seconds.
+			return Math.abs(remoteLastModified - timestamp)/1000 <= 2;
+		} catch (MalformedURLException e) {
+			return false;
+		} catch (IOException e) {
+			return false;
+		}
+	}
+	/**
+	 * The file is associated with a lookup key.
+	 * @param key optional lookup key, or <code>null</code>.
+	 * @param temp the local working file
+	 */
+	public synchronized static void mapLocalFileFragment(String key, FileFragment temp) {
+		// create file association 
+		if (key != null) {
+			if (localFileFragmentMap == null)
+				localFileFragmentMap = new HashMap();
+			localFileFragmentMap.put(key, temp);
+		}
+	}
+
+	/**
+	 * The file is associated with a lookup key.
+	 * @param key optional lookup key, or <code>null</code>.
+	 */
+	public synchronized static void unMapLocalFileFragment(String key) {
+		// remove file association 
+		if (key != null && localFileFragmentMap !=null) {
+			localFileFragmentMap.remove(key);
+		}
+	}
+	
+	/**
+	 * Returns a previously cached local file (in temporary area) matching the
+	 * specified key. 
+	 * 
+	 * @param key lookup key
+	 * @return cached file, or <code>null</code>.
+	 */
+	public static synchronized FileFragment lookupLocalFileFragment(String key) {
+		if (localFileFragmentMap == null)
+			return null;
+		return (FileFragment) localFileFragmentMap.get(key);
+	}
+	
+	/**
+	 * Copies specified input stream to the output stream. Neither stream
+	 * is closed as part of this operation.
+	 * 
+	 * @param is input stream
+	 * @param os output stream
+	 * @param monitor progress monitor
+     * @param expectedLength - if > 0, the number of bytes from InputStream will be verified
+	 * @@return the offset in the input stream where copying stopped. Returns -1 if end of input stream is reached.
+	 * @since 2.0
+	 */
+	public static long copy(InputStream is, OutputStream os, InstallMonitor monitor, long expectedLength) {
+		byte[] buf = getBuffer();
+		long offset=0;
+		try {
+			int len = is.read(buf);
+			int nextIncrement = 0;
+			while (len != -1) {
+				os.write(buf, 0, len);
+					offset += len;
+				if (monitor != null) {
+					nextIncrement += len;
+					// update monitor periodically
+					if (nextIncrement >= INCREMENT_SIZE){ 	
+						monitor.incrementCount(nextIncrement);
+						nextIncrement = 0;
+					}
+					if (monitor.isCanceled()) {
+						return offset;
+					}
+				}
+				if (expectedLength > 0 && offset == expectedLength) {
+					// everything read do not return offset, otherwise trying
+					// to read again from this offset will result in HTTP 416
+					break;
+				}
+				
+				len = is.read(buf);
+			}
+			if (nextIncrement > 0 && monitor != null)
+				monitor.incrementCount(nextIncrement);
+			if(expectedLength>0 && offset!=expectedLength)
+				throw new IOException(NLS.bind(Messages.UpdateManagerUtils_inputStreamEnded, (new String[] { String.valueOf(offset), String.valueOf(expectedLength) })));
+			return -1;
+		} catch(IOException e){
+			// Log the actual error, as this is no longer
+			// passed up the calling stack
+			UpdateCore.log(Messages.UpdateManagerUtils_copy + offset, e); 
+			return offset;
+		} finally {
+			freeBuffer(buf);
+		}
+	}
+
+	private static synchronized byte[] getBuffer() {
+		if (bufferPool == null) {
+			return new byte[BUFFER_SIZE];
+		}
+
+		try {
+			return (byte[]) bufferPool.pop();
+		} catch (EmptyStackException e) {
+			return new byte[BUFFER_SIZE];
+		}
+	}
+
+	private static synchronized void freeBuffer(byte[] buf) {
+		if (bufferPool == null)
+			bufferPool = new Stack();
+		bufferPool.push(buf);
+	}
+	
+	
+	/**
+	 * Returns a list of fragments. Zero length if no fragments.
+	 * @param bundle the bundle to get fragments for
+	 */
+	public static FragmentEntry[] getFragments(Bundle bundle) {
+		PackageAdmin pkgAdmin = UpdateCore.getPlugin().getPackageAdmin();
+		Bundle[] fragmentBundles = pkgAdmin.getFragments(bundle);
+		if (fragmentBundles == null) 
+			return noFragments;
+		
+		FragmentEntry[] fragments = new FragmentEntry[fragmentBundles.length];
+		for (int i = 0; i < fragments.length; i++) {
+			fragments[i] = new FragmentEntry((String) fragmentBundles[i]
+					.getHeaders().get(Constants.BUNDLE_SYMBOLICNAME),
+					(String) fragmentBundles[i].getHeaders().get(
+							Constants.BUNDLE_VERSION), Platform
+							.getResourceString(fragmentBundles[i],
+									(String) fragmentBundles[i].getHeaders()
+											.get(Constants.BUNDLE_VERSION)),
+					fragmentBundles[i].getLocation());
+		}
+		return fragments;	
+	}
+	
+	public static String getWritableXMLString(String value) {
+		StringBuffer buf = new StringBuffer();
+		if(value == null)
+			return buf.toString();
+		for (int i = 0; i < value.length(); i++) {
+			char c = value.charAt(i);
+			switch (c) {
+				case '&' :
+					buf.append("&amp;"); //$NON-NLS-1$
+					break;
+				case '<' :
+					buf.append("&lt;"); //$NON-NLS-1$
+					break;
+				case '>' :
+					buf.append("&gt;"); //$NON-NLS-1$
+					break;
+				case '\'' :
+					buf.append("&apos;"); //$NON-NLS-1$
+					break;
+				case '\"' :
+					buf.append("&quot;"); //$NON-NLS-1$
+					break;
+				case 0x00 :
+					buf.append(" "); //$NON-NLS-1$
+					break;						
+				default :
+					buf.append(c);
+					break;
+			}
+		}
+		return buf.toString();
+	}
+	
+	public static LiteFeature[] getLightFeatures(ExtendedSite site) {
+		
+		URL fullDigestURL;
+		try {
+			fullDigestURL = getFullDigestURL( site, Locale.getDefault().getCountry(), Locale.getDefault().getLanguage());
+		} catch (MalformedURLException e) {
+			UpdateCore.log("Could not access digest on the site: " + e.getMessage(), null); //$NON-NLS-1$
+			return null;
+		}
+		
+		Digest digest = new Digest( fullDigestURL);
+		try {
+			LiteFeature[] features =  (LiteFeature[])digest.parseDigest();
+			for(int i = 0; i < features.length; i++) {
+				features[i].setSite(site);
+			}
+			return features;
+		} catch(Exception e){ 
+			UpdateCore.log("Digest could not be parsed:" + e.getMessage(), null); //$NON-NLS-1$
+			return null;
+		}
+	}
+	
+	private static URL getFullDigestURL(ExtendedSite site, String country, String language) throws MalformedURLException {
+		
+		String digestURL = (site.getDigestURL().endsWith("/")? site.getDigestURL(): site.getDigestURL() + "/"); //$NON-NLS-1$ //$NON-NLS-2$ 
+		
+		if (digestURL.indexOf("://") == -1) { //$NON-NLS-1$
+			String siteURL = site.getLocationURL().toExternalForm();
+			if (siteURL.endsWith(Site.SITE_XML)) {
+				siteURL = siteURL.substring(0, siteURL.length() - Site.SITE_XML.length());
+			} 
+			if (digestURL.equals("/")) { //$NON-NLS-1$
+				digestURL = siteURL;
+			} else {
+				if (digestURL.startsWith("/")) { //$NON-NLS-1$
+					digestURL = digestURL.substring(1, digestURL.length());
+				}
+				digestURL = siteURL + digestURL;
+			}
+		}
+		
+		digestURL += "digest";  //$NON-NLS-1$
+		
+		if ( isLocalSupported(site, country, language)) {
+			return new URL(digestURL + "_" + language + "_" + country + ".zip"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		}
+		if ( isLangaugeSupported(site, language)) {
+			return new URL(digestURL + "_" + language + ".zip"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		return new URL(digestURL + ".zip"); //$NON-NLS-1$
+	}
+
+	private static boolean isLangaugeSupported(ExtendedSite site, String language) {
+		String[] availableLanguages =  site.getAvailableLocals();
+		if ((availableLanguages == null) || (availableLanguages.length == 0)) {
+			return false;
+		}
+		for(int i = 0; i < availableLanguages.length; i++) {
+			if (availableLanguages[i].equals(language)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private static boolean isLocalSupported(ExtendedSite site, String country, String language) {
+		String localeCode = language + "_" + country; //$NON-NLS-1$
+		String[] availableLocals =  site.getAvailableLocals();
+		if ((availableLocals == null) || (availableLocals.length == 0)) {
+			return false;
+		}
+		for(int i = 0; i < availableLocals.length; i++) {
+			if (availableLocals[i].equals(localeCode)) {
+				return true;
+			}
+		}
+		return false;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdatePreferencesInitializer.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdatePreferencesInitializer.java
new file mode 100644
index 0000000..3d5a5db
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdatePreferencesInitializer.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+
+/**
+ * Class to initialize the preferences for the Update core plugin.
+ */
+public class UpdatePreferencesInitializer extends AbstractPreferenceInitializer {
+
+	/**
+	 * Default constructor
+	 */
+	public UpdatePreferencesInitializer() {
+		super();
+	}
+
+	/**
+	 * Initializes the default preferences settings for this plug-in.
+	 * <p>
+	 * This method is called sometime after the preference store for this
+	 * plug-in is created. Default values are never stored in preference
+	 * stores; they must be filled in each time. This method provides the
+	 * opportunity to initialize the default values.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method does nothing. A subclass that needs
+	 * to set default values for its preferences must reimplement this method.
+	 * Default values set at a later point will override any default override
+	 * settings supplied from outside the plug-in (product configuration or
+	 * platform start up).
+	 * </p>
+	 */
+	public void initializeDefaultPreferences() {
+		Plugin plugin = UpdateCore.getPlugin();
+		plugin.getPluginPreferences().setDefault(UpdateCore.P_CHECK_SIGNATURE, true);
+		plugin.getPluginPreferences().setDefault(UpdateCore.P_AUTOMATICALLY_CHOOSE_MIRROR, false);
+		plugin.getPluginPreferences().setDefault(UpdateCore.P_HISTORY_SIZE, UpdateCore.DEFAULT_HISTORY);
+		plugin.getPluginPreferences().setDefault(UpdateCore.P_UPDATE_VERSIONS, UpdateCore.EQUIVALENT_VALUE);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateSession.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateSession.java
new file mode 100644
index 0000000..9b2cb64
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateSession.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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 - Initial API and implementation
+ *     James D Miles (IBM Corp.) - bug 191783, NullPointerException in FeatureDownloader
+ *******************************************************************************/
+
+package org.eclipse.update.internal.core;
+
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public class UpdateSession {
+	
+	private boolean enabled = false;
+	private Set visitedURLs = Collections.synchronizedSet(new HashSet());
+	
+	UpdateSession() {
+	}
+	
+	public boolean isVisited(URL url) {
+		if (!enabled)
+			return false;
+		return visitedURLs.contains(url.toExternalForm());
+	}
+
+	public void markVisited(URL url) {
+		if (!enabled)
+			return ;
+		visitedURLs.add(url.toExternalForm());
+	}
+	
+	/*
+	 * Session will not start caching URLs prior to calling this
+	 * method. If you want to use update session facility make sure
+	 * you call this method first
+	 */
+	public void reset() {
+		this.enabled = true;
+		visitedURLs.clear();
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateSiteFeatureReference.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateSiteFeatureReference.java
new file mode 100644
index 0000000..1a906a5
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateSiteFeatureReference.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.update.core.*;
+
+/**
+ * Feature reference on an update site.
+ * @since 3.1
+ */
+public class UpdateSiteFeatureReference extends SiteFeatureReference {
+    private String os;
+    private String ws;
+    private String nl;
+    private String arch;
+    private String patch;  
+
+    /**
+     * Get optional operating system specification as a comma-separated string.
+     *
+     * @return the operating system specification string, or <code>null</code>.
+     * @since 3.1
+     */
+    public String getOS() {
+        return os;
+    }
+
+
+    /**
+     * Get optional windowing system specification as a comma-separated string.
+     *
+     * @return the windowing system specification string, or <code>null</code>.
+     * @since 3.1
+     */
+    public String getWS() {
+        return ws;
+    }
+
+
+    /**
+     * Get optional system architecture specification as a comma-separated string.
+     *
+     * @return the system architecture specification string, or <code>null</code>.
+     * @since 3.1
+     */
+    public String getOSArch() {
+        return arch;
+    }
+
+
+    /**
+     * Get optional locale specification as a comma-separated string.
+     *
+     * @return the locale specification string, or <code>null</code>.
+     * @since 3.1
+     */
+    public String getNL() {
+        return nl;
+    }
+
+    /**
+     * Sets the operating system specification.
+     * Throws a runtime exception if this object is marked read-only.
+     *
+     * @param os operating system specification as a comma-separated list
+     * @since 3.1
+     */
+    public void setOS(String os) {
+        assertIsWriteable();
+        this.os = os;
+    }
+
+
+    /**
+     * Sets the windowing system specification.
+     * Throws a runtime exception if this object is marked read-only.
+     *
+     * @param ws windowing system specification as a comma-separated list
+     * @since 3.1
+     */
+    public void setWS(String ws) {
+        assertIsWriteable();
+        this.ws = ws;
+    }
+
+
+    /**
+     * Sets the locale specification.
+     * Throws a runtime exception if this object is marked read-only.
+     *
+     * @param nl locale specification as a comma-separated list
+     * @since 3.1
+     */
+    public void setNL(String nl) {
+        assertIsWriteable();
+        this.nl = nl;
+    }
+
+
+    /**
+     * Sets the system architecture specification.
+     * Throws a runtime exception if this object is marked read-only.
+     *
+     * @param arch system architecture specification as a comma-separated list
+     * @since 3.1
+     */
+    public void setArch(String arch) {
+        assertIsWriteable();
+        this.arch = arch;
+    }
+
+    /**
+     * Returns the patch mode.
+     * @since 3.1
+     */
+    public String getPatch() {
+        return patch;
+    }
+
+
+    /**
+     * Sets the patch mode.
+     * @since 3.1
+     */
+    public void setPatch(String patch) {
+        this.patch = patch;
+    }
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateSiteIncludedFeatureReference.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateSiteIncludedFeatureReference.java
new file mode 100644
index 0000000..372d74f
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/UpdateSiteIncludedFeatureReference.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import org.eclipse.update.core.*;
+
+/**
+ * Feature reference on an update site.
+ * @since 3.1
+ */
+public class UpdateSiteIncludedFeatureReference extends IncludedFeatureReference{
+    private String os;
+    private String ws;
+    private String nl;
+    private String arch;
+    private String patch;
+ 
+ public UpdateSiteIncludedFeatureReference() {
+  super();
+ }
+
+    public UpdateSiteIncludedFeatureReference(IIncludedFeatureReference include) {
+  super(include);
+ }
+
+
+ /**
+     * Get optional operating system specification as a comma-separated string.
+     *
+     * @return the operating system specification string, or <code>null</code>.
+     * @since 3.1
+     */
+    public String getOS() {
+        return os;
+    }
+
+
+    /**
+     * Get optional windowing system specification as a comma-separated string.
+     *
+     * @return the windowing system specification string, or <code>null</code>.
+     * @since 3.1
+     */
+    public String getWS() {
+        return ws;
+    }
+
+
+    /**
+     * Get optional system architecture specification as a comma-separated string.
+     *
+     * @return the system architecture specification string, or <code>null</code>.
+     * @since 3.1
+     */
+    public String getOSArch() {
+        return arch;
+    }
+
+
+    /**
+     * Get optional locale specification as a comma-separated string.
+     *
+     * @return the locale specification string, or <code>null</code>.
+     * @since 3.1
+     */
+    public String getNL() {
+        return nl;
+    }
+
+    /**
+     * Sets the operating system specification.
+     * Throws a runtime exception if this object is marked read-only.
+     *
+     * @param os operating system specification as a comma-separated list
+     * @since 3.1
+     */
+    public void setOS(String os) {
+        assertIsWriteable();
+        this.os = os;
+    }
+
+
+    /**
+     * Sets the windowing system specification.
+     * Throws a runtime exception if this object is marked read-only.
+     *
+     * @param ws windowing system specification as a comma-separated list
+     * @since 3.1
+     */
+    public void setWS(String ws) {
+        assertIsWriteable();
+        this.ws = ws;
+    }
+
+
+    /**
+     * Sets the locale specification.
+     * Throws a runtime exception if this object is marked read-only.
+     *
+     * @param nl locale specification as a comma-separated list
+     * @since 3.1
+     */
+    public void setNL(String nl) {
+        assertIsWriteable();
+        this.nl = nl;
+    }
+
+
+    /**
+     * Sets the system architecture specification.
+     * Throws a runtime exception if this object is marked read-only.
+     *
+     * @param arch system architecture specification as a comma-separated list
+     * @since 3.1
+     */
+    public void setArch(String arch) {
+        assertIsWriteable();
+        this.arch = arch;
+    }
+
+    /**
+     * Returns the patch mode.
+     * @since 3.1
+     */
+    public String getPatch() {
+        return patch;
+    }
+
+
+    /**
+     * Sets the patch mode.
+     * @since 3.1
+     */
+    public void setPatch(String patch) {
+        this.patch = patch;
+    }
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/Volume.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/Volume.java
new file mode 100644
index 0000000..6bd66de
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/Volume.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core;
+
+import java.io.File;
+
+import org.eclipse.update.configuration.IVolume;
+import org.eclipse.update.core.model.ModelObject;
+
+/**
+ * Default implementation of a IVolume
+ */
+public class Volume extends ModelObject implements IVolume {
+
+	private long size;
+	private int type;
+	private String label;
+	private File root;
+
+	/**
+	 * Constructor for Volume.
+	 */
+	public Volume(File root,String label,int type,long size) {
+		super();
+		this.root = root;
+		this.label = label;
+		this.type = type;
+		this.size = size;
+	}
+
+	/**
+	 * @see IVolume#getFreeSpace()
+	 */
+	public long getFreeSpace() {
+		return size;
+	}
+
+	/**
+	 * @see IVolume#getLabel()
+	 */
+	public String getLabel() {
+		return label;
+	}
+
+	/**
+	 * @see IVolume#getType()
+	 */
+	public int getType() {
+		return type;
+	}
+
+	/**
+	 * @see IVolume#getFile()
+	 */
+	public File getFile() {
+		return root;
+	}
+
+	public Object getAdapter(Class arg0) {
+		return null;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/AbstractResponse.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/AbstractResponse.java
new file mode 100644
index 0000000..c82bb32
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/AbstractResponse.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.core.connection;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLConnection;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.update.internal.core.UpdateCore;
+
+/**
+ * @author btripkov
+ *
+ */
+public abstract class AbstractResponse implements IResponse {
+
+	private static final long POLLING_INTERVAL = 200;
+	protected URLConnection connection;
+
+	protected InputStream openStreamWithCancel(URLConnection urlConnection, IProgressMonitor monitor) throws IOException, CoreException, TooManyOpenConnectionsException {
+	
+		ConnectionThreadManager.StreamRunnable runnable =
+			new ConnectionThreadManager.StreamRunnable(urlConnection);
+		Thread t = ConnectionThreadManagerFactory.getConnectionManager().getConnectionThread(
+				runnable);
+		t.start();
+		InputStream is = null;
+		try {
+			for (;;) {
+				if (monitor.isCanceled()) {
+					runnable.disconnect();
+	                connection = null;
+					break;
+				}
+				if (runnable.getInputStream() != null || !t.isAlive()) {
+					is = runnable.getInputStream();
+					break;
+				}
+				if (runnable.getIOException() != null) 
+					throw runnable.getIOException();
+				if (runnable.getException() != null) 
+						throw new CoreException(new Status(IStatus.ERROR,
+															UpdateCore.getPlugin().getBundle().getSymbolicName(), 
+															IStatus.OK,
+															runnable.getException().getMessage(), 
+															runnable.getException()));
+				t.join(POLLING_INTERVAL);
+				}
+		} catch (InterruptedException e) {
+		}
+		return is;
+	}
+
+	
+	
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/ConnectionFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/ConnectionFactory.java
new file mode 100644
index 0000000..6c2e3e0
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/ConnectionFactory.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.core.connection;
+
+import java.io.IOException;
+import java.net.URL;
+
+public class ConnectionFactory {
+
+	
+	public static IResponse get(URL url) throws IOException {
+		//Request request = null;
+		IResponse response = null;
+		
+		if ("file".equals(url.getProtocol())) { //$NON-NLS-1$
+			response = new FileResponse(url);
+		} else if (url != null && url.getProtocol().startsWith("http")) { //$NON-NLS-1$
+			response = new HttpResponse(url);
+		} else {
+			response = new OtherResponse(url);
+		}
+
+		return response;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/ConnectionThreadManager.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/ConnectionThreadManager.java
new file mode 100644
index 0000000..d747cac
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/ConnectionThreadManager.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core.connection;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.core.UpdateCore;
+
+/**
+ * This class manages threads that are dispatched to 
+ * obtained a valid input stream from an HTTP connection.
+ * Since obtaining an input stream is an I/O operation
+ * that may block for a long time, it is performed
+ * on a separate thread to keep the UI responsive.
+ * <p>
+ * In case that a connection blocks and does not
+ * terminate with an IOException after a timeout, 
+ * active threads may accumulate. The manager will
+ * refuse to create more than MAX_COUNT threads and
+ * instead will throw a CoreException with a child
+ * status object for each connection that is still pending.
+ * <p>
+ * If the connection is responsive but slow, the user
+ * may cancel it. In that case, the manager will
+ * close the stream to avoid resource leak.
+ */
+public class ConnectionThreadManager {
+	
+	// set connection timeout to 1 minute
+	private static final String CONNECT_TIMEOUT = "60000"; //$NON-NLS-1$
+	// set read timeout to 1 minute
+	private static final String READ_TIMEOUT = "60000"; //$NON-NLS-1$
+	// max number of active threads
+	private static final int MAX_COUNT = 9;
+	private List threads = new ArrayList(MAX_COUNT);
+	
+	
+
+	public static class StreamRunnable implements Runnable {
+		
+		private URLConnection urlConnection;
+		private IOException ioException;
+		private Exception exception;
+		private InputStream is;
+		private boolean disconnected;
+
+		public StreamRunnable(URLConnection urlConnection) {
+			this.urlConnection = urlConnection;
+		}
+
+		public InputStream getInputStream() {
+			return is;
+		}
+
+		public URL getURL() {
+			return urlConnection.getURL();
+		}
+
+		public IOException getIOException() {
+			return ioException;
+		}
+		
+		public Exception getException() {
+			return exception;
+		}
+
+		public void disconnect() {
+			if (urlConnection instanceof HttpURLConnection)
+				((HttpURLConnection)urlConnection).disconnect();
+			disconnected = true;
+		}
+
+		public void run() {
+			try {
+				is = urlConnection.getInputStream();
+				if (disconnected) {
+					// The connection was slow, but returned
+					// a valid input stream. However,
+					// the user canceled the connection
+					// so we must close to avoid 
+					// resource leak.
+					if (is != null) {
+						try {
+							is.close();
+						} catch (IOException ex) {
+							// at this point, we don't care
+						} finally {
+							is = null;
+						}
+					}
+				}
+			} catch (IOException e) {
+				ioException = e;
+			} catch (Exception e) {
+				exception = e;
+			} finally {
+				//threads.
+			}
+		}
+	}
+
+	
+	class ConnectionThread extends Thread {
+		
+		private StreamRunnable runnable;
+		
+		public ConnectionThread(StreamRunnable runnable) {
+			super(runnable, "update-connection"); //$NON-NLS-1$
+			this.runnable = runnable;
+		}
+
+		public StreamRunnable getRunnable() {
+			return runnable;
+		}
+	}
+
+	public ConnectionThreadManager() {
+		// In case we are running Sun's code.
+		setIfNotDefaultProperty("sun.net.client.defaultConnectTimeout", CONNECT_TIMEOUT); //$NON-NLS-1$
+		setIfNotDefaultProperty("sun.net.client.defaultReadTimeout", READ_TIMEOUT);  //$NON-NLS-1$
+	}
+	
+	private void setIfNotDefaultProperty(String key, String value) {
+		String oldValue = System.getProperty(key);
+		if (oldValue==null || oldValue.equals("-1")) //$NON-NLS-1$
+			System.setProperty(key, value);
+	}
+
+	public Thread getConnectionThread(StreamRunnable runnable) throws CoreException {
+		
+		validateExistingThreads();
+	
+		//if (threads == null)
+		//	threads = new Vector();
+		Thread t = new Thread(runnable);
+		t.setDaemon(true);
+		threads.add(t);
+		return t;
+	}
+
+	/*
+	 * Removes threads that are not alive any more from the 
+	 * list and ensures that there are at most MAX_COUNT threads
+	 * still working.
+	 */
+	private void validateExistingThreads() throws CoreException {
+		
+		if ((threads == null) || (threads.size() == 0))
+			return;
+		
+		int aliveCount = purgeTerminatedThreads();
+
+		if (aliveCount > MAX_COUNT) {
+			ArrayList children = new ArrayList();
+			String pluginId =
+				UpdateCore.getPlugin().getBundle().getSymbolicName();
+			for (int i = 0; i < threads.size(); i++) {
+				ConnectionThread t = (ConnectionThread) threads.get(i);
+				String url = t.getRunnable().getURL().toString();
+				IStatus status =
+					new Status(
+						IStatus.ERROR,
+						pluginId,
+						IStatus.OK,
+						NLS.bind(Messages.ConnectionThreadManager_unresponsiveURL, (new String[] { url })),
+						null);
+				children.add(status);
+			}
+			MultiStatus parentStatus =
+				new MultiStatus(
+					pluginId,
+					IStatus.OK,
+					(IStatus[]) children.toArray(new IStatus[children.size()]),
+					Messages.ConnectionThreadManager_tooManyConnections, 
+					null);
+			throw new CoreException(parentStatus);
+		}
+	}
+	
+	/*
+	 * Removes terminated threads from the list and returns
+	 * the number of those still active.
+	 */
+	
+	private int purgeTerminatedThreads() {
+		
+		if (threads.size() == 0) {
+			return 0;
+		}
+		
+		int aliveCount = 0;
+
+		Object[] array = threads.toArray();
+		for (int i = 0; i < array.length; i++) {
+			Thread t = (Thread) array[i];
+			if (!t.isAlive())
+				threads.remove(t);
+			else
+				aliveCount++;
+		}
+		return aliveCount;
+	}
+
+	public void shutdown() {
+		// We might want to kill the active threads but
+		// this is not really necessary since they are all
+		// daemons and will not prevent JVM to terminate.
+		threads.clear();
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/ConnectionThreadManagerFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/ConnectionThreadManagerFactory.java
new file mode 100644
index 0000000..3257ead
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/ConnectionThreadManagerFactory.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.core.connection;
+
+public class ConnectionThreadManagerFactory {
+
+	
+	//Connection manager
+	private static ConnectionThreadManager connectionManager;
+	
+	/**
+	 * Returns the manager that manages URL connection threads.
+	 */
+	public static ConnectionThreadManager getConnectionManager() {
+		
+		if (connectionManager == null)
+			connectionManager = new ConnectionThreadManager();
+		return connectionManager;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/FileResponse.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/FileResponse.java
new file mode 100644
index 0000000..6facd86
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/FileResponse.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core.connection;
+import org.eclipse.update.internal.core.UpdateCore;
+
+import java.io.*;
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+
+public class FileResponse implements IResponse {
+
+	protected URL url;
+	protected long lastModified;
+
+	protected FileResponse(URL url) {
+		this.url = url;
+	}
+
+	public InputStream getInputStream() throws IOException {
+		return url.openStream();
+	}
+
+	public InputStream getInputStream(IProgressMonitor monitor)
+		throws IOException, CoreException {
+		return getInputStream();
+	}
+
+	public long getContentLength() {
+		return 0;
+	}
+
+	public int getStatusCode() {
+		return UpdateCore.HTTP_OK;
+	}
+	
+	public void close() {
+		// nothing to close
+	}
+
+	public String getStatusMessage() {
+		return ""; //$NON-NLS-1$
+	}
+
+	public long getLastModified() {
+		if (lastModified == 0) {
+			File f = new File(url.getFile());
+			if (f.isDirectory())
+				f = new File(f, "site.xml"); //$NON-NLS-1$
+			lastModified = f.lastModified();
+		}
+		return lastModified;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/HttpResponse.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/HttpResponse.java
new file mode 100644
index 0000000..a3cfa3a
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/HttpResponse.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core.connection;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.core.UpdateCore;
+
+public class HttpResponse extends AbstractResponse {
+	/**
+	 * Monitored InputStream.  Upon IOException, discards
+	 * connection so it is not reused.
+	 *
+	 */
+	private class MonitoringInputStream extends FilterInputStream {
+		private URLConnection connection;
+
+		public MonitoringInputStream(InputStream in, URLConnection connection) {
+			super(in);
+			this.connection = connection;
+		}
+
+		public int available() throws IOException {
+			try {
+				return in!=null?super.available():0;
+			} catch (IOException ioe) {
+				connection = null;
+				throw ioe;
+			}
+		}
+
+		public void close() throws IOException {
+			try {
+				if (in!=null)
+					super.close();
+				if (connection instanceof HttpURLConnection) {
+					((HttpURLConnection)connection).disconnect();
+				}
+			} catch (IOException ioe) {
+				connection = null;
+				throw ioe;
+			}
+		}
+
+		public int read() throws IOException {
+			try {
+				return in!=null?super.read():-1;
+			} catch (IOException ioe) {
+				connection = null;
+				throw ioe;
+			}
+		}
+
+		public synchronized void reset() throws IOException {
+			try {
+				if (in!=null)
+					super.reset();
+			} catch (IOException ioe) {
+				connection = null;
+				throw ioe;
+			}
+		}
+
+		public int read(byte[] b) throws IOException {
+			try {
+				return in!=null?super.read(b):-1;
+			} catch (IOException ioe) {
+				connection = null;
+				throw ioe;
+			}
+		}
+
+		public int read(byte[] b, int off, int len) throws IOException {
+			try {
+				return in!=null?super.read(b, off, len):-1;
+			} catch (IOException ioe) {
+				connection = null;
+				throw ioe;
+			}
+		}
+
+		public long skip(long n) throws IOException {
+			try {
+				return in!=null?super.skip(n):0;
+			} catch (IOException ioe) {
+				connection = null;
+				throw ioe;
+			}
+		}
+
+	}
+	
+	protected URL url;
+	protected InputStream in;
+	protected long lastModified;
+	protected long offset;
+
+	protected HttpResponse(URL url) {
+		
+        this.url = url;
+	}
+
+	public InputStream getInputStream() throws IOException {
+		if (in == null && url != null) {
+			if (connection == null || offset > 0)
+				connection = url.openConnection();
+			if (offset > 0)
+				connection.setRequestProperty("Range", "bytes=" + offset + "-"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			try {
+				in = new MonitoringInputStream(connection.getInputStream(), connection);
+			} catch (IOException ioe) {
+				connection = null;
+				throw ioe;
+			}
+			checkOffset();
+		}
+		return in;
+	}
+	
+	public void close() {
+        if( null != in ) {
+                try {
+					in.close();
+				} catch (IOException e) {
+				}
+                in = null;
+        }
+        if (connection!=null) {
+        	((HttpURLConnection)connection).disconnect();
+        	connection = null;
+        }
+	}
+	
+	/**
+	 * @see IResponse#getInputStream(IProgressMonitor)
+	 */
+	public InputStream getInputStream(IProgressMonitor monitor)
+		throws IOException, CoreException, TooManyOpenConnectionsException {
+		if (in == null && url != null) {
+			if (connection == null || offset > 0)
+				connection = url.openConnection();
+			if (offset > 0)
+				connection.setRequestProperty("Range", "bytes=" + offset + "-"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+			if (monitor != null) {
+				try {
+					this.in = new MonitoringInputStream(openStreamWithCancel(
+							connection, monitor), connection);
+				} catch (IOException ioe) {
+					connection = null;
+					throw ioe;
+				}
+			} else {
+				try {
+					this.in = new MonitoringInputStream(connection
+							.getInputStream(), connection);
+				} catch (IOException ioe) {
+					connection = null;
+					throw ioe;
+				}
+			}
+			// this can also be run inside a monitoring thread, but it is safe
+			// to
+			// just call it now, if the input stream has already been obtained
+			checkOffset();
+			if (connection != null) {
+				this.lastModified = connection.getLastModified();
+			}
+		}
+		return in;
+	}
+
+	public long getContentLength() {
+		if (connection != null)
+			return connection.getContentLength();
+		return 0;
+	}
+
+	public int getStatusCode() {
+		if (connection == null)
+			try {
+				connection = url.openConnection();
+			} catch (IOException e) {
+			}
+		if (connection != null) {
+			try {
+				return ((HttpURLConnection) connection).getResponseCode();
+			} catch (IOException e) {
+				UpdateCore.warn("", e); //$NON-NLS-1$
+			}
+		}
+		return UpdateCore.HTTP_OK;
+	}
+
+	public String getStatusMessage() {
+		if (connection != null) {
+			try {
+				return ((HttpURLConnection) connection).getResponseMessage();
+			} catch (IOException e) {
+				UpdateCore.warn("", e); //$NON-NLS-1$
+			}
+		}
+		return ""; //$NON-NLS-1$
+	}
+
+	public long getLastModified() {
+		if (lastModified == 0) {
+			if (connection == null)
+				try {
+					connection = url.openConnection();
+				} catch (IOException e) {
+				}
+			if (connection != null)
+				lastModified = connection.getLastModified();
+		}
+		return lastModified;
+	}
+
+	public void setOffset(long offset) {
+		this.offset = offset;
+	}
+	private void checkOffset() throws IOException {
+		if (offset == 0)
+			return;
+		String range = connection.getHeaderField("Content-Range"); //$NON-NLS-1$
+		//System.out.println("Content-Range=" + range);
+		if (range == null) {
+			//System.err.println("Server does not support ranges");
+			throw new IOException(Messages.HttpResponse_rangeExpected); 
+		} else if (!range.startsWith("bytes " + offset + "-")) { //$NON-NLS-1$ //$NON-NLS-2$
+			//System.err.println("Server returned wrong range");
+			throw new IOException(Messages.HttpResponse_wrongRange); 
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/IResponse.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/IResponse.java
new file mode 100644
index 0000000..f37b819
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/IResponse.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core.connection;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public interface IResponse {
+
+	/**
+	 * Method getInputStream.
+	 * 
+	 * @return InputStream
+	 */
+	public InputStream getInputStream() throws IOException;
+
+	/**
+	 * A special version of 'getInputStream' that can be canceled.
+	 * A monitor thread checks the state of the monitor
+	 * and disconnects the connection if 'isCanceled()' is detected.
+	 * 
+	 * @param monitor
+	 *            the progress monitor
+	 * @return InputStream an opened stream or null if failed.
+	 * @throws IOException
+	 *             if there are problems
+	 * @throws CoreException
+	 *             if no more connection threads are available
+	 */
+	public InputStream getInputStream(IProgressMonitor monitor)
+		throws IOException, CoreException, TooManyOpenConnectionsException;
+
+	/**
+	 * Method getContentLength.
+	 * 
+	 * @return long
+	 */
+	public long getContentLength();
+
+	/**
+	 * Method getStatusCode.
+	 * 
+	 * @return int
+	 */
+	public int getStatusCode();
+
+	/**
+	 * Method getStatusMessage.
+	 * 
+	 * @return String
+	 */
+	public String getStatusMessage();
+
+	/**
+	 * Returns the timestamp of last modification to the resource
+	 * 
+	 * @return
+	 */
+	public long getLastModified();
+	
+	/**
+	 * Close the connection if open.
+	 */
+	public void close();
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/OtherResponse.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/OtherResponse.java
new file mode 100644
index 0000000..fe9d82e
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/OtherResponse.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.core.connection;
+
+import org.eclipse.update.internal.core.UpdateCore;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class OtherResponse extends AbstractResponse {
+
+	protected URL url;
+	protected InputStream in;
+	protected long lastModified;
+
+	protected OtherResponse(URL url) {
+		this.url = url;
+	}
+
+	public InputStream getInputStream() throws IOException {
+		if (in == null && url != null) {
+            if (connection == null)
+                connection = url.openConnection();
+			in = connection.getInputStream();
+			this.lastModified = connection.getLastModified();
+		}
+		return in;
+	}
+	
+	public void close() {
+        if( null != in ) {
+                try {
+					in.close();
+				} catch (IOException e) {
+				}
+                in = null;
+        }
+	}	
+	
+	/**
+	 * @see IResponse#getInputStream(IProgressMonitor)
+	 */
+	public InputStream getInputStream(IProgressMonitor monitor)
+		throws IOException, CoreException {
+		if (in == null && url != null) {
+            if (connection == null)
+                connection = url.openConnection();
+
+			if (monitor != null) {
+				this.in =
+					openStreamWithCancel(connection, monitor);
+			} else {
+				this.in = connection.getInputStream();
+			}
+			if (in != null) {
+				this.lastModified = connection.getLastModified();
+			}
+		}
+		return in;
+	}
+
+	public long getContentLength() {
+		if (connection != null)
+			return connection.getContentLength();
+		return 0;
+	}
+
+	public int getStatusCode() {
+		return UpdateCore.HTTP_OK;
+	}
+
+	public String getStatusMessage() {
+		return ""; //$NON-NLS-1$
+	}
+
+	public long getLastModified() {
+		if (lastModified == 0 && connection != null) {
+			lastModified = connection.getLastModified();
+		}
+		return lastModified;
+	}
+	
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/TooManyOpenConnectionsException.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/TooManyOpenConnectionsException.java
new file mode 100644
index 0000000..a8f846e
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/connection/TooManyOpenConnectionsException.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.core.connection;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+
+public class TooManyOpenConnectionsException extends CoreException {
+
+	private static final long serialVersionUID = 1L;
+	
+	public TooManyOpenConnectionsException(IStatus status) {
+		super(status);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/messages.properties b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/messages.properties
new file mode 100644
index 0000000..c8020cb
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/messages.properties
@@ -0,0 +1,279 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+###############################################################################
+# Install Update Core Properties File
+#
+
+ProductProvider=Update Manager
+BaseSiteFactory_CannotRetriveParentDirectory=Unable to retrieve parent directory for URL \"{0}\".
+ContentReference_UnableToCreateInputStream= Unable to create an input stream for the reference \"{0}\".
+ContentReference_UnableToReturnReferenceAsFile= Unable to return reference \"{0}\" as File.
+ContentReference_UnableToReturnReferenceAsURL= Unable to return reference \"{0}\" as URL.
+ContentReference_HttpNok= Server returned HTTP response code: \"{0} {1}\" for URL: {2}.
+ContentReference_FileDoesNotExist=The file \"{0}\" does not exist on the file system.
+Feature_SiteAlreadySet= Internal Error: Site already set for the feature \"{0}\".
+Feature_TaskInstallFeatureFiles= Installing feature files:
+Feature_TaskInstallPluginFiles= Installing plug-in \"{0}\" files:
+Feature_NoContentProvider= Internal Error. The feature \"{0}\" does not have a content provider.
+Feature_NoFeatureContentConsumer= Internal Error. The Feature \"{0}\" does not have a content consumer.
+Feature_NoURL= Unknown URL.
+Feature_FeatureVersionToString= Feature: \"{0}\" Version: \"{1}\".
+Feature_InstallationCancelled= Installation has been cancelled by the User.
+Feature_UnableToInitializeFeatureReference= Unable to initialize feature reference for versioned identifier \"{0}\".
+FeatureContentProvider_Downloading= Downloading:
+FeatureContentProvider_UnableToRetrieve= Unable to retrieve remote reference \"{0}\".
+FeatureContentProvider_UnableToCreate= Unable to create local file \"{0}\".
+FeatureContentProvider_ExceptionDownloading = An exception occurred while downloading feature from \"{0}\".
+InstallHandler_unableToCreateHandler = Unable to create custom install handler for feature \"{0}\".
+InstallHandler_notFound = Custom install handler required by feature \"{0}\" was not found.
+InstallHandler_invalidHandler = Feature \"{0}\" contains invalid custom install handler.
+InstallHandler_callException = Error reported by custom install handler for feature \"{0}\".
+InstallHandler_error = Unable to complete action for feature \"{0}\" due to errors.
+InstallCommand_site=site {0}
+InstallMonitor_DownloadSize = ({0}K bytes)
+InstallMonitor_DownloadSizeLong = ({0}K of {1}K bytes)
+JarContentReference_Unpacking= Unpacking:
+Site_CannotFindCategory= Unable to find category: \"{0}\" in Site: \"{1}\".
+Site_NoCategories= The Site does not contain any categories.
+Site_NoContentProvider= Internal Error. Content Provider not set for Site: \"{0}\".
+VersionedIdentifier_IdOrVersionNull= Internal Error. Unable to create an Identifier. The unique identifier or the version is null or empty: unique identifier=\"{0}\" version=\"{1}\".
+SiteFile_CannotRemovePlugin= Unable to remove plug-in: \"{0}\" from Site: \"{1}\".
+SiteFile_CannotRemoveFeature= Unable to remove feature: \"{0}\" from Site: \"{1}\".
+SiteFile_UnableToCreateURL= Unable to create URL for location \"{0}\".
+SiteFile_Removing= Removing:
+SiteFileFactory_UnableToCreateURL= Internal Error. Unable to create URL from \"{0}\".
+SiteFileFactory_UnableToAccessSite= Unable to access site
+SiteFileFactory_DirectoryDoesNotExist=The directory \"{0}\" does not exist on the file system.
+DefaultFeatureParser_location= Feature location: {0}
+DefaultFeatureParser_NoFeatureTag= Error parsing feature stream. Unable to find root element \"feature\" in the stream.
+DefaultFeatureParser_WrongParsingStack= Internal Error parsing feature stream. Unexpected Parsing Stack: \"{0}\"
+DefaultFeatureParser_UnknownElement= Error parsing feature stream. Unknown element \"{0}\" in parsing state \"{1}\". Check the validity of the XML file.
+DefaultFeatureParser_TooManyURLtag= Error parsing feature stream. There is more than one \"URL\" element in the XML stream. There should be only one.
+DefaultFeatureParser_UnknownStartState= Internal Error parsing feature stream. Unknown start state \"{0}\".
+DefaultFeatureParser_IdOrVersionInvalid= Error parsing feature stream. The unique identifier or the version is null or empty for the State: \"{2}\": unique identifier=\"{0}\" version=\"{1}\".
+DefaultFeatureParser_MissingId= Error parsing feature stream. The \"id\" tag of the element \"{0}\" is null or empty. Value is required.
+DefaultFeatureParser_ParsingStackBackToInitialState= Internal Error parsing feature stream. Parsing stack back to Initial State.
+DefaultFeatureParser_ElementAlreadySet= Error parsing feature stream. Element: \"{0}\" already set for the feature.
+DefaultFeatureParser_StateIncludeWrongElement= Error parsing feature stream. State: \"{0}\" should not include Element \"{1}\".
+DefaultFeatureParser_RequireStateWithoutImportElement=Error parsing feature stream. State: \"require\" must include at least an \"import\" element.
+DefaultFeatureParser_MissingPatchVersion=Error parsing feature stream. Attribute "version" of the element "import" must be set when "patch" is set to "true".
+DefaultFeatureParser_wrongMatchForPatch=Error parsing feature stream. When attribute "patch" of the element "import" is set to "true", the only valid value for the "match" attribute is "perfect".
+DefaultFeatureParser_patchWithPlugin=Error parsing feature stream. Attribute "patch" can only be used for features.
+DefaultFeatureParser_MultiplePatchImports=Error parsing feature stream. State: "require" must not contain more than one "import" element with the attribute "patch" set to "true".
+DefaultFeatureParser_UnknownEndState= Internal Error parsing feature stream. Unknown end state \"{0}\".
+DefaultFeatureParser_ErrorParsing= Error Parsing feature stream. Error: \"{0}\"
+DefaultFeatureParser_ErrorlineColumnMessage= Error Parsing feature stream. Element \"{0}\" line: \"{1}\" column:\"{2}\". Error: \"{3}\".
+DefaultFeatureParser_ErrorParsingFeature= Error Parsing feature stream.
+DefaultFeatureParser_UnknownState= Unknown State \"{0}\".
+DefaultFeatureParser_NoLicenseText= Error parsing feature stream. State: \"license\" must include some text.
+DefaultFeatureParser_PluginAndFeatureId=One Import statement is incorrect: Both feature and plug-in ID are either null or specified.
+SiteContentProvider_ErrorCreatingURLForArchiveID= Internal Error. Unable to create URL for Archive Identifier \"{0}\" on Site \"{1}\".
+DefaultSiteParser_NoSiteTag= Error parsing site stream. Unable to find root element \"site\" in the stream.
+DefaultSiteParser_WrongParsingStack= Internal Error parsing site stream. Unexpected Parsing Stack: \"{0}\"
+DefaultSiteParser_UnknownElement= Error parsing site stream. Unknown element \"{0}\" in parsing state \"{1}\". Check the validity of the XML file.
+DefaultSiteParser_UnknownStartState= Internal Error parsing site stream. Unknown start state \"{0}\".
+DefaultSiteParser_Missing= Error parsing site stream. The \"{0}\" tag of the element \"{1}\" is null or empty. Value is required.
+DefaultSiteParser_ParsingStackBackToInitialState= Internal Error parsing site stream. Parsing stack back to Initial State.
+DefaultSiteParser_ElementAlreadySet= Error parsing site stream. Element: \"{0}\" already set for the Site.
+DefaultSiteParser_UnknownEndState= Internal Error parsing site stream. Unknown end state \"{0}\".
+DefaultSiteParser_ErrorParsing= Error Parsing site stream. Error: \"{0}\"
+DefaultSiteParser_ErrorlineColumnMessage= Error Parsing site stream. Element \"{0}\" line: \"{1}\" column:\"{2}\". Error: \"{3}\".
+DefaultSiteParser_ErrorParsingSite= Error Parsing site stream.
+DefaultSiteParser_UnknownState= Unknown State \"{0}\".
+DefaultSiteParser_InvalidXMLStream= The XML stream is not a valid default \"site.xml\" file. The root tag is not site.
+ModelObject_ModelReadOnly= Internal Error. The Model Object is read-only.
+SiteModelObject_ErrorParsingSiteStream= Error parsing site stream.
+SiteModelObject_ErrorAccessingSiteStream= Error accessing site stream.
+InstallConfiguration_ErrorDuringFileAccess= Error accessing file: \"{0}\".
+InstallConfigurationParser_FeatureReferenceNoURL= Error Parsing Stream. A feature reference element does not have a URL tag. Value is required.
+FeatureExecutableContentProvider_FileDoesNotExist= The file \"{0}\" does not exist.
+FeatureExecutableContentProvider_InvalidDirectory= The path \"{0}\" is not a valid directory.
+FeatureExecutableContentProvider_UnableToCreateURLFor=Unable to create a URL for \"{0}\".
+FeatureExecutableContentProvider_UnableToRetrieveNonPluginEntry=Error retrieving the non-plug-in entry: \"{0}\".
+FeatureExecutableContentProvider_UnableToRetrieveFeatureEntry=Error retrieving feature entry content reference: \"{0}\".
+FeatureExecutableContentProvider_UnableToRetrievePluginEntry =Error retrieving the plug-in entry: \"{0}\".
+ConfiguredSite_NonInstallableSite= You cannot install in the site \"{0}\". It is considered non updateable.
+ConfiguredSite_NullFeatureToInstall= Internal Error. The feature to be installed is null.
+ConfiguredSite_NonUninstallableSite= You cannot uninstall from the site \"{0}\". It is considered non updateable.
+ConfiguredSite_NoSite= No Site
+ConfiguredSite_CannotFindFeatureToUnconfigure= Internal Error. Unable to disable feature \"{0}\" on site \"{1}\". Cannot find feature.
+ConfiguredSite_CannotFindFeatureToConfigure= Internal Error. Unable to enable feature \"{0}\". Cannot find feature.
+ConfiguredSite_CannotFindPluginEntry= Unable to retrieve Plug-in Entry \"{0}\" on site \"{1}\". Cannot find plug-in entry. Do you want to Continue ?
+ConfiguredSite_MissingPluginsBrokenFeature= Plug-in \"{0}\" version \"{1}\" referenced by this feature is missing.
+ConfiguredSite_UnableToRemoveConfiguredFeature= Unable to remove a enabled feature: \"{0}\" You must disable the feature first.
+ConfiguredSite_UnableToFindFeature= Unable to Find the feature \"{0}\" on this site.
+ConfiguredSite_SiteURLNull=The Site URL is null.
+ConfiguredSite_NonLocalSite=The Site is not on the local file system. Cannot validate.
+ConfiguredSite_NotSameProductId=The site cannot be modified by this product. It is already associated with product: \"{0}\".
+ConfiguredSite_ContainedInAnotherSite=This site is contained in another site: \"{0}\".
+ConfiguredSite_ReadOnlySite=The site is marked as read only.
+ConfiguredSite_UnableResolveURL= Internal Error. Unable to resolve URL \"{0}\".
+ConfiguredSite_UnableToAccessSite= Internal Error. Unable to access platform site \"{0}\".
+FeatureFactory_CreatingError= Error creating feature \"{0}\".
+FeatureModelFactory_ErrorAccesingFeatureStream= Error accessing feature stream.
+FeatureExecutableFactory_NullURL= Error creating feature. The URL used to create the feature is null.
+FeatureExecutableFactory_CannotCreateURL= Error creating feature. Unable to create URL for \"{0}\".
+FeaturePackagedContentProvider_NoManifestFile= Unable to retrieve \"{0}\" in feature located at \"{1}\".
+FeaturePackagedContentProvider_InvalidDirectory= The directory \"{0}\" is not a valid directory.
+FeaturePackagedContentProvider_ErrorRetrieving= Error retrieving \"{0}\".
+FeatureReference_UnableToResolveURL= Internal Error: Unable to resolve model using URL: \"{0}\".
+FeatureTypeFactory_UnableToFindFeatureFactory= Unable to find a feature factory for the extension id \"{0}\".
+InstallConfiguration_UnableToCreateURL= Unable to create URL from \"{0}\".
+InstallConfiguration_UnableToCast= Internal Error. The Configuration Site object is not a subclass of ConfiguredSiteModel
+InstallConfiguration_UnableToSavePlatformConfiguration=Unable to save platform configuration in \"{0}\".
+InstallConfiguration_AlreadyNativelyLinked=The site is already linked.
+InstallConfiguration_AlreadyProductSite=The location is already a product site.
+InstallConfiguration_unableToFindSite=Unable to find site {0} in platform configuration {1}.
+InternalSiteManager_UnableToCreateSiteWithType= Extension Error. The Site Factory of type \"{0}\" cannot access the Site \"{1}\".
+InternalSiteManager_UnableToAccessURL= Unable to access \"{0}\".
+InternalSiteManager_UnableToCreateURL= Unable to create URL from \"{0}\".
+InternalSiteManager_FailedRetryAccessingSite= Failed retry accessing site using default installed format instead of default packaged format.
+InternalSiteManager_ConnectingToSite = Connecting To Site...
+GlobalConsumer_ErrorCreatingFile= Unable to create file \"{0}\".
+SiteFileContentConsumer_UnableToCreateURL= Unable to create URL from \"{0}\".
+SiteFileContentConsumer_UnableToCreateURLForFile= Unable to create URL for the file \"{0}\".
+SiteFileContentConsumer_unableToDelete=Unable to delete {0}
+ContentConsumer_UnableToRename = Internal Error. Unable to rename \"{0}\" to \"{1}\".
+SiteFileFactory_UnableToObtainParentDirectory= Unable obtain the parent directory from the file \"{0}\".
+SiteFileFactory_FileDoesNotExist= Unable to access site \"{0}\". The directory does not exist.
+SiteFileFactory_UnableToCreateURLForFile= Unable to create URL from \"{0}\".
+SiteFileFactory_ErrorParsingFile= Unable to parse file \"{0}\".
+SiteFileFactory_ErrorAccessing= Unable to access file \"{0}\".
+SiteTypeFactory_UnableToFindSiteFactory= Unable to find a site factory for the extension id \"{0}\".
+UpdateManagerUtils_UnableToRemoveFile= Unable to remove \"{0}\" from the file system.
+UpdateManagerUtils_FileAlreadyExists= Unable to create \"{0}\" on the file system. File already exists.
+SiteLocal_UnableToCreateURLFor= Unable to create URL from \"{0}\".
+SiteLocal_UnableToDetermineFeatureStatusSiteNull=Unable to determine status of feature\"{0}\" The site is NULL.
+SiteLocal_TwoVersionSamePlugin1=Plug-in: \"{0}\" version: \"{1}\" referenced by this feature is not included at runtime. Runtime includes plug-in version \"{2}\".
+SiteLocal_TwoVersionSamePlugin2=Plug-in: \"{0}\" version: \"{1}\" referenced by this feature is not included at runtime. Runtime includes plug-in version \"{2}\" supplied by feature \"{3}\" version \"{4}\".
+SiteLocal_FeatureUnHappy=The feature is not configured properly.
+SiteLocal_FeatureHappy=The feature is configured properly.
+SiteLocal_FeatureAmbiguous=The feature may not be configured properly.
+SiteLocal_NestedFeatureUnHappy=Included feature \"{0}\" version \"{1}\" contains problems.
+SiteLocal_NestedFeatureUnavailable=Included feature \"{0}\" is missing.
+SiteLocal_NoPluginVersion=No plug-in: \"{0}\" included at runtime.
+SiteLocal_UnableToDetermineFeatureStatusConfiguredSiteNull=Unable to determine status of feature\"{0}\" The Configured Site is NULL.
+SiteLocal_FeatureDisable=The feature is disabled.
+SiteLocal_FeatureStatusUnknown=Unknown state.
+SiteLocal_NestedFeatureDisable=Included feature \"{0}\" version \"{1}\" is disabled.
+SiteURLFactory_UnableToCreateURL= Internal Error. Unable to create a URL from \"{0}\".
+SiteURLFactory_UnableToAccessSiteStream= Unable to access site: \"{0}\"
+JarVerifier_Verify= Verifying: \"{0}\"
+JarVerifier_UnableToFindEncryption= Unable to find algorithm to verify integrity of KeyStore \"{0}\".
+JarVerifier_UnableToLoadCertificate= Unable to load one or multiples certificates in the KeyStore \"{0}\".
+JarVerifier_UnableToFindProviderForKeystore= Unable to find provider for the KeyStore type \"{0}\".
+JarVerifier_KeyStoreNotLoaded= Internal Error. KeyStore not Initialized/Loaded.
+JarVerifier_UnableToAccessJar= Unable to access JAR file \"{0}\".
+JarVerifier_InvalidFile= The File \"{0}\" is not a valid JAR file. It does not contain a Manifest.
+JarVerifier_InvalidJar= The File \"{0}\" is not a valid JAR file.
+JarVerificationResult_ValidBetween= Valid between \"{0}\" and \"{1}\".
+JarVerificationResult_ExpiredCertificate= * EXPIRED CERTIFICATE *
+JarVerificationResult_CertificateNotYetValid= * CERTIFICATE NOT YET VALID *
+JarVerificationResult_CertificateValid= Valid certificate.
+JarVerificationService_UnsucessfulVerification=Verification of feature unsuccessful. Installation cancelled.
+JarVerificationService_CancelInstall=Installation cancelled.
+UpdateManagerUtils_UnableToLog=Unable to access error recovery log file: \"{0}\".
+ConnectionThreadManager_tooManyConnections = There are too many network connections still active. \
+If you are experiencing network problems, try again later. If the error persists, restart the \
+application.
+ConnectionThreadManager_unresponsiveURL = Still waiting for response: {0}
+IncludedFeatureReference_featureUninstalled= Feature {0} is uninstalled.
+
+# Properties moved mostly from the ui plugin
+
+ActivityConstraints_warning=The current configuration contains errors and this operation can have unpredictable results.
+ActivityConstraints_rootMessage = Requested operation cannot be performed because it would invalidate the current configuration. See details for more information.
+ActivityConstraints_rootMessageInitial = Current configuration contains errors that are not corrected by the requested operation and more errors would be introduced. See details for more information.
+ActivityConstraints_beforeMessage = ----- Current configuration problems -----
+ActivityConstraints_afterMessage = ----- Configuration problems after the operation -----
+ActivityConstraints_platform = Resulting configuration does not contain the platform.
+ActivityConstraints_primary = Resulting configuration does not contain the primary feature.
+ActivityConstaints_prereq_plugin = plug-in
+ActivityConstaints_prereq_feature = feature
+ActivityConstraints_prereq = requires {0} "{1}".
+ActivityConstraints_prereqPerfect = requires {0} "{1} ({2})".
+ActivityConstraints_prereqEquivalent = requires {0} "{1} ({2})", or equivalent.
+ActivityConstraints_prereqCompatible = requires {0} "{1} ({2})", or compatible.
+ActivityConstraints_prereqGreaterOrEqual = requires {0} "{1} ({2})", or later version.
+ActivityConstraints_os = operating system does not match current environment.
+ActivityConstraints_ws = windowing system does not match current environment.
+ActivityConstraints_arch = platform architecture does not match current environment.
+ActivityConstraints_cycle = definition contains a nested features cycle: {0}_{1}prereq
+ActivityConstraints_childMessage = {0} ({1}) {2}
+ActivityConstraints_optionalChild = Feature included in another feature cannot be enabled if the parent is disabled. Enable the parent first.
+ActivityConstraints_exclusive = must be processed separately from other features.
+ActivityConstraints_noLicense = does not have a valid license agreement.
+ActivityConstraints_readOnly = The site is not updateable: {0}.
+ActivityConstraints_platformModified = Platform configuration has been modified outside this program. A restart is recommended.
+DuplicateConflictsDialog_conflict = Version {0} in {1}
+OperationsManager_error_old= {0}: Error while updating the old feature version
+OperationsManager_installing=Initializing...
+OperationsManager_error_uninstall= {0} : Error while uninstalling feature
+Search_networkProblems=Network connection problems encountered during search.
+InstallConfiguration_location_exists = Site already exists.
+InstallLogParser_errors = Errors generated while parsing installation history file.
+SiteLocal_cloneConfig=Error clonning current configuration.
+
+UninstallCommand_featureNotInstalledByUM=Feature not installed by Update Manager: {0}
+
+UpdateManagerUtils_inputStreamEnded=InputStream ended after {0} bytes (expected {1} )
+UpdateSearchRequest_loadingPolicy=Loading update policy ...
+UpdateManagerUtils_copy=UpdateManagerUtils copy() at offset:
+UpdatePolicy_parsePolicy=Errors while parsing update policy
+UpdatePolicy_policyExpected=' is expected.
+UpdateSearchRequest_searching=Searching...
+UpdateSearchRequest_contacting=Contacting {0} ...
+UpdateSearchRequest_checking=Checking {0} ...
+UpdatePolicy_invalidURL=invalid URL -
+UpdatePolicy_nameNoNull= cannot be null.
+UpdatePolicy_UpdatePolicy=Update Policy:
+SiteFile_featureNotRemoved=Feature {0} was not removed
+SiteFile_pluginNotRemoved=Plugin {0} was not removed
+ErrorRecoveryLog_noFiletoRemove=Unable to find file to remove:
+UpdatesSearchCategory_errorSearchingForUpdates=Error while initializing the search for new updates
+Standalone_siteConfigured=Site is already configured:
+Standalone_noSite=Cannot find site:
+Standalone_noSite3=No site specified
+Standalone_noConfiguredSite=Cannot find configured site:
+Standalone_installing=Installing feature
+Standalone_notFoundOrNewer=Feature {0} cannot be found on {1} \nor a newer version is already installed.
+Standalone_duplicate=Duplicate conflicts
+Standalone_installed= Feature {0} has successfully been installed
+Standalone_cannotInstall=Cannot install feature
+Standalone_noFeatures1=There are no unconfigured features with id {0}
+Standalone_noFeatures2=Cannot find unconfigured feature  {0} with version {1}
+Standalone_noFeatures3=There are no configured features with id {0}
+Standalone_noFeatures4=Cannot find configured feature  {0} with version {1}
+Standalone_noConfigSiteForFeature=There are no configured sites for feature {0}
+Standalone_invalidCmd=Invalid command:
+Standalone_connection = Connection error
+Standalone_searching = Searching on:
+Standalone_cmdFailed = Command failed. Please check log file {0} for details.
+Standalone_cmdFailedNoLog = Command failed.
+Standalone_cmdCompleteWithErrors = Command completed with errors. Please check log file {0} for details.
+Standalone_cmdOK = Command completed successfully.
+Standalone_updating = Begin updating
+Standalone_noUpdate = Feature {0} cannot be updated.
+Standalone_updated= Feature {0} has successfully been updated.
+SiteFilePluginContentConsumer_unableToDelete=Unable to delete {0}
+SiteFilePackedPluginContentConsumer_unableToDelete=Unable to delete {0}
+
+JarProcessor_unpackNotFound = The unpack200 command cannot be found.
+JarProcessor_noPackUnpack = Pack, repack or sign cannot be specified with unpack.
+JarProcessor_packNotFound = The pack200 command cannot be found.
+SiteOptimizer_inputNotSpecified = No input file was specified;
+SiteOptimizer_inputFileNotFound = The input file \"{0}\" was not found.
+
+HttpResponse_rangeExpected = Server does not support ranges.
+HttpResponse_wrongRange = Server returned wrong range.
+DefaultSiteParser_mirrors = Error processing update site mirror.
+FeatureExecutableContentProvider_UnableToRetriveArchiveContentRef = Unable to retrieve archive content reference
+SiteCategory_other_label = Other
+SiteCategory_other_description = Features found under this category are either not categorized or their categories could not be found on server.
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorCommand.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorCommand.java
new file mode 100644
index 0000000..9b039c7
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorCommand.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.mirror;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.PluginVersionIdentifier;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.core.JarContentReference;
+import org.eclipse.update.core.SiteFeatureReference;
+import org.eclipse.update.core.SiteFeatureReferenceModel;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.eclipse.update.core.model.InvalidSiteTypeException;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.standalone.ScriptedCommand;
+import org.eclipse.update.standalone.StandaloneUpdateApplication;
+
+/**
+ * Mirrors a remote site locally.
+ */
+public class MirrorCommand extends ScriptedCommand {
+
+	private String featureId;
+	private String featureVersion;
+	private String fromSiteUrl;
+	private String toSiteDir;
+	private String mirrorURL;
+	private boolean ignoreNonPresentPlugins = false;
+	private MirrorSite mirrorSite;
+
+	public MirrorCommand(
+		String featureId,
+		String featureVersion,
+		String fromSiteUrl,
+		String toSiteDir,
+		String mirrorUrl, 
+		String ignoreNonPresentPlugins) {
+		this.featureId = featureId;
+		this.featureVersion = featureVersion;
+		this.fromSiteUrl = fromSiteUrl;
+		this.toSiteDir = toSiteDir;
+		this.mirrorURL = mirrorUrl;
+		this.ignoreNonPresentPlugins = (ignoreNonPresentPlugins != null) && (ignoreNonPresentPlugins.equals("true")); //$NON-NLS-1$
+	}
+
+	/**
+	 * true if success
+	 */
+	public boolean run(IProgressMonitor monitor) {
+		if (!validateParameters()) {
+			return false;
+		}
+
+		try {
+			if (getMirrorSite() == null)
+				return false;
+
+			URL remoteSiteUrl = new URL(fromSiteUrl);
+			ISite remoteSite =
+				SiteManager.getSite(remoteSiteUrl, new NullProgressMonitor());
+
+			ISiteFeatureReference featureReferencesToMirror[] =
+				findFeaturesToMirror(remoteSite);
+			if (featureReferencesToMirror.length == 0) {
+				StandaloneUpdateApplication.exceptionLogged();
+				UpdateCore.log(
+					Utilities.newCoreException(
+						"No matching features found on " + remoteSiteUrl + ".", //$NON-NLS-1$ //$NON-NLS-2$
+						null));
+				return false;
+			}
+
+			mirrorSite.mirrorAndExpose(
+				remoteSite,
+				featureReferencesToMirror,
+				null,
+				mirrorURL);
+			return true;
+		} catch (MalformedURLException e) {
+			StandaloneUpdateApplication.exceptionLogged();
+			UpdateCore.log(e);
+			return false;
+		} catch (CoreException ce) {
+			StandaloneUpdateApplication.exceptionLogged();
+			UpdateCore.log(ce);
+			return false;
+		} finally {
+			JarContentReference.shutdown();
+		}
+	}
+	private boolean validateParameters() {
+		if (fromSiteUrl == null || fromSiteUrl.length() <= 0) {
+			StandaloneUpdateApplication.exceptionLogged();
+			UpdateCore.log(
+				Utilities.newCoreException("from parameter is missing.", null)); //$NON-NLS-1$
+			return false;
+		}
+		try {
+			new URL(fromSiteUrl);
+		} catch (MalformedURLException mue) {
+			StandaloneUpdateApplication.exceptionLogged();
+			UpdateCore.log(
+				Utilities.newCoreException("from must be a valid URL", null)); //$NON-NLS-1$
+			return false;
+		}
+		if (toSiteDir == null || toSiteDir.length() <= 0) {
+			StandaloneUpdateApplication.exceptionLogged();
+			UpdateCore.log(
+				Utilities.newCoreException("to parameter is missing.", null)); //$NON-NLS-1$
+			return false;
+		}
+		return true;
+	}
+	private MirrorSite getMirrorSite()
+		throws MalformedURLException, CoreException {
+		// Create mirror site
+		if (mirrorSite == null) {
+			if (toSiteDir != null) {
+				MirrorSiteFactory factory = new MirrorSiteFactory();
+				System.out.print("Analyzing features already mirrored ..."); //$NON-NLS-1$
+				try {
+					mirrorSite =
+						(MirrorSite) factory.createSite(new File(toSiteDir));
+					mirrorSite.setIgnoreNonPresentPlugins(ignoreNonPresentPlugins);
+				} catch (InvalidSiteTypeException iste) {
+				}
+				System.out.println("  Done."); //$NON-NLS-1$
+			}
+			if (mirrorSite == null) {
+				StandaloneUpdateApplication.exceptionLogged();
+				UpdateCore.log(
+					Utilities.newCoreException(
+						"Mirror site at " + toSiteDir + " cannot be accessed.", //$NON-NLS-1$ //$NON-NLS-2$
+						null));
+				return null;
+			}
+		}
+		return mirrorSite;
+
+	}
+	/**
+	 * Returns subset of feature references on remote site
+	 * as specified by optional featureId and featureVersion
+	 * parameters
+	 * @param remoteSite
+	 * @return ISiteFeatureReference[]
+	 * @throws CoreException
+	 */
+	private ISiteFeatureReference[] findFeaturesToMirror(ISite remoteSite)
+		throws CoreException {
+		ISiteFeatureReference remoteSiteFeatureReferences[] =
+			remoteSite.getRawFeatureReferences();
+		SiteFeatureReferenceModel existingFeatureModels[] =
+			mirrorSite.getFeatureReferenceModels();
+		Collection featureReferencesToMirror = new ArrayList();
+
+		PluginVersionIdentifier featureVersionIdentifier = null;
+
+		if (featureId == null) {
+			System.out.println(
+				"Parameter feature not specified.  All features on the remote site will be mirrored."); //$NON-NLS-1$
+		}
+		if (featureVersion == null) {
+			System.out.println(
+				"Parameter version not specified.  All versions of features on the remote site will be mirrored."); //$NON-NLS-1$
+		} else {
+			featureVersionIdentifier =
+				new PluginVersionIdentifier(featureVersion);
+		}
+		for (int i = 0; i < remoteSiteFeatureReferences.length; i++) {
+			VersionedIdentifier remoteFeatureVersionedIdentifier =
+				remoteSiteFeatureReferences[i].getVersionedIdentifier();
+
+			if (featureId != null
+				&& !featureId.equals(
+					remoteFeatureVersionedIdentifier.getIdentifier())) {
+				// id does not match
+				continue;
+			}
+			if (featureVersionIdentifier != null
+				&& !featureVersionIdentifier.isPerfect(
+					remoteFeatureVersionedIdentifier.getVersion())) {
+				// version does not match
+				continue;
+			}
+
+			for (int e = 0; e < existingFeatureModels.length; e++) {
+				if (existingFeatureModels[e]
+					.getVersionedIdentifier()
+					.equals(remoteFeatureVersionedIdentifier)) {
+					System.out.println(
+						"Feature " //$NON-NLS-1$
+							+ remoteFeatureVersionedIdentifier
+							+ " already mirrored and exposed."); //$NON-NLS-1$
+					// feature already mirrored and exposed in site.xml
+					continue;
+				}
+			}
+
+			// Check feature type
+			String type =
+				((SiteFeatureReference) remoteSiteFeatureReferences[i])
+					.getType();
+			if (type != null
+				&& !ISite.DEFAULT_PACKAGED_FEATURE_TYPE.equals(type)) {
+				// unsupported
+				throw Utilities.newCoreException(
+					"Feature " //$NON-NLS-1$
+						+ remoteFeatureVersionedIdentifier
+						+ " is of type " //$NON-NLS-1$
+						+ type
+						+ ".  Only features of type " //$NON-NLS-1$
+						+ ISite.DEFAULT_PACKAGED_FEATURE_TYPE
+						+ " are supported.", //$NON-NLS-1$
+					null);
+			}
+
+			featureReferencesToMirror.add(remoteSiteFeatureReferences[i]);
+			System.out.println(
+				"Feature " //$NON-NLS-1$
+					+ remoteSiteFeatureReferences[i].getVersionedIdentifier()
+					+ " will be mirrored."); //$NON-NLS-1$
+		}
+		return (ISiteFeatureReference[]) featureReferencesToMirror.toArray(
+			new ISiteFeatureReference[featureReferencesToMirror.size()]);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSite.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSite.java
new file mode 100644
index 0000000..7c40fe3
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSite.java
@@ -0,0 +1,822 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.mirror;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.update.core.ContentReference;
+import org.eclipse.update.core.ICategory;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureContentProvider;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.INonPluginEntry;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.core.IURLEntry;
+import org.eclipse.update.core.IVerificationListener;
+import org.eclipse.update.core.Site;
+import org.eclipse.update.core.SiteFeatureReferenceModel;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.eclipse.update.core.model.CategoryModel;
+import org.eclipse.update.core.model.SiteModelFactory;
+import org.eclipse.update.core.model.URLEntryModel;
+import org.eclipse.update.internal.core.CoreExceptionWithRootCause;
+import org.eclipse.update.internal.core.FatalIOException;
+import org.eclipse.update.internal.core.FeaturePackagedContentProvider;
+import org.eclipse.update.internal.core.ISiteContentConsumer;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.standalone.StandaloneUpdateApplication;
+
+/**
+ * Local mirror site.  Read/Write
+ */
+public class MirrorSite extends Site {
+	private final static String INDENT = "   "; //$NON-NLS-1$
+	private SiteModelFactory factory;
+	/**
+	 * plugin entries 
+	 */
+	private Collection downloadedPluginEntries = new ArrayList();
+	private Collection downloadedFeatureReferenceModels = new ArrayList();
+	private boolean ignoreNonPresentPlugins;
+	public MirrorSite(SiteModelFactory factory) {
+		this.factory = factory;
+	}
+
+	/**
+	 * Mirrors the specified features and listed optional features on this site.
+	 * @see ISite#install(IFeature, IVerificationListener, IProgressMonitor)
+	 * @param mirrorSiteUrl external URL of the mirror site or null;
+	 * if parameter is provided policy fragment will be generated
+	 * @exception CoreException
+	 */
+	public void mirrorAndExpose(
+		ISite remoteSite,
+		ISiteFeatureReference[] sourceFeatureRefs,
+		IFeatureReference[] optionalfeatures,
+		String mirrorSiteUrl)
+		throws CoreException {
+
+		mirrorAndExposeFeatures(
+			remoteSite,
+			sourceFeatureRefs,
+			optionalfeatures);
+
+		System.out.println(
+			"Installing features finished. Updating categories ..."); //$NON-NLS-1$
+		updateCategories(remoteSite);
+		System.out.println(
+			"Updating categories finished. Updating site description ..."); //$NON-NLS-1$
+		updateDescription(remoteSite);
+		System.out.println(
+			"Updating site description finished. Saving site.xml ..."); //$NON-NLS-1$
+		save();
+		if (mirrorSiteUrl != null) {
+			generateUpdatePolicy(mirrorSiteUrl);
+		}
+	}
+	private void mirrorAndExposeFeatures(
+		ISite remoteSite,
+		ISiteFeatureReference[] sourceFeatureRefs,
+		IFeatureReference[] optionalfeatures)
+		throws CoreException {
+
+		// Features that failed will be retried once again
+		Collection failedFeatures = new ArrayList();
+		for (int i = 0; i < sourceFeatureRefs.length; i++) {
+			try {
+				IFeature sourceFeature =
+					sourceFeatureRefs[i].getFeature(new NullProgressMonitor());
+				SiteFeatureReferenceModel featureRef =
+					mirrorFeature(
+						remoteSite,
+						sourceFeature,
+						optionalfeatures,
+						1);
+				// Set categories of the new feature
+				ICategory remoteCategories[] =
+					sourceFeatureRefs[i].getCategories();
+				for (int j = 0; j < remoteCategories.length; j++) {
+					featureRef.addCategoryName(remoteCategories[j].getName());
+				}
+
+				addFeatureReferenceModel(remoteSite, featureRef);
+			} catch (CoreException ce) {
+				failedFeatures.add(sourceFeatureRefs[i]);
+			}
+		}
+
+		// do we need to retry?
+		if (failedFeatures.size() > 0) {
+			sourceFeatureRefs =
+				(ISiteFeatureReference[]) failedFeatures.toArray(
+					new ISiteFeatureReference[failedFeatures.size()]);
+		} else {
+			return;
+		}
+
+		for (int i = 0; i < sourceFeatureRefs.length; i++) {
+			IFeature sourceFeature =
+				sourceFeatureRefs[i].getFeature(new NullProgressMonitor());
+			SiteFeatureReferenceModel featureRef =
+				mirrorFeature(remoteSite, sourceFeature, optionalfeatures, 1);
+			// Set categories of the new feature
+			ICategory remoteCategories[] = sourceFeatureRefs[i].getCategories();
+			for (int j = 0; j < remoteCategories.length; j++) {
+				featureRef.addCategoryName(remoteCategories[j].getName());
+			}
+
+			addFeatureReferenceModel(remoteSite, featureRef);
+		}
+	}
+
+	/**
+	 * Install the specified feature and listed optional features on this site.
+	 * @see ISite#install(IFeature, IVerificationListener, IProgressMonitor)
+	 * @exception CoreException
+	 */
+	private SiteFeatureReferenceModel mirrorFeature(
+		ISite remoteSite,
+		IFeature sourceFeature,
+		IFeatureReference[] optionalfeatures,
+		int indent)
+		throws CoreException {
+		String tab = ""; //$NON-NLS-1$
+		for (int i = 0; i < indent; i++)
+			tab += " "; //$NON-NLS-1$
+		System.out.println(
+			tab
+				+ "Mirroring feature " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		SiteFeatureReferenceModel existingFeatures[] =
+			getDownloadedFeatureReferenceModels();
+		for (int e = 0; e < existingFeatures.length; e++) {
+			if (existingFeatures[e]
+				.getVersionedIdentifier()
+				.equals(sourceFeature.getVersionedIdentifier())) {
+				System.out.println(
+					tab
+						+ "Feature " //$NON-NLS-1$
+						+ sourceFeature.getVersionedIdentifier()
+						+ " already exists.  Skipping downloading."); //$NON-NLS-1$
+				return existingFeatures[e];
+			}
+		}
+
+		final IFeatureContentProvider provider =
+			sourceFeature.getFeatureContentProvider();
+		
+		// TODO: passing command options could be made more general in future, so this 
+		// cast is not needed. 
+		if (provider instanceof FeaturePackagedContentProvider) {
+			((FeaturePackagedContentProvider) provider).setContinueOnError(ignoreNonPresentPlugins);
+		}
+		
+		System.out.println(
+			tab
+				+ "Getting plugin entries for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		final IPluginEntry[] sourceFeaturePluginEntries =
+			sourceFeature.getRawPluginEntries();
+
+		// determine list of plugins to install
+		// find the intersection between the plugin entries already contained
+		// on the target site, and plugin entries packaged in source feature
+
+		IPluginEntry[] pluginsToInstall =
+			UpdateManagerUtils.diff(
+				sourceFeaturePluginEntries,
+				getDownloadedPluginEntries());
+
+		System.out.println(
+			tab
+				+ "Getting non plugin entries for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		final INonPluginEntry[] nonPluginsToInstall =
+			sourceFeature.getRawNonPluginEntries();
+
+		System.out.println(
+			tab
+				+ "Getting included features for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		IFeatureReference[] children =
+			sourceFeature.getRawIncludedFeatureReferences();
+		if (optionalfeatures != null) {
+			children =
+				UpdateManagerUtils.optionalChildrenToInstall(
+					children,
+					optionalfeatures);
+		}
+
+		System.out.println(
+			tab
+				+ "Downloading feature archives for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		// download feature archives
+		provider.getFeatureEntryArchiveReferences(null);
+
+		System.out.println(
+			tab
+				+ "Downloading plug-in archives for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		// download plugin archives
+		for (int i = 0; i < pluginsToInstall.length; i++) {
+			try {
+				provider.getPluginEntryArchiveReferences(pluginsToInstall[i], null);
+			} catch (CoreException ce) {
+				if ( ignoreNonPresentPlugins && 
+						(ce instanceof CoreExceptionWithRootCause) &&
+						(((CoreExceptionWithRootCause)ce).getRootException() != null) && 
+						(((CoreExceptionWithRootCause)ce).getRootException() instanceof FatalIOException) ) {
+					System.out.println("Could not mirror plug-in " + pluginsToInstall[i].getVersionedIdentifier().toString() + ". It does not exist on the given site");  //$NON-NLS-1$//$NON-NLS-2$
+				} else {
+					throw ce;
+				}
+			}
+		}
+
+		System.out.println(
+			tab
+				+ "Downloading non plug-in archives for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		// download non-plugin archives
+		for (int i = 0; i < nonPluginsToInstall.length; i++) {
+			provider.getNonPluginEntryArchiveReferences(
+				nonPluginsToInstall[i],
+				null);
+		}
+
+		System.out.println(
+			tab
+				+ "Installing child features for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		// install child features first
+		for (int i = 0; i < children.length; i++) {
+			IFeature childFeature = children[i].getFeature(null);
+			mirrorFeature(
+				remoteSite,
+				childFeature,
+				optionalfeatures,
+				indent + 1);
+		}
+
+		System.out.println(
+			tab
+				+ "Storing plug-in archives for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		// store plugins' archives
+		for (int i = 0; i < pluginsToInstall.length; i++) {
+			try {
+				ContentReference[] references = provider.getPluginEntryArchiveReferences( pluginsToInstall[i], null);
+				storePluginArchive(references[0]);
+				addDownloadedPluginEntry(pluginsToInstall[i]);
+			} catch (CoreException ce) {
+				if ( ignoreNonPresentPlugins && 
+						(ce instanceof CoreExceptionWithRootCause) &&
+						(((CoreExceptionWithRootCause)ce).getRootException() != null) && 
+						(((CoreExceptionWithRootCause)ce).getRootException() instanceof FatalIOException) ) {
+					System.out.println("Could not write plug-in " + pluginsToInstall[i].getVersionedIdentifier().toString() + ". It does not exist on the given site"); //$NON-NLS-1$ //$NON-NLS-2$
+				} else {
+					//System.out.println("ignoreNonPresentPlugins:"+ignoreNonPresentPlugins); //$NON-NLS-1$
+					throw ce;
+				}
+			}
+		}
+
+		System.out.println(
+			tab
+				+ "Storing non plug-in archives for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		// store non plugins' archives
+		for (int i = 0; i < nonPluginsToInstall.length; i++) {
+			ContentReference[] references =
+				provider.getNonPluginEntryArchiveReferences(
+					nonPluginsToInstall[i],
+					null);
+			for (int r = 0; r < references.length; r++) {
+				storeNonPluginArchive(
+					sourceFeature.getVersionedIdentifier(),
+					references[r]);
+			}
+		}
+
+		System.out.println(
+			tab
+				+ "Storing feature archives for " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " ..."); //$NON-NLS-1$
+		// store feature archive
+		ContentReference[] references =
+			provider.getFeatureEntryArchiveReferences(null);
+		storeFeatureArchive(references[0]);
+
+		System.out.println(
+			tab
+				+ "Adding feature " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " to model ..."); //$NON-NLS-1$
+
+		// add feature model to site model
+		SiteFeatureReferenceModel featureRef =
+			factory.createFeatureReferenceModel();
+		featureRef.setSiteModel(this);
+		//featureRef.setURLString(featureURL.toExternalForm());
+		featureRef.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+		featureRef.setFeatureIdentifier(
+			sourceFeature.getVersionedIdentifier().getIdentifier());
+		featureRef.setFeatureVersion(
+			sourceFeature.getVersionedIdentifier().getVersion().toString());
+		addDownloadedFeatureReferenceModel(featureRef);
+
+		System.out.println(
+			tab
+				+ "Mirroring feature " //$NON-NLS-1$
+				+ sourceFeature.getVersionedIdentifier()
+				+ " finished."); //$NON-NLS-1$
+		return featureRef;
+
+	}
+	/**
+	 * Adds a feature reference model to this site,
+	 * and exposes in site.xml if remote site exposes given feature.
+	 */
+	public void addFeatureReferenceModel(
+		ISite remoteSite,
+		SiteFeatureReferenceModel featureReference) {
+		// check if remote site exposes this feature
+		ISiteFeatureReference remoteFeatures[] =
+			remoteSite.getRawFeatureReferences();
+		for (int i = 0; i < remoteFeatures.length; i++) {
+			ISiteFeatureReference remoteFeatureRef = remoteFeatures[i];
+			try {
+				if (remoteFeatureRef
+					.getVersionedIdentifier()
+					.equals(featureReference.getVersionedIdentifier())) {
+					addFeatureReferenceModel(featureReference);
+				}
+			} catch (CoreException ce) {
+				StandaloneUpdateApplication.exceptionLogged();
+				UpdateCore.log(ce);
+			}
+		}
+		save();
+		System.out.println(
+			"Feature " //$NON-NLS-1$
+				+ featureReference.getVersionedIdentifier()
+				+ " added to site.xml."); //$NON-NLS-1$
+	}
+	/**
+	 * Adds feature model to site model, removing old feature
+	 */
+	public void addFeatureReferenceModel(SiteFeatureReferenceModel featureReference) {
+		SiteFeatureReferenceModel[] existingModels =
+			getFeatureReferenceModels();
+		for (int j = 0; j < existingModels.length; j++) {
+			if (existingModels[j]
+				.getVersionedIdentifier()
+				.equals(featureReference.getVersionedIdentifier())) {
+				super.removeFeatureReferenceModel(existingModels[j]);
+			}
+		}
+		super.addFeatureReferenceModel(featureReference);
+	}
+
+	/**
+	 * @see ISiteContentConsumer#store(ContentReference, IProgressMonitor)
+	 */
+	private void storeFeatureArchive(ContentReference contentReference)
+		throws CoreException {
+		InputStream inStream = null;
+		String featurePath = null;
+
+		try {
+			URL newURL =
+				new URL(
+					this.getURL(),
+					Site.DEFAULT_INSTALLED_FEATURE_PATH
+						+ contentReference.getIdentifier()
+						+ ".jar"); //$NON-NLS-1$
+			featurePath = newURL.getFile();
+			inStream = contentReference.getInputStream();
+			UpdateManagerUtils.copyToLocal(inStream, featurePath, null);
+		} catch (IOException e) {
+			throw Utilities.newCoreException(
+				"Error occurred while creating "+ featurePath+" file.", //$NON-NLS-1$ //$NON-NLS-2$
+				e);
+		} finally {
+			if (inStream != null) {
+				try {
+					inStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+
+	}
+	/**
+	* @see ISiteContentConsumer#store(ContentReference, IProgressMonitor)
+	*/
+	private void storePluginArchive(ContentReference contentReference)
+		throws CoreException {
+
+		InputStream inStream = null;
+		String pluginPath = null;
+		try {
+			URL newURL = new URL(getURL(), contentReference.getIdentifier());
+			pluginPath = newURL.getFile();
+			inStream = contentReference.getInputStream();
+			// added null check here,  since contentReference can, in theory, return null for input stream. 
+			if (inStream != null) {
+				UpdateManagerUtils.copyToLocal(inStream, pluginPath, null);
+			}
+		} catch (IOException e) {
+			throw Utilities.newCoreException(
+			"Error occurred while creating "+ pluginPath+" file.", //$NON-NLS-1$ //$NON-NLS-2$
+				e);
+		} finally {
+			if (inStream != null) {
+				try {
+					inStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+	}
+
+	private void storeNonPluginArchive(
+		VersionedIdentifier featureVersionedIdentifier,
+		ContentReference contentReference)
+		throws CoreException {
+
+		InputStream inStream = null;
+		File nonPluginArchivePath = null;
+		try {
+			URL newDirURL =
+				new URL(
+					getURL(),
+					Site.DEFAULT_INSTALLED_FEATURE_PATH
+						+ "/" //$NON-NLS-1$
+						+ featureVersionedIdentifier);
+			File dir = new File(newDirURL.getFile());
+			dir.mkdirs();
+			inStream = contentReference.getInputStream();
+			nonPluginArchivePath =
+				new File(dir, contentReference.getIdentifier());
+			UpdateManagerUtils.copyToLocal(
+				inStream,
+				nonPluginArchivePath.getAbsolutePath(),
+				null);
+		} catch (IOException e) {
+			throw Utilities.newCoreException(
+			"Error occurred while creating "+ nonPluginArchivePath.getAbsolutePath()+" file." //$NON-NLS-1$ //$NON-NLS-2$
+				,e);
+		} finally {
+			if (inStream != null) {
+				try {
+					inStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+	}
+
+	private void save() {
+		FileOutputStream fos = null;
+		try {
+			URL siteURL = new URL(this.getURL(), "site.xml"); //$NON-NLS-1$
+			fos = new FileOutputStream(new File(siteURL.getFile()));
+			OutputStreamWriter outWriter = new OutputStreamWriter(fos, "UTF-8"); //$NON-NLS-1$
+			PrintWriter writer = new PrintWriter(outWriter);
+			save(writer);
+			writer.flush();
+		} catch (IOException ioe) {
+			StandaloneUpdateApplication.exceptionLogged();
+			UpdateCore.log(
+				Utilities.newCoreException(
+					"Site XML could not be saved.", //$NON-NLS-1$
+					ioe));
+		} finally {
+			if (fos != null) {
+				try {
+					fos.close();
+				} catch (IOException ioe2) {
+				}
+			}
+		}
+	}
+	private void save(PrintWriter writer) {
+		writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
+		//writer.println("<!DOCTYPE site SYSTEM \"dtd/site.dtd\">");
+		writeSite("", writer); //$NON-NLS-1$
+	}
+
+	private void writeSite(String indent, PrintWriter writer) {
+		writer.print(indent + "<site"); //$NON-NLS-1$
+		String indent2 = indent + INDENT;
+		// default type
+		//writeIfDefined(indenta, writer, "type", getType());
+		// stored relative to site.xml
+		//writeIfDefined(indenta, writer, "url", getURL());
+		writer.println(">"); //$NON-NLS-1$
+		URLEntryModel description = getDescriptionModel();
+		if (description != null) {
+			writer.println();
+			writeDescription(indent2, writer, description);
+			writer.println();
+		}
+		writeFeatures(indent2, writer);
+		writeCategories(indent2, writer);
+		writer.println(indent + "</site>"); //$NON-NLS-1$
+	}
+	private void writeFeatures(String indent, PrintWriter writer) {
+		SiteFeatureReferenceModel[] featureReferenceModels =
+			getFeatureReferenceModels();
+		for (int i = 0; i < featureReferenceModels.length; i++) {
+			writer.print(indent);
+			writer.print("<feature"); //$NON-NLS-1$
+			writer.print(
+				" url=\"features/" //$NON-NLS-1$
+					+ featureReferenceModels[i].getFeatureIdentifier()
+					+ "_" //$NON-NLS-1$
+					+ featureReferenceModels[i].getFeatureVersion()
+					+ ".jar\""); //$NON-NLS-1$
+			writer.print(
+				" id=\"" //$NON-NLS-1$
+					+ featureReferenceModels[i].getFeatureIdentifier()
+					+ "\""); //$NON-NLS-1$
+			writer.print(
+				" version=\"" //$NON-NLS-1$
+					+ featureReferenceModels[i].getFeatureVersion()
+					+ "\""); //$NON-NLS-1$
+			writer.println(">"); //$NON-NLS-1$
+
+			String[] categoryNames =
+				featureReferenceModels[i].getCategoryNames();
+			for (int cn = 0; cn < categoryNames.length; cn++) {
+				writer.print(indent + INDENT);
+				writer.println(
+					"<category name=\"" + categoryNames[cn] + "\" />"); //$NON-NLS-1$ //$NON-NLS-2$
+
+			}
+
+			writer.print(indent);
+			writer.println("</feature>"); //$NON-NLS-1$
+			writer.println();
+		}
+	}
+	private void writeCategories(String indent, PrintWriter writer) {
+		CategoryModel[] categoryModels = getCategoryModels();
+		if (categoryModels.length <= 0) {
+			return;
+		}
+		for (int i = 0; i < categoryModels.length; i++) {
+			writer.print(indent);
+			writer.print("<category-def"); //$NON-NLS-1$
+			writer.print(
+				" name=\"" //$NON-NLS-1$
+					+ categoryModels[i].getName()
+					+ "\" label=\"" //$NON-NLS-1$
+					+ categoryModels[i].getLabel()
+					+ "\""); //$NON-NLS-1$
+			writer.println(">"); //$NON-NLS-1$
+			if (categoryModels[i].getDescriptionModel() != null) {
+				writeDescription(
+						indent + INDENT,
+						writer,
+						categoryModels[i].getDescriptionModel());
+			}
+			writer.print(indent);
+			writer.println("</category-def>"); //$NON-NLS-1$
+			writer.println();
+		}
+	}
+	private void writeDescription(
+		String indent,
+		PrintWriter writer,
+		URLEntryModel urlEntryModel) {
+		String url = urlEntryModel.getURLString();
+		String text = urlEntryModel.getAnnotationNonLocalized();
+		writer.print(indent);
+		writer.print("<description"); //$NON-NLS-1$
+		if (url != null)
+			writer.print(" url=\"" + url + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+		if (text == null || text.length() <= 0) {
+			writer.println(" />"); //$NON-NLS-1$
+		} else {
+			writer.println(">"); //$NON-NLS-1$
+			if (text != null) {
+				writer.println(
+					indent + INDENT + UpdateManagerUtils.xmlSafe(text));
+			}
+			writer.println(indent + "</description>"); //$NON-NLS-1$
+		}
+	}
+	/**
+	 * Adds a plugin entry 
+	 * Either from parsing the file system or 
+	 * installing a feature
+	 * 
+	 * We cannot figure out the list of plugins by reading the Site.xml as
+	 * the archives tag are optionals
+	 */
+	public void addDownloadedPluginEntry(IPluginEntry pluginEntry) {
+		downloadedPluginEntries.add(pluginEntry);
+	}
+
+	private IPluginEntry[] getDownloadedPluginEntries() {
+		return (IPluginEntry[]) downloadedPluginEntries.toArray(
+			new IPluginEntry[downloadedPluginEntries.size()]);
+	}
+	/**
+	 * Adds a plugin entry 
+	 * Either from parsing the file system or 
+	 * installing a feature
+	 * 
+	 * We cannot figure out the list of plugins by reading the Site.xml as
+	 * the archives tag are optionals
+	 */
+	public void addDownloadedFeatureReferenceModel(SiteFeatureReferenceModel featureModel) {
+		downloadedFeatureReferenceModels.add(featureModel);
+	}
+
+	private SiteFeatureReferenceModel[] getDownloadedFeatureReferenceModels() {
+		return (
+			SiteFeatureReferenceModel[]) downloadedFeatureReferenceModels
+				.toArray(
+			new SiteFeatureReferenceModel[downloadedFeatureReferenceModels
+				.size()]);
+	}
+	/**
+	 * Checks if mirror site contains a feature with given ID and version
+	 * @param featureRefModel
+	 * @return true if such feature exists
+	 */
+	/*private boolean contains(SiteFeatureReferenceModel featureRefModel) {
+		ISiteFeatureReference featureRefs[] = getRawFeatureReferences();
+		for (int i = 0; i < featureRefs.length; i++) {
+			try {
+				if (featureRefs[i]
+					.getVersionedIdentifier()
+					.equals(featureRefModel.getVersionedIdentifier())) {
+					return true;
+				}
+			} catch (CoreException ce) {
+				ce.printStackTrace();
+			}
+		}
+		return false;
+	}*/
+
+	/**
+	 * Updates description of this site
+	 * from description of the remote site.
+	 */
+	private void updateDescription(ISite remoteSite) {
+		IURLEntry urlEntry = remoteSite.getDescription();
+		if (urlEntry != null) {
+			URLEntryModel newUrlEntryModel = new URLEntryModel();
+			URL url = urlEntry.getURL();
+			newUrlEntryModel.setAnnotation(urlEntry.getAnnotation());
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=136249
+			// URL is not required, so might be null
+			// The null case is (already) handled correctly in
+			// writeDescription
+			if (url != null) {
+				newUrlEntryModel.setURLString(url.toExternalForm());
+			}
+			this.setDescriptionModel(newUrlEntryModel);
+		}
+	}
+	/**
+	 * Updates all categories used by features on this site
+	 * from categories defined on remote site.
+	 * Categories not defined on remote site are unchanged.
+	 */
+	private void updateCategories(ISite remoteSite) {
+		// collect name of categories used on this site
+		Set usedCategoryNames = new HashSet();
+		SiteFeatureReferenceModel featureRefModels[] =
+			getFeatureReferenceModels();
+		for (int f = 0; f < featureRefModels.length; f++) {
+			String[] featureCategoryNames =
+				featureRefModels[f].getCategoryNames();
+
+			for (int c = 0; c < featureCategoryNames.length; c++) {
+				usedCategoryNames.add(featureCategoryNames[c]);
+			}
+		}
+
+		Collection newCategoryModels = new ArrayList();
+		for (Iterator it = usedCategoryNames.iterator(); it.hasNext();) {
+			String name = (String) it.next();
+			ICategory remoteCategory = remoteSite.getCategory(name);
+			if (remoteCategory == null) {
+				// remote site does not define this category
+				CategoryModel oldCategory = null;
+				try {
+					oldCategory = (CategoryModel) getCategory(name);
+				} catch (NullPointerException npe) {
+					// cannot reproduce npe anymore
+				}
+				if (oldCategory != null) {
+					newCategoryModels.add(oldCategory);
+				}
+			} else {
+				newCategoryModels.add(remoteCategory);
+			}
+
+		}
+		setCategoryModels(
+			(CategoryModel[]) newCategoryModels.toArray(
+				new CategoryModel[newCategoryModels.size()]));
+
+	}
+	private void generateUpdatePolicy(String url) {
+		FileOutputStream fos = null;
+		try {
+			URL siteURL = new URL(this.getURL(), "policy.xml"); //$NON-NLS-1$
+			fos = new FileOutputStream(new File(siteURL.getFile()));
+			OutputStreamWriter outWriter = new OutputStreamWriter(fos, "UTF-8"); //$NON-NLS-1$
+			PrintWriter writer = new PrintWriter(outWriter);
+
+			writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
+			writer.println("<update-policy>"); //$NON-NLS-1$
+
+			writer.println(
+				"<!-- You can paste the following fragment, containing url-map elements, into another policy file. -->"); //$NON-NLS-1$
+			writeUrlMaps(writer, url);
+			writer.println("<!-- End of fragment with url-map elements. -->"); //$NON-NLS-1$
+
+			writer.println("</update-policy>"); //$NON-NLS-1$
+
+			writer.flush();
+		} catch (IOException ioe) {
+			StandaloneUpdateApplication.exceptionLogged();
+			UpdateCore.log(
+				Utilities.newCoreException(
+					"policy.xml could not be saved", //$NON-NLS-1$
+					ioe));
+		} finally {
+			if (fos != null) {
+				try {
+					fos.close();
+				} catch (IOException ioe2) {
+				}
+			}
+		}
+	}
+	private void writeUrlMaps(PrintWriter writer, String url) {
+		SiteFeatureReferenceModel[] featureReferenceModels =
+			getFeatureReferenceModels();
+		for (int i = 0; i < featureReferenceModels.length; i++) {
+			writer.print("\t"); //$NON-NLS-1$
+			writer.print("<url-map"); //$NON-NLS-1$
+			writer.print(
+				" pattern=\"" //$NON-NLS-1$
+					+ featureReferenceModels[i].getFeatureIdentifier()
+					+ "\""); //$NON-NLS-1$
+			writer.print(" url=\"" + url + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+			writer.println(" />"); //$NON-NLS-1$
+		}
+	}
+
+	public void setIgnoreNonPresentPlugins(boolean ignoreNonPresentPlugins) {
+		this.ignoreNonPresentPlugins = ignoreNonPresentPlugins;
+		
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSiteFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSiteFactory.java
new file mode 100644
index 0000000..482ab68
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/mirror/MirrorSiteFactory.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.mirror;
+import java.io.*;
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.model.*;
+import org.eclipse.update.standalone.*;
+import org.xml.sax.*;
+
+public class MirrorSiteFactory extends BaseSiteFactory {
+	/*
+	 * @see SiteModelFactory#createSiteMapModel()
+	 */
+	public SiteModel createSiteMapModel() {
+		return new MirrorSite(this);
+	}
+	/*
+	 * @see ISiteFactory#createSite(URL)
+	 */
+	public ISite createSite(URL url)
+		throws CoreException, InvalidSiteTypeException {
+		return createSite(new File(url.getFile()));
+	}
+	/*
+	 * @see ISiteFactory#createSite(URL)
+	 */
+	public ISite createSite(File siteLocation)
+		throws CoreException, InvalidSiteTypeException {
+
+		InputStream siteStream = null;
+
+		if (!siteLocation.exists()) {
+			if (!siteLocation.mkdirs()) {
+				throw Utilities.newCoreException(
+					"Directory " //$NON-NLS-1$
+						+ siteLocation.getAbsolutePath()
+						+ " could not be created.", //$NON-NLS-1$
+					null);
+			}
+		}
+		if (!siteLocation.isDirectory() || !siteLocation.canWrite())
+			throw Utilities.newCoreException(
+				siteLocation.getAbsolutePath()
+					+ " is not a directory or is not writtable.", //$NON-NLS-1$
+				null);
+
+		MirrorSite site = null;
+		// parse public features
+		if (new File(siteLocation, Site.SITE_XML).exists()) {
+			try {
+				siteStream =
+					new FileInputStream(new File(siteLocation, Site.SITE_XML));
+			} catch (FileNotFoundException fnfe) {
+			}
+			site = (MirrorSite) parseSite(siteStream);
+			try {
+				if (siteStream != null)
+					siteStream.close();
+			} catch (IOException e) {
+			}
+		}
+		if (site == null) {
+			site = (MirrorSite) createSiteMapModel();
+		}
+		// parse downloaded plugins and fragments
+		parseDownloadedPluginsAndFragments(
+			site,
+			new File(siteLocation, Site.DEFAULT_PLUGIN_PATH));
+		// parse downloaded features
+		parseDownloadedFeatures(
+			site,
+			new File(siteLocation, Site.DEFAULT_FEATURE_PATH));
+
+		URL url;
+		try {
+			url = siteLocation.toURL();
+		} catch (MalformedURLException mue) {
+			throw Utilities.newCoreException(
+				"A URL for site " //$NON-NLS-1$
+					+ siteLocation.getAbsolutePath()
+					+ " could not be created.", //$NON-NLS-1$
+				mue);
+		}
+		SiteContentProvider contentProvider = null;
+		contentProvider = new SiteFileContentProvider(url);
+
+		site.setSiteContentProvider(contentProvider);
+		contentProvider.setSite(site);
+		try {
+			site.resolve(url, url);
+		} catch (MalformedURLException mue) {
+			throw Utilities.newCoreException(
+				"Unable to resolve URL " //$NON-NLS-1$
+					+ (url == null ? "" : url.toExternalForm()), //$NON-NLS-1$
+				mue);
+		}
+		return site;
+	}
+	/**
+	 *  
+	 */
+	private void parseDownloadedPluginsAndFragments(MirrorSite site,
+			File pluginDir) throws CoreException {
+		if (!pluginDir.exists()) {
+			return;
+		}
+		String[] dir = pluginDir.list(FeaturePackagedContentProvider.filter);
+		for (int i = 0; i < dir.length; i++) {
+			InputStream in = null;
+			try {
+				File file = new File(pluginDir, dir[i]);
+				JarContentReference jarReference = new JarContentReference(
+						null, file);
+				ContentReference ref = jarReference.peek("META-INF/MANIFEST.MF", null, null); //$NON-NLS-1$
+				if (ref != null) {
+					try {
+						in = ref.getInputStream();
+					}
+					catch (SecurityException e) {
+						// in case of an invalid signature in jar, we will catch 
+						// and re-throw a little more specific message. Otherwise, it's 
+						// impossible to tell which jar had the problem. 
+						String filename = file.getName();
+						CoreException updateException = Utilities.newCoreException(filename,e);
+						throw updateException;
+					}
+					BundleManifest manifest = new BundleManifest(in);
+					if (manifest.exists()) {
+						site
+								.addDownloadedPluginEntry(manifest
+										.getPluginEntry());
+						continue;
+					}
+				}
+				ref = jarReference.peek("plugin.xml", null, null); //$NON-NLS-1$
+				if (ref == null) {
+					ref = jarReference.peek("fragment.xml", null, null); //$NON-NLS-1$
+				}
+				if (ref != null) {
+					in = ref.getInputStream();
+					PluginEntry entry = new DefaultPluginParser().parse(in);
+					site.addDownloadedPluginEntry(entry);
+				}
+			} catch (IOException e) {
+				StandaloneUpdateApplication.exceptionLogged();
+				UpdateCore.log(e);
+			} catch (SAXException e) {
+				StandaloneUpdateApplication.exceptionLogged();
+				UpdateCore.log(e);
+			} finally {
+				if(in !=null){
+					try{
+						in.close();
+					}catch(IOException ce){
+					}
+				}
+			}
+		}
+	}
+	/**
+	* Method parseFeature.
+	* @throws CoreException
+	*/
+	private void parseDownloadedFeatures(MirrorSite site, File featureDir)
+		throws CoreException {
+		if (featureDir.exists()) {
+			String[] dir;
+			SiteFeatureReferenceModel featureRef;
+			URL featureURL;
+			File currentFeatureFile;
+			String newFilePath = null;
+
+			try {
+				// only list JAR files
+				dir = featureDir.list(FeaturePackagedContentProvider.filter);
+				for (int index = 0; index < dir.length; index++) {
+
+					// check if the JAR file contains a feature.xml
+					currentFeatureFile = new File(featureDir, dir[index]);
+					JarContentReference ref =
+						new JarContentReference("", currentFeatureFile); //$NON-NLS-1$
+					ContentReference result = null;
+					try {
+						result = ref.peek(Feature.FEATURE_XML, null, null);
+					} catch (IOException e) {
+						UpdateCore.warn(
+							"Exception retrieving feature.xml in file:" //$NON-NLS-1$
+								+ currentFeatureFile,
+							e);
+					}
+					if (result == null) {
+						UpdateCore.warn(
+							"Unable to find feature.xml in file:" //$NON-NLS-1$
+								+ currentFeatureFile);
+					} else {
+						featureURL = currentFeatureFile.toURL();
+						featureRef = createFeatureReferenceModel();
+						featureRef.setSiteModel(site);
+						featureRef.setURLString(featureURL.toExternalForm());
+						featureRef.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+						featureRef.setFeatureIdentifier(
+							featureRef
+								.getVersionedIdentifier()
+								.getIdentifier());
+						featureRef.setFeatureVersion(
+							featureRef
+								.getVersionedIdentifier()
+								.getVersion()
+								.toString());
+						site.addDownloadedFeatureReferenceModel(featureRef);
+					}
+				}
+			} catch (MalformedURLException e) {
+				throw Utilities.newCoreException(
+					"Unable to create URL for file " + newFilePath + ".", //$NON-NLS-1$ //$NON-NLS-2$
+					e);
+			}
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/BundleManifest.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/BundleManifest.java
new file mode 100644
index 0000000..fbbeeee
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/BundleManifest.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.model;
+import java.io.*;
+import java.util.jar.*;
+
+import org.eclipse.osgi.util.*;
+import org.eclipse.update.core.*;
+import org.osgi.framework.*;
+/**
+ * Parses MANIFEST.MF
+ */
+public class BundleManifest {
+	private PluginEntry pluginEntry;
+	private IOException exception;
+	/**
+	 * Constructor for local file
+	 */
+public BundleManifest(File manifest) {
+		super();
+		if (manifest.exists() && !manifest.isDirectory()) {
+			FileInputStream fos = null;
+			try {
+				fos = new FileInputStream(manifest);
+				parse(fos);
+			} catch (IOException ioe) {
+			} finally {
+				if (fos != null) {
+					try {
+						fos.close();
+					} catch (IOException e) {
+					}
+				}
+			}
+		}
+	}
+	/**
+	 * Constructor for local file
+	 */
+	public BundleManifest(InputStream input) {
+		super();
+		if (input != null) {
+			parse(input);
+		}
+	}
+	/**
+	 * Parses manifest, creates PluginEntry if manifest is valid, stores
+	 * exception if any occurs
+	 * 
+	 * @param in
+	 *            InputStream
+	 */
+	private void parse(InputStream in) {
+		try {
+			Manifest m = new Manifest(in);
+			Attributes a = m.getMainAttributes();
+			// plugin id
+			String symbolicName = a.getValue(Constants.BUNDLE_SYMBOLICNAME);
+			if (symbolicName == null) {
+				// In Eclipse manifest must have Bundle-SymbolicName attribute
+				return;
+			}
+			String id;
+			try {
+				ManifestElement[] elements = ManifestElement.parseHeader(
+						Constants.BUNDLE_SYMBOLICNAME, symbolicName);
+				id = elements[0].getValue();
+			} catch (BundleException be) {
+				throw new IOException(be.getMessage());
+			}
+			// plugin version
+			String version = a.getValue(Constants.BUNDLE_VERSION);
+			if (version == null) {
+				return;
+			}
+			String hostPlugin = a.getValue(Constants.FRAGMENT_HOST);
+			pluginEntry = new PluginEntry();
+			pluginEntry.setVersionedIdentifier(new VersionedIdentifier(id,
+					version));
+			pluginEntry.isFragment(hostPlugin != null
+					&& hostPlugin.length() > 0);
+		} catch (IOException ioe) {
+			exception = ioe;
+		}
+	}
+	public boolean exists() {
+		return exception != null || pluginEntry != null;
+	}
+	/**
+	 * Obtains PluginEntry from a manifest.
+	 * 
+	 * @return PluginEntry or null if valid manifest does not exist
+	 * @throws IOException
+	 *             if exception during parsing
+	 */
+	public PluginEntry getPluginEntry() throws IOException {
+		if (exception != null) {
+			throw exception;
+		} else {
+			return pluginEntry;
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ConfigurationActivityModel.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ConfigurationActivityModel.java
new file mode 100644
index 0000000..faf1b63
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ConfigurationActivityModel.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.model;
+ 
+import java.util.Date;
+
+import org.eclipse.update.core.model.*;
+
+public class ConfigurationActivityModel extends ModelObject{
+	
+	private String label;
+	private int action;
+	private Date date;
+	private int status;
+	private InstallConfigurationModel installConfiguration;
+	
+
+	/**
+	 * Constructor for ConfigurationActivityModel.
+	 */
+	public ConfigurationActivityModel() {
+		super();
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public int getAction() {
+		return action;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public Date getDate() {
+		return date;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public int getStatus() {
+		return status;
+	}
+
+	/**
+	 * Sets the date.
+	 * @param date The date to set
+	 */
+	public void setDate(Date date) {
+		assertIsWriteable();
+		this.date = date;
+	}
+
+	/**
+	 * Sets the status.
+	 * @param status The status to set
+	 */
+	public void setStatus(int status) {
+		assertIsWriteable();
+		this.status = status;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public String getLabel() {
+		return label;
+	}
+
+	/**
+	 * Sets the label.
+	 * @param label The label to set
+	 */
+	public void setLabel(String label) {
+		assertIsWriteable();
+		this.label = label;
+	}
+
+	/**
+	 * Sets the action.
+	 * @param action The action to set
+	 */
+	public void setAction(int action) {
+		assertIsWriteable();
+		this.action = action;
+	}
+
+	/**
+	 * Gets the installConfiguration.
+	 * @return Returns a InstallConfigurationModel
+	 */
+	public InstallConfigurationModel getInstallConfigurationModel() {
+		return installConfiguration;
+	}
+
+	/**
+	 * Sets the installConfiguration.
+	 * @param installConfiguration The installConfiguration to set
+	 */
+	public void setInstallConfigurationModel(InstallConfigurationModel installConfiguration) {
+		assertIsWriteable();		
+		this.installConfiguration = installConfiguration;
+	}
+
+}
+
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ConfigurationPolicyModel.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ConfigurationPolicyModel.java
new file mode 100644
index 0000000..34e5116
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ConfigurationPolicyModel.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.model;
+
+import java.net.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.*;
+
+/**
+ * 
+ */
+public class ConfigurationPolicyModel extends ModelObject {
+
+	
+	
+
+	private int policy;
+	private Map /* of FeatureReferenceModel */configuredFeatureReferences;
+	private Map /* of FeatureReferenceModel */unconfiguredFeatureReferences;
+	
+	// since 2.0.2
+	private ConfiguredSiteModel configuredSiteModel;
+	
+	// since 2.1
+	private boolean enable;
+
+	/**
+	 * Constructor for ConfigurationPolicyModel.
+	 */
+	public ConfigurationPolicyModel() {
+		super();
+		enable = true;
+		configuredFeatureReferences = new HashMap();
+//		unconfiguredFeatureReferences = new HashMap();		
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public int getPolicy() {
+		return policy;
+	}
+
+	/**
+	 * Sets the policy.
+	 * @param policy The policy to set
+	 */
+	public void setPolicy(int policy) {
+		assertIsWriteable();
+		this.policy = policy;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public FeatureReferenceModel[] getConfiguredFeaturesModel() {
+		if (configuredFeatureReferences==null || configuredFeatureReferences.isEmpty())
+			return new FeatureReferenceModel[0];
+		return (FeatureReferenceModel[]) configuredFeatureReferences.keySet().toArray(arrayTypeFor(configuredFeatureReferences.keySet()));
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public FeatureReferenceModel[] getUnconfiguredFeaturesModel() {
+		// obtain unconfigured features by comparing configured ones with those installed
+		if (unconfiguredFeatureReferences == null
+				&& configuredSiteModel != null
+				&& configuredSiteModel.getSiteModel() != null) {
+			ISite site = (ISite) configuredSiteModel.getSiteModel();
+			ISiteFeatureReference[] siteFeatures = site.getFeatureReferences();
+			if (siteFeatures.length > getConfiguredFeaturesModel().length) {
+				for (int i=0; i<siteFeatures.length; i++) {
+					if (!(siteFeatures[i] instanceof SiteFeatureReference))
+						continue;
+					Iterator iterator = configuredFeatureReferences.keySet().iterator();
+					boolean found = false;
+					while(!found && iterator.hasNext()) {
+						FeatureReferenceModel f = (FeatureReferenceModel)iterator.next();
+						if (UpdateManagerUtils.sameURL(f.getURL(), siteFeatures[i].getURL()))
+							found = true;
+					}
+					if (!found)
+						addUnconfiguredFeatureReference((SiteFeatureReference)siteFeatures[i]);
+				}
+			}
+		}
+		if (unconfiguredFeatureReferences == null
+				|| unconfiguredFeatureReferences.isEmpty())
+			return new FeatureReferenceModel[0];
+		return (FeatureReferenceModel[]) unconfiguredFeatureReferences.keySet()
+				.toArray(arrayTypeFor(unconfiguredFeatureReferences.keySet()));
+	}
+
+	/**
+	 * Gets the configuredSiteModel.
+	 * @return Returns a ConfiguredSiteModel
+	 * @since 2.0.2
+	 */
+	public ConfiguredSiteModel getConfiguredSiteModel() {
+		return configuredSiteModel;
+	}
+
+	/**
+	 * Sets the configuredSiteModel.
+	 * @param configuredSiteModel The configuredSiteModel to set
+	 * @since 2.0.2
+	 */
+	public void setConfiguredSiteModel(ConfiguredSiteModel configuredSiteModel) {
+		this.configuredSiteModel = configuredSiteModel;
+	}
+
+	/**
+	 * 
+	 */
+	private boolean remove(FeatureReferenceModel feature, Map list) {
+		URL featureURL = feature.getURL();
+		boolean found = false;
+		Iterator iter = list.keySet().iterator();
+		while (iter.hasNext() && !found) {
+			FeatureReferenceModel element = (FeatureReferenceModel) iter.next();
+			if (UpdateManagerUtils.sameURL(element.getURL(),featureURL)) {
+				list.remove(element);
+				found = true;
+			}
+		}
+		return found;
+	}
+
+	/**
+	 * returns an array of string corresponding to plugins file
+	 */
+	/*package*/
+
+	
+	/**
+	 * 
+	 */
+	private void add(FeatureReferenceModel feature, Map list) {
+		URL featureURL = feature.getURL();
+		boolean found = false;
+		Iterator iter = list.keySet().iterator();
+		while (iter.hasNext() && !found) {
+			FeatureReferenceModel element = (FeatureReferenceModel) iter.next();
+			if (UpdateManagerUtils.sameURL(element.getURL(),featureURL)) {
+				found = true;
+			}
+		}
+
+		if (!found) {
+			list.put(feature,null);
+		} else {
+			UpdateCore.warn("Feature Reference :"+feature+" already part of the list."); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+
+	/**
+	 * adds a feature in the configuredReference list
+	 * also used by the parser to avoid creating another activity
+	 */
+	public void addConfiguredFeatureReference(FeatureReferenceModel feature) {
+		assertIsWriteable();
+		
+		if (configuredFeatureReferences == null)
+			this.configuredFeatureReferences = new HashMap();
+		if (!configuredFeatureReferences.containsKey(feature)){
+			//DEBUG:
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION){
+				UpdateCore.debug("Configuring "+feature.getURLString()); //$NON-NLS-1$
+			}
+			this.add(feature, configuredFeatureReferences);
+		}	
+
+		// when user configure a feature,
+		// we have to remove it from unconfigured feature if it exists
+		// because the user doesn't know...
+		if (unconfiguredFeatureReferences != null) {
+			boolean success = remove(feature, unconfiguredFeatureReferences);
+			if (!success)
+				UpdateCore.warn("Feature not part of Unconfigured list: "+feature.getURLString());			 //$NON-NLS-1$
+		}
+
+	}
+
+	/**
+	 * adds a feature in the list
+	 * also used by the parser to avoid creating another activity
+	 */
+	public void addUnconfiguredFeatureReference(FeatureReferenceModel feature) {
+		assertIsWriteable();
+		if (unconfiguredFeatureReferences == null)
+			this.unconfiguredFeatureReferences = new HashMap();
+		if (!unconfiguredFeatureReferences.containsKey(feature)){
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION){
+				UpdateCore.debug("Unconfiguring "+feature.getURLString()); //$NON-NLS-1$
+			}
+			this.add(feature, unconfiguredFeatureReferences);
+		}	
+
+		// an unconfigured feature is always from a configured one no ?
+		// unless it was parsed right ?
+		if (configuredFeatureReferences != null) {
+			boolean success = remove(feature, configuredFeatureReferences);
+			if (!success)
+				UpdateCore.warn("Feature not part of Configured list: "+feature.getURLString());				 //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * removes a feature from any list
+	 */
+	public void removeFeatureReference(FeatureReferenceModel feature) {
+		assertIsWriteable();
+		if (unconfiguredFeatureReferences!=null){
+			boolean success = remove(feature, unconfiguredFeatureReferences);
+			if (!success)
+				UpdateCore.warn(feature.getURLString()+" not part of unconfigured list.");							 //$NON-NLS-1$
+		}
+
+		if (configuredFeatureReferences != null) {
+			boolean success = remove(feature, configuredFeatureReferences);
+			if (!success)
+				UpdateCore.warn(feature.getURLString()+" not part of configured list.");							 //$NON-NLS-1$
+		}
+	}
+	
+	/**
+	 * Sets the unconfiguredFeatureReferences.
+	 * @param featureReferences The unconfiguredFeatureReferences to set
+	 */
+	protected void setUnconfiguredFeatureReferences(IFeatureReference[] featureReferences) {
+		unconfiguredFeatureReferences = new HashMap();
+		for (int i = 0; i < featureReferences.length; i++) {
+			unconfiguredFeatureReferences.put(featureReferences[i],null);
+		}
+	}
+
+
+	/**
+	 * Sets the configuredFeatureReferences.
+	 * @param featureReferences The configuredFeatureReferences to set
+	 */
+	protected void setConfiguredFeatureReferences(IFeatureReference[] featureReferences) {
+		configuredFeatureReferences = new HashMap();
+		for (int i = 0; i < featureReferences.length; i++) {
+			configuredFeatureReferences.put(featureReferences[i],null);
+		}		
+	
+	}
+
+	/**
+	 * @return boolean
+	 */
+	public boolean isEnabled() {
+		return enable;
+	}
+
+	/**
+	 * @param value
+	 */
+	public void setEnabled(boolean value) {
+		enable = value;
+	}
+
+
+	
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ConfiguredSiteModel.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ConfiguredSiteModel.java
new file mode 100644
index 0000000..a45b2c4
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ConfiguredSiteModel.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.model;
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.*;
+
+/**
+ * 
+ */
+public class ConfiguredSiteModel extends ModelObject {
+	private String[] previousPluginPath;
+
+	private SiteModel site;
+	private String platformURLString;
+	private ConfigurationPolicyModel policy;
+	private InstallConfigurationModel installConfiguration;
+	private boolean installable = false;
+
+	/**
+	 * Constructor
+	 */
+	public ConfiguredSiteModel() {
+		super();
+	}
+
+	/**
+	 * returns the site
+	 * @return The ISite 
+	 * @since 2.0
+	 */
+	public SiteModel getSiteModel() {
+		return site;
+	}
+
+	/**
+	 * Sets the site.
+	 * @param site The site to set
+	 */
+	public void setSiteModel(SiteModel site) {
+		assertIsWriteable();
+		this.site = site;
+	}
+
+	/**
+	 * returns the policy
+	 */
+	public ConfigurationPolicyModel getConfigurationPolicyModel() {
+		return policy;
+	}
+
+	/**
+	 * 
+	 * @since 2.0
+	 */
+	public void setConfigurationPolicyModel(ConfigurationPolicyModel policy) {
+		assertIsWriteable();
+		this.policy = policy;
+		policy.setConfiguredSiteModel(this);
+	}
+
+	/**
+	 * @since
+	 */
+	public boolean isUpdatable() {
+		return installable;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public void setUpdatable(boolean installable) {
+		assertIsWriteable();
+		this.installable = installable;
+	}
+
+	/**
+	 * Gets the installConfiguration.
+	 * @return Returns a InstallConfigurationModel
+	 */
+	public InstallConfigurationModel getInstallConfigurationModel() {
+		return installConfiguration;
+	}
+
+	/**
+	 * Sets the installConfiguration.
+	 * @param installConfiguration The installConfiguration to set
+	 */
+	public void setInstallConfigurationModel(InstallConfigurationModel installConfiguration) {
+		assertIsWriteable();
+		this.installConfiguration = installConfiguration;
+	}
+
+	/**
+	 * Gets the platformURLString.
+	 * @return Returns a String
+	 */
+	public String getPlatformURLString() {
+		return platformURLString;
+	}
+
+	/**
+	 * Sets the platformURLString.
+	 * @param platformURLString The platformURLString to set
+	 */
+	public void setPlatformURLString(String platformURLString) {
+		this.platformURLString = platformURLString;
+	}
+
+	
+		/**
+	 * Gets the previousPluginPath. The list of plugins the platform had.
+	 * @return Returns a String[]
+	 */
+	public String[] getPreviousPluginPath() {
+		if (previousPluginPath == null)
+			previousPluginPath = new String[0];
+		return previousPluginPath;
+	}
+
+	/**
+	 * Sets the previousPluginPath.
+	 * @param previousPluginPath The previousPluginPath to set
+	 */
+	public void setPreviousPluginPath(String[] previousPluginPath) {
+		this.previousPluginPath = new String[previousPluginPath.length];
+		System.arraycopy(previousPluginPath, 0, this.previousPluginPath, 0, previousPluginPath.length);
+	}
+
+	/*
+	 * creates a Status
+	 */
+	protected IStatus createStatus(int statusType, String msg, Exception e){
+		if (statusType!=IStatus.OK) statusType = IStatus.ERROR;
+		return createStatus(statusType,IStatus.OK, msg.toString(), e);
+	}
+
+	/*
+	 * creates a Status
+	 */
+	protected IStatus createStatus(int statusSeverity, int statusCode, String msg, Exception e){
+		String id =	UpdateCore.getPlugin().getBundle().getSymbolicName();
+	
+		StringBuffer completeString = new StringBuffer(""); //$NON-NLS-1$
+		if (msg!=null)
+			completeString.append(msg);
+		if (e!=null){
+			completeString.append("\r\n["); //$NON-NLS-1$
+			completeString.append(e.toString());
+			completeString.append("]\r\n"); //$NON-NLS-1$
+		}
+		return new Status(statusSeverity, id, statusCode, completeString.toString(), e);
+	}
+	
+	/**
+	 * @see org.eclipse.update.configuration.IConfiguredSite#isEnabled()
+	 */
+	public boolean isEnabled() {
+		return getConfigurationPolicyModel().isEnabled();
+	}
+
+	/**
+	 * @see org.eclipse.update.configuration.IConfiguredSite#setEnabled(boolean)
+	 */
+	public void setEnabled(boolean value) {
+		getConfigurationPolicyModel().setEnabled(value);
+	}
+	
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/DefaultPluginParser.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/DefaultPluginParser.java
new file mode 100644
index 0000000..f406130
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/DefaultPluginParser.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.model;
+
+
+import java.io.*;
+import javax.xml.parsers.*;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+/**
+ * Parse default feature.xml
+ */
+
+public class DefaultPluginParser extends DefaultHandler {
+	private final static SAXParserFactory parserFactory =
+		SAXParserFactory.newInstance();
+	private SAXParser parser;
+	private String id = null;
+	private String version = null;
+	private PluginEntry pluginEntry;
+
+	private static final String PLUGIN = "plugin"; //$NON-NLS-1$
+	private static final String FRAGMENT = "fragment"; //$NON-NLS-1$
+
+	private class ParseCompleteException extends SAXException {
+
+        private static final long serialVersionUID = 1L;
+
+        public ParseCompleteException(String arg0) {
+			super(arg0);
+		}
+	}
+
+	/**
+	 * Constructor for DefaultFeatureParser
+	 */
+	public DefaultPluginParser() {
+		super();
+		try {
+			parserFactory.setNamespaceAware(true);
+			this.parser = parserFactory.newSAXParser();
+		} catch (ParserConfigurationException e) {
+			UpdateCore.log(e);
+		} catch (SAXException e) {
+			UpdateCore.log(e);
+		}
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public synchronized PluginEntry parse(InputStream in) throws SAXException, IOException {
+		try {
+			pluginEntry = new PluginEntry();
+			parser.parse(new InputSource(in), this);
+		} catch (ParseCompleteException e) {
+			// expected, we stopped the parsing when we have the information we need
+			/// no need to pursue the parsing
+		}
+
+		if (id == null || id.trim().length() == 0)
+			id = "_no_id_"; //$NON-NLS-1$
+		pluginEntry.setVersionedIdentifier(new VersionedIdentifier(id, version));
+		return pluginEntry;
+	}
+
+	/**
+	 * @see DefaultHandler#startElement(String, String, String, Attributes)
+	 */
+	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+
+		String tag = localName.trim();
+
+		if (tag.equalsIgnoreCase(PLUGIN)) {
+			pluginEntry.isFragment(false);			
+			processPlugin(attributes);
+			return;
+		}
+
+		if (tag.equalsIgnoreCase(FRAGMENT)) {
+			pluginEntry.isFragment(true);			
+			processPlugin(attributes);
+			return;
+		}
+	}
+
+	/** 
+	 * process plugin entry info
+	 */
+	private void processPlugin(Attributes attributes) throws ParseCompleteException {
+		id = attributes.getValue("id"); //$NON-NLS-1$
+		version = attributes.getValue("version"); //$NON-NLS-1$
+		throw new ParseCompleteException(""); //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ITimestamp.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ITimestamp.java
new file mode 100644
index 0000000..246287b
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/ITimestamp.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.model;
+
+import java.util.Date;
+
+public interface ITimestamp {
+
+	public Date getTimestamp();
+	
+	public void setTimestamp( Date timestamp);
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/InstallConfigurationModel.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/InstallConfigurationModel.java
new file mode 100644
index 0000000..97d1013
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/InstallConfigurationModel.java
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.model;
+
+import java.io.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.*;
+
+/**
+ * An InstallConfigurationModel is 
+ * 
+ */
+
+public class InstallConfigurationModel extends ModelObject {
+
+	// performance
+	private URL bundleURL;
+	private URL base;
+	private boolean resolved = false;
+
+	private boolean isCurrent = false;
+	private URL locationURL;
+	private String locationURLString;
+	protected Date date;
+	private String label;
+	private List /* of ConfiguretionActivityModel */ activities;
+	private List /* of configurationSiteModel */ configurationSites;
+
+	protected boolean initialized = false;
+	protected boolean lightlyInitialized = false;
+
+	/**
+	 * default constructor. Create
+	 */
+	public InstallConfigurationModel() {
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public ConfiguredSiteModel[] getConfigurationSitesModel() {
+		if (!initialized) 
+			initialize();
+		if (configurationSites == null || configurationSites.size() == 0)
+			return new ConfiguredSiteModel[0];
+	
+		return (ConfiguredSiteModel[]) configurationSites.toArray(arrayTypeFor(configurationSites));
+	}
+
+	/**
+	 * Adds the configuration to the list
+	 * is called when adding a Site or parsing the XML file
+	 * in this case we do not want to create a new activity, so we do not want t call
+	 * addConfigurationSite()
+	 */
+	public void addConfigurationSiteModel(ConfiguredSiteModel site) {
+		if (configurationSites == null) {
+			configurationSites = new ArrayList();
+		}
+		if (!configurationSites.contains(site)) {
+			configurationSites.add(site);
+		}
+	}
+
+	public void setConfigurationSiteModel(ConfiguredSiteModel[] sites) {
+		configurationSites = null;
+		for (int i = 0; i < sites.length; i++) {
+			addConfigurationSiteModel(sites[i]);
+		}
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public boolean removeConfigurationSiteModel(ConfiguredSiteModel site) {
+		if (!initialized) initialize();
+
+		if (configurationSites != null) {
+			return configurationSites.remove(site);
+		}
+
+		return false;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public boolean isCurrent() {
+		if (!lightlyInitialized && !initialized ) 
+			doLightInitialization();
+		
+		return isCurrent;
+	}
+
+	/**
+	 *  @since 2.0
+	 */
+	public void setCurrent(boolean isCurrent) {
+		// do not check if writable as we may
+		// set an install config as Not current
+		this.isCurrent = isCurrent;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public ConfigurationActivityModel[] getActivityModel() {
+		if (activities == null && !initialized) 
+			initialize();
+		if (activities == null || activities.size() == 0)
+			return new ConfigurationActivityModel[0];
+		return (ConfigurationActivityModel[]) activities.toArray(arrayTypeFor(activities));
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public void addActivityModel(ConfigurationActivityModel activity) {
+		if (activities == null)
+			activities = new ArrayList();
+		if (!activities.contains(activity)) {
+			activities.add(activity);
+			activity.setInstallConfigurationModel(this);
+		}
+	}
+	/**
+	 * 
+	 */
+	public Date getCreationDate() {
+//		if (!initialized) initialize();
+		if (date == null)
+			doLightInitialization();
+		return date;
+	}
+	/**
+	 * Sets the date.
+	 * @param date The date to set
+	 */
+	public void setCreationDate(Date date) {
+		assertIsWriteable();
+		this.date = date;
+	}
+	/**
+	 * @since 2.0
+	 */
+	public URL getURL() {
+		//if (!initialized) initialize();
+		//no need to initialize, always set
+		delayedResolve();
+		return locationURL;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public String getLabel() {
+//		if (!initialized) initialize();
+		if (label == null)
+			doLightInitialization();
+		return label;
+	}
+
+	/**
+	 * @since 2.0.2
+	 */
+
+	public String toString() {
+		return getLabel();
+	}
+
+	/**
+	 * Sets the label.
+	 * @param label The label to set
+	 */
+	public void setLabel(String label) {
+		assertIsWriteable();
+		this.label = label;
+	}
+
+	/**
+	 * Gets the locationURLString.
+	 * @return Returns a String
+	 */
+	public String getLocationURLString() {
+		if (!initialized) delayedResolve();
+		return locationURLString;
+	}
+
+	/**
+	 * Sets the locationURLString.
+	 * @param locationURLString The locationURLString to set
+	 */
+	public void setLocationURLString(String locationURLString) {
+		assertIsWriteable();
+		this.locationURLString = locationURLString;
+		this.locationURL = null;
+	}
+
+	/*
+	 * @see ModelObject#resolve(URL, ResourceBundle)
+	 */
+	public void resolve(URL base, URL bundleURL) throws MalformedURLException {
+
+		this.base = base;
+		this.bundleURL = bundleURL;
+
+	}
+
+	/**
+	 * Returns the timeline.
+	 * @return long
+	 */
+	public long getTimeline() {
+		return 0;
+//		if (!initialized) initialize();
+//		return timeline;
+	}
+
+
+	/*
+	 * initialize the configurations from the persistent model.
+	 */
+	private void initialize() {
+		
+		try {
+			try {
+				IPlatformConfiguration platformConfig = getPlatformConfiguration();
+				
+				new InstallConfigurationParser(platformConfig, this, false);
+			} catch (FileNotFoundException exception) {
+				UpdateCore.warn(locationURLString + " does not exist, The local site is not in synch with the file system and is pointing to a file that doesn't exist.", exception); //$NON-NLS-1$
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_ErrorDuringFileAccess, (new String[] { locationURLString })), exception);
+			} catch (IOException exception) {
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_ErrorDuringFileAccess, (new String[] { locationURLString })), exception);
+			}
+			
+		} catch (CoreException e) {
+			UpdateCore.warn("Error processing configuration history:" + locationURL.toExternalForm(), e); //$NON-NLS-1$
+		} finally {
+			initialized = true;
+		}
+		
+		//finish resolve
+		// PERF:
+		try {
+			// delegate
+			resolveListReference(getActivityModel(), base, bundleURL);
+			resolveListReference(getConfigurationSitesModel(), base, bundleURL);
+		} catch (MalformedURLException e){}		
+	}
+
+	private IPlatformConfiguration getPlatformConfiguration() throws IOException {
+		IPlatformConfiguration platformConfig;
+		if (UpdateManagerUtils.sameURL(getURL(), ConfiguratorUtils.getCurrentPlatformConfiguration().getConfigurationLocation()))
+			platformConfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		else 
+			platformConfig = ConfiguratorUtils.getPlatformConfiguration(getURL());
+		return platformConfig;
+	}
+	
+	private void doLightInitialization() {
+		try {
+			try {
+				IPlatformConfiguration platformConfig = getPlatformConfiguration();
+			
+				new InstallConfigurationParser(platformConfig, this, true);
+			} catch (FileNotFoundException exception) {
+				UpdateCore.warn(locationURLString + " does not exist, The local site is not in synch with the file system and is pointing to a file that doesn't exist.", exception); //$NON-NLS-1$
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_ErrorDuringFileAccess, (new String[] { locationURLString })), exception);
+			} catch (IOException exception) {
+				throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_ErrorDuringFileAccess, (new String[] { locationURLString })), exception);
+			} 
+		} catch (CoreException e) {
+			UpdateCore.warn("Error processing configuration history:" + locationURL.toExternalForm(), e); //$NON-NLS-1$
+		} finally {
+			lightlyInitialized = true;
+		}
+	}
+
+	/*
+	 * 
+	 */
+	private void delayedResolve() {
+
+		// PERF: delay resolution
+		if (resolved)
+			return;
+
+		resolved = true;
+		// resolve local elements
+		try {
+			//locationURL = resolveURL(base, bundleURL, locationURLString);		
+			locationURL = new URL(locationURLString);
+		} catch (MalformedURLException e){
+			File f = new File(locationURLString);
+			try {
+				if (f.exists())
+					locationURL = f.toURL();
+				else
+					locationURL = base;
+			} catch (MalformedURLException e1) {
+				locationURL = base;
+			}
+		}
+	}
+	
+	public void resetActivities() {
+		activities = null;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/InstallConfigurationParser.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/InstallConfigurationParser.java
new file mode 100644
index 0000000..b367bb0
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/InstallConfigurationParser.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.model;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Date;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.SiteFeatureReference;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.core.model.SiteModel;
+import org.eclipse.update.internal.configurator.FeatureEntry;
+import org.eclipse.update.internal.configurator.PlatformConfiguration;
+import org.eclipse.update.internal.configurator.SiteEntry;
+import org.eclipse.update.internal.core.BaseSiteLocalFactory;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+
+
+/**
+ * parse the default site.xml
+ */
+
+public class InstallConfigurationParser {
+	private PlatformConfiguration platformConfig;
+	private URL siteURL;
+	private InstallConfigurationModel config;
+	private ConfiguredSiteModel configSite;
+
+	/**
+	 * Constructor for DefaultSiteParser
+	 */
+	public InstallConfigurationParser(
+		IPlatformConfiguration platformConfig,
+		InstallConfigurationModel config, boolean light)
+		throws IOException, CoreException {
+
+		Assert.isTrue(platformConfig instanceof PlatformConfiguration);
+		this.platformConfig = (PlatformConfiguration)platformConfig;
+		
+		this.config = config;
+
+		// DEBUG:		
+		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) {
+			UpdateCore.debug("Start parsing Configuration:" + (config).getURL().toExternalForm()); //$NON-NLS-1$
+		}
+		
+		if (light) {
+			processConfigurationLight(this.platformConfig);
+		} else {
+			processConfig(this.platformConfig);
+		}
+	}
+	
+	
+
+
+
+	/** 
+	 * process the Site info
+	 */
+	private void processSite(SiteEntry siteEntry) throws CoreException, IOException {
+
+		//site url
+		siteURL = siteEntry.getURL();
+		try {
+			siteURL = FileLocator.toFileURL(siteURL);
+			// TODO workaround bug in platform url resolution
+			if (siteURL.getProtocol().equals("file")) //$NON-NLS-1$
+				siteURL = new File(siteURL.getFile()).toURL();
+		} catch (IOException e) {
+			// keep original url
+		}
+
+		// policy
+		ISite site = SiteManager.getSite(siteURL,null);
+
+		// configuration site
+		BaseSiteLocalFactory factory = new BaseSiteLocalFactory();
+		configSite = factory.createConfigurationSiteModel((SiteModel) site, siteEntry.getSitePolicy().getType());
+
+		//platform url
+		configSite.setPlatformURLString(siteEntry.getURL().toExternalForm());
+		
+		// configured
+		configSite.setEnabled(siteEntry.isEnabled());
+
+		// check if the site exists and is updatable
+	 	configSite.setUpdatable(siteEntry.isUpdateable());
+	 	
+		// add to install configuration
+	 	config.addConfigurationSiteModel(configSite);
+	 	configSite.setInstallConfigurationModel(config);
+		
+		FeatureEntry[] features = siteEntry.getFeatureEntries();
+		for (int i=0; i<features.length; i++) {
+			processFeature(features[i]);
+		}
+	}
+
+	/** 
+	 * process the DefaultFeature info
+	 */
+	private void processFeature(FeatureEntry feature) throws CoreException, IOException {
+
+		// url
+		String path = feature.getURL(); 
+		URL url = UpdateManagerUtils.getURL(siteURL, path, null);
+
+		if (url != null) {
+			SiteFeatureReference ref = new SiteFeatureReference();
+			ref.setSite((ISite) configSite.getSiteModel());
+			ref.setURL(url);
+			(configSite.getConfigurationPolicyModel()).addConfiguredFeatureReference(ref);
+
+			//updateURL
+//TODO do we need the update url and to resolve it?
+//			String updateURLString = attributes.getValue("updateURL"); //$NON-NLS-1$
+//			URLEntry entry = new URLEntry();
+//			entry.setURLString(updateURLString);
+//			entry.resolve(siteURL,null);
+
+			// DEBUG:		
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) {
+				UpdateCore.debug("End Processing DefaultFeature Tag: url:" + url.toExternalForm()); //$NON-NLS-1$
+			}
+
+		} else {
+			UpdateCore.log( Messages.InstallConfigurationParser_FeatureReferenceNoURL, new Exception()); 
+		}
+
+	}
+
+	/** 
+	 * process the Activity info
+	 */
+//	private void processActivity(Attributes attributes) {
+//
+//		// action
+//		String actionString = attributes.getValue("action"); //$NON-NLS-1$
+//		int action = Integer.parseInt(actionString);
+//
+//		// create
+//		ConfigurationActivityModel activity =
+//			new BaseSiteLocalFactory().createConfigurationActivityModel();
+//		activity.setAction(action);
+//
+//		// label
+//		String label = attributes.getValue("label"); //$NON-NLS-1$
+//		if (label != null)
+//			activity.setLabel(label);
+//
+//		// date
+//		String dateString = attributes.getValue("date"); //$NON-NLS-1$
+//		Date date = new Date(Long.parseLong(dateString));
+//		activity.setDate(date);
+//
+//		// status
+//		String statusString = attributes.getValue("status"); //$NON-NLS-1$
+//		int status = Integer.parseInt(statusString);
+//		activity.setStatus(status);
+//
+//		config.addActivityModel(activity);
+//
+//		// DEBUG:		
+//		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) {
+//			UpdateCore.debug("End Processing Activity: action:" + actionString + " label: " + label + " date:" + dateString + " status" + statusString); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+//		}
+//
+//	}
+
+	/** 
+	 * process the Config info
+	 */
+	private void processConfig(PlatformConfiguration platformConfig) throws IOException, CoreException {
+
+		// date
+		processConfigurationLight(platformConfig);
+		
+		//timeline
+//		String timelineString = attributes.getValue("timeline"); //$NON-NLS-1$
+//		long timeline = config.getCreationDate().getTime();
+//		if (timelineString!=null) {
+//			timeline = Long.parseLong(timelineString);
+//		}
+//		config.setTimeline(timeline);
+
+		SiteEntry[] sites = platformConfig.getConfiguration().getSites();
+		for (int i=0; i<sites.length; i++)
+			processSite(sites[i]);
+
+	}
+
+
+
+	private void processConfigurationLight(PlatformConfiguration platformConfig) {
+		Date date = new Date(platformConfig.getChangeStamp());
+		config.setCreationDate(date);
+		config.setLabel(date.toString());
+		
+		config.setCurrent( date.equals(org.eclipse.update.internal.configurator.PlatformConfiguration.getCurrent().getConfiguration().getDate()));
+	}
+	
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/SiteLocalModel.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/SiteLocalModel.java
new file mode 100644
index 0000000..499d471
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/SiteLocalModel.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.model;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.MissingResourceException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.update.core.model.ModelObject;
+import org.eclipse.update.internal.core.BaseSiteLocalFactory;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+
+/**
+ * This class manages the configurations.
+ */
+
+public class SiteLocalModel extends ModelObject {
+	public static final String CONFIG_FILE = "platform.xml"; //$NON-NLS-1$
+	private long stamp;
+	private String label;
+	private URL location;
+	private String locationURLString;
+	private int history = UpdateCore.DEFAULT_HISTORY;
+	private List /* of InstallConfigurationModel */configurations;
+	private List /* of InstallConfigurationModel */preservedConfigurations;
+	private InstallConfigurationModel currentConfiguration;
+
+	/**
+	 * Constructor for LocalSite
+	 */
+	public SiteLocalModel(){
+		super();
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public InstallConfigurationModel getCurrentConfigurationModel() {
+		return currentConfiguration;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public InstallConfigurationModel[] getConfigurationHistoryModel() {
+		if (configurations==null)
+			// initialize history
+			processHistory();
+		
+		if (configurations == null || configurations.size() == 0)
+			return new InstallConfigurationModel[0];
+		else
+			return (InstallConfigurationModel[])configurations.toArray(arrayTypeFor(configurations));
+	}
+
+	/**
+	 * adds a new configuration to the LocalSite
+	 *  the newly added configuration is teh current one
+	 */
+	public void addConfigurationModel(InstallConfigurationModel config) {
+		if (config != null) {
+			if (configurations == null)
+				configurations = new ArrayList();
+			if (!configurations.contains(config))
+				configurations.add(config);
+		}
+	}
+
+	/**
+	 * adds a new configuration to the LocalSite
+	 *  the newly added configuration is teh current one
+	 */
+	public boolean removeConfigurationModel(InstallConfigurationModel config) {
+		if (config != null) {
+			return configurations.remove(config);
+		}
+		return false;
+	}
+	/**
+	 * Gets the location of the local site.
+	 * @return Returns a URL
+	 */
+	public URL getLocationURL() {
+		return location;
+	}
+
+	/**
+	 * Gets the locationURLString.
+	 * @return Returns a String
+	 */
+	public String getLocationURLString() {
+		return locationURLString;
+	}
+
+
+	/**
+	 * Sets the locationURLString.
+	 * @param locationURLString The locationURLString to set
+	 */
+	public void setLocationURLString(String locationURLString) {
+		assertIsWriteable();
+		this.locationURLString = locationURLString;
+		this.location=null;
+	}
+
+
+	/**
+	 * @since 2.0
+	 */
+	public String getLabel() {
+		return label;
+	}
+
+	/**
+	 * Sets the label.
+	 * @param label The label to set
+	 */
+	public void setLabel(String label) {
+		assertIsWriteable();
+		this.label = label;
+	}
+
+	
+	/**
+	 * @since 2.0
+	 */
+	public int getMaximumHistoryCount() {
+		return history;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public void setMaximumHistoryCount(int history) {
+		assertIsWriteable();
+		this.history = history;
+	}
+
+	
+	/**
+	 * Adds a preserved configuration into teh collection
+	 * do not save the configuration
+	 * @since 2.0
+	 */
+	public void addPreservedInstallConfigurationModel(InstallConfigurationModel configuration) {
+		if (preservedConfigurations == null)
+			preservedConfigurations = new ArrayList();
+
+		preservedConfigurations.add(configuration);
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public boolean removePreservedConfigurationModel(InstallConfigurationModel configuration) {
+		if (preservedConfigurations != null) {
+			return preservedConfigurations.remove(configuration);
+		}
+		return false;
+	}
+
+	/**
+	 * @since 2.0
+	 */
+	public InstallConfigurationModel[] getPreservedConfigurationsModel() {
+		if (preservedConfigurations==null || preservedConfigurations.isEmpty())
+			return new InstallConfigurationModel[0];
+		return (InstallConfigurationModel[])preservedConfigurations.toArray(arrayTypeFor(preservedConfigurations));
+	}
+
+
+	/**
+	 * Sets the currentConfiguration.
+	 * @param currentConfiguration The currentConfiguration to set
+	 */
+	public void setCurrentConfigurationModel(InstallConfigurationModel currentConfiguration) {
+		assertIsWriteable();
+		this.currentConfiguration = currentConfiguration;
+		
+		//2.0.2 set the configuredSite of sites
+		ConfiguredSiteModel[] confSites = currentConfiguration.getConfigurationSitesModel();
+		for (int i = 0; i < confSites.length; i++) {
+			confSites[i].getSiteModel().setConfiguredSiteModel(confSites[i]);
+		}
+	}
+
+	/*
+	 * @see ModelObject#resolve(URL)
+	 */
+	public void resolve(URL base,URL bundleURL) throws MalformedURLException {
+		// local
+		location = resolveURL(base,bundleURL,getLocationURLString());
+		
+		// delegate
+		resolveListReference(getConfigurationHistoryModel(),base,bundleURL);
+		resolveListReference(getPreservedConfigurationsModel(),base,bundleURL);
+		resolveReference(getCurrentConfigurationModel(),base,bundleURL);
+	}
+	
+
+	/**
+	 * Gets the stamp.
+	 * @return Returns a long
+	 */
+	public long getStamp() {
+		return stamp;
+	}
+
+	/**
+	 * Sets the stamp.
+	 * @param stamp The stamp to set
+	 */
+	public void setStamp(long stamp) {
+		this.stamp = stamp;
+	}
+
+	/**
+	 * @see org.eclipse.update.core.model.ModelObject#getPropertyName()
+	 */
+	protected String getPropertyName() {
+		return "platform"; //$NON-NLS-1$
+	}
+
+	/*
+	 * reads the configuration/history directory
+	 */
+	private void processHistory() {
+		try {
+			URL historyURL = new URL(getLocationURL(), "history"); //$NON-NLS-1$
+			historyURL = FileLocator.toFileURL(historyURL);
+			File historyDir = new File(historyURL.getFile());
+			if (historyDir.exists()) {
+				File[] backedConfigs = historyDir.listFiles();
+				BaseSiteLocalFactory factory = new BaseSiteLocalFactory();
+				for (int i=0; i<backedConfigs.length; i++) {
+					String name = backedConfigs[i].getName();
+					if (name.endsWith(".xml")) //$NON-NLS-1$
+						name = name.substring(0, name.length()-4);
+					else 
+						continue;
+					Date date = new Date(Long.parseLong(name));
+					InstallConfigurationModel config = factory.createInstallConfigurationModel();
+					config.setLocationURLString(backedConfigs[i].getAbsolutePath().replace('\\', '/'));
+					config.setLabel(date.toString());
+					config.setCreationDate(date);
+					config.resolve(backedConfigs[i].toURL(), getResourceBundleURL());
+	
+					// add the config
+					addConfigurationModel(config);
+				}
+			}
+		} catch (Exception e) {
+			UpdateCore.warn("Error processing history: ", e); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * return the appropriate resource bundle for this sitelocal
+	 */
+	URL getResourceBundleURL() throws CoreException {
+		URL url = null;
+		try {
+			url = UpdateManagerUtils.asDirectoryURL(getLocationURL());
+		} catch (MissingResourceException e) {
+			UpdateCore.warn(e.getLocalizedMessage() + ":" + url.toExternalForm()); //$NON-NLS-1$
+		} catch (MalformedURLException e) {
+			UpdateCore.warn(e.getLocalizedMessage()); 
+		}
+		return url;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/SiteLocalParser.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/SiteLocalParser.java
new file mode 100644
index 0000000..4b72663
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/SiteLocalParser.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.model;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.configuration.ILocalSite;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.internal.configurator.PlatformConfiguration;
+import org.eclipse.update.internal.core.BaseSiteLocalFactory;
+import org.eclipse.update.internal.core.InstallConfiguration;
+import org.eclipse.update.internal.core.LocalSite;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+
+/**
+ * parse the default site.xml
+ */
+
+public class SiteLocalParser {
+
+	private PlatformConfiguration platformConfig;
+	private SiteLocalModel site;
+	public static final String CONFIG = "config"; //$NON-NLS-1$
+	private ResourceBundle bundle;
+	private BaseSiteLocalFactory factory = new BaseSiteLocalFactory();
+
+	/**
+	 * return the appropriate resource bundle for this sitelocal
+	 */
+	private ResourceBundle getResourceBundle() throws CoreException {
+		ResourceBundle bundle = null;
+		URL url = null;
+		try {
+			url = UpdateManagerUtils.asDirectoryURL(site.getLocationURL());
+			ClassLoader l = new URLClassLoader(new URL[] { url }, null);
+			bundle = ResourceBundle.getBundle("platform", Locale.getDefault(), l); //$NON-NLS-1$
+		} catch (MissingResourceException e) {
+			UpdateCore.warn(e.getLocalizedMessage() + ":" + url.toExternalForm()); //$NON-NLS-1$
+		} catch (MalformedURLException e) {
+			UpdateCore.warn(e.getLocalizedMessage()); 
+		}
+		return bundle;
+	}
+
+	/**
+	 * Constructor for DefaultSiteParser
+	 */
+	public SiteLocalParser(IPlatformConfiguration platformConfig, ILocalSite site) throws IOException, CoreException {
+		Assert.isTrue(platformConfig instanceof PlatformConfiguration);
+		this.platformConfig = (PlatformConfiguration)platformConfig;
+		
+		Assert.isTrue(site instanceof SiteLocalModel);
+		this.site = (SiteLocalModel) site;
+
+		// DEBUG:		
+		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) {
+			UpdateCore.debug("Start parsing localsite:" + ((SiteLocalModel) site).getLocationURLString()); //$NON-NLS-1$
+		}
+		
+		bundle = getResourceBundle();
+		
+		processConfig();
+		//processHistory();
+	}
+
+	
+//	/** 
+//	 * process the Site info
+//	 */
+//	private void processSite(Attributes attributes) throws MalformedURLException {
+//		//
+//		String info = attributes.getValue("label"); //$NON-NLS-1$
+//		info = UpdateManagerUtils.getResourceString(info, bundle);
+//		site.setLabel(info);
+//	
+//		// history
+//		String historyString = attributes.getValue("history"); //$NON-NLS-1$
+//		int history;
+//		if (historyString == null || historyString.equals("")) { //$NON-NLS-1$
+//			history = SiteLocalModel.DEFAULT_HISTORY;
+//		} else {
+//			history = Integer.parseInt(historyString);
+//		}
+//		site.setMaximumHistoryCount(history);
+//	
+//		//stamp
+//		String stampString = attributes.getValue("stamp"); //$NON-NLS-1$
+//		long stamp = Long.parseLong(stampString);
+//		site.setStamp(stamp);
+//	
+//		// DEBUG:		
+//		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) {
+//			UpdateCore.debug("End process Site label:" + info); //$NON-NLS-1$
+//		}
+//	
+//	}
+
+	/** 
+	 * process the Config info
+	 */
+	private void processConfig() throws MalformedURLException, CoreException {
+
+		String label = platformConfig.getConfiguration().getDate().toString();
+		label = UpdateManagerUtils.getResourceString(label, bundle);
+		site.setLabel(label);
+
+		URL url = site.getLocationURL();
+		InstallConfigurationModel config = factory.createInstallConfigurationModel();
+		config.setLocationURLString(url.toExternalForm());
+		config.setLabel(label);
+		config.resolve(url, site.getResourceBundleURL());
+
+		// add the config
+		((LocalSite)site).addConfiguration((InstallConfiguration)config);
+
+		// DEBUG:		
+		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) {
+			UpdateCore.debug("End Processing Config Tag: url:" + url.toExternalForm()); //$NON-NLS-1$
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/SiteWithTimestamp.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/SiteWithTimestamp.java
new file mode 100644
index 0000000..a74d323
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/model/SiteWithTimestamp.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.model;
+
+import java.util.Date;
+
+import org.eclipse.update.core.Site;
+
+/**
+ * This is a wrapper class for Site class that adds timestamp
+ * 
+ *
+ */
+public class SiteWithTimestamp extends Site implements ITimestamp {
+
+	private Date timestamp;
+	
+	/*private Site site;
+	
+	public SiteWithTimestamp( Site site) {
+		this.site = site;
+	}*/
+	
+	public Date getTimestamp() {
+		return timestamp;
+	}
+
+	public void setTimestamp(Date timestamp) {
+		this.timestamp = timestamp;
+		
+	}
+/*
+	public boolean isReadOnly() {
+		return site.isReadOnly();
+	}
+
+	public Object getAdapter(Class adapter) {		
+		return site.getAdapter(adapter);
+	}
+
+	public void addPluginEntry(IPluginEntry pluginEntry) {		
+		site.addPluginEntry(pluginEntry);
+	}
+
+	public IFeature createFeature(String type, URL url) throws CoreException {	
+		return site.createFeature(type, url);
+	}
+
+	public IFeature createFeature(String type, URL url, IProgressMonitor monitor) throws CoreException {		
+		return site.createFeature(type, url, monitor);
+	}
+
+	public IArchiveReference[] getArchives() {		
+		return site.getArchives();
+	}
+
+	public ICategory[] getCategories() {		
+		return site.getCategories();
+	}
+
+	public ICategory getCategory(String key) {		
+		return site.getCategory(key);
+	}
+
+	public IConfiguredSite getCurrentConfiguredSite() {	
+		return site.getCurrentConfiguredSite();
+	}
+
+	public String getDefaultPackagedFeatureType() {	
+		return site.getDefaultPackagedFeatureType();
+	}
+
+	public IURLEntry getDescription() {	
+		return site.getDescription();
+	}
+
+	public long getDownloadSizeFor(IFeature feature) {	
+		return site.getDownloadSizeFor(feature);
+	}
+
+	public ISiteFeatureReference getFeatureReference(IFeature feature) {	
+		return site.getFeatureReference(feature);
+	}
+
+	public ISiteFeatureReference[] getFeatureReferences() {	
+		return site.getFeatureReferences();
+	}
+
+	public long getInstallSizeFor(IFeature feature) {	
+		return site.getInstallSizeFor(feature);
+	}
+
+	public IURLEntry[] getMirrorSiteEntries() {	
+		return site.getMirrorSiteEntries();
+	}
+
+	public IPluginEntry[] getPluginEntries() {	
+		return site.getPluginEntries();
+	}
+
+	public IPluginEntry[] getPluginEntriesOnlyReferencedBy(IFeature feature) throws CoreException {	
+		return site.getPluginEntriesOnlyReferencedBy(feature);
+	}
+
+	public int getPluginEntryCount() {		
+		return site.getPluginEntryCount();
+	}
+
+	public ISiteFeatureReference[] getRawFeatureReferences() {	
+		return site.getRawFeatureReferences();
+	}
+
+	public ISiteContentProvider getSiteContentProvider() throws CoreException {	
+		return site.getSiteContentProvider();
+	}
+
+	public URL getURL() {	
+		return site.getURL();
+	}
+
+	public IFeatureReference install(IFeature sourceFeature, IFeatureReference[] optionalFeatures, IFeatureContentConsumer parentContentConsumer, IVerifier parentVerifier, IVerificationListener verificationListener, IProgressMonitor progress) throws CoreException {	
+		return site.install(sourceFeature, optionalFeatures, parentContentConsumer,
+				parentVerifier, verificationListener, progress);
+	}
+
+	public IFeatureReference install(IFeature sourceFeature, IFeatureReference[] optionalFeatures, IVerificationListener verificationListener, IProgressMonitor progress) throws InstallAbortedException, CoreException {		
+		return site.install(sourceFeature, optionalFeatures, verificationListener,
+				progress);
+	}
+
+	public IFeatureReference install(IFeature sourceFeature, IVerificationListener verificationListener, IProgressMonitor progress) throws InstallAbortedException, CoreException {		
+		return site.install(sourceFeature, verificationListener, progress);
+	}
+
+	public void remove(IFeature feature, IProgressMonitor progress) throws CoreException {		
+		site.remove(feature, progress);
+	}
+
+	public void setSiteContentProvider(ISiteContentProvider siteContentProvider) {		
+		site.setSiteContentProvider(siteContentProvider);
+	}
+
+	public void addArchiveReferenceModel(ArchiveReferenceModel archiveReference) {		
+		site.addArchiveReferenceModel(archiveReference);
+	}
+
+	public void addCategoryModel(CategoryModel category) {		
+		site.addCategoryModel(category);
+	}
+
+	public void addFeatureReferenceModel(SiteFeatureReferenceModel featureReference) {		
+		site.addFeatureReferenceModel(featureReference);
+	}
+
+	public void addMirrorModel(URLEntryModel mirror) {		
+		site.addMirrorModel(mirror);
+	}
+
+	public ArchiveReferenceModel[] getArchiveReferenceModels() {		
+		return site.getArchiveReferenceModels();
+	}
+
+	public CategoryModel[] getCategoryModels() {	
+		return site.getCategoryModels();
+	}
+
+	public ConfiguredSiteModel getConfiguredSiteModel() {	
+		return site.getConfiguredSiteModel();
+	}
+
+	public URLEntryModel getDescriptionModel() {	
+		return site.getDescriptionModel();
+	}
+
+	public SiteFeatureReferenceModel[] getFeatureReferenceModels() {		
+		return site.getFeatureReferenceModels();
+	}
+
+	public URL getLocationURL() {		
+		return site.getLocationURL();
+	}
+
+	public String getLocationURLString() {		
+		return site.getLocationURLString();
+	}
+
+	public URLEntryModel[] getMirrorSiteEntryModels() {	
+		return site.getMirrorSiteEntryModels();
+	}
+
+	public String getType() {	
+		return site.getType();
+	}
+
+	public void markReadOnly() {	
+		site.markReadOnly();
+	}
+
+	public void removeArchiveReferenceModel(ArchiveReferenceModel archiveReference) {	
+		site.removeArchiveReferenceModel(archiveReference);
+	}
+
+	public void removeCategoryModel(CategoryModel category) {	
+		site.removeCategoryModel(category);
+	}
+
+	public void removeFeatureReferenceModel(FeatureReferenceModel featureReference) {	
+		site.removeFeatureReferenceModel(featureReference);
+	}
+
+	public void removeMirror(URLEntryModel mirror) {		
+		site.removeMirror(mirror);
+	}
+
+	public void resolve(URL base, URL bundleURL) throws MalformedURLException {		
+		site.resolve(base, bundleURL);
+	}
+
+	public void setArchiveReferenceModels(ArchiveReferenceModel[] archiveReferences) {		
+		site.setArchiveReferenceModels(archiveReferences);
+	}
+
+	public void setCategoryModels(CategoryModel[] categories) {		
+		site.setCategoryModels(categories);
+	}
+
+	public void setConfiguredSiteModel(ConfiguredSiteModel configuredSiteModel) {		
+		site.setConfiguredSiteModel(configuredSiteModel);
+	}
+
+	public void setDescriptionModel(URLEntryModel description) {		
+		site.setDescriptionModel(description);
+	}
+
+	public void setFeatureReferenceModels(FeatureReferenceModel[] featureReferences) {		
+		site.setFeatureReferenceModels(featureReferences);
+	}
+
+	public void setLocationURLString(String locationURLString) {		
+		site.setLocationURLString(locationURLString);
+	}
+
+	public void setMirrorSiteEntryModels(URLEntryModel[] mirrors) {		
+		site.setMirrorSiteEntryModels(mirrors);
+	}
+
+	public void setMirrorsURLString(String mirrorsURL) {		
+		site.setMirrorsURLString(mirrorsURL);
+	}
+
+	public void setType(String type) {		
+		site.setType(type);
+	}
+*/
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/BatchFeatureOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/BatchFeatureOperation.java
new file mode 100644
index 0000000..cf8436f
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/BatchFeatureOperation.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.IOperationListener;
+
+public abstract class BatchFeatureOperation extends Operation implements IBatchFeatureOperation {
+
+	private IFeature[] features;
+	private IConfiguredSite[] targetSites;
+	
+	
+	public BatchFeatureOperation(IConfiguredSite[] targetSites, IFeature[] features) {
+		super();
+		this.features = features;
+		this.targetSites = targetSites;
+	}
+	
+	public IFeature[] getFeatures() {
+		return features;
+	}
+
+	public IConfiguredSite[] getTargetSites() {
+		return targetSites;
+	}
+
+	public void setTargetSites(IConfiguredSite[] targetSites) {
+		this.targetSites = targetSites;
+		
+	}
+	
+	public boolean execute(IProgressMonitor pm, IOperationListener listener)
+		throws CoreException, InvocationTargetException {
+
+		if (getFeatures() == null || getFeatures().length == 0)
+			return false;
+		IOperation[] operations = new IOperation[getFeatures().length];
+		
+		for ( int i = 0; i < getFeatures().length; i ++) { 
+			operations[i] = createOperation(getTargetSites()[i], getFeatures()[i]);
+		}
+		
+		boolean restartNeeded = false;
+
+		for ( int i = 0; i < operations.length; i ++) { 
+			try {
+				boolean status = operations[i].execute(pm, listener);
+				if (status)
+					restartNeeded = true; 
+			} catch (Throwable t) {
+				t.printStackTrace();
+			}
+		}	
+
+		return restartNeeded;
+
+	}
+
+	protected abstract IOperation createOperation(IConfiguredSite targetSite, IFeature feature);
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/BatchInstallOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/BatchInstallOperation.java
new file mode 100644
index 0000000..d524d2d
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/BatchInstallOperation.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import java.lang.reflect.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.operations.*;
+
+public class BatchInstallOperation
+	extends Operation
+	implements IBatchOperation {
+		
+	protected IInstallFeatureOperation[] operations;
+
+	public BatchInstallOperation(IInstallFeatureOperation[] operations) {
+		super();
+		this.operations = operations;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.operations.IMultiOperation#getOperations()
+	 */
+	public IFeatureOperation[] getOperations() {
+		return operations;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.operations.IOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public boolean execute(IProgressMonitor monitor, IOperationListener listener) throws CoreException, InvocationTargetException {
+		int installCount = 0;
+
+		if (operations == null || operations.length == 0)
+			return false;
+					
+		IStatus status = OperationsManager.getValidator().validatePendingChanges(operations);
+		if (status != null && status.getCode() == IStatus.ERROR) {
+			throw new CoreException(status);
+		}
+		
+//		// Check for duplication conflicts
+//		ArrayList conflicts =
+//			DuplicateConflictsValidator.computeDuplicateConflicts(
+//				operations,
+//				config);
+//		if (conflicts != null) {
+//			boolean continueProcessing = false;
+//			if (listener != null)
+//				continueProcessing = listener.beforeExecute(this, conflicts);
+//			if (!continueProcessing)
+//				return false;
+//		}
+		
+		OperationsManager.setInProgress(true);
+		if (monitor == null) 
+			monitor = new NullProgressMonitor();
+			
+		try {			
+			if (listener != null)
+				listener.beforeExecute(this, null);
+			
+			monitor.beginTask(
+				Messages.OperationsManager_installing,
+				operations.length);
+			for (int i = 0; i < operations.length; i++) {
+				SubProgressMonitor subMonitor =
+					new SubProgressMonitor(
+						monitor,
+						1,
+						SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+
+				operations[i].execute(subMonitor, listener);
+				OperationsManager.addPendingOperation(operations[i]);
+
+				operations[i].markProcessed();
+				if (listener != null)
+					listener.afterExecute(operations[i], null);
+
+				//monitor.worked(1);
+				installCount++;
+			}
+			return SiteManager.getLocalSite().save();
+        } catch (InstallAbortedException e) {
+            // saves the current configuration
+            if (installCount > 0) {
+                try {
+                    SiteManager.getLocalSite().save();
+                } catch (CoreException ce) {
+                    UpdateUtils.logException(ce);
+                }
+            }
+            throw new InvocationTargetException(e);
+        } catch (CoreException e) {
+            // saves the current configuration
+            if (installCount > 0) {
+                try {
+                    SiteManager.getLocalSite().save();
+                } catch (CoreException ce) {
+                    UpdateUtils.logException(ce);
+                }
+            }
+            throw new InvocationTargetException(e);
+        } finally {
+			OperationsManager.setInProgress(false);
+			monitor.done();
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigOperation.java
new file mode 100644
index 0000000..3bb18c0
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigOperation.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.operations.*;
+
+/**
+ * Configure a feature.
+ * ConfigOperation
+ */
+public class ConfigOperation
+extends FeatureOperation
+implements IConfigFeatureOperation {
+
+	public ConfigOperation(
+			IConfiguredSite site,
+			IFeature feature) {
+		super(site, feature);
+	}
+
+	public boolean execute(IProgressMonitor pm, IOperationListener listener)
+	throws CoreException {
+
+		IStatus status =
+			OperationsManager.getValidator().validatePendingConfig(feature);
+		if (status != null && status.getCode() == IStatus.ERROR) {
+			throw new CoreException(status);
+		}
+		try {
+			targetSite.configure(feature);
+			//ensureUnique();
+
+			// Restart not needed
+			boolean restartNeeded = false;
+
+			// Check if this operation is cancelling one that's already pending
+			IOperation pendingOperation =
+				OperationsManager.findPendingOperation(feature);
+
+			if (pendingOperation instanceof IUnconfigFeatureOperation) {
+				// no need to do either pending change
+				OperationsManager.removePendingOperation(pendingOperation);
+			} else {
+				OperationsManager.addPendingOperation(this);
+			}
+
+			markProcessed();
+			if (listener != null)
+				listener.afterExecute(this, null);
+
+			restartNeeded = SiteManager.getLocalSite().save() && restartNeeded;
+
+			// notify the model
+			OperationsManager.fireObjectChanged(feature, null);
+
+			return restartNeeded;
+		} catch (CoreException e) {
+			undo();
+			UpdateUtils.logException(e);
+			throw e;
+		}
+	}
+
+	public void undo() throws CoreException {
+		targetSite.unconfigure(feature);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigureFeaturesOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigureFeaturesOperation.java
new file mode 100644
index 0000000..3247973
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ConfigureFeaturesOperation.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class ConfigureFeaturesOperation extends BatchFeatureOperation implements
+		IConfigureFeaturesOperation {
+
+	public ConfigureFeaturesOperation(IConfiguredSite[] targetSites,
+			IFeature[] features) {
+		super(targetSites, features);
+	}
+
+	
+	protected IOperation createOperation(IConfiguredSite targetSite, IFeature feature) {
+		return OperationsManager.getOperationFactory().createConfigOperation(targetSite, feature);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/DuplicateConflictsValidator.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/DuplicateConflictsValidator.java
new file mode 100644
index 0000000..dda495e
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/DuplicateConflictsValidator.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IIncludedFeatureReference;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.operations.IInstallFeatureOperation;
+
+
+/**
+ * 
+ */
+public class DuplicateConflictsValidator  {
+
+	public static class IdEntry {
+		IConfiguredSite csite;
+		IFeature feature;
+
+		public IdEntry(IFeature feature, IConfiguredSite csite) {
+			this.feature = feature;
+			this.csite = csite;
+			if (csite == null) {
+				System.out.println("csite null"); //$NON-NLS-1$
+			}
+		}
+		public boolean isInstallCandidate() {
+			return csite != null;
+		}
+		public IFeature getFeature() {
+			return feature;
+		}
+
+		public String getIdentifier() {
+			return feature.getVersionedIdentifier().getIdentifier();
+		}
+		public IConfiguredSite getConfiguredSite() {
+			if (csite != null)
+				return csite;
+			return feature.getSite().getCurrentConfiguredSite();
+		}
+		public boolean sameLevel(IdEntry entry) {
+			VersionedIdentifier vid = feature.getVersionedIdentifier();
+			VersionedIdentifier evid =
+				entry.getFeature().getVersionedIdentifier();
+			return vid.equals(evid);
+		}
+		public String toString() {
+			IConfiguredSite configSite = getConfiguredSite();
+			String version =
+				feature.getVersionedIdentifier().getVersion().toString();
+			String location = configSite.getSite().getURL().getFile();
+			return NLS.bind(Messages.DuplicateConflictsDialog_conflict, (new String[] { version, location }));
+		}
+	}
+
+	public static ArrayList computeDuplicateConflicts(
+		IInstallFeatureOperation job,
+		IInstallConfiguration config,
+		IConfiguredSite targetSite,
+		IFeatureReference[] optionalFeatures) {
+		Hashtable featureTable = new Hashtable();
+		try {
+			computePresentState(featureTable, config);
+			computeNewFeature(
+				job.getFeature(),
+				targetSite,
+				featureTable,
+				optionalFeatures);
+			return computeConflicts(featureTable);
+		} catch (CoreException e) {
+			return null;
+		}
+	}
+
+	public static ArrayList computeDuplicateConflicts(
+		IInstallFeatureOperation[] jobs,
+		IInstallConfiguration config) {
+		Hashtable featureTable = new Hashtable();
+		computePresentState(featureTable, config);
+		computeNewFeatures(jobs, featureTable);
+		return computeConflicts(featureTable);
+	}
+
+	private static ArrayList computeConflicts(Hashtable featureTable) {
+		ArrayList result = null;
+		for (Enumeration iterator = featureTable.elements();
+			iterator.hasMoreElements();
+			) {
+			ArrayList candidate = (ArrayList) iterator.nextElement();
+			if (candidate.size() == 1)
+				continue;
+			ArrayList conflict = checkForConflict(candidate);
+			if (conflict != null) {
+				if (result == null)
+					result = new ArrayList();
+				result.add(conflict);
+			}
+		}
+		return result;
+	}
+
+	private static ArrayList checkForConflict(ArrayList candidate) {
+		IdEntry firstEntry = null;
+		for (int i = 0; i < candidate.size(); i++) {
+			IdEntry entry = (IdEntry) candidate.get(i);
+			if (firstEntry == null)
+				firstEntry = entry;
+			else if (!entry.sameLevel(firstEntry))
+				return candidate;
+		}
+		return null;
+	}
+
+	private static void computePresentState(
+		Hashtable table,
+		IInstallConfiguration config) {
+		IConfiguredSite[] csites = config.getConfiguredSites();
+		for (int i = 0; i < csites.length; i++) {
+			IConfiguredSite csite = csites[i];
+			IFeatureReference[] refs = csite.getConfiguredFeatures();
+			for (int j = 0; j < refs.length; j++) {
+				try {
+					addEntry(refs[j].getFeature(null), csite, table);
+				} catch (CoreException e) {
+					// don't let one bad feature stop the loop
+				}
+			}
+		}
+	}
+
+	private static void computeNewFeatures(
+		IInstallFeatureOperation[] jobs,
+		Hashtable featureTable) {
+		for (int i = 0; i < jobs.length; i++) {
+			IInstallFeatureOperation job = jobs[i];
+			IConfiguredSite targetSite = job.getTargetSite();
+			IFeature newFeature = job.getFeature();
+			try {
+				computeNewFeature(newFeature, targetSite, featureTable, null);
+			} catch (CoreException e) {
+			}
+		}
+	}
+
+	private static void computeNewFeature(
+		IFeature feature,
+		IConfiguredSite csite,
+		Hashtable table,
+		IFeatureReference[] optionalFeatures)
+		throws CoreException {
+		addEntry(feature, csite, table);
+		IIncludedFeatureReference[] irefs =
+			feature.getIncludedFeatureReferences();
+		for (int i = 0; i < irefs.length; i++) {
+			IIncludedFeatureReference iref = irefs[i];
+			boolean add = true;
+
+			if (iref.isOptional() && optionalFeatures != null) {
+				boolean found = false;
+				for (int j = 0; j < optionalFeatures.length; j++) {
+					IFeatureReference checked = optionalFeatures[j];
+					if (checked.equals(iref)) {
+						found = true;
+						break;
+					}
+				}
+				add = found;
+			}
+			if (add)
+				computeNewFeature(
+					iref.getFeature(null),
+					csite,
+					table,
+					optionalFeatures);
+		}
+	}
+
+	private static void addEntry(
+		IFeature feature,
+		IConfiguredSite csite,
+		Hashtable featureTable) {
+		String id = feature.getVersionedIdentifier().getIdentifier();
+		ArrayList entries = (ArrayList) featureTable.get(id);
+		if (entries == null) {
+			entries = new ArrayList();
+			featureTable.put(id, entries);
+		}
+		IdEntry entry = new IdEntry(feature, csite);
+		boolean replaced = false;
+		for (int i = 0; i < entries.size(); i++) {
+			IdEntry existingEntry = (IdEntry) entries.get(i);
+			IConfiguredSite existingSite = existingEntry.getConfiguredSite();
+			if (existingSite.equals(entry.getConfiguredSite())) {
+				// same site - replace it if not new
+				if (entry.isInstallCandidate()) {
+					entries.set(i, entry);
+					entries.remove(existingEntry);
+				}
+				replaced = true;
+				break;
+			}
+		}
+		if (!replaced)
+			entries.add(entry);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/FeatureHierarchyElement.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/FeatureHierarchyElement.java
new file mode 100644
index 0000000..1e71d39
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/FeatureHierarchyElement.java
@@ -0,0 +1,446 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+
+/**
+ * This class is used to construct a joint feature hiearchy.
+ * Old feature reference represents feature that is
+ * found on in the current configuration. New feature
+ * reference is found in the feature that is an install/update
+ * candidate. The element is used to join nodes of the
+ * hiearchy formed by including features so that
+ * each node in the hiearchy contains references to the
+ * old and the new feature. Old and new features have
+ * the same IDs but different versions, except in 
+ * the case of optional features, where the tree may
+ * be constructed to bring in an optional feature
+ * that was not installed initially. In that case,
+ * some nodes may have old an new references with the
+ * same ID and version. 
+ * <p>
+ * Old feature reference may be null. That means
+ * that the older feature with the same ID but lower
+ * version was not found in the current configuration.
+ */
+public class FeatureHierarchyElement {
+
+	private Object root;
+	private ArrayList children;
+	private IFeatureReference oldFeatureRef;
+	private IFeatureReference newFeatureRef;
+	private boolean checked;
+	private boolean optionalChildren;
+	private boolean nativeUpgrade = false;
+
+	public FeatureHierarchyElement(
+		IFeatureReference oldRef,
+		IFeatureReference newRef) {
+		oldFeatureRef = oldRef;
+		newFeatureRef = newRef;
+	}
+
+	public void setRoot(Object root) {
+		this.root = root;
+	}
+
+	public Object getRoot() {
+		return root;
+	}
+
+	/*
+	 * Return true if element can be checked, false otherwise.
+	 */
+	public boolean isEditable() {
+		// cannot uncheck non-optional features
+		if (isOptional() == false)
+			return false;
+		// cannot uncheck optional feature that
+		// has already been installed
+		if (oldFeatureRef != null)
+			return false;
+		return true;
+	}
+
+	/**
+	 * A hirearchy node represents a 'false update' if
+	 * both old and new references exist and both
+	 * point to the feature with the same ID and version.
+	 * These nodes will not any bytes to be downloaded - 
+	 * they simply exist to allow the hirarchy to
+	 * reach the optional children that are missing
+	 * and will be installed.
+	 */
+
+	public boolean isFalseUpdate() {
+		if (oldFeatureRef != null && newFeatureRef != null) {
+			try {
+				return oldFeatureRef.getVersionedIdentifier().equals(
+					newFeatureRef.getVersionedIdentifier());
+			} catch (CoreException e) {
+			}
+		}
+		return false;
+	}
+	/**
+	 * Returns true if feature is included as optional.
+	 */
+	public boolean isOptional() {
+		return newFeatureRef instanceof IIncludedFeatureReference
+			&& ((IIncludedFeatureReference) newFeatureRef).isOptional();
+	}
+	/**
+	 * Returns true if this optional feature is selected
+	 * for installation. Non-optional features or non-editable
+	 * features are always checked.
+	 */
+	public boolean isChecked() {
+		return checked;
+	}
+
+	void setNativeUpgrade(boolean nativeUpgrade) {
+		this.nativeUpgrade = nativeUpgrade;
+	}
+
+	/**
+	 * Returns true if this optional feature should
+	 * be enabled when installed. By default, all
+	 * features in the hiearchy should be enabled.
+	 * The exception is for optional features that
+	 * are updated to a new version in case where
+	 * the older version of the optional feature
+	 * is disabled in the given configuration. 
+	 * In this case, the feature is
+	 * updated and disabled in order to maintain
+	 * its state.
+	 */
+	public boolean isEnabled(IInstallConfiguration config) {
+		if (nativeUpgrade)
+			return true;
+		if (isOptional() && oldFeatureRef != null) {
+			try {
+				IFeature oldFeature = oldFeatureRef.getFeature(null);
+				IConfiguredSite csite =
+					UpdateUtils.getConfigSite(oldFeature, config);
+				return csite.isConfigured(oldFeature);
+			} catch (CoreException e) {
+			}
+		}
+		return true;
+	}
+
+	public IFeature getFeature() {
+		try {
+			IFeature feature = newFeatureRef.getFeature(null);
+			return feature;
+		} catch (CoreException e) {
+			return null;
+		}
+	}
+
+	/**
+	 * Selects an editable feature for installation.
+	 */
+	public void setChecked(boolean checked) {
+		this.checked = checked;
+	}
+	/**
+	 * Returns label for UI presentation.
+	 */
+	public String getLabel() {
+		try {
+			return getFeatureLabel(newFeatureRef);
+		} catch (CoreException e) {
+			if (newFeatureRef instanceof IIncludedFeatureReference) {
+				String iname =
+					((IIncludedFeatureReference) newFeatureRef).getName();
+				if (iname != null)
+					return iname;
+			}
+			try {
+				VersionedIdentifier vid =
+					newFeatureRef.getVersionedIdentifier();
+				return vid.toString();
+			} catch (CoreException e2) {
+			}
+		}
+		return null;
+	}
+	/**
+	 * Computes label from the feature.
+	 */
+	private String getFeatureLabel(IFeatureReference featureRef)
+		throws CoreException {
+		IFeature feature = featureRef.getFeature(null);
+		return feature.getLabel()
+			+ " " //$NON-NLS-1$
+			+ feature.getVersionedIdentifier().getVersion().toString();
+	}
+	/**
+	 * Computes children by linking matching features from the
+	 * old feature's and new feature's hierarchy.
+	 */
+	public FeatureHierarchyElement[] getChildren(
+		boolean update,
+		boolean patch,
+		IInstallConfiguration config) {
+		computeChildren(update, patch, config);
+		FeatureHierarchyElement[] array =
+			new FeatureHierarchyElement[children.size()];
+		children.toArray(array);
+		return array;
+	}
+
+	public FeatureHierarchyElement[] getChildren() {
+		if (children != null) {
+			FeatureHierarchyElement[] array =
+				new FeatureHierarchyElement[children.size()];
+			children.toArray(array);
+			return array;
+		}
+
+		return new FeatureHierarchyElement[0];
+	}
+	/**
+	 * Computes children of this node.
+	 */
+	public void computeChildren(
+		boolean update,
+		boolean patch,
+		IInstallConfiguration config) {
+		if (children == null) {
+			children = new ArrayList();
+			try {
+				IFeature oldFeature = null;
+				IFeature newFeature = null;
+				newFeature = newFeatureRef.getFeature(null);
+				if (oldFeatureRef != null)
+					oldFeature = oldFeatureRef.getFeature(null);
+				optionalChildren =
+					computeElements(
+						oldFeature,
+						newFeature,
+						update,
+						patch,
+						config,
+						children);
+				for (int i = 0; i < children.size(); i++) {
+					FeatureHierarchyElement element =
+						(FeatureHierarchyElement) children.get(i);
+					element.setRoot(getRoot());
+				}
+			} catch (CoreException e) {
+			}
+		}
+	}
+	/**
+	 * 
+	 */
+	public boolean hasOptionalChildren() {
+		return optionalChildren;
+	}
+	/**
+	 * Adds checked optional features to the provided set.
+	 */
+	public void addCheckedOptionalFeatures(
+		boolean update,
+		boolean patch,
+		IInstallConfiguration config,
+		Set set) {
+		if (isOptional() && isChecked()) {
+			// Do not add checked optional features
+			// if this is an update case but
+			// the node is not a 'true' update
+			// (old and new feature are the equal)
+			if (!update || !isFalseUpdate())
+				set.add(newFeatureRef);
+		}
+		FeatureHierarchyElement[] elements = getChildren(update, patch, config);
+		for (int i = 0; i < elements.length; i++) {
+			elements[i].addCheckedOptionalFeatures(update, patch, config, set);
+		}
+	}
+
+	/**
+	 * Computes first-level children of the linked hierarchy
+	 * for the provided old and new features (same ID, different version
+	 * where new version is greater or equal the old version).
+	 * Old feature may be null. 
+	 */
+	public static boolean computeElements(
+		IFeature oldFeature,
+		IFeature newFeature,
+		boolean update,
+		boolean patch,
+		IInstallConfiguration config,
+		ArrayList list) {
+		Object[] oldChildren = null;
+		Object[] newChildren = getIncludedFeatures(newFeature);
+		boolean optionalChildren = false;
+
+		try {
+			if (oldFeature != null) {
+				oldChildren = getIncludedFeatures(oldFeature);
+			}
+			for (int i = 0; i < newChildren.length; i++) {
+				IFeatureReference oldRef = null;
+				IFeatureReference newRef = (IFeatureReference) newChildren[i];
+				if (oldChildren != null) {
+					String newId =
+						newRef.getVersionedIdentifier().getIdentifier();
+
+					for (int j = 0; j < oldChildren.length; j++) {
+						IFeatureReference cref =
+							(IFeatureReference) oldChildren[j];
+						try {
+							if (cref
+								.getVersionedIdentifier()
+								.getIdentifier()
+								.equals(newId)) {
+								oldRef = cref;
+								break;
+							}
+						} catch (CoreException ex) {
+						}
+					}
+				} else if (patch) {
+					// 30849 - find the old reference in the
+					// configuration.
+					if (!UpdateUtils.isPatch(newFeature)) {
+						oldRef = findPatchedReference(newRef, config);
+					}
+				}
+				// test if the old optional feature exists
+				if (oldRef != null
+					&& ((oldRef instanceof IIncludedFeatureReference
+						&& ((IIncludedFeatureReference) oldRef).isOptional())
+						|| patch)) {
+					try {
+						IFeature f = oldRef.getFeature(null);
+						if (f == null)
+							oldRef = null;
+					} catch (CoreException e) {
+						// missing
+						oldRef = null;
+					}
+				}
+				FeatureHierarchyElement element =
+					new FeatureHierarchyElement(oldRef, newRef);
+				// If this is an update (old feature exists), 
+				// only check the new optional feature if the old exists.
+				// Otherwise, always check.
+				if (element.isOptional() && (update || patch)) {
+					element.setChecked(oldRef != null);
+					if (oldRef == null) {
+						// Does not have an old reference,
+						// but it may contain an older
+						// feature that may still qualify
+						// for update. For example,
+						// an older version may have been
+						// installed natively from the CD-ROM.
+						if (hasOlderVersion(newRef)) {
+							element.setNativeUpgrade(true);
+							element.setChecked(true);
+						}
+					}
+				} else
+					element.setChecked(true);
+				list.add(element);
+				element.computeChildren(update, patch, config);
+				if (element.isOptional() || element.hasOptionalChildren())
+					optionalChildren = true;
+			}
+		} catch (CoreException e) {
+		}
+		return optionalChildren;
+	}
+	public static boolean hasOlderVersion(IFeatureReference newRef) {
+		try {
+			VersionedIdentifier vid = newRef.getVersionedIdentifier();
+			PluginVersionIdentifier version = vid.getVersion();
+			String mode = getUpdateVersionsMode();
+
+			IFeature[] allInstalled =
+				UpdateUtils.getInstalledFeatures(vid, false);
+			for (int i = 0; i < allInstalled.length; i++) {
+				IFeature candidate = allInstalled[i];
+				PluginVersionIdentifier cversion =
+					candidate.getVersionedIdentifier().getVersion();
+				// Verify that the difference qualifies as
+				// an update.
+				if (mode.equals(UpdateCore.EQUIVALENT_VALUE)) {
+					if (version.isEquivalentTo(cversion))
+						return true;
+				} else if (mode.equals(UpdateCore.COMPATIBLE_VALUE)) {
+					if (version.isCompatibleWith(cversion))
+						return true;
+				}
+			}
+		} catch (CoreException e) {
+		}
+		return false;
+	}
+
+	private static IFeatureReference findPatchedReference(
+		IFeatureReference newRef,
+		IInstallConfiguration config)
+		throws CoreException {
+		VersionedIdentifier vid = newRef.getVersionedIdentifier();
+		IConfiguredSite[] csites = config.getConfiguredSites();
+		for (int i = 0; i < csites.length; i++) {
+			IConfiguredSite csite = csites[i];
+			IFeatureReference[] refs = csite.getConfiguredFeatures();
+			for (int j = 0; j < refs.length; j++) {
+				IFeatureReference ref = refs[j];
+				VersionedIdentifier refVid = ref.getVersionedIdentifier();
+				if (vid.getIdentifier().equals(refVid.getIdentifier()))
+					return ref;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns included feature references for the given reference.
+	 */
+	public static Object[] getIncludedFeatures(IFeatureReference ref) {
+		try {
+			IFeature feature = ref.getFeature(null);
+			return getIncludedFeatures(feature);
+		} catch (CoreException e) {
+		}
+		return new Object[0];
+	}
+
+	/**
+	 * Returns included feature references for the given feature.
+	 */
+
+	public static Object[] getIncludedFeatures(IFeature feature) {
+		try {
+			return feature.getIncludedFeatureReferences();
+		} catch (CoreException e) {
+		}
+		return new Object[0];
+	}
+
+	private static String getUpdateVersionsMode() {
+		Preferences store = UpdateCore.getPlugin().getPluginPreferences();
+		return store.getString(UpdateCore.P_UPDATE_VERSIONS);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/FeatureOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/FeatureOperation.java
new file mode 100644
index 0000000..dd7f988
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/FeatureOperation.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.operations.*;
+
+
+public abstract class FeatureOperation extends Operation implements IFeatureOperation {
+	
+	protected IFeature feature;
+	protected IFeature oldFeature;
+	protected IConfiguredSite targetSite;
+
+//	private boolean optionalDelta;
+	
+	
+	public FeatureOperation(IConfiguredSite targetSite, IFeature feature) {
+		super();
+		this.feature = feature;
+		this.targetSite = targetSite;
+	}
+
+	public IFeature getFeature() {
+		return feature;
+	}
+	
+	public IFeature getOldFeature() {
+		return oldFeature;
+	}
+	
+//	public boolean isOptionalDelta() {
+//		return optionalDelta;
+//	}
+	
+	public IConfiguredSite getTargetSite() {
+		return targetSite;
+	}
+
+	public void setTargetSite(IConfiguredSite targetSite) {
+		this.targetSite = targetSite;
+	}
+	
+
+	static boolean unconfigure(IFeature feature, IConfiguredSite site)
+		throws CoreException {
+		IInstallConfiguration config = SiteManager.getLocalSite().getCurrentConfiguration();
+		if (site == null)
+			site = UpdateUtils.getConfigSite(feature, config);
+		
+		if (site != null) {
+			PatchCleaner cleaner = new PatchCleaner(site, feature);
+			boolean result = site.unconfigure(feature);
+			cleaner.dispose();
+			return result;
+		}
+		return false;
+	}
+
+	public void setFeature(IFeature feature) {
+		this.feature = feature;
+	}
+	
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/FeatureStatus.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/FeatureStatus.java
new file mode 100644
index 0000000..982ed53
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/FeatureStatus.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+
+
+/**
+ * The feature status provide info about the broken features and what is
+ * wrong.
+ */
+public class FeatureStatus extends Status {
+	public final static int CODE_OTHER = IStatus.OK;//0
+	public final static int CODE_PREREQ_FEATURE = 1;
+	public final static int CODE_PREREQ_PLUGIN = 2;
+	public final static int CODE_EXCLUSIVE = 4;
+	public final static int CODE_CYCLE = 8;
+	public final static int CODE_OPTIONAL_CHILD = 16;
+	public final static int CODE_ENVIRONMENT = 32;
+	IFeature feature;
+
+	public FeatureStatus(IFeature feature, int severity, String pluginId, int code, String message, Throwable exception) {
+		super(severity, pluginId, code, message, exception);
+		this.feature = feature;
+	}
+	public IFeature getFeature() {
+		return feature;
+	}
+	public boolean equals(Object obj) {
+		if (!(obj instanceof FeatureStatus))
+			return false;
+		FeatureStatus fs = (FeatureStatus) obj;
+		// only check for feature, regardless of status type
+		if (fs.getFeature() == feature)
+			return true;
+		else if (fs.getFeature() == null && feature == null)
+			return fs.getMessage().equals(getMessage());
+		else if (fs.getFeature() == null && feature != null)
+			return false;
+		else if (fs.getFeature() != null && feature == null)
+			return false;
+		else if (fs.getFeature().equals(feature))
+			return true;
+		else
+			return false;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IBatchFeatureOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IBatchFeatureOperation.java
new file mode 100644
index 0000000..75d7ada
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IBatchFeatureOperation.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.operations.IOperation;
+
+public interface IBatchFeatureOperation extends IOperation {
+
+	/**
+	 * Returns the features to operate on.
+	 * @return the features to operate on.
+	 */
+	public abstract IFeature[] getFeatures();
+	/**
+	 * Returns the site in which the operation is applied.
+	 * @return the site that owns or will own the feature.
+	 */
+	public abstract IConfiguredSite[] getTargetSites();
+
+	/**
+	 * Sets the site in which the feature is being operated on.
+	 * @param targetSite the site in which the featre is being operated on.
+	 */
+	public abstract void setTargetSites(IConfiguredSite[] targetSite);
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IConfigureFeaturesOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IConfigureFeaturesOperation.java
new file mode 100644
index 0000000..b1c3534
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IConfigureFeaturesOperation.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+public interface IConfigureFeaturesOperation extends IBatchFeatureOperation {
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUnconfigureAndUninstallFeatureOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUnconfigureAndUninstallFeatureOperation.java
new file mode 100644
index 0000000..ce5006d
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUnconfigureAndUninstallFeatureOperation.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.update.operations.IFeatureOperation;
+
+public interface IUnconfigureAndUninstallFeatureOperation extends
+		IFeatureOperation {
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUnconfigureAndUninstallFeaturesOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUnconfigureAndUninstallFeaturesOperation.java
new file mode 100644
index 0000000..de9216f
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUnconfigureAndUninstallFeaturesOperation.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+public interface IUnconfigureAndUninstallFeaturesOperation extends
+		IBatchFeatureOperation {
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUnconfigureFeaturesOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUnconfigureFeaturesOperation.java
new file mode 100644
index 0000000..bdf5d5d
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUnconfigureFeaturesOperation.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+
+public interface IUnconfigureFeaturesOperation extends IBatchFeatureOperation {
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUninstallFeaturesOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUninstallFeaturesOperation.java
new file mode 100644
index 0000000..46e6117
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/IUninstallFeaturesOperation.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+public interface IUninstallFeaturesOperation extends IBatchFeatureOperation {
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/InstallOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/InstallOperation.java
new file mode 100644
index 0000000..a282a70
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/InstallOperation.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import java.util.HashSet;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.operations.*;
+
+/**
+ * Configure a feature.
+ * ConfigOperation
+ */
+public class InstallOperation
+	extends FeatureOperation
+	implements IInstallFeatureOperation {
+	
+	public boolean equals(Object arg) {
+		if (arg == null) {
+			return false;
+		}
+		
+		if (!(arg instanceof InstallOperation)) {
+			return false;
+		}
+		
+		InstallOperation io = (InstallOperation)arg;
+		
+		return io.getFeature().getVersionedIdentifier().equals(this.getFeature().getVersionedIdentifier());
+	}
+
+	public int hashCode() {
+		// TODO Auto-generated method stub
+		return super.getFeature().hashCode();
+	}
+
+	private IFeatureReference[] optionalFeatures;
+	private IFeature[] unconfiguredOptionalFeatures;
+	private IVerificationListener verifier;
+
+	/**
+	 * Constructor
+	 * @param site
+	 * @param feature
+	 * @param optionalFeatures optional features to install. If null, the operation will install them all (if any)
+	 * @param unconfiguredOptionalElements optional features unconfigured before the operation. They should remain unconfigured after the install.
+	 * @param verifier
+	 */
+	public InstallOperation(
+		IConfiguredSite site,
+		IFeature feature,
+		IFeatureReference[] optionalFeatures,
+		IFeature[] unconfiguredOptionalElements,
+		IVerificationListener verifier) {
+		super(site, feature);
+		IFeature[] installed = UpdateUtils.getInstalledFeatures(feature);
+		if (installed.length > 0)
+			this.oldFeature = installed[0];
+		this.unconfiguredOptionalFeatures = unconfiguredOptionalElements;
+		this.optionalFeatures = optionalFeatures;
+		this.verifier = verifier;
+	}
+
+	public IFeatureReference[] getOptionalFeatures() {
+		return optionalFeatures;
+	}
+
+	public boolean execute(IProgressMonitor pm, IOperationListener listener)
+		throws CoreException {
+
+		boolean reinstall = false;
+		if (oldFeature != null
+			&& feature.getVersionedIdentifier().equals(
+				oldFeature.getVersionedIdentifier()))
+			reinstall = true;
+
+		setOptionalFeatures();
+
+		if (optionalFeatures == null)
+			targetSite.install(feature, verifier, pm);
+		else
+			targetSite.install(feature, optionalFeatures, verifier, pm);
+
+		if (!reinstall) {
+
+			if (oldFeature != null) { //&& isOptionalDelta()) {
+				preserveOptionalState();
+
+				boolean oldSuccess = unconfigure(oldFeature, null); // pick any site containing old feature
+				if (!oldSuccess) {
+					IInstallConfiguration config = SiteManager.getLocalSite().getCurrentConfiguration();
+					if (!UpdateUtils.isNestedChild(config, oldFeature)) {
+						// "eat" the error if nested child
+						String message =
+							NLS.bind(Messages.OperationsManager_error_old, (new String[] { oldFeature.getLabel() }));
+						IStatus status =
+							new Status(
+								IStatus.ERROR,
+								UpdateUtils.getPluginId(),
+								IStatus.OK,
+								message,
+								null);
+						throw new CoreException(status);
+					}
+				}
+			}
+
+//			if (oldFeature == null) {
+//				ensureUnique();
+//			}
+		}
+		return true;
+	}
+
+	private void preserveOptionalState() {
+		if (unconfiguredOptionalFeatures == null)
+			return;
+
+		for (int i = 0; i < unconfiguredOptionalFeatures.length; i++) {
+			try {
+				// Get the feature that matches the original unconfigured ones.
+				IFeature localFeature =
+					UpdateUtils.getLocalFeature(
+						targetSite,
+						unconfiguredOptionalFeatures[i]);
+				if (localFeature != null)
+					targetSite.unconfigure(localFeature);
+
+			} catch (CoreException e) {
+				// Ignore this - we will leave with it
+			}
+		}
+	}
+	
+	private void setOptionalFeatures() {
+		try {
+			// Ensure optional features are correctly set
+			if (optionalFeatures == null && UpdateUtils.hasOptionalFeatures(feature) ) {
+				JobRoot jobRoot = new JobRoot(this);
+				IInstallConfiguration config = SiteManager.getLocalSite().getCurrentConfiguration();
+				HashSet set = new HashSet();
+				boolean update = oldFeature != null;
+				boolean patch = UpdateUtils.isPatch(feature);
+				FeatureHierarchyElement[] elements = jobRoot.getElements();
+				for (int i = 0; i < elements.length; i++) {
+					elements[i].addCheckedOptionalFeatures(update, patch, config, set);
+				}
+				optionalFeatures = new IFeatureReference[set.size()];
+				set.toArray(optionalFeatures);
+				unconfiguredOptionalFeatures = jobRoot.getUnconfiguredOptionalFeatures(config, targetSite);
+			}
+		} catch (CoreException e) {
+			UpdateUtils.logException(e);
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/JobRoot.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/JobRoot.java
new file mode 100644
index 0000000..bc4a535
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/JobRoot.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.operations.*;
+
+public class JobRoot {
+	private IInstallFeatureOperation job;
+	private FeatureHierarchyElement[] elements;
+
+	public JobRoot(IInstallFeatureOperation job) {
+		this.job = job;
+	}
+
+	public IInstallFeatureOperation getJob() {
+		return job;
+	}
+
+	public FeatureHierarchyElement[] getElements() {
+		if (elements == null)
+			computeElements();
+		return elements;
+	}
+
+	/**
+	 * Returns unconfigured features before an install.
+	 * After installing the features, the caller must get the local features that match
+	 * these unconfigured features and unconfigure them.
+	 * @param config
+	 * @param targetSite
+	 * @return
+	 */
+	public IFeature[] getUnconfiguredOptionalFeatures(
+		IInstallConfiguration config,
+		IConfiguredSite targetSite) {
+
+		ArrayList unconfiguredOptionalFeatures = new ArrayList();
+		getUnconfiguredOptionalFeatures(unconfiguredOptionalFeatures, config, targetSite, getElements(), UpdateUtils.isPatch(job.getFeature()));
+		IFeature[] unconfiguredOptionalFeaturesArray =
+			new IFeature[unconfiguredOptionalFeatures.size()];
+		unconfiguredOptionalFeatures.toArray(unconfiguredOptionalFeaturesArray);
+		return unconfiguredOptionalFeaturesArray;
+	}
+
+	private void getUnconfiguredOptionalFeatures(
+		ArrayList unconfiguredOptionalFeatures,
+		IInstallConfiguration config,
+		IConfiguredSite targetSite,
+		FeatureHierarchyElement[] optionalElements,
+		boolean isPatch) {
+		for (int i = 0; i < optionalElements.length; i++) {
+			FeatureHierarchyElement[] children =
+				optionalElements[i].getChildren(true, isPatch, config);
+			getUnconfiguredOptionalFeatures(
+				unconfiguredOptionalFeatures,
+				config,
+				targetSite,
+				children,
+				isPatch);
+			if (!optionalElements[i].isEnabled(config)) {
+				unconfiguredOptionalFeatures.add(optionalElements[i].getFeature());
+			}
+		}
+	}
+
+	private void computeElements() {
+		try {
+			IFeature oldFeature = job.getOldFeature();
+			IFeature newFeature = job.getFeature();
+			ArrayList list = new ArrayList();
+			boolean patch = UpdateUtils.isPatch(newFeature);
+			FeatureHierarchyElement.computeElements(
+				oldFeature,
+				newFeature,
+				oldFeature != null,
+				patch,
+				SiteManager.getLocalSite().getCurrentConfiguration(),
+				list);
+			elements = new FeatureHierarchyElement[list.size()];
+			list.toArray(elements);
+			for (int i = 0; i < elements.length; i++) {
+				elements[i].setRoot(this);
+			}
+		} catch (CoreException e) {
+			UpdateUtils.logException(e);
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/Operation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/Operation.java
new file mode 100644
index 0000000..5250bb2
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/Operation.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.update.operations.*;
+
+
+public abstract class Operation implements IOperation {
+	
+	private boolean processed;
+	
+	
+	public Operation() {
+	}
+	
+	public boolean isProcessed() {
+		return processed;
+	}
+	
+	public void markProcessed() {
+		processed = true;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationFactory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationFactory.java
new file mode 100644
index 0000000..636f376
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationFactory.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.operations.*;
+
+public class OperationFactory implements IOperationFactory {
+
+	public OperationFactory() {
+	}
+
+	public IConfigFeatureOperation createConfigOperation(
+		IConfiguredSite targetSite,
+		IFeature feature) {
+		return new ConfigOperation(targetSite, feature);
+	}
+
+	public IBatchOperation createBatchInstallOperation(IInstallFeatureOperation[] operations) {
+		return new BatchInstallOperation(operations);
+	}
+
+	public IInstallFeatureOperation createInstallOperation(
+		IConfiguredSite targetSite,
+		IFeature feature,
+		IFeatureReference[] optionalFeatures,
+		IFeature[] unconfiguredOptionalFeatures,
+		IVerificationListener verifier) {
+		return new InstallOperation(
+			targetSite,
+			feature,
+			optionalFeatures,
+			unconfiguredOptionalFeatures,
+			verifier);
+	}
+
+	public IUnconfigFeatureOperation createUnconfigOperation(
+		IConfiguredSite targetSite,
+		IFeature feature) {
+		return new UnconfigOperation(targetSite, feature);
+	}
+
+	public IConfigFeatureOperation createReplaceFeatureVersionOperation(
+		IFeature feature,
+		IFeature anotherFeature) {
+	
+		return new ReplaceFeatureVersionOperation(feature, anotherFeature);		
+	}
+		
+	public IUninstallFeatureOperation createUninstallOperation(
+		IConfiguredSite targetSite,
+		IFeature feature) {
+		return new UninstallOperation(targetSite, feature);
+	}
+
+	public IRevertConfigurationOperation createRevertConfigurationOperation(
+		IInstallConfiguration config,
+		IProblemHandler problemHandler) {
+		return new RevertConfigurationOperation(
+			config,
+			problemHandler);
+	}
+
+	public IToggleSiteOperation createToggleSiteOperation(
+		IConfiguredSite site) {
+		return new ToggleSiteOperation(site);
+	}
+	
+	public IUnconfigureAndUninstallFeatureOperation createUnconfigureAndUninstallFeatureOperation(
+			IConfiguredSite targetSite,
+			IFeature feature) {
+			return new UnconfigureAndUninstallFeatureOperation(targetSite, feature);
+	}
+	
+	public IUnconfigureFeaturesOperation createUnconfigureFeaturesOperation (
+			IConfiguredSite[] targetSites,
+			IFeature[] features) {
+			return new UnconfigureFeaturesOperation(targetSites, features);
+		}
+
+	public IConfigureFeaturesOperation createConfigureFeaturesOperation(
+			IConfiguredSite[] targetSites,
+			IFeature[] features) {
+		
+			return new ConfigureFeaturesOperation(targetSites, features);		
+	}
+			
+	public IUninstallFeaturesOperation createUninstallFeaturesOperation(
+			IConfiguredSite[] targetSites,
+			IFeature[] features) {
+			return new UninstallFeaturesOperation(targetSites, features);
+	}
+	
+	public IUnconfigureAndUninstallFeaturesOperation createUnconfigureAndUninstallFeaturesOperation(
+			IConfiguredSite[] targetSites,
+			IFeature[] features) {
+			return new UnconfigureAndUninstallFeaturesOperation(targetSites, features);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationValidator.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationValidator.java
new file mode 100644
index 0000000..03af25b
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/OperationValidator.java
@@ -0,0 +1,1397 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+//import java.io.*;
+//import java.net.*;
+//import java.nio.channels.*;
+import org.eclipse.update.core.IUpdateConstants;
+
+import org.eclipse.osgi.service.resolver.PlatformAdmin;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.service.resolver.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.configurator.PlatformConfiguration;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.operations.IInstallFeatureOperation;
+import org.eclipse.update.operations.IOperationValidator;
+import org.osgi.framework.*;
+
+/**
+ *  
+ */
+public class OperationValidator implements IOperationValidator {
+	/**
+	 * Checks if the platform configuration has been modified outside this program.
+	 * @return the error status, or null if no errors
+	 */
+	public IStatus validatePlatformConfigValid() {
+		ArrayList status = new ArrayList(1);
+		checkPlatformWasModified(status);
+		
+		// report status
+		if (status.size() > 0)
+			return createMultiStatus(Messages.ActivityConstraints_rootMessage, status, IStatus.ERROR);
+		return null;
+	}
+	
+	/*
+	 * Called by UI before performing operation. Returns null if no errors, a
+	 * status with IStatus.WARNING code when the initial configuration is
+	 * broken, or a status with IStatus.ERROR when there the operation
+	 * introduces new errors
+	 */
+	public IStatus validatePendingInstall(
+		IFeature oldFeature,
+		IFeature newFeature) {
+		// check initial state
+		ArrayList beforeStatus = new ArrayList();
+		validateInitialState(beforeStatus);
+
+		// check proposed change
+		ArrayList status = new ArrayList();
+		checkPlatformWasModified(status);
+		validateInstall(oldFeature, newFeature, status);
+
+		// report status
+		return createCombinedReportStatus(beforeStatus, status);
+	}
+
+	/*
+	 * Called by UI before performing operation
+	 */
+	public IStatus validatePendingUnconfig(IFeature feature) {
+		// check initial state
+		ArrayList beforeStatus = new ArrayList();
+		validateInitialState(beforeStatus);
+
+		// check proposed change
+		ArrayList status = new ArrayList();
+		checkPlatformWasModified(status);
+		validateUnconfigure(feature, status);
+
+		// report status
+		return createCombinedReportStatus(beforeStatus, status);
+	}
+
+	/*
+	 * Called by UI before performing operation
+	 */
+	public IStatus validatePendingConfig(IFeature feature) {
+		// check initial state
+		ArrayList beforeStatus = new ArrayList();
+		validateInitialState(beforeStatus);
+
+		// check proposed change
+		ArrayList status = new ArrayList();
+		checkPlatformWasModified(status);
+		validateConfigure(feature, status);
+
+		// report status
+		return createCombinedReportStatus(beforeStatus, status);
+	}
+
+	/**
+	 * Called before performing operation.
+	 */
+	public IStatus validatePendingReplaceVersion(
+		IFeature feature,
+		IFeature anotherFeature) {
+		// check initial state
+		ArrayList beforeStatus = new ArrayList();
+		validateInitialState(beforeStatus);
+
+		// check proposed change
+		ArrayList status = new ArrayList();
+		checkPlatformWasModified(status);
+		validateReplaceVersion(feature, anotherFeature, status);
+
+		// report status
+		return createCombinedReportStatus(beforeStatus, status);
+	}
+
+
+	/*
+	 * Called by the UI before doing a revert/ restore operation
+	 */
+	public IStatus validatePendingRevert(IInstallConfiguration config) {
+		// check initial state
+		ArrayList beforeStatus = new ArrayList();
+		validateInitialState(beforeStatus);
+
+		// check proposed change
+		ArrayList status = new ArrayList();
+		checkPlatformWasModified(status);
+		validateRevert(config, status);
+
+		// report status
+		return createCombinedReportStatus(beforeStatus, status);
+	}
+
+	/*
+	 * Called by the UI before doing a batched processing of several pending
+	 * changes.
+	 */
+	public IStatus validatePendingChanges(IInstallFeatureOperation[] jobs) {
+		// check initial state
+		ArrayList beforeStatus = new ArrayList();
+		validateInitialState(beforeStatus);
+		checkPlatformWasModified(beforeStatus);
+
+		// check proposed change
+		ArrayList status = new ArrayList();
+		validatePendingChanges(jobs, status, beforeStatus);
+
+		// report status
+		return createCombinedReportStatus(beforeStatus, status);
+	}
+	
+	/*
+	 * Called by the UI before doing a batched processing of several pending
+	 * changes.
+	 */
+	public RequiredFeaturesResult getRequiredFeatures(IInstallFeatureOperation[] jobs) {
+		
+		RequiredFeaturesResult requiredFeaturesResult = new RequiredFeaturesResult();
+		// check initial state
+		ArrayList beforeStatus = new ArrayList();
+		validateInitialState(beforeStatus);
+		checkPlatformWasModified(beforeStatus);
+
+		// check proposed change
+		ArrayList status = new ArrayList();
+		Set requiredFeatures = validatePendingChanges(jobs, status, beforeStatus);
+
+		// report status
+		//return createCombinedReportStatus(beforeStatus, status);
+		requiredFeaturesResult.setRequiredFeatures(requiredFeatures);
+		requiredFeaturesResult.setStatus(createCombinedReportStatus(beforeStatus, status));
+		return requiredFeaturesResult;
+	}
+
+	/*
+	 * Check the current state.
+	 */
+	public IStatus validateCurrentState() {
+		// check the state
+		ArrayList status = new ArrayList();
+		checkPlatformWasModified(status);
+		validateInitialState(status);
+
+		// report status
+		if (status.size() > 0)
+			return createMultiStatus(Messages.ActivityConstraints_rootMessage, status, IStatus.ERROR);
+		return null;
+	}
+
+	/*
+	 * Check to see if we are not broken even before we start
+	 */
+	private static void validateInitialState(ArrayList status) {
+		try {
+			ArrayList features = computeFeatures();
+			// uncomment this when patch released in boot
+			//checkConfigurationLock(status);
+			checkConstraints(features, status);
+		} catch (CoreException e) {
+			status.add(e.getStatus());
+		}
+	}
+
+	/*
+	 * handle unconfigure
+	 */
+	private static void validateUnconfigure(
+		IFeature feature,
+		ArrayList status) {
+		try {
+			checkSiteReadOnly(feature,status);
+			ArrayList features = computeFeatures();
+			features = computeFeaturesAfterOperation(features, null, feature);
+			checkConstraints(features, status);
+		} catch (CoreException e) {
+			status.add(e.getStatus());
+		}
+	}
+
+
+	/*
+	 * handle configure
+	 */
+	private static void validateConfigure(IFeature feature, ArrayList status) {
+		try {
+			checkSiteReadOnly(feature,status);
+			ArrayList features = computeFeatures();
+			checkOptionalChildConfiguring(feature, status);
+			checkForCycles(feature, null, features);
+			features = computeFeaturesAfterOperation(features, feature, null);
+			checkConstraints(features, status);
+
+		} catch (CoreException e) {
+			status.add(e.getStatus());
+		}
+	}
+
+	/*
+	 * handle replace version
+	 */
+	private static void validateReplaceVersion(
+		IFeature feature,
+		IFeature anotherFeature,
+		ArrayList status) {
+		try {
+			checkSiteReadOnly(feature,status);
+			ArrayList features = computeFeatures();
+			checkForCycles(feature, null, features);
+			features =
+				computeFeaturesAfterOperation(
+					features,
+					anotherFeature,
+					feature);
+			checkConstraints(features, status);
+		} catch (CoreException e) {
+			status.add(e.getStatus());
+		}
+	}
+
+	/*
+	 * handle install and update
+	 */
+	private static void validateInstall(
+		IFeature oldFeature,
+		IFeature newFeature,
+		ArrayList status) {
+		try {
+			checkSiteReadOnly(oldFeature,status);
+			ArrayList features = computeFeatures();
+			checkForCycles(newFeature, null, features);
+			features =
+				computeFeaturesAfterOperation(features, newFeature, oldFeature);
+			checkConstraints(features, status);
+			checkLicense(newFeature, status);
+		} catch (CoreException e) {
+			status.add(e.getStatus());
+		}
+	}
+
+	/*
+	 * handle revert and restore
+	 */
+	private static void validateRevert(
+		IInstallConfiguration config,
+		ArrayList status) {
+		try {
+//			// check the timeline and don't bother
+//			// to check anything else if negative
+//			if (!checkTimeline(config, status))
+//				return;
+			ArrayList features = computeFeaturesAfterRevert(config);
+			checkConstraints(features, status);
+			checkRevertConstraints(features, status);
+
+		} catch (CoreException e) {
+			status.add(e.getStatus());
+		}
+	}
+
+
+	/*
+	 * Handle one-click changes as a batch
+	 */
+	private static Set validatePendingChanges(
+		IInstallFeatureOperation[] jobs,
+		ArrayList status,
+		ArrayList beforeStatus) {
+		try {
+			ArrayList features = computeFeatures();
+			ArrayList savedFeatures = features;
+			int nexclusives = 0;
+
+			// pass 1: see if we can process the entire "batch"
+			ArrayList tmpStatus = new ArrayList();
+			for (int i = 0; i < jobs.length; i++) {
+				IInstallFeatureOperation job = jobs[i];
+
+				IFeature newFeature = job.getFeature();
+				IFeature oldFeature = job.getOldFeature();
+				checkLicense(newFeature, status);
+				if (jobs.length > 1 && newFeature.isExclusive()) {
+					nexclusives++;
+					status.add(
+						createStatus(
+							newFeature,
+							FeatureStatus.CODE_EXCLUSIVE,
+							Messages.ActivityConstraints_exclusive));
+					continue;
+				}
+				checkForCycles(newFeature, null, features);
+				features =
+					computeFeaturesAfterOperation(
+						features,
+						newFeature,
+						oldFeature);
+			}
+			if (nexclusives > 0)
+				return Collections.EMPTY_SET;
+			checkConstraints(features, tmpStatus);
+			if (tmpStatus.size() == 0) // the whole "batch" is OK
+				return Collections.EMPTY_SET;
+
+			// pass 2: we have conflicts
+			features = savedFeatures;
+			for (int i = 0; i < jobs.length; i++) {
+				IInstallFeatureOperation job = jobs[i];
+				IFeature newFeature = job.getFeature();
+				IFeature oldFeature = job.getOldFeature();
+
+				features =
+					computeFeaturesAfterOperation(
+						features,
+						newFeature,
+						oldFeature);
+
+				Set result = checkConstraints(features, status);
+				if (status.size() > 0
+					&& !isBetterStatus(beforeStatus, status)) {
+// bug 75613
+//					IStatus conflict =
+//						createStatus(
+//							newFeature,
+//							FeatureStatus.CODE_OTHER,
+//							Policy.bind(KEY_CONFLICT));
+//					status.add(0, conflict);
+					return result;
+				}
+			}
+		} catch (CoreException e) {
+			status.add(e.getStatus());
+		}
+		
+		return Collections.EMPTY_SET;
+	}
+	
+	private static void checkPlatformWasModified(ArrayList status) {
+		try {
+			// checks if the platform has been modified outside this eclipse instance
+			IPlatformConfiguration platformConfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+			
+			long currentTimeStamp = platformConfig.getChangeStamp();
+			// get the last modified value for this config, from this process point of view
+			if (platformConfig instanceof PlatformConfiguration) 
+				currentTimeStamp = ((PlatformConfiguration)platformConfig).getConfiguration().lastModified();
+				
+			// get the real last modified value
+			URL platformXML = platformConfig.getConfigurationLocation();
+			long actualTimeStamp = currentTimeStamp;
+			if ("file".equals(platformXML.getProtocol())) //$NON-NLS-1$
+				actualTimeStamp = new File(platformXML.getFile()).lastModified();
+			else {
+				URLConnection connection = platformXML.openConnection();
+				actualTimeStamp = connection.getLastModified();
+			}
+			if (currentTimeStamp != actualTimeStamp)
+				status.add(createStatus(
+								null,
+								FeatureStatus.CODE_OTHER,
+								Messages.ActivityConstraints_platformModified)); 
+		} catch (IOException e) {
+			// ignore
+		}
+	}
+	
+	private static void checkSiteReadOnly(IFeature feature, ArrayList status) {
+		if(feature == null){
+			return;
+		}
+		IConfiguredSite csite = feature.getSite().getCurrentConfiguredSite();
+		if (csite != null && !csite.isUpdatable())
+			status.add(createStatus(feature, FeatureStatus.CODE_OTHER,
+					NLS.bind(Messages.ActivityConstraints_readOnly, (new String[] { csite.getSite().getURL().toExternalForm() }))));
+	}
+
+	/*
+	 * Compute a list of configured features
+	 */
+	private static ArrayList computeFeatures() throws CoreException {
+		return computeFeatures(true);
+	}
+	/*
+	 * Compute a list of configured features
+	 */
+	private static ArrayList computeFeatures(boolean configuredOnly)
+		throws CoreException {
+		ArrayList features = new ArrayList();
+		ILocalSite localSite = SiteManager.getLocalSite();
+		IInstallConfiguration config = localSite.getCurrentConfiguration();
+		IConfiguredSite[] csites = config.getConfiguredSites();
+
+		for (int i = 0; i < csites.length; i++) {
+			IConfiguredSite csite = csites[i];
+
+			IFeatureReference[] crefs;
+
+			if (configuredOnly)
+				crefs = csite.getConfiguredFeatures();
+			else
+				crefs = csite.getSite().getFeatureReferences();
+			for (int j = 0; j < crefs.length; j++) {
+				IFeatureReference cref = crefs[j];
+				IFeature cfeature = cref.getFeature(null);
+				features.add(cfeature);
+			}
+		}
+
+		return features;
+	}
+
+	/*
+	 * Compute the nested feature subtree starting at the specified base
+	 * feature
+	 */
+	public static ArrayList computeFeatureSubtree(
+			IFeature top,
+			IFeature feature,
+			ArrayList features,
+			boolean tolerateMissingChildren,
+			ArrayList configuredFeatures,
+			ArrayList visitedFeatures)
+	throws CoreException {
+
+		// check arguments
+		if (top == null)
+			return features;
+		if (feature == null)
+			feature = top;
+		if (features == null)
+			features = new ArrayList();
+		if (visitedFeatures == null)
+			visitedFeatures = new ArrayList();
+
+		// check for <includes> cycle
+		if (visitedFeatures.contains(feature)) {
+			IStatus status =
+			createStatus(top, FeatureStatus.CODE_CYCLE, Messages.ActivityConstraints_cycle);
+			throw new CoreException(status);
+		} else {
+			// keep track of visited features so we can detect cycles
+			visitedFeatures.add(feature);
+		}
+
+		// return specified base feature and all its children
+		if (!features.contains(feature))
+			features.add(feature);
+		IIncludedFeatureReference[] children =
+		feature.getIncludedFeatureReferences();
+		for (int i = 0; i < children.length; i++) {
+			try {
+				IFeature child = UpdateUtils.getIncludedFeature(feature, children[i]);
+				features =
+				computeFeatureSubtree(
+						top,
+						child,
+						features,
+						tolerateMissingChildren,
+						null,
+						visitedFeatures);
+			} catch (CoreException e) {
+				if (!children[i].isOptional() && !tolerateMissingChildren)
+					throw e;
+			}
+		}
+		// no cycles for this feature during DFS
+		visitedFeatures.remove(feature);
+		return features;
+	}
+
+	private static void checkLicense(IFeature feature, ArrayList status) {
+		IURLEntry licenseEntry = feature.getLicense();
+		if (licenseEntry != null) {
+			String license = licenseEntry.getAnnotation();
+			if (license != null && license.trim().length() > 0)
+				return;
+		}
+		status.add(
+			createStatus(feature, FeatureStatus.CODE_OTHER, Messages.ActivityConstraints_noLicense));
+	}
+
+	/*
+	 * Compute a list of features that will be configured after the operation
+	 */
+	private static ArrayList computeFeaturesAfterOperation(
+		ArrayList features,
+		IFeature add,
+		IFeature remove)
+		throws CoreException {
+
+		ArrayList addTree = computeFeatureSubtree(add, null, null, false,
+		/* do not tolerate missing children */
+		features, null);
+		ArrayList removeTree =
+			computeFeatureSubtree(
+				remove,
+				null,
+				null,
+				true /* tolerate missing children */,
+				null,
+				null
+		);
+		if (remove != null) {
+			// Patches to features are removed together with
+			// those features. Include them in the list.
+			contributePatchesFor(removeTree, features, removeTree);
+		}
+
+		if (remove != null)
+			features.removeAll(removeTree);
+
+		if (add != null)
+			features.addAll(addTree);
+
+		return features;
+	}
+
+	private static void contributePatchesFor(
+		ArrayList removeTree,
+		ArrayList features,
+		ArrayList result)
+		throws CoreException {
+
+		for (int i = 0; i < removeTree.size(); i++) {
+			IFeature feature = (IFeature) removeTree.get(i);
+			contributePatchesFor(feature, features, result);
+		}
+	}
+
+	private static void contributePatchesFor(
+		IFeature feature,
+		ArrayList features,
+		ArrayList result)
+		throws CoreException {
+		for (int i = 0; i < features.size(); i++) {
+			IFeature candidate = (IFeature) features.get(i);
+			if (UpdateUtils.isPatch(feature, candidate)) {
+				ArrayList removeTree =
+					computeFeatureSubtree(candidate, null, null, true,null,null);
+				result.addAll(removeTree);
+			}
+		}
+	}
+
+	/*
+	 * Compute a list of features that will be configured after performing the
+	 * revert
+	 */
+	private static ArrayList computeFeaturesAfterRevert(IInstallConfiguration config)
+		throws CoreException {
+
+		ArrayList list = new ArrayList();
+		IConfiguredSite[] csites = config.getConfiguredSites();
+		for (int i = 0; i < csites.length; i++) {
+			IConfiguredSite csite = csites[i];
+			IFeatureReference[] features = csite.getConfiguredFeatures();
+			for (int j = 0; j < features.length; j++) {
+				list.add(features[j].getFeature(null));
+			}
+		}
+		return list;
+	}
+
+
+
+	/*
+	 * Compute a list of plugin entries for the specified features.
+	 */
+	private static ArrayList computePluginsForFeatures(ArrayList features)
+		throws CoreException {
+		if (features == null)
+			return new ArrayList();
+
+		HashMap plugins = new HashMap();
+		for (int i = 0; i < features.size(); i++) {
+			IFeature feature = (IFeature) features.get(i);
+			IPluginEntry[] entries = feature.getPluginEntries();
+			for (int j = 0; j < entries.length; j++) {
+				IPluginEntry entry = entries[j];
+				plugins.put(entry.getVersionedIdentifier(), entry);
+			}
+		}
+		ArrayList result = new ArrayList();
+		result.addAll(plugins.values());
+		return result;
+	}
+
+
+	/**
+	 * Check for feature cycles:
+	 * - visit feature
+	 * - if feature is in the cycle candidates list, then cycle found, else add it to candidates list
+	 * - DFS children 
+	 * - when return from DFS remove the feature from the candidates list
+	 */
+	private static void checkForCycles(
+			IFeature feature,
+			ArrayList candidates,
+			ArrayList configuredFeatures)
+	throws CoreException {
+
+		// check arguments
+		if (feature == null)
+			return;
+		if (configuredFeatures == null)
+			configuredFeatures = new ArrayList();
+		if (candidates == null)
+			candidates = new ArrayList();
+		
+		// check for <includes> cycle
+		if (candidates.contains(feature)) {
+			String msg = NLS.bind(Messages.ActivityConstraints_cycle, (new String[] {feature.getLabel(), 
+            feature.getVersionedIdentifier().toString()}));
+			IStatus status = createStatus(feature, FeatureStatus.CODE_CYCLE, msg);
+			throw new CoreException(status);
+		}
+
+		// potential candidate
+		candidates.add(feature);
+		
+		// recursively, check cycles with children
+		IIncludedFeatureReference[] children =
+		feature.getIncludedFeatureReferences();
+		for (int i = 0; i < children.length; i++) {
+			try {
+				IFeature child = UpdateUtils.getIncludedFeature(feature, children[i]);
+				checkForCycles(child, candidates, configuredFeatures);
+			} catch (CoreException e) {
+				if (!children[i].isOptional())
+					throw e;
+			}
+		}
+		// no longer a candidate, because no cycles with children
+		candidates.remove(feature);
+	}
+	
+	/*
+	 * validate constraints
+	 */
+	private static Set  checkConstraints(ArrayList features, ArrayList status)
+		throws CoreException {
+		if (features == null)
+			return Collections.EMPTY_SET;
+
+		ArrayList plugins = computePluginsForFeatures(features);
+
+		checkEnvironment(features, status);
+		checkPlatformFeature(features, plugins, status);
+		checkPrimaryFeature(features, plugins, status);
+		return checkPrereqs(features, plugins, status);
+	}
+
+	/*
+	 * Verify all features are either portable, or match the current
+	 * environment
+	 */
+	private static void checkEnvironment(
+		ArrayList features,
+		ArrayList status) {
+
+		String os = Platform.getOS();
+		String ws = Platform.getWS();
+		String arch = Platform.getOSArch();
+
+		for (int i = 0; i < features.size(); i++) {
+			IFeature feature = (IFeature) features.get(i);
+			ArrayList fos = createList(feature.getOS());
+			ArrayList fws = createList(feature.getWS());
+			ArrayList farch = createList(feature.getOSArch());
+
+			if (fos.size() > 0) {
+				if (!fos.contains(os)) {
+					IStatus s =
+						createStatus(feature, FeatureStatus.CODE_ENVIRONMENT, Messages.ActivityConstraints_os);
+					if (!status.contains(s))
+						status.add(s);
+					continue;
+				}
+			}
+
+			if (fws.size() > 0) {
+				if (!fws.contains(ws)) {
+					IStatus s =
+						createStatus(feature, FeatureStatus.CODE_ENVIRONMENT, Messages.ActivityConstraints_ws);
+					if (!status.contains(s))
+						status.add(s);
+					continue;
+				}
+			}
+
+			if (farch.size() > 0) {
+				if (!farch.contains(arch)) {
+					IStatus s =
+						createStatus(feature, FeatureStatus.CODE_ENVIRONMENT, Messages.ActivityConstraints_arch);
+					if (!status.contains(s))
+						status.add(s);
+					continue;
+				}
+			}
+		}
+	}
+
+	/*
+	 * Verify we end up with a version of platform configured
+	 */
+	private static void checkPlatformFeature(
+		ArrayList features,
+		ArrayList plugins,
+		ArrayList status) {
+
+		// find the plugin that defines the product
+		IProduct product = Platform.getProduct();
+		if (product == null)
+			return; // normally this shouldn't happen
+		Bundle primaryBundle = product.getDefiningBundle();
+		// check if that plugin is among the resulting plugins
+		boolean found = false;
+		for (int j = 0; j < plugins.size(); j++) {
+			IPluginEntry plugin = (IPluginEntry) plugins.get(j);
+			if (primaryBundle.getSymbolicName().equals(plugin.getVersionedIdentifier().getIdentifier())) {
+				found = true;
+				break;
+			}
+		}
+		
+		if (!found) {
+			IStatus s =
+				createStatus(null, FeatureStatus.CODE_OTHER, Messages.ActivityConstraints_platform);
+			if (!status.contains(s))
+				status.add(s);
+		}
+	}
+
+	/*
+	 * Verify we end up with a version of primary feature configured
+	 */
+	private static void checkPrimaryFeature(
+		ArrayList features,
+		ArrayList plugins,
+		ArrayList status) {
+
+		String featureId =
+			ConfiguratorUtils
+				.getCurrentPlatformConfiguration()
+				.getPrimaryFeatureIdentifier();
+		
+		if (featureId != null) {
+			// primary feature is defined
+			for (int i = 0; i < features.size(); i++) {
+				IFeature feature = (IFeature) features.get(i);
+				if (featureId
+					.equals(feature.getVersionedIdentifier().getIdentifier()))
+					return;
+			}
+	
+			IStatus s = createStatus(null, FeatureStatus.CODE_OTHER, Messages.ActivityConstraints_primary);
+			if (!status.contains(s))
+				status.add(s);
+		} else {
+			// check if the product still ends up contributed
+			// find the plugin that defines the product
+			IProduct product = Platform.getProduct();
+			if (product == null)
+				return; // normally this shouldn't happen
+			Bundle primaryBundle = product.getDefiningBundle();
+			// check if that plugin is among the resulting plugins
+
+			for (int j = 0; j < plugins.size(); j++) {
+				IPluginEntry plugin = (IPluginEntry) plugins.get(j);
+				if (primaryBundle.getSymbolicName().equals(plugin.getVersionedIdentifier().getIdentifier())) {
+					return; // product found
+				}
+			}
+			IStatus s =
+				createStatus(null, FeatureStatus.CODE_OTHER, Messages.ActivityConstraints_primary);
+			if (!status.contains(s))
+				status.add(s);
+		}
+	}
+
+	/*
+	 * Verify we do not break prereqs
+	 */
+	private static Set checkPrereqs(
+		ArrayList features,
+		ArrayList plugins,
+		ArrayList status) {
+		
+		HashSet result = new HashSet();
+
+		for (int i = 0; i < features.size(); i++) {
+			IFeature feature = (IFeature) features.get(i);
+			IImport[] imports = feature.getImports();
+
+			for (int j = 0; j < imports.length; j++) {
+				IImport iimport = imports[j];
+				// for each import determine plugin or feature, version, match
+				// we need
+				VersionedIdentifier iid = iimport.getVersionedIdentifier();
+				String id = iid.getIdentifier();
+				PluginVersionIdentifier version = iid.getVersion();
+				boolean featurePrereq =
+					iimport.getKind() == IImport.KIND_FEATURE;
+				boolean ignoreVersion =
+					version.getMajorComponent() == 0
+						&& version.getMinorComponent() == 0
+						&& version.getServiceComponent() == 0;
+				int rule = iimport.getRule();
+				if (rule == IUpdateConstants.RULE_NONE)
+					rule = IUpdateConstants.RULE_COMPATIBLE;
+
+				boolean found = false;
+
+				ArrayList candidates;
+
+				if (featurePrereq)
+					candidates = features;
+				else
+					candidates = plugins;
+				for (int k = 0; k < candidates.size(); k++) {
+					VersionedIdentifier cid;
+					if (featurePrereq) {
+						// the candidate is a feature
+						IFeature candidate = (IFeature) candidates.get(k);
+						// skip self
+						if (feature.equals(candidate))
+							continue;
+						cid = candidate.getVersionedIdentifier();
+					} else {
+						// the candidate is a plug-in
+						IPluginEntry plugin = (IPluginEntry) candidates.get(k);
+						cid = plugin.getVersionedIdentifier();
+					}
+					PluginVersionIdentifier cversion = cid.getVersion();
+					if (id.equals(cid.getIdentifier())) {
+						// have a candidate
+						if (ignoreVersion)
+							found = true;
+						else if (
+							rule == IUpdateConstants.RULE_PERFECT
+								&& cversion.isPerfect(version))
+							found = true;
+						else if (
+							rule == IUpdateConstants.RULE_EQUIVALENT
+								&& cversion.isEquivalentTo(version))
+							found = true;
+						else if (
+							rule == IUpdateConstants.RULE_COMPATIBLE
+								&& cversion.isCompatibleWith(version))
+							found = true;
+						else if (
+							rule == IUpdateConstants.RULE_GREATER_OR_EQUAL
+								&& cversion.isGreaterOrEqualTo(version))
+							found = true;
+					}
+					if (found)
+						break;
+				}
+				
+				// perhaps the bundle that we are looking for was installed
+				// but isn't a part of a feature
+				if (!found && !featurePrereq)
+					found = isInstalled(iid, rule, ignoreVersion);
+
+				if (!found) {
+					// report status
+					String target =
+						featurePrereq
+							? Messages.ActivityConstaints_prereq_feature
+							: Messages.ActivityConstaints_prereq_plugin;
+					int errorCode = featurePrereq
+							? FeatureStatus.CODE_PREREQ_FEATURE
+							: FeatureStatus.CODE_PREREQ_PLUGIN;
+					String msg =
+						NLS.bind(Messages.ActivityConstraints_prereq, (new String[] { target, id }));
+
+					if (!ignoreVersion) {
+						if (rule == IUpdateConstants.RULE_PERFECT)
+							msg =
+								NLS.bind(Messages.ActivityConstraints_prereqPerfect, (new String[] {
+                                target,
+                                id,
+                                version.toString()}));
+						else if (rule == IUpdateConstants.RULE_EQUIVALENT)
+							msg =
+								NLS.bind(Messages.ActivityConstraints_prereqEquivalent, (new String[] {
+                                target,
+                                id,
+                                version.toString()}));
+						else if (rule == IUpdateConstants.RULE_COMPATIBLE)
+							msg =
+								NLS.bind(Messages.ActivityConstraints_prereqCompatible, (new String[] {
+                                target,
+                                id,
+                                version.toString()}));
+						else if (rule == IUpdateConstants.RULE_GREATER_OR_EQUAL)
+							msg =
+								NLS.bind(Messages.ActivityConstraints_prereqGreaterOrEqual, (new String[] {
+                                target,
+                                id,
+                                version.toString()}));
+					}
+					IStatus s = createStatus(feature, errorCode, msg);
+					result.add(new InternalImport(iimport));
+					if (!status.contains(s))
+						status.add(s);
+				}
+			}
+		}
+		
+		return result;
+	}
+	
+	/*
+	 * Return a boolean value indicating whether or not the bundle with the given id and version
+	 * is installed in the system.
+	 */
+	private static boolean isInstalled(VersionedIdentifier vid, int rule, boolean ignoreVersion) {
+		BundleContext context = UpdateCore.getPlugin().getBundleContext();
+		if (context == null)
+			return false;
+		ServiceReference reference = context.getServiceReference(PlatformAdmin.class.getName());
+		if (reference == null)
+			return false;
+		PlatformAdmin admin = (PlatformAdmin) context.getService(reference);
+		try {
+			State state = admin.getState(false);
+			String id = vid.getIdentifier();
+			PluginVersionIdentifier version = vid.getVersion();
+			BundleDescription[] bundles = state.getBundles(id);
+			if (bundles == null || bundles.length == 0)
+				return false;
+			for (int i=0; i<bundles.length; i++) {
+				BundleDescription bundle = bundles[i];
+				PluginVersionIdentifier cversion = new PluginVersionIdentifier(bundle.getVersion().toString());
+				// have a candidate
+				if (ignoreVersion)
+					return true;
+				if (rule == IUpdateConstants.RULE_PERFECT && cversion.isPerfect(version))
+					return true;
+				else if (rule == IUpdateConstants.RULE_EQUIVALENT && cversion.isEquivalentTo(version))
+					return true;
+				else if (rule == IUpdateConstants.RULE_COMPATIBLE && cversion.isCompatibleWith(version))
+					return true;
+				else if (rule == IUpdateConstants.RULE_GREATER_OR_EQUAL && cversion.isGreaterOrEqualTo(version))
+					return true;
+			}
+			return false;
+		} finally {
+			context.ungetService(reference);
+		}
+	}
+
+	/*
+	 * Verify we end up with valid nested features after revert
+	 */
+	private static void checkRevertConstraints(
+		ArrayList features,
+		ArrayList status) {
+
+		for (int i = 0; i < features.size(); i++) {
+			IFeature feature = (IFeature) features.get(i);
+			try {
+				computeFeatureSubtree(
+					feature,
+					null,
+					null,
+					false /* do not tolerate missing children */,
+					null,
+					null
+				);
+			} catch (CoreException e) {
+				status.add(e.getStatus());
+			}
+		}
+	}
+
+	/*
+	 * Verify that a parent of an optional child is configured before we allow
+	 * the child to be configured as well
+	 */
+
+	private static void checkOptionalChildConfiguring(
+		IFeature feature,
+		ArrayList status)
+		throws CoreException {
+		ILocalSite localSite = SiteManager.getLocalSite();
+		IInstallConfiguration config = localSite.getCurrentConfiguration();
+		IConfiguredSite[] csites = config.getConfiguredSites();
+
+		boolean included = false;
+		for (int i = 0; i < csites.length; i++) {
+			IConfiguredSite csite = csites[i];
+			ISiteFeatureReference[] crefs =
+				csite.getSite().getFeatureReferences();
+			for (int j = 0; j < crefs.length; j++) {
+				IFeatureReference cref = crefs[j];
+				IFeature cfeature = null;
+				try {
+					cfeature = cref.getFeature(null);
+				} catch (CoreException e) {
+					//FIXME: cannot ask 'isOptional' here
+					// Ignore missing optional feature.
+					/*
+					 * if (cref.isOptional()) continue;
+					 */
+					throw e;
+				}
+				if (isParent(cfeature, feature, true)) {
+					// Included in at least one feature as optional
+					included = true;
+					if (csite.isConfigured(cfeature)) {
+						// At least one feature parent
+						// is enabled - it is OK to
+						// configure optional child.
+						return;
+					}
+				}
+			}
+		}
+		if (included) {
+			// feature is included as optional but
+			// no parent is currently configured.
+			String msg = Messages.ActivityConstraints_optionalChild;
+			status.add(createStatus(feature, FeatureStatus.CODE_OPTIONAL_CHILD, msg));
+		} else {
+			//feature is root - can be configured
+		}
+	}
+//
+//	/**
+//	 * Checks if the configuration is locked by other instances
+//	 * 
+//	 * @param status
+//	 */
+//	private static void checkConfigurationLock(ArrayList status) {
+//		IPlatformConfiguration config =
+//			BootLoader.getCurrentPlatformConfiguration();
+//		URL configURL = config.getConfigurationLocation();
+//		if (!"file".equals(configURL.getProtocol())) {
+//			status.add(
+//				createStatus(
+//					null,
+//					"Configuration location is not writable:" + configURL));
+//			return;
+//		}
+//		String locationString = configURL.getFile();
+//		File configDir = new File(locationString);
+//		if (!configDir.isDirectory())
+//			configDir = configDir.getParentFile();
+//		if (!configDir.exists()) {
+//			status.add(
+//				createStatus(null, "Configuration location does not exist"));
+//			return;
+//		}
+//		File locksDir = new File(configDir, "locks");
+//		// check all the possible lock files
+//		File[] lockFiles = locksDir.listFiles();
+//		File configLock = BootLoader.getCurrentPlatformConfiguration().getLockFile();
+//		for (int i = 0; i < lockFiles.length; i++) {
+//			if (lockFiles[i].equals(configLock))
+//				continue;
+//			try {
+//				RandomAccessFile raf = new RandomAccessFile(lockFiles[i], "rw");
+//				FileChannel channel = raf.getChannel();
+//				System.out.println(channel.isOpen());
+//				FileLock lock = channel.tryLock();
+//				if (lock == null){
+//					// there is another eclipse instance running
+//					raf.close();
+//					status.add(
+//						createStatus(
+//							null,
+//							"Another instance is running, please close it before performing any configuration operations"));
+//					return;
+//				}
+//
+//			} catch (Exception e) {
+//				status.add(createStatus(null, "Failed to create lock:"+lockFiles[i]));
+//				return;
+//			} 
+//		}
+//	}
+
+	private static boolean isParent(
+		IFeature candidate,
+		IFeature feature,
+		boolean optionalOnly)
+		throws CoreException {
+		IIncludedFeatureReference[] refs =
+			candidate.getIncludedFeatureReferences();
+		for (int i = 0; i < refs.length; i++) {
+			IIncludedFeatureReference child = refs[i];
+			VersionedIdentifier fvid = feature.getVersionedIdentifier();
+			VersionedIdentifier cvid = child.getVersionedIdentifier();
+
+			if (fvid.getIdentifier().equals(cvid.getIdentifier()) == false)
+				continue;
+			// same ID
+			PluginVersionIdentifier fversion = fvid.getVersion();
+			PluginVersionIdentifier cversion = cvid.getVersion();
+
+			if (fversion.equals(cversion)) {
+				// included and matched; return true if optionality is not
+				// important or it is and the inclusion is optional
+				return optionalOnly == false || child.isOptional();
+			}
+		}
+		return false;
+	}
+
+//	private static boolean checkTimeline(
+//		IInstallConfiguration config,
+//		ArrayList status) {
+//		try {
+//			ILocalSite lsite = SiteManager.getLocalSite();
+//			IInstallConfiguration cconfig = lsite.getCurrentConfiguration();
+//			if (cconfig.getTimeline() != config.getTimeline()) {
+//				// Not the same timeline - cannot revert
+//				String msg =
+//					UpdateUtils.getFormattedMessage(
+//						KEY_WRONG_TIMELINE,
+//						config.getLabel());
+//				status.add(createStatus(null, FeatureStatus.CODE_OTHER, msg));
+//				return false;
+//			}
+//		} catch (CoreException e) {
+//			status.add(e.getStatus());
+//		}
+//		return true;
+//	}
+
+	private static IStatus createMultiStatus(
+		String message,
+		ArrayList children,
+		int code) {
+		IStatus[] carray =
+			(IStatus[]) children.toArray(new IStatus[children.size()]);
+		return new MultiStatus(
+			UpdateCore.getPlugin().getBundle().getSymbolicName(),
+			code,
+			carray,
+			message,
+			null);
+	}
+
+	private static IStatus createStatus(IFeature feature, int errorCode, String message) {
+
+		String fullMessage;
+		if (feature == null)
+			fullMessage = message;
+		else {
+			PluginVersionIdentifier version =
+				feature.getVersionedIdentifier().getVersion();
+			fullMessage =
+				NLS.bind(Messages.ActivityConstraints_childMessage, (new String[] {
+                feature.getLabel(),
+                version.toString(),
+                message }));
+		}
+
+		return new FeatureStatus(
+			feature,
+			IStatus.ERROR,
+			UpdateCore.getPlugin().getBundle().getSymbolicName(),
+			errorCode,
+			fullMessage,
+			null);
+	}
+
+	//	private static IStatus createReportStatus(ArrayList beforeStatus,
+	// ArrayList status) {
+	//		// report status
+	//		if (status.size() > 0) {
+	//			if (beforeStatus.size() > 0)
+	//				return createMultiStatus(KEY_ROOT_MESSAGE_INIT,
+	// beforeStatus,IStatus.ERROR);
+	//			else
+	//				return createMultiStatus(KEY_ROOT_MESSAGE, status,IStatus.ERROR);
+	//		}
+	//		return null;
+	//	}
+
+	private static IStatus createCombinedReportStatus(
+		ArrayList beforeStatus,
+		ArrayList status) {
+		if (beforeStatus.size() == 0) { // good initial config
+			if (status.size() == 0) {
+				return null; // all fine
+			} else {
+				return createMultiStatus(Messages.ActivityConstraints_rootMessage,
+					status,
+					IStatus.ERROR);
+				// error after operation
+			}
+		} else { // beforeStatus.size() > 0 : initial config errors
+			if (status.size() == 0) {
+				return null; // errors will be fixed
+			} else {
+				if (isBetterStatus(beforeStatus, status)) {
+					return createMultiStatus(
+						Messages.ActivityConstraints_warning,
+						beforeStatus,
+						IStatus.WARNING);
+					// errors may be fixed
+				} else {
+					ArrayList combined = new ArrayList();
+					combined.add(
+						createMultiStatus(
+							Messages.ActivityConstraints_beforeMessage,
+							beforeStatus,
+							IStatus.ERROR));
+					combined.add(
+						createMultiStatus(
+							Messages.ActivityConstraints_afterMessage,
+							status,
+							IStatus.ERROR));
+					return createMultiStatus(
+						Messages.ActivityConstraints_rootMessageInitial,
+						combined,
+						IStatus.ERROR);
+				}
+			}
+		}
+	}
+
+	private static ArrayList createList(String commaSeparatedList) {
+		ArrayList list = new ArrayList();
+		if (commaSeparatedList != null) {
+			StringTokenizer t =
+				new StringTokenizer(commaSeparatedList.trim(), ","); //$NON-NLS-1$
+			while (t.hasMoreTokens()) {
+				String token = t.nextToken().trim();
+				if (!token.equals("")) //$NON-NLS-1$
+					list.add(token);
+			}
+		}
+		return list;
+	}
+
+	/**
+	 * Returns true if status is a subset of beforeStatus
+	 * 
+	 * @param beforeStatus
+	 * @param status
+	 * @return
+	 */
+	private static boolean isBetterStatus(
+		ArrayList beforeStatus,
+		ArrayList status) {
+		// if no status at all, then it's a subset
+		if (status == null || status.size() == 0)
+			return true;
+		// there is some status, so if there is no initial status, then it's
+		// not a subset
+		if (beforeStatus == null || beforeStatus.size() == 0)
+			return false;
+		// quick check
+		if (beforeStatus.size() < status.size())
+			return false;
+
+		// check if all the status elements appear in the original status
+		for (int i = 0; i < status.size(); i++) {
+			IStatus s = (IStatus) status.get(i);
+			// if this is not a feature status, something is wrong, so return
+			// false
+			if (!(s instanceof FeatureStatus))
+				return false;
+			FeatureStatus fs = (FeatureStatus) s;
+			// check against all status elements
+			boolean found = false;
+			for (int j = 0; !found && j < beforeStatus.size(); j++) {
+				if (fs.equals(beforeStatus.get(j)))
+					found = true;
+			}
+			if (!found)
+				return false;
+		}
+		return true;
+	}
+	
+	public class RequiredFeaturesResult {
+		
+		private IStatus status;
+		private Set requiredFeatures;
+		
+		public Set getRequiredFeatures() {
+			return requiredFeatures;
+		}
+		public void setRequiredFeatures(Set requiredFeatures) {
+			this.requiredFeatures = requiredFeatures;
+		}
+		public void addRequiredFeatures(Set requiredFeatures) {
+			if (requiredFeatures == null) {
+				requiredFeatures = new HashSet();
+			}
+			this.requiredFeatures.addAll(requiredFeatures);
+		}
+		public IStatus getStatus() {
+			return status;
+		}
+		public void setStatus(IStatus status) {
+			this.status = status;
+		}
+		
+		
+	}
+	
+	public static class InternalImport {
+		
+		private IImport iimport;
+
+		public InternalImport(IImport iimport) {
+			this.iimport = iimport;
+		}
+		
+		public IImport getImport() {
+			return iimport;
+		}
+
+		public void setImport(IImport iimport) {
+			this.iimport = iimport;
+		}
+		
+		public boolean equals(Object object) {
+
+			if ( ( object == null) || !(object instanceof InternalImport))
+				return false;
+			
+			if ( object == this)
+				return true;
+			
+			return iimport.getVersionedIdentifier().equals( ((InternalImport)object).getImport().getVersionedIdentifier()) && (getImport().getRule() == ((InternalImport)object).getImport().getRule());
+
+		}
+
+		public int hashCode() {
+			return iimport.getVersionedIdentifier().hashCode() * iimport.getRule();
+		}
+		
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/PatchCleaner.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/PatchCleaner.java
new file mode 100644
index 0000000..91f419c
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/PatchCleaner.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+
+/**
+ * This utility class attaches as a listened to the provided
+ * configured site, and for every unconfigured feature 
+ * it tests if it is a patch and cleans up its backup configuration.
+ */
+
+public class PatchCleaner {
+	private IConfiguredSite csite;
+	private SiteListener listener;
+	class SiteListener implements IConfiguredSiteChangedListener {
+		public void featureInstalled(IFeature feature) {
+		}
+		public void featureRemoved(IFeature feature) {
+			cleanSavedConfigs(feature);
+		}
+		public void featureConfigured(IFeature feature) {
+		}
+		public void featureUnconfigured(IFeature feature) {
+			cleanSavedConfigs(feature);
+		}
+	}
+	public PatchCleaner(IConfiguredSite csite, IFeature root) {
+		this.csite = csite;
+		listener = new SiteListener();
+		csite.addConfiguredSiteChangedListener(listener);
+	}
+
+	public void dispose() {
+		csite.removeConfiguredSiteChangedListener(listener);
+	}
+	private void cleanSavedConfigs(IFeature feature) {
+		if (feature.isPatch()) {
+			IInstallConfiguration backupConfig = UpdateUtils.getBackupConfigurationFor(feature);
+			if (backupConfig!=null) {
+				// clean it
+				remove(backupConfig);
+			}
+		}
+	}
+	private void remove(IInstallConfiguration config) {
+		try {
+			ILocalSite localSite = SiteManager.getLocalSite();
+			localSite.removeFromPreservedConfigurations(config);
+		}
+		catch (CoreException e) {
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ReplaceFeatureVersionOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ReplaceFeatureVersionOperation.java
new file mode 100644
index 0000000..6d5858b
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ReplaceFeatureVersionOperation.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.operations.*;
+
+/**
+ * Swaps a feature.
+ * ReplaceFeatureVersionOperation
+ */
+public class ReplaceFeatureVersionOperation
+	extends FeatureOperation
+	implements IConfigFeatureOperation {
+
+	private IFeature anotherFeature;
+	
+	public ReplaceFeatureVersionOperation(
+		IFeature feature,
+		IFeature anotherFeature) {
+		super(feature.getSite().getCurrentConfiguredSite(), feature);
+		this.anotherFeature = anotherFeature;
+	}
+
+	public boolean execute(IProgressMonitor pm, IOperationListener listener)
+		throws CoreException {
+
+		IStatus status =
+			OperationsManager.getValidator().validatePendingReplaceVersion(feature, anotherFeature);
+		if (status != null) {
+			throw new CoreException(status);
+		}
+
+		// unconfigure current feature first, then configure the other one
+		
+		PatchCleaner cleaner = new PatchCleaner(targetSite, feature);
+		targetSite.unconfigure(feature);
+		cleaner.dispose();
+		
+		targetSite.configure(anotherFeature);
+//		ensureUnique();
+
+		try {
+			// Restart not needed
+			boolean restartNeeded = false;
+
+			// Check if this operation is cancelling one that's already pending
+			IOperation pendingOperation =
+				OperationsManager.findPendingOperation(feature);
+
+			if (pendingOperation instanceof IConfigFeatureOperation) {
+				// no need to do either pending change
+				OperationsManager.removePendingOperation(pendingOperation);
+			} else {
+				OperationsManager.addPendingOperation(this);
+				restartNeeded = true;
+			}
+			
+			pendingOperation =
+				OperationsManager.findPendingOperation(anotherFeature);
+				
+			if (pendingOperation instanceof IUnconfigFeatureOperation) {
+				// no need to do either pending change
+				OperationsManager.removePendingOperation(pendingOperation);
+			} else {
+				OperationsManager.addPendingOperation(this);
+				restartNeeded = true;
+			}
+			
+			markProcessed();
+			if (listener != null)
+				listener.afterExecute(this, null);
+
+			restartNeeded = SiteManager.getLocalSite().save() && restartNeeded;
+
+			// notify the model
+			OperationsManager.fireObjectChanged(feature, null);
+
+			return restartNeeded;
+		} catch (CoreException e) {
+			undo();
+			UpdateUtils.logException(e);
+			throw e;
+		}
+	}
+
+	public void undo() throws CoreException {
+		targetSite.unconfigure(anotherFeature);
+		targetSite.configure(feature);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/RevertConfigurationOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/RevertConfigurationOperation.java
new file mode 100644
index 0000000..83e9702
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/RevertConfigurationOperation.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import java.lang.reflect.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.operations.*;
+
+public class RevertConfigurationOperation extends Operation implements IRevertConfigurationOperation {
+
+	private IInstallConfiguration config;
+	private IProblemHandler problemHandler;
+
+	public RevertConfigurationOperation(
+		IInstallConfiguration config,
+		IProblemHandler problemHandler) {
+		super();
+		this.config = config;
+		this.problemHandler = problemHandler;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.operations.IOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public boolean execute(IProgressMonitor monitor, IOperationListener listener)
+		throws CoreException, InvocationTargetException {
+		IStatus status =
+			OperationsManager.getValidator().validatePendingRevert(config);
+		if (status != null && status.getCode() == IStatus.ERROR) {
+			throw new CoreException(status);
+		}
+
+		try {
+			ILocalSite localSite = SiteManager.getLocalSite();
+			localSite.revertTo(config, monitor, problemHandler);
+			localSite.save();
+			return true;
+		} catch (CoreException e) {
+			UpdateUtils.logException(e);
+			throw e;
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ToggleSiteOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ToggleSiteOperation.java
new file mode 100644
index 0000000..d9fcd21
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/ToggleSiteOperation.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.operations.*;
+
+public class ToggleSiteOperation
+	extends Operation
+	implements IToggleSiteOperation {
+
+	private IConfiguredSite site;
+
+	public ToggleSiteOperation(IConfiguredSite site) {
+		super();
+		this.site = site;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.operations.IOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public boolean execute(
+		IProgressMonitor monitor,
+		IOperationListener listener)
+		throws CoreException {
+		if (site == null)
+			return false;
+		boolean oldValue = site.isEnabled();
+		site.setEnabled(!oldValue);
+		IStatus status = OperationsManager.getValidator().validateCurrentState();
+		if (status != null) {
+			// revert
+			site.setEnabled(oldValue);
+			throw new CoreException(status);
+		} else {
+			try {
+				boolean restartNeeded = SiteManager.getLocalSite().save();
+				OperationsManager.fireObjectChanged(site, ""); //$NON-NLS-1$
+				return restartNeeded; // will restart only if changes could not be applied to current config
+			} catch (CoreException e) {
+				//revert
+				site.setEnabled(oldValue);
+				UpdateUtils.logException(e);
+				throw e;
+			}
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigOperation.java
new file mode 100644
index 0000000..f0c8808
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigOperation.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.operations.*;
+
+/**
+ * Unconfigure a feature.
+ * UnconfigOperation
+ */
+public class UnconfigOperation
+	extends FeatureOperation
+	implements IUnconfigFeatureOperation {
+
+	public UnconfigOperation(
+		IConfiguredSite site,
+		IFeature feature) {
+		super(site, feature);
+	}
+
+	public boolean execute(IProgressMonitor pm, IOperationListener listener)
+		throws CoreException {
+
+		IStatus status =
+			OperationsManager.getValidator().validatePendingUnconfig(feature);
+		if (status != null && status.getCode() == IStatus.ERROR) {
+			throw new CoreException(status);
+		}
+
+		PatchCleaner cleaner = new PatchCleaner(targetSite, feature);
+		targetSite.unconfigure(feature);
+		cleaner.dispose();
+
+		try {
+			// Restart not needed
+			boolean restartNeeded = false;
+
+			// Check if this operation is cancelling one that's already pending
+			IOperation pendingOperation =
+				OperationsManager.findPendingOperation(feature);
+
+			if (pendingOperation instanceof IConfigFeatureOperation) {
+				// no need to do either pending change
+				OperationsManager.removePendingOperation(pendingOperation);
+			} else {
+				OperationsManager.addPendingOperation(this);
+				restartNeeded = true;
+			}
+
+			markProcessed();
+			if (listener != null)
+				listener.afterExecute(this, null);
+
+			restartNeeded = SiteManager.getLocalSite().save() && restartNeeded;
+
+			// notify the model
+			OperationsManager.fireObjectChanged(feature, null);
+
+			return restartNeeded;
+		} catch (CoreException e) {
+			undo();
+			UpdateUtils.logException(e);
+			throw e;
+		}
+	}
+
+	public void undo() throws CoreException {
+		targetSite.configure(feature);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigureAndUninstallFeatureOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigureAndUninstallFeatureOperation.java
new file mode 100644
index 0000000..ed22c60
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigureAndUninstallFeatureOperation.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.Properties;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.operations.IOperationListener;
+import org.eclipse.update.operations.IUnconfigFeatureOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class UnconfigureAndUninstallFeatureOperation extends FeatureOperation
+		implements IUnconfigureAndUninstallFeatureOperation {
+
+	public UnconfigureAndUninstallFeatureOperation(IConfiguredSite targetSite, IFeature feature) {
+		super(targetSite, feature);
+	}
+
+	public boolean execute(IProgressMonitor pm, IOperationListener listener)
+			throws CoreException, InvocationTargetException {
+		
+		IUnconfigFeatureOperation unconfigOperation = OperationsManager.getOperationFactory().createUnconfigOperation(targetSite, feature);
+
+		/*boolean isRestartNeeded = */unconfigOperation.execute(pm, listener);
+		
+
+		URL platformXML = ConfiguratorUtils.getCurrentPlatformConfiguration().getConfigurationLocation();
+		
+		File f = new File(platformXML.getFile());
+
+		f = new File(f.getParentFile(), "toBeUninstalled"); //$NON-NLS-1$
+		try {
+			if (!f.exists()) {
+				f.createNewFile();
+			}
+			FileInputStream fis = new FileInputStream(f);
+			Properties toBeUninstalled = new Properties();
+			toBeUninstalled.load(fis);
+			toBeUninstalled.put(new Integer(toBeUninstalled.size()+1).toString(), targetSite.getSite().getURL() + ";" + feature.getVersionedIdentifier().toString()); //$NON-NLS-1$
+			fis.close();
+			FileOutputStream fos = new FileOutputStream(f);
+			toBeUninstalled.store(fos, "to be uninstalled on start-up"); //$NON-NLS-1$
+			fos.close();
+			
+		} catch (IOException ioe) {
+			
+		}
+
+		
+		return true;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigureAndUninstallFeaturesOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigureAndUninstallFeaturesOperation.java
new file mode 100644
index 0000000..a96108f
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigureAndUninstallFeaturesOperation.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class UnconfigureAndUninstallFeaturesOperation extends
+		BatchFeatureOperation implements
+		IUnconfigureAndUninstallFeaturesOperation {
+
+	public UnconfigureAndUninstallFeaturesOperation(IConfiguredSite[] targetSites,
+			IFeature[] features) {
+		super(targetSites, features);
+	}
+
+	protected IOperation createOperation(IConfiguredSite targetSite, IFeature feature) {
+		return ((OperationFactory)OperationsManager.getOperationFactory()).createUnconfigureAndUninstallFeatureOperation(targetSite, feature);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigureFeaturesOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigureFeaturesOperation.java
new file mode 100644
index 0000000..184c8b8
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UnconfigureFeaturesOperation.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class UnconfigureFeaturesOperation 
+	extends BatchFeatureOperation implements IUnconfigureFeaturesOperation {
+
+	public UnconfigureFeaturesOperation(IConfiguredSite[] targetSites, IFeature[] features) {
+		super(targetSites, features);
+	}
+	
+	protected IOperation createOperation(IConfiguredSite targetSite, IFeature feature) {
+		return OperationsManager.getOperationFactory().createUnconfigOperation(targetSite, feature);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UninstallFeaturesOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UninstallFeaturesOperation.java
new file mode 100644
index 0000000..c6879de
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UninstallFeaturesOperation.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class UninstallFeaturesOperation extends BatchFeatureOperation implements
+		IUninstallFeaturesOperation {
+
+	public UninstallFeaturesOperation(IConfiguredSite[] targetSites, IFeature[] features) {
+		super(targetSites, features);
+	}
+
+
+	protected IOperation createOperation(IConfiguredSite targetSite, IFeature feature) {
+		return OperationsManager.getOperationFactory().createUninstallOperation(targetSite, feature);
+	}
+
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UninstallOperation.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UninstallOperation.java
new file mode 100644
index 0000000..136b7a4
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UninstallOperation.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.operations.*;
+
+/**
+ * Configure a feature.
+ * ConfigOperation
+ */
+public class UninstallOperation extends FeatureOperation implements IUninstallFeatureOperation{
+
+	public UninstallOperation(IConfiguredSite site, IFeature feature) {
+		super(site, feature);
+	}
+
+	public void setTargetSite(IConfiguredSite targetSite) {
+		this.targetSite = targetSite;
+	}
+
+	public boolean execute(IProgressMonitor pm, IOperationListener listener) throws CoreException {
+		
+		if (targetSite == null)
+			targetSite = UpdateUtils.getConfigSite(feature, SiteManager.getLocalSite().getCurrentConfiguration());
+
+		// Restart not needed
+		boolean restartNeeded = false;
+
+		if (targetSite != null) {
+			// if needed, unconfigure the feature first
+			if (targetSite.isConfigured(feature)) {
+				IStatus status = OperationsManager.getValidator().validatePendingUnconfig(feature);
+				if (status != null && status.getCode() == IStatus.ERROR)
+					throw new CoreException(status);
+				if (unconfigure(feature, targetSite))
+					restartNeeded = true;
+				else
+					throw Utilities.newCoreException(NLS.bind(Messages.OperationsManager_error_uninstall, (new String[] { feature.getVersionedIdentifier().toString() })), null);
+			}
+			targetSite.remove(feature, pm);
+		} else {
+			// we should do something here
+			String message =
+				NLS.bind(Messages.OperationsManager_error_uninstall, (new String[] { feature.getLabel() }));
+			IStatus status =
+				new Status(
+					IStatus.ERROR,
+					UpdateUtils.getPluginId(),
+					IStatus.OK,
+					message,
+					null);
+			throw new CoreException(status);
+		}
+
+		markProcessed();
+		if (listener != null)
+			listener.afterExecute(this, null);
+
+		restartNeeded = SiteManager.getLocalSite().save() && restartNeeded;
+
+		// notify the model
+		OperationsManager.fireObjectChanged(feature, UNINSTALL);
+		
+		return restartNeeded;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UpdateUtils.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UpdateUtils.java
new file mode 100644
index 0000000..6914a0a
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/operations/UpdateUtils.java
@@ -0,0 +1,692 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *     James D Miles (IBM Corp.) - bug 191368, Policy URL doesn't support UTF-8 characters
+ *******************************************************************************/
+package org.eclipse.update.internal.operations;
+
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.core.URLEncoder;
+import org.eclipse.update.internal.search.*;
+import org.eclipse.update.operations.*;
+import org.eclipse.update.search.*;
+
+
+/**
+ * Helper class for performing update related tasks, queries, etc.
+ * All the methods are static and this class should be a singleton.
+ */
+public class UpdateUtils {
+	public static final String P_UPDATE_POLICY_URL = "updatePolicyURL"; //$NON-NLS-1$
+
+	/**
+	 * Private constructor
+	 */
+	private UpdateUtils() {
+	}
+	
+
+	public static String getPluginId() {
+		return UpdateCore.getPlugin().getBundle().getSymbolicName();
+	}
+
+
+	public static void logException(Throwable e) {
+		
+		if (e instanceof InvocationTargetException) {
+			e = ((InvocationTargetException) e).getTargetException();
+		}
+
+		IStatus status = null;
+		if (e instanceof CoreException) {
+			status = ((CoreException) e).getStatus();
+		} else {
+			String message = e.getMessage();
+			if (message == null)
+				message = e.toString();
+			status = new Status(IStatus.ERROR, getPluginId(), IStatus.OK, message, e);
+		}
+		log(status);
+	}
+
+	public static void log(IStatus status) {
+		if (status.getSeverity() != IStatus.INFO) {
+			UpdateCore.getPlugin().getLog().log(status);
+		} 
+	}
+
+	public static IFeature[] searchSite(String featureId, IConfiguredSite site, boolean onlyConfigured) throws CoreException {
+		IFeatureReference[] references = null;
+
+		if (onlyConfigured)
+			references = site.getConfiguredFeatures();
+		else
+			references = site.getSite().getFeatureReferences();
+		Vector result = new Vector();
+
+		for (int i = 0; i < references.length; i++) {
+			IFeature feature = references[i].getFeature(null);
+			String id = feature.getVersionedIdentifier().getIdentifier();
+			if (featureId.equals(id)) {
+				result.add(feature);
+			}
+		}
+		return (IFeature[]) result.toArray(new IFeature[result.size()]);
+	}
+
+	public static IFeature[] getInstalledFeatures(IFeature feature) {
+		return getInstalledFeatures(feature, true);
+	}
+
+	/**
+	 * 
+	 * @param feature
+	 * @param onlyConfigured
+	 * @return IFeature[] with features matching feature ID
+	 */
+	public static IFeature[] getInstalledFeatures(IFeature feature, boolean onlyConfigured) {
+		return getInstalledFeatures(feature.getVersionedIdentifier(), onlyConfigured);
+	}
+	/**
+	 * @param vid
+	 * @param onlyConfigured
+	 * @return IFeature[] with features matching feature ID
+	 */
+	public static IFeature[] getInstalledFeatures(VersionedIdentifier vid, boolean onlyConfigured) {
+		Vector features = new Vector();
+		try {
+			ILocalSite localSite = SiteManager.getLocalSite();
+			IInstallConfiguration config = localSite.getCurrentConfiguration();
+			IConfiguredSite[] isites = config.getConfiguredSites();
+			String id = vid.getIdentifier();
+
+			for (int i = 0; i < isites.length; i++) {
+				IConfiguredSite isite = isites[i];
+				IFeature[] result = UpdateUtils.searchSite(id, isite, onlyConfigured);
+				for (int j = 0; j < result.length; j++) {
+					IFeature installedFeature = result[j];
+					features.add(installedFeature);
+				}
+			}
+		} catch (CoreException e) {
+			UpdateUtils.logException(e);
+		}
+		return (IFeature[]) features.toArray(new IFeature[features.size()]);
+	}
+	
+	/**
+	 * @param patch
+	 * @return IFeature or null
+	 */
+	public static IFeature getPatchedFeature(IFeature patch) {
+		IImport[] imports = patch.getImports();
+		for (int i = 0; i < imports.length; i++) {
+			IImport iimport = imports[i];
+			if (iimport.isPatch()) {
+				VersionedIdentifier patchedVid = iimport
+						.getVersionedIdentifier();
+				// features with matching id
+				IFeature[] features = getInstalledFeatures(patchedVid, false);
+				for (int f = 0; f < features.length; f++) {
+					// check if version match
+					if (patchedVid.equals(features[f].getVersionedIdentifier())) {
+						return features[f];
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	public static boolean isPatch(IFeature candidate) {
+		IImport[] imports = candidate.getImports();
+
+		for (int i = 0; i < imports.length; i++) {
+			IImport iimport = imports[i];
+			if (iimport.isPatch()) return true;
+		}
+		return false;
+	}
+
+	public static boolean isPatch(IFeature target, IFeature candidate) {
+		VersionedIdentifier vid = target.getVersionedIdentifier();
+		IImport[] imports = candidate.getImports();
+
+		for (int i = 0; i < imports.length; i++) {
+			IImport iimport = imports[i];
+			if (iimport.isPatch()) {
+				VersionedIdentifier ivid = iimport.getVersionedIdentifier();
+				if (vid.equals(ivid)) {
+					// Bingo.
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	public static IInstallConfiguration getBackupConfigurationFor(IFeature feature) {
+		VersionedIdentifier vid = feature.getVersionedIdentifier();
+		String key = "@" + vid.getIdentifier() + "_" + vid.getVersion(); //$NON-NLS-1$ //$NON-NLS-2$
+		try {
+			ILocalSite lsite = SiteManager.getLocalSite();
+			IInstallConfiguration[] configs = lsite.getPreservedConfigurations();
+			for (int i = 0; i < configs.length; i++) {
+				IInstallConfiguration config = configs[i];
+				if (config.getLabel().startsWith(key))
+					return config;
+			}
+		} catch (CoreException e) {
+		}
+		return null;
+	}
+	
+	
+	public static boolean hasLicense(IFeature feature) {
+		IURLEntry info = feature.getLicense();
+		if (info == null)
+			return false;
+		String licenseTxt = info.getAnnotation();
+		if (licenseTxt == null)
+			return false;
+		return licenseTxt.trim().length() > 0;
+	}
+	public static boolean hasOptionalFeatures(IFeature feature) {
+		try {
+			IIncludedFeatureReference[] irefs = feature.getIncludedFeatureReferences();
+			for (int i = 0; i < irefs.length; i++) {
+				IIncludedFeatureReference iref = irefs[i];
+				if (iref.isOptional())
+					return true;
+				// see if it has optional children
+				IFeature child = getIncludedFeature( feature, iref);
+				if (hasOptionalFeatures(child))
+					return true;
+			}
+		} catch (CoreException e) {
+		}
+		return false;
+	}
+
+	public static IFeature getLocalFeature(
+		IConfiguredSite csite,
+		IFeature feature)
+		throws CoreException {
+		IFeatureReference[] refs = csite.getConfiguredFeatures();
+		for (int i = 0; i < refs.length; i++) {
+			IFeatureReference ref = refs[i];
+			VersionedIdentifier refVid = ref.getVersionedIdentifier();
+			if (feature.getVersionedIdentifier().equals(refVid))
+				return ref.getFeature(null);
+		}
+		return null;
+	}
+	
+	public static IConfiguredSite getConfigSite(
+		IFeature feature,
+		IInstallConfiguration config)
+		throws CoreException {
+		IConfiguredSite[] configSites = config.getConfiguredSites();
+		for (int i = 0; i < configSites.length; i++) {
+			IConfiguredSite site = configSites[i];
+			if (site.getSite().equals(feature.getSite())) {
+				return site;
+			}
+		}
+		return null;
+	}
+	
+	public static IConfiguredSite getDefaultTargetSite(
+		IInstallConfiguration config,
+		IInstallFeatureOperation pendingChange) {
+		return getDefaultTargetSite(config, pendingChange, true);
+	}
+
+	public  static IConfiguredSite getDefaultTargetSite(
+		IInstallConfiguration config,
+		IInstallFeatureOperation pendingChange,
+		boolean checkAffinityFeature) {
+		IFeature oldFeature = pendingChange.getOldFeature();
+		IFeature newFeature = pendingChange.getFeature();
+		if (oldFeature != null) {
+			// We should install into the same site as
+			// the old feature
+			try {
+				return getConfigSite(oldFeature, config);
+			} catch (CoreException e) {
+				logException(e);
+				return null;
+			}
+		}
+
+		// This is a new install. Check if there is 
+		// a disabled feature with the same ID
+		String newFeatureID =
+			newFeature.getVersionedIdentifier().getIdentifier();
+		IConfiguredSite sameSite = getSiteWithFeature(config, newFeatureID);
+		if (sameSite != null) {
+			return sameSite;
+		}
+
+		if (checkAffinityFeature) {
+			return getAffinitySite(config, newFeature);
+		}
+		return null;
+	}
+	
+	public static IConfiguredSite getAffinitySite(
+		IInstallConfiguration config,
+		IFeature newFeature) {
+		// check if the affinity feature is installed
+		String affinityID = newFeature.getAffinityFeature();
+		if (affinityID != null) {
+			IConfiguredSite affinitySite =
+				getSiteWithFeature(config, affinityID);
+			if (affinitySite != null)
+				return affinitySite;
+		} else {
+			// if this is a patch, collocate with the feature
+			IFeature patchedFeature = getPatchedFeature(newFeature);
+			if (patchedFeature != null)
+				return getSiteWithFeature(config, patchedFeature.getVersionedIdentifier().getIdentifier());
+		}
+		return null;
+	}
+
+	public static IConfiguredSite getSiteWithFeature(
+		IInstallConfiguration config,
+		String featureID) {
+		if (featureID == null)
+			return null;
+		IConfiguredSite[] sites = config.getConfiguredSites();
+		for (int i = 0; i < sites.length; i++) {
+			IConfiguredSite site = sites[i];
+			IFeatureReference[] refs = site.getFeatureReferences();
+			for (int j = 0; j < refs.length; j++) {
+				IFeatureReference ref = refs[j];
+				try {
+					IFeature feature = ref.getFeature(null);
+					if (featureID
+						.equals(
+							feature
+								.getVersionedIdentifier()
+								.getIdentifier())) {
+						// found it
+						return site;
+					}
+				} catch (CoreException e) {
+					logException(e);
+				}
+			}
+		}
+		return null;
+	}
+	
+	public static void collectOldFeatures(
+		IFeature feature,
+		IConfiguredSite targetSite,
+		ArrayList result)
+		throws CoreException {
+		IIncludedFeatureReference[] included =
+			feature.getIncludedFeatureReferences();
+		for (int i = 0; i < included.length; i++) {
+			IIncludedFeatureReference iref = included[i];
+
+			IFeature ifeature;
+
+			try {
+				ifeature = iref.getFeature(null);
+			} catch (CoreException e) {
+				if (iref.isOptional())
+					continue;
+				throw e;
+			}
+			// find other features and unconfigure
+			String id = iref.getVersionedIdentifier().getIdentifier();
+			IFeature[] sameIds = UpdateUtils.searchSite(id, targetSite, true);
+			for (int j = 0; j < sameIds.length; j++) {
+				IFeature sameId = sameIds[j];
+				// Ignore self.
+				if (sameId.equals(ifeature))
+					continue;
+				result.add(sameId);
+			}
+			collectOldFeatures(ifeature, targetSite, result);
+		}
+	}
+
+//
+//	public static IInstallConfiguration createInstallConfiguration() throws CoreException{
+//		try {
+//			ILocalSite localSite = SiteManager.getLocalSite();
+//			IInstallConfiguration config =
+//				localSite.cloneCurrentConfiguration();
+//			config.setLabel(Utilities.format(config.getCreationDate()));
+//			return config;
+//		} catch (CoreException e) {
+//			// Let callers handle logging
+//			//logException(e);
+//			throw e;
+//		}
+//	}
+	
+	public static UpdateSearchRequest createNewUpdatesRequest(IFeature [] features) {
+		return createNewUpdatesRequest(features, true);
+	}
+	
+	public static UpdateSearchRequest createNewUpdatesRequest(IFeature [] features, boolean automatic) {
+		UpdateSearchScope scope = new UpdateSearchScope();
+		scope.setUpdateMapURL(UpdateUtils.getUpdateMapURL());
+		UpdatesSearchCategory category = new UpdatesSearchCategory(automatic);
+		if (features!=null)
+			category.setFeatures(features);
+		UpdateSearchRequest searchRequest = new UpdateSearchRequest(category, scope);
+		searchRequest.addFilter(new EnvironmentFilter());
+		searchRequest.addFilter(new BackLevelFilter());
+		return searchRequest;
+	}
+
+	public static boolean isNestedChild(IInstallConfiguration config, IFeature feature) {
+		IConfiguredSite[] csites = config.getConfiguredSites();
+		try {
+			for (int i = 0; csites != null && i < csites.length; i++) {
+				IFeatureReference[] refs = csites[i].getConfiguredFeatures();
+				for (int j = 0; refs != null && j < refs.length; j++) {
+					IFeature parent = refs[j].getFeature(null);
+					IFeatureReference[] children =
+						parent.getIncludedFeatureReferences();
+					for (int k = 0;
+						children != null && k < children.length;
+						k++) {
+						IFeature child = children[k].getFeature(null);
+						if (feature.equals(child))
+							return true;
+					}
+				}
+			}
+		} catch (CoreException e) {
+			// will return false
+		}
+		return false;
+	}
+	
+	
+	public static boolean hasObsoletePatches(IFeature feature) {
+		// Check all the included features that
+		// are unconfigured, and see if their patch 
+		// references are better than the original.
+		try {
+			IFeatureReference[] irefs = feature.getIncludedFeatureReferences();
+			for (int i = 0; i < irefs.length; i++) {
+				IFeatureReference iref = irefs[i];
+				IFeature ifeature = iref.getFeature(null);
+				IConfiguredSite csite = ifeature.getSite().getCurrentConfiguredSite();
+				if (!csite.isConfigured(ifeature)) {
+					if (!isPatchHappy(ifeature))
+						return false;
+				}
+			}
+		} catch (CoreException e) {
+			return false;
+		}
+		// All checks went well
+		return true;
+	}
+	
+	public static boolean isPatchHappy(IFeature feature) throws CoreException {
+		// If this is a patch and it includes 
+		// another patch and the included patch
+		// is disabled but the feature it was declared
+		// to patch is now newer (and is presumed to
+		// contain the now disabled patch), and
+		// the newer patched feature is enabled,
+		// a 'leap of faith' assumption can be
+		// made:
+
+		// Although the included patch is disabled,
+		// the feature it was designed to patch
+		// is now newer and most likely contains
+		// the equivalent fix and more. Consequently,
+		// we can claim that the status and the error
+		// icon overlay are misleading because
+		// all the right plug-ins are configured.
+		IImport[] imports = feature.getImports();
+		IImport patchReference = null;
+		for (int i = 0; i < imports.length; i++) {
+			IImport iimport = imports[i];
+			if (iimport.isPatch()) {
+				patchReference = iimport;
+				break;
+			}
+		}
+		if (patchReference == null)
+			return false;
+		VersionedIdentifier refVid = patchReference.getVersionedIdentifier();
+
+		// Find the patched feature and 
+		IConfiguredSite csite = feature.getSite().getCurrentConfiguredSite();
+		if (csite == null)
+			return false;
+
+		IFeatureReference[] crefs = csite.getConfiguredFeatures();
+		for (int i = 0; i < crefs.length; i++) {
+			IFeatureReference cref = crefs[i];
+			VersionedIdentifier cvid = cref.getVersionedIdentifier();
+			if (cvid.getIdentifier().equals(refVid.getIdentifier())) {
+				// This is the one.
+				if (cvid.getVersion().isGreaterThan(refVid.getVersion())) {
+					// Bingo: we found the referenced feature
+					// and its version is greater - 
+					// we can assume that it contains better code
+					// than the patch that referenced the
+					// older version.
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	public static URL getUpdateMapURL() {
+		Preferences pref = UpdateCore.getPlugin().getPluginPreferences();
+		String mapFile = pref.getString(UpdateUtils.P_UPDATE_POLICY_URL);
+		if (mapFile!=null && mapFile.length()>0) {
+			try {
+				URL url = new URL(mapFile);
+				URL resolvedURL = URLEncoder.encode(url);
+				return resolvedURL;
+			}
+			catch (MalformedURLException e) {
+				UpdateUtils.logException(e);
+			}
+		}
+		return null;
+	}
+	
+	/*
+	 * Load the update map using the map URL found in the scope.
+	 */	
+	public static IStatus loadUpdatePolicy(UpdatePolicy map, URL url, IProgressMonitor monitor) throws CoreException {
+		monitor.subTask(Messages.UpdateSearchRequest_loadingPolicy); 
+		try {
+			map.load(url, monitor);
+			monitor.worked(1);
+		}
+		catch (CoreException e) {
+			IStatus status = e.getStatus();
+			if (status == null
+				|| status.getCode() != ISite.SITE_ACCESS_EXCEPTION)
+				throw e;
+			monitor.worked(1);
+			return status;
+		}
+		return null;
+	}
+
+	public static void downloadFeatureContent(
+        IConfiguredSite targetSite,
+		IFeature feature,
+		IFeatureReference[] optionalChildren, // null when feature has no optional features
+		IProgressMonitor progress)
+		throws InstallAbortedException, CoreException {
+		
+		//DEBUG
+		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_INSTALL) {
+			UpdateCore.debug(
+				"Downloading...:" + feature.getURL().toExternalForm()); //$NON-NLS-1$
+		}
+
+		// Get source feature provider and verifier.
+		// Initialize target variables.
+		final IFeatureContentProvider provider =
+			feature.getFeatureContentProvider();
+		IPluginEntry[] targetSitePluginEntries = null;
+
+		// determine list of plugins to install
+		// find the intersection between the plugin entries already contained
+		// on the target site, and plugin entries packaged in source feature
+		IPluginEntry[] sourceFeaturePluginEntries = feature.getPluginEntries();
+
+        boolean featureAlreadyInstalled = false;
+        if (targetSite == null)
+            targetSite = getSiteWithFeature(SiteManager.getLocalSite()
+                    .getCurrentConfiguration(), ((Feature) feature)
+                    .getFeatureIdentifier());
+		if (targetSite == null) {
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_INSTALL) {
+				UpdateCore.debug("The site to install in is null"); //$NON-NLS-1$
+			}
+
+			targetSitePluginEntries = new IPluginEntry[0];
+		} else {
+			targetSitePluginEntries = targetSite.getSite().getPluginEntries();
+            featureAlreadyInstalled = UpdateUtils.getLocalFeature(targetSite,feature) != null;
+		}
+		IPluginEntry[] pluginsToInstall =
+			UpdateManagerUtils.diff(
+				sourceFeaturePluginEntries,
+				targetSitePluginEntries);
+		INonPluginEntry[] nonPluginsToInstall = feature.getNonPluginEntries();
+		
+		IFeatureReference[] children = feature.getIncludedFeatureReferences();
+		if (optionalChildren != null) {
+			children =
+				UpdateManagerUtils.optionalChildrenToInstall(
+					children,
+					optionalChildren);
+		}
+
+		// make sure we have an InstallMonitor		
+		InstallMonitor monitor;
+		if (progress == null)
+			monitor = new InstallMonitor(new NullProgressMonitor());
+		else if (progress instanceof InstallMonitor)
+			monitor = (InstallMonitor) progress;
+		else
+			monitor = new InstallMonitor(progress);
+
+		try {
+			// determine number of monitor tasks
+			//   1 task1 for the feature jar (download)
+			// + n tasks for plugin entries (download for each)
+			// + m tasks per non-plugin data entry (download for each)
+			// TODO custom install handler  + 1 task for custom non-plugin entry handling (1 for all combined)
+			// + 3*x tasks for children features (3 subtasks per install)
+			int taskCount =
+					1
+					+ pluginsToInstall.length
+					+ nonPluginsToInstall.length
+//				+ 1
+					+ 3 * children.length;
+			monitor.beginTask("", taskCount); //$NON-NLS-1$
+			
+			// Download feature archive(s)
+			provider.getFeatureEntryArchiveReferences(monitor);
+			monitorWork(monitor,1);
+			
+			// Download plugin archives
+			for (int i = 0; i < pluginsToInstall.length; i++) {
+				provider.getPluginEntryArchiveReferences(pluginsToInstall[i], monitor);
+				monitorWork(monitor,1);
+			}
+			
+			
+
+			// Download non-plugin archives. Verification handled by optional install handler
+            // Note: do not download non-plugin archives for installed features
+            if (nonPluginsToInstall.length > 0) {
+                // Setup optional install handler
+                InstallHandlerProxy handler = null;
+                if (feature.getInstallHandlerEntry()!=null)
+                    handler = new InstallHandlerProxy(
+                        IInstallHandler.HANDLER_ACTION_INSTALL,
+                        feature,
+                        feature.getInstallHandlerEntry(),
+                        monitor);
+            	
+                if (!featureAlreadyInstalled)
+                    for (int i = 0; i < nonPluginsToInstall.length; i++) {
+                        if (handler==null || handler.acceptNonPluginData(nonPluginsToInstall[i]))
+                        	provider.getNonPluginEntryArchiveReferences(
+                                nonPluginsToInstall[i], monitor);
+                        monitorWork(monitor, 1);
+                    }
+                else
+                    monitorWork(monitor, nonPluginsToInstall.length);
+            }
+           
+			// Download child features
+			for (int i = 0; i < children.length; i++) {
+				IFeature childFeature = null;
+				try {
+					childFeature = children[i].getFeature(null);
+				} catch (CoreException e) {
+					UpdateCore.warn(null, e);
+				}
+				if (childFeature != null) {
+					SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 3);
+					downloadFeatureContent(targetSite, childFeature, optionalChildren, subMonitor);
+				}
+			}
+		} finally {
+			if (monitor != null)
+				monitor.done();
+		}
+	}
+	
+	private static void monitorWork(IProgressMonitor monitor, int tick)
+	throws CoreException {
+	if (monitor != null) {
+		monitor.worked(tick);
+		if (monitor.isCanceled()) {
+			String msg = "download cancelled";//Policy.bind("Feature.InstallationCancelled"); //$NON-NLS-1$
+			throw new InstallAbortedException(msg, null);
+		}
+	}
+}
+	public static IFeature getIncludedFeature(IFeature feature, IFeatureReference iref) throws CoreException {
+		IFeature ifeature = null;
+		if (feature.getSite() instanceof ExtendedSite) {
+			ifeature = ((ExtendedSite)feature.getSite()).getLiteFeature(iref.getVersionedIdentifier());
+		}
+		if (ifeature == null) {
+			ifeature = iref.getFeature(new NullProgressMonitor());
+		}
+		return ifeature;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/provisional/SiteOptimizerApplication.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/provisional/SiteOptimizerApplication.java
new file mode 100644
index 0000000..1a979a2
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/provisional/SiteOptimizerApplication.java
@@ -0,0 +1,907 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 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
+ *     Chris Aniszczyk (IBM Corp.) - NL-enabled the site optimizer
+ *******************************************************************************/
+package org.eclipse.update.internal.provisional;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPlatformRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.IIncludedFeatureReference;
+import org.eclipse.update.core.IncludedFeatureReference;
+import org.eclipse.update.core.model.DefaultSiteParser;
+import org.eclipse.update.core.model.FeatureModel;
+import org.eclipse.update.core.model.FeatureModelFactory;
+import org.eclipse.update.core.model.FeatureReferenceModel;
+import org.eclipse.update.core.model.ImportModel;
+import org.eclipse.update.core.model.PluginEntryModel;
+import org.eclipse.update.core.model.SiteModel;
+import org.eclipse.update.core.model.URLEntryModel;
+import org.eclipse.update.internal.core.ExtendedSiteURLFactory;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.internal.jarprocessor.JarProcessor;
+import org.eclipse.update.internal.jarprocessor.JarProcessorExecutor;
+import org.eclipse.update.internal.jarprocessor.Main;
+import org.xml.sax.SAXException;
+
+/**
+ * The application class used to perform update site optimizations.
+ * <p>
+ * This class can only be referenced from <code>org.eclipse.runtime.applications</code>
+ * extension point. It should not be extended or instantiated.
+ * <p>
+ * <b>Note:</b> This class/interface is part of an interim API that is still
+ * under development and expected to change significantly before reaching
+ * stability. It is being made available at this early stage to solicit feedback
+ * from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.
+ * </p>
+ * 
+ * @since 3.2
+ */
+public class SiteOptimizerApplication implements IPlatformRunnable {
+	public final static Integer EXIT_ERROR = new Integer(1);
+
+	public final static String JAR_PROCESSOR = "-jarProcessor"; //$NON-NLS-1$
+
+	public final static String DIGEST_BUILDER = "-digestBuilder"; //$NON-NLS-1$
+
+	public final static String INPUT = "input"; //$NON-NLS-1$
+
+	public final static String OUTPUT_DIR = "-outputDir"; //$NON-NLS-1$
+
+	public final static String VERBOSE = "-verbose"; //$NON-NLS-1$
+
+	public final static String JAR_PROCESSOR_PACK = "-pack"; //$NON-NLS-1$
+
+	public final static String JAR_PROCESSOR_UNPACK = "-unpack"; //$NON-NLS-1$
+
+	public final static String JAR_PROCESSOR_REPACK = "-repack"; //$NON-NLS-1$
+
+	public final static String JAR_PROCESSOR_SIGN = "-sign"; //$NON-NLS-1$
+
+	public final static String JAR_PROCESSOR_PROCESS_ALL = "-processAll"; //$NON-NLS-1$
+
+	public final static String SITE_XML = "-siteXML"; //$NON-NLS-1$
+
+	public final static String SITE_ATTRIBUTES_FILE = "siteAttributes.txt"; //$NON-NLS-1$
+
+	public final static String DIGEST_OUTPUT_DIR = "-digestOutputDir"; //$NON-NLS-1$
+
+	/*
+	 * private final static String DESCRIPTION = "DESCRIPTION"; private final
+	 * static String LICENCE = "LICENCE"; private final static String COPYRIGHT =
+	 * "COPYRIGHT"; private final static String FEATURE_LABEL = "FEATURE_LABEL";
+	 */
+
+	/**
+	 * Parses the command line in the form: [-key [value]]* [inputvalue] If the
+	 * last argument does not start with a "-" then it is taken as the input
+	 * value and not the value for a preceding -key
+	 * 
+	 * @param args
+	 * @return
+	 */
+	private Map parseCmdLine(String[] args) {
+		Map cmds = new HashMap();
+		for (int i = 0; i < args.length; i++) {
+			if (i == args.length - 1 && !args[i].startsWith("-")) { //$NON-NLS-1$
+				cmds.put(INPUT, args[i]);
+			} else {
+				String key = args[i];
+				String val = null;
+				if (i < args.length - 2 && !args[i + 1].startsWith("-")) { //$NON-NLS-1$
+					val = args[++i];
+				}
+
+				if (key.startsWith(SITE_XML)) {
+					// System.out.println(val.indexOf(":null"));
+					val = key.substring(key.indexOf("=") + 1); //$NON-NLS-1$
+					// System.out.println(key + ":" + val);
+					cmds.put(SITE_XML, val);
+				} else if (key.startsWith(DIGEST_OUTPUT_DIR)) {
+					val = key.substring(key.indexOf("=") + 1); //$NON-NLS-1$
+					// System.out.println(key + ":" + val);
+					cmds.put(DIGEST_OUTPUT_DIR, val);
+				} else {
+
+					// System.out.println(key + ":" + val);
+					cmds.put(key, val);
+				}
+			}
+		}
+		return cmds;
+	}
+
+	private boolean runJarProcessor(Map params) {
+		Main.Options options = new Main.Options();
+		options.pack = params.containsKey(JAR_PROCESSOR_PACK);
+		options.unpack = params.containsKey(JAR_PROCESSOR_UNPACK);
+		options.repack = params.containsKey(JAR_PROCESSOR_REPACK);
+		options.processAll = params.containsKey(JAR_PROCESSOR_PROCESS_ALL);
+		options.verbose = params.containsKey(VERBOSE);
+		options.signCommand = (String) params.get(JAR_PROCESSOR_SIGN);
+		options.outputDir = (String) params.get(OUTPUT_DIR);
+
+		String problem = null;
+
+		String input = (String) params.get(INPUT);
+		if (input == null)
+			problem = Messages.SiteOptimizer_inputNotSpecified;
+		else {
+			File inputFile = new File(input);
+			if (inputFile.exists())
+				options.input = inputFile;
+			else
+				problem = NLS.bind(Messages.SiteOptimizer_inputFileNotFound,
+						new String[] { input });
+		}
+
+		if (options.unpack) {
+			if (!JarProcessor.canPerformUnpack()) {
+				problem = Messages.JarProcessor_unpackNotFound;
+			} else if (options.pack || options.repack
+					|| options.signCommand != null) {
+				problem = Messages.JarProcessor_noPackUnpack;
+			}
+		} else if ((options.pack || options.repack)
+				&& !JarProcessor.canPerformPack()) {
+			problem = Messages.JarProcessor_packNotFound;
+		}
+
+		if (problem != null) {
+			System.out.println(problem);
+			return false;
+		}
+
+		new JarProcessorExecutor().runJarProcessor(options);
+		return true;
+	}
+
+	private boolean runDigestBuilder(Map params) {
+
+		List featureList = getFeatureList(params);
+
+		if ((featureList == null) || featureList.isEmpty()) {
+			System.out.println("no features to process"); //$NON-NLS-1$
+			return false;
+		}
+		Map perFeatureLocales = new HashMap();
+		Map availableLocales = getAvailableLocales(featureList,
+				perFeatureLocales);
+		try {
+			openInputStremas(availableLocales);
+		} catch (IOException e1) {
+			e1.printStackTrace();
+			System.out.println("Can not create file in output direcotry"); //$NON-NLS-1$
+			return false;
+		}
+
+		for(int i = 0; i < featureList.size(); i++) {
+
+			String featureJarFileName = (String) featureList.get(i);
+
+			if (featureJarFileName.endsWith("jar")) { //$NON-NLS-1$
+				System.out.println("Processing... " + featureJarFileName); //$NON-NLS-1$
+			} else {
+				System.out.println("Skipping... " + featureJarFileName); //$NON-NLS-1$
+				continue;
+			}
+
+			JarFile featureJar = null;
+			try {
+				featureJar = new JarFile(featureJarFileName);
+			} catch (IOException e) {
+				System.out.println("Problem with opening jar: " //$NON-NLS-1$
+						+ featureJarFileName);
+				e.printStackTrace();
+				return false;
+			}
+			FeatureModelFactory fmf = new FeatureModelFactory();
+
+			try {
+				ZipEntry featureXMLEntry = featureJar.getEntry("feature.xml"); //$NON-NLS-1$
+				Map featureProperties = loadProperties(featureJar,
+						featureJarFileName, perFeatureLocales);
+
+				FeatureModel featureModel = fmf.parseFeature(featureJar
+						.getInputStream(featureXMLEntry));
+
+				featureList = addFeaturesToList( (String) params.get(SITE_XML), featureList, featureModel.getFeatureIncluded(), availableLocales, perFeatureLocales);
+
+				Iterator availableLocalesIterator = availableLocales.values()
+				.iterator();
+				while (availableLocalesIterator.hasNext()) {
+					((AvailableLocale) availableLocalesIterator.next())
+					.writeFeatureDigests(featureModel,
+							featureProperties);
+				}
+
+			} catch (SAXException e) {
+				e.printStackTrace();
+				return false;
+			} catch (IOException e) {
+				e.printStackTrace();
+				return false;
+			} catch (CoreException e) {
+				e.printStackTrace();
+				return false;
+			}
+		}
+		Iterator availableLocalesIterator = availableLocales.values()
+		.iterator();
+		String outputDirectory = (String) params.get(DIGEST_OUTPUT_DIR);
+
+		outputDirectory = outputDirectory.substring(outputDirectory
+				.indexOf("=") + 1); //$NON-NLS-1$
+		if (!outputDirectory.endsWith(File.separator)) {
+			outputDirectory = outputDirectory + File.separator;
+		}
+		while (availableLocalesIterator.hasNext()) {
+			try {
+				((AvailableLocale) availableLocalesIterator.next())
+				.finishDigest(outputDirectory);
+			} catch (IOException e) {
+				System.out.println("Can not write in digest output directory: " //$NON-NLS-1$
+						+ outputDirectory);
+				e.printStackTrace();
+				return false;
+			}
+		}
+		System.out.println("Done"); //$NON-NLS-1$
+		return true;
+	}
+
+	private List addFeaturesToList( String siteXML, List featureList, IIncludedFeatureReference[] iIncludedFeatureReferences, Map availableLocales, Map perFeatureLocales ) throws CoreException {
+
+		String directoryName = (new File(siteXML)).getParent();
+		if (!directoryName.endsWith(File.separator)) {
+			directoryName = directoryName + File.separator;
+		}
+		directoryName = directoryName + "features" + File.separator; //$NON-NLS-1$
+
+		for (int i = 0; i < iIncludedFeatureReferences.length; i++) {
+			String featureURL = directoryName + iIncludedFeatureReferences[i].getVersionedIdentifier() + ".jar"; //$NON-NLS-1$
+			if (!(isFeatureAlreadyInList(featureList, featureURL))) {
+				try {
+					System.out.println("Extracting locales from included feature " + featureURL); //$NON-NLS-1$
+					processLocalesInJar(availableLocales, featureURL, perFeatureLocales, true);
+				} catch (IOException e) {
+					if (iIncludedFeatureReferences[i].isOptional()) 
+						continue;
+					System.out.println("Error while extracting locales from included feature " + featureURL);//$NON-NLS-1$	
+					e.printStackTrace();
+					throw new CoreException( new Status( IStatus.ERROR, UpdateCore.getPlugin().getBundle().getSymbolicName(), IStatus.OK, "Error while extracting locales from included feature " + featureURL, e)); //$NON-NLS-1$ 
+				}
+				featureList.add(featureURL);
+			}
+		}
+
+		return featureList;
+	}
+
+	private boolean isFeatureAlreadyInList(List featureList, String featureURL) {
+		for (int i = 0; i < featureList.size(); i++) {
+			String currentFeatureURL = (String)featureList.get(i);
+			if (currentFeatureURL.equals(featureURL)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private Map loadProperties(JarFile featureJar, String featureJarFileName,
+			Map perFeatureLocales) {
+		// System.out.println(
+		// ((List)perFeatureLocales.get(featureJarFileName)).size());
+		Iterator it = ((List) perFeatureLocales.get(featureJarFileName))
+		.iterator();
+		Map result = new HashMap();
+		while (it.hasNext()) {
+			String propertyFileName = (String) it.next();
+
+			ZipEntry featurePropertiesEntry = featureJar
+			.getEntry(propertyFileName);
+			Properties featureProperties = new Properties();
+			if (featurePropertiesEntry != null) {
+				try {
+					featureProperties.load(featureJar
+							.getInputStream(featurePropertiesEntry));
+					String localeString = null;
+					if (propertyFileName.endsWith("feature.properties")) { //$NON-NLS-1$
+						localeString = ""; //$NON-NLS-1$
+					} else {
+						localeString = propertyFileName.substring(8,
+								propertyFileName.indexOf('.'));
+					}
+					result.put(localeString, featureProperties);
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return result;
+	}
+
+	private void openInputStremas(Map availableLocales) throws IOException {
+		Iterator locales = availableLocales.values().iterator();
+		while (locales.hasNext()) {
+			AvailableLocale availableLocale = (AvailableLocale) locales.next();
+			availableLocale.openLocalizedOutputStream();
+		}
+	}
+
+	private Map getAvailableLocales(List featureList, Map perFeatureLocales) {
+		Iterator features = featureList.iterator();
+		Map locales = new HashMap();
+		while (features.hasNext()) {
+			String feature = (String) features.next();
+			try {
+				System.out.println("Extracting locales from " + feature); //$NON-NLS-1$
+				processLocalesInJar(locales, feature, perFeatureLocales, false);
+			} catch (IOException e) {
+				System.out.println("Error while extracting locales from " //$NON-NLS-1$
+						+ feature);
+				e.printStackTrace();
+				return null;
+			}
+		}
+		return locales;
+	}
+
+	private void processLocalesInJar(Map locales, String feature,
+			Map perFeatureLocales, boolean ignoreNewLocales) throws IOException {
+
+		JarFile jar = new JarFile(feature);
+		// System.out.println(feature);
+		Enumeration files = jar.entries();
+
+		List localesTemp = new ArrayList();
+		perFeatureLocales.put(feature, localesTemp);
+
+		while (files.hasMoreElements()) {
+			ZipEntry file = (ZipEntry) files.nextElement();
+			String localeString = null;
+			String name = file.getName();
+			// System.out.println("processLocalesInJar:"+name);
+			if (name.startsWith("feature") && name.endsWith(".properties")) { //$NON-NLS-1$ //$NON-NLS-2$
+				// System.out.println(name);
+				localesTemp.add(name);
+				// System.out.println(name);
+				if (name.endsWith("feature.properties")) { //$NON-NLS-1$
+					localeString = ""; //$NON-NLS-1$
+				} else {
+					localeString = name.substring(8, name.indexOf('.'));
+				}
+				// System.out.println(name +"::::\"" + localeString + "\"");
+				if ( !ignoreNewLocales && !locales.containsKey(localeString)) {
+					locales.put(localeString, new AvailableLocale(localeString));
+				}
+				if (locales.containsKey(localeString)) {
+					AvailableLocale currentLocale = (AvailableLocale) locales.get(localeString);
+					currentLocale.addFeatures(feature);
+				}
+			}
+		}
+
+	}
+
+	private List getFeatureList(Map params) {
+		if (params.containsKey(SITE_XML)
+				&& (fileExists((String) params.get(SITE_XML)))) {
+			return getFeatureListFromSiteXML((String) params.get(SITE_XML));
+		} else if (params.containsKey(INPUT)
+				&& isDirectory((String) params
+						.get(SiteOptimizerApplication.INPUT))) {
+			return getFeatureListFromDirectory((String) params.get(INPUT));
+		}
+		return null;
+	}
+
+	private boolean fileExists(String fileName) {
+		// System.out.println("fileExists:"+fileName);
+		File file = new File(fileName);
+		if ((file != null) && file.exists())
+			return true;
+		return false;
+	}
+
+	private List getFeatureListFromDirectory(String directoryName) {
+		List featuresURLs = new ArrayList();
+		File directory = new File(directoryName);
+		String[] featureJarFileNames = directory.list();
+		for (int i = 0; i < featureJarFileNames.length; i++) {
+			featuresURLs.add(directoryName + File.separator
+					+ featureJarFileNames[i]);
+		}
+		return featuresURLs;
+	}
+
+	private boolean isDirectory(String fileName) {
+
+		File directory = new File(fileName);
+		if ((directory != null) && directory.exists()
+				&& directory.isDirectory())
+			return true;
+		return false;
+	}
+
+	private List getFeatureListFromSiteXML(String siteXML) {
+
+		List featuresURLs = new ArrayList();
+		String directoryName = (new File(siteXML)).getParent();
+		if (!directoryName.endsWith(File.separator)) {
+			directoryName = directoryName + File.separator;
+		}
+
+		DefaultSiteParser siteParser = new DefaultSiteParser();
+		siteParser.init(new ExtendedSiteURLFactory());
+
+		try {
+			SiteModel site = siteParser.parse(new FileInputStream(siteXML));
+			if(site.getFeatureReferenceModels().length > 0) {
+				site.getFeatureReferenceModels()[0].getURLString();
+				FeatureReferenceModel[] featureReferenceModel = site
+				.getFeatureReferenceModels();
+				for (int i = 0; i < featureReferenceModel.length; i++) {
+					featuresURLs.add(directoryName
+							+ featureReferenceModel[i].getURLString());
+				}
+			}
+			return featuresURLs;
+		} catch (FileNotFoundException e) {
+			System.out.println("File not found: " + e.getMessage()); //$NON-NLS-1$
+			e.printStackTrace();
+		} catch (SAXException e) {
+			System.out.println("Parsing problem: " + e.getMessage()); //$NON-NLS-1$
+			e.printStackTrace();
+		} catch (IOException e) {
+			System.out.println("Problem while parsing: " + e.getMessage()); //$NON-NLS-1$
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.IPlatformRunnable#run(java.lang.Object)
+	 */
+	public Object run(Object args) throws Exception {
+		Platform.endSplash();
+		if (args == null)
+			return EXIT_ERROR;
+		if (args instanceof String[]) {
+			Map params = parseCmdLine((String[]) args);
+			if (params.containsKey(JAR_PROCESSOR)) {
+				if (!runJarProcessor(params))
+					return EXIT_ERROR;
+			}
+
+			if (params.containsKey(DIGEST_BUILDER)) {
+				if (!runDigestBuilder(params))
+					return EXIT_ERROR;
+			}
+		}
+		return IPlatformRunnable.EXIT_OK;
+	}
+
+	private class AvailableLocale {
+
+		private String PREFIX = "temp"; //$NON-NLS-1$
+
+		private String locale;
+
+		private Map /* VersionedIdentifier */features = new HashMap();
+
+		private PrintWriter localizedPrintWriter;
+
+		private File tempDigestDirectory;
+
+		public void finishDigest(String outputDirectory) throws IOException {
+			localizedPrintWriter.println("</digest>"); //$NON-NLS-1$
+			if (localizedPrintWriter != null) {
+				localizedPrintWriter.close();
+			}
+
+			File digest = new File(outputDirectory + File.separator + "digest" //$NON-NLS-1$
+					+ (locale == null || locale.equals("") ? "" : "_"+locale) + ".zip"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+			System.out.println(digest.getAbsolutePath());
+			System.out.println(digest.getName());
+			if (digest.exists()) {
+				digest.delete();
+			}
+			digest.createNewFile();
+			OutputStream os = new FileOutputStream(digest);
+			JarOutputStream jos = new JarOutputStream(os);
+			jos.putNextEntry(new ZipEntry("digest.xml")); //$NON-NLS-1$
+			InputStream is = new FileInputStream(tempDigestDirectory);
+			byte[] b = new byte[4096];
+			int bytesRead = 0;
+			do {
+				bytesRead = is.read(b);
+				if (bytesRead > 0) {
+					jos.write(b, 0, bytesRead);
+				}
+			} while (bytesRead > 0);
+
+			jos.closeEntry();
+			jos.close();
+			os.close();
+			is.close();
+			tempDigestDirectory.delete();
+
+		}
+
+		public AvailableLocale(String locale) {
+			this.locale = locale;
+		}
+
+		public void addFeatures(String feature) {
+			features.put(feature, feature);
+		}
+
+		public void openLocalizedOutputStream() throws IOException {
+			tempDigestDirectory = File.createTempFile(PREFIX, null);
+			FileOutputStream fstream = new FileOutputStream(tempDigestDirectory);
+			localizedPrintWriter = new PrintWriter(new OutputStreamWriter(fstream, "UTF-8")); //$NON-NLS-1$
+			localizedPrintWriter
+			.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <digest>"); //$NON-NLS-1$
+			tempDigestDirectory.deleteOnExit();
+		}
+
+		public int hashCode() {
+			return locale.hashCode();
+		}
+
+		public boolean equals(Object obj) {
+
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			final AvailableLocale other = (AvailableLocale) obj;
+			if (locale == null) {
+				if (other.locale != null)
+					return false;
+			} else if (!locale.equals(other.locale))
+				return false;
+			return true;
+		}
+
+		public void writeFeatureDigests(FeatureModel featureModel,
+				Map featureProperties) {
+
+			if (this.locale.equals("")) { //$NON-NLS-1$
+				writeFeatureDigest(localizedPrintWriter, featureModel,
+						(Properties) featureProperties.get("")); //$NON-NLS-1$
+				return;
+			}
+			Properties temp = new Properties();
+			if (locale.indexOf("_") < 0) { //$NON-NLS-1$
+				temp = combineProperties(
+						(Properties) featureProperties.get(""), //$NON-NLS-1$
+						(Properties) featureProperties.get(locale), null);
+				writeFeatureDigest(localizedPrintWriter, featureModel, temp);
+			} else {
+				temp = combineProperties(
+						(Properties) featureProperties.get(""), //$NON-NLS-1$
+						(Properties) featureProperties.get(locale.substring(0, locale.indexOf("_"))), //$NON-NLS-1$
+						(Properties) featureProperties.get(locale) );
+				writeFeatureDigest(localizedPrintWriter, featureModel, temp);
+			}
+
+		}
+		
+		/**
+		 * @param defaults	Should be lang_country
+		 * @param secondary	Should be lang
+		 * @param preferred	Should be default
+		 * @return
+		 */
+
+		private Properties combineProperties(Properties defaults,
+				Properties secondary, Properties preferred) {
+			return new CombinedProperties(preferred, secondary, defaults);
+
+		}
+
+	}
+
+	public static void writeFeatureDigest(PrintWriter digest,
+			FeatureModel featureModel, Properties featureProperties) {
+
+		String label = null;
+		String provider = null;
+		String description = null;
+		String license = null;
+		String copyright = null;
+
+		if ((featureProperties != null)
+				&& featureModel.getLabel().startsWith("%")) { //$NON-NLS-1$
+			label = featureProperties.getProperty(featureModel.getLabel()
+					.substring(1));
+		} else {
+			label = featureModel.getLabel();
+		}
+		if ((featureProperties != null)
+				&& (featureModel.getDescriptionModel() != null)
+				&& (featureModel.getDescriptionModel().getAnnotation() != null)
+				&& featureModel.getDescriptionModel().getAnnotation()
+				.startsWith("%")) { //$NON-NLS-1$
+			// System.out.println(featureProperties.getProperty(featureModel.getDescriptionModel().getAnnotation().substring(1)));
+			description = featureProperties.getProperty(featureModel
+					.getDescriptionModel().getAnnotation().substring(1));
+		} else {
+			URLEntryModel descriptionModel = featureModel.getDescriptionModel();
+			if( descriptionModel == null )
+				description = "";
+			else
+				description = descriptionModel.getAnnotation();
+		}
+		String pvalue = featureModel.getProvider();
+		if ((featureProperties != null)
+				&& pvalue!=null && pvalue.startsWith("%")) { //$NON-NLS-1$
+			provider = featureProperties.getProperty(featureModel.getProvider()
+					.substring(1));
+		} else {
+			provider = pvalue;
+		}
+		if (provider==null) provider = "";
+
+		if (((featureProperties != null) && featureModel.getCopyrightModel() != null)
+				&& featureModel.getCopyrightModel().getAnnotation().startsWith(
+				"%")) { //$NON-NLS-1$
+			copyright = featureProperties.getProperty(featureModel
+					.getCopyrightModel().getAnnotation().substring(1));
+		} else {
+			if (featureModel.getCopyrightModel() != null) {
+				copyright = featureModel.getCopyrightModel().getAnnotation();
+			} else {
+				copyright = null;
+			}
+		}
+
+		if ((featureProperties != null)
+				&& (featureModel.getLicenseModel() != null)
+				&& featureModel.getLicenseModel().getAnnotation().startsWith(
+				"%")) { //$NON-NLS-1$
+			license = featureProperties.getProperty(featureModel
+					.getLicenseModel().getAnnotation().substring(1));
+		} else {
+			license = featureModel.getLicenseModel().getAnnotation();
+		}
+
+		digest.print("<feature "); //$NON-NLS-1$
+		digest.print("label=\"" + getUTF8String(label) + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+		digest.print("provider-name=\"" + getUTF8String(provider) + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
+		digest.print("id=\"" + featureModel.getFeatureIdentifier() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+		digest.print("version=\"" + featureModel.getFeatureVersion() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
+		if (featureModel.getOS() != null)
+			digest.print("os=\"" + featureModel.getOS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+		if (featureModel.getNL() != null)
+			digest.print("nl=\"" + featureModel.getNL() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+		if (featureModel.getWS() != null)
+			digest.print("ws=\"" + featureModel.getWS() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
+		if (featureModel.getOSArch() != null)
+			digest.print("arch=\"" + featureModel.getOSArch() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+		if (featureModel.isExclusive())
+			digest.print("exclusive=\"" + featureModel.isExclusive() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+
+		if (((featureModel.getImportModels() == null) || (featureModel
+				.getImportModels().length == 0))
+				&& ((featureModel.getDescriptionModel() == null)
+						|| (featureModel.getDescriptionModel().getAnnotation() == null) || (featureModel
+								.getDescriptionModel().getAnnotation().trim().length() == 0))
+								&& ((featureModel.getCopyrightModel() == null)
+										|| (featureModel.getCopyrightModel().getAnnotation() == null) || (featureModel
+												.getCopyrightModel().getAnnotation().trim().length() == 0))
+												&& ((featureModel.getLicenseModel() == null)
+														|| (featureModel.getLicenseModel().getAnnotation() == null) || (featureModel
+																.getLicenseModel().getAnnotation().trim().length() == 0)) 
+																&& ((featureModel.getFeatureIncluded() == null) || (featureModel
+																		.getFeatureIncluded().length == 0))){
+			digest.println("/> "); //$NON-NLS-1$
+		} else {
+			digest.println("> "); //$NON-NLS-1$
+			if (featureModel.getImportModels().length > 0) {
+
+				digest.println("\t<requires> "); //$NON-NLS-1$
+				ImportModel[] imports = featureModel.getImportModels();
+				for (int j = 0; j < imports.length; j++) {
+					digest.print("\t\t<import "); //$NON-NLS-1$
+					if (imports[j].isFeatureImport()) {
+						digest.print("feature=\""); //$NON-NLS-1$
+					} else {
+						digest.print("plugin=\""); //$NON-NLS-1$
+					}
+					digest.print(imports[j].getIdentifier() + "\" "); //$NON-NLS-1$
+					digest.print("version=\""); //$NON-NLS-1$
+					digest.print(imports[j].getVersion() + "\" "); //$NON-NLS-1$
+					digest.print("match=\""); //$NON-NLS-1$
+					digest.print(imports[j].getMatchingRuleName() + "\" "); //$NON-NLS-1$
+					if (imports[j].isPatch()) {
+						digest.print("patch=\"true\" "); //$NON-NLS-1$
+					}
+					digest.println(" />"); //$NON-NLS-1$
+				}
+
+				digest.println("\t</requires>"); //$NON-NLS-1$
+
+			}
+
+			if ((featureModel.getDescriptionModel() != null)
+					&& (featureModel.getDescriptionModel().getAnnotation() != null)
+					&& (featureModel.getDescriptionModel().getAnnotation()
+							.trim().length() != 0)) {
+				digest.println("\t<description>"); //$NON-NLS-1$
+				digest.println("\t\t" + UpdateManagerUtils.getWritableXMLString(description)); //$NON-NLS-1$
+				digest.println("\t</description>"); //$NON-NLS-1$
+			}
+
+			if (featureModel.getCopyrightModel() != null) {
+				if (featureModel.getCopyrightModel().getAnnotation() != null) {
+					// if
+					// (featureModel.getDescriptionModel().getAnnotation().length()
+					// != 0) {
+					digest.println("\t<copyright>"); //$NON-NLS-1$
+					digest.println("\t\t" + UpdateManagerUtils.getWritableXMLString(copyright)); //$NON-NLS-1$
+					digest.println("\t</copyright>"); //$NON-NLS-1$
+					// }
+				}
+			}
+
+			if ((featureModel.getLicenseModel() != null)
+					&& (featureModel.getLicenseModel().getAnnotation() != null)
+					&& (featureModel.getLicenseModel().getAnnotation()
+							.trim().length() != 0)) {
+				digest.println("\t<license>"); //$NON-NLS-1$
+				digest.println("\t\t" + UpdateManagerUtils.getWritableXMLString(license)); //$NON-NLS-1$
+				digest.println("\t</license>"); //$NON-NLS-1$
+			}
+
+			PluginEntryModel[] plugins = featureModel.getPluginEntryModels();
+			if ((plugins != null) && (plugins.length != 0)) {
+				for (int i = 0; i < plugins.length; i++) {
+					digest.print("\t<plugin "); //$NON-NLS-1$
+					digest.print("id=\"" + plugins[i].getPluginIdentifier() //$NON-NLS-1$
+							+ "\" "); //$NON-NLS-1$
+					digest.print("version=\"" + plugins[i].getPluginVersion() //$NON-NLS-1$
+							+ "\" "); //$NON-NLS-1$
+					if (plugins[i].getOS() != null)
+						digest.print("os=\"" + plugins[i].getOS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+					if (plugins[i].getNL() != null)
+						digest.print("nl=\"" + plugins[i].getNL() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
+					if (plugins[i].getWS() != null)
+						digest.print("ws=\"" + plugins[i].getWS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+					if (plugins[i].getOSArch() != null)
+						digest
+						.print("arch=\"" + plugins[i].getOSArch() //$NON-NLS-1$
+								+ "\" "); //$NON-NLS-1$
+					if (plugins[i].getDownloadSize() > 0)
+						digest.print("download-size=\"" //$NON-NLS-1$
+								+ plugins[i].getDownloadSize() + "\" "); //$NON-NLS-1$
+					if (plugins[i].getInstallSize() > 0)
+						digest.print("install-size=\"" //$NON-NLS-1$
+								+ plugins[i].getInstallSize() + "\" "); //$NON-NLS-1$
+					if (!plugins[i].isUnpack())
+						digest.print("unpack=\"" + plugins[i].isUnpack() //$NON-NLS-1$
+								+ "\" "); //$NON-NLS-1$
+
+					digest.println("/> "); //$NON-NLS-1$
+				}
+			}	
+
+			IIncludedFeatureReference[] includedFeatures = featureModel.getFeatureIncluded();
+
+			if ((includedFeatures != null) && (includedFeatures.length != 0)) {
+				for (int i = 0; i < includedFeatures.length; i++) {
+					try {
+						digest.print("\t<includes "); //$NON-NLS-1$
+
+						digest.print("id=\"" + includedFeatures[i].getVersionedIdentifier().getIdentifier() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
+						digest.print("version=\"" + includedFeatures[i].getVersionedIdentifier().getVersion() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
+						if (includedFeatures[i].getOS() != null)
+							digest.print("os=\"" + includedFeatures[i].getOS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+						if (includedFeatures[i].getNL() != null)
+							digest.print("nl=\"" + includedFeatures[i].getNL() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
+						if (includedFeatures[i].getWS() != null)
+							digest.print("ws=\"" + includedFeatures[i].getWS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
+						if (includedFeatures[i].getOSArch() != null)
+							digest.print("arch=\"" + includedFeatures[i].getOSArch() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$											
+						if ( (includedFeatures[i] instanceof IncludedFeatureReference) && (((IncludedFeatureReference)includedFeatures[i]).getLabel() != null))
+							digest.print("name=\"" + includedFeatures[i].getName() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$									
+						if (includedFeatures[i].isOptional())
+							digest.print("optional=\"true\" "); //$NON-NLS-1$
+						digest.print("search-location=\"" + includedFeatures[i].getSearchLocation() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
+
+						digest.println("/> "); //$NON-NLS-1$
+					} catch (CoreException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				}
+			}
+			digest.println("</feature>"); //$NON-NLS-1$
+		}
+	}
+
+	private class CombinedProperties extends Properties {
+
+		private Properties properties1;
+
+		private Properties properties2;
+
+		private Properties properties3;
+
+		/**
+		 * @param preferred preferred, such as lang_country
+		 * @param secondary secondary, such as lang
+		 * @param defaults default,
+		 */
+		public CombinedProperties(Properties preferred,
+				Properties secondary, Properties defaults) {
+			this.properties1 = preferred;
+			this.properties2 = secondary;
+			this.properties3 = defaults;
+		}
+
+		/**
+		 * 
+		 */
+		private static final long serialVersionUID = 1L;
+
+		public String getProperty(String key) {
+			String result = null;
+			if (properties3 != null && properties3.containsKey(key))
+				result = properties3.getProperty(key);
+			if (properties2 != null && properties2.containsKey(key))
+				result = properties2.getProperty(key);
+			if (properties1 != null && properties1.containsKey(key))
+				result = properties1.getProperty(key);
+			return result;
+		}
+
+	}
+	
+	public static final String getUTF8String(String s) {
+		if(s == null)
+			return "";
+		return UpdateManagerUtils.getWritableXMLString(s);
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/BaseSearchCategory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/BaseSearchCategory.java
new file mode 100644
index 0000000..0ee1501
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/BaseSearchCategory.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.search;
+
+import org.eclipse.update.search.*;
+
+public abstract class BaseSearchCategory implements IUpdateSearchCategory {
+	private String id;
+	
+	protected BaseSearchCategory(String id) {
+		setId(id);
+	}
+	
+	public String getId() {
+		return id;
+	}
+	
+	public void setId(String id) {
+		if (this.id==null)
+			this.id = id;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/OptionalFeatureSearchCategory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/OptionalFeatureSearchCategory.java
new file mode 100644
index 0000000..fa463d0
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/OptionalFeatureSearchCategory.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.search;
+
+import java.net.*;
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.search.*;
+
+/**
+ * Searches for optional features
+ */
+public class OptionalFeatureSearchCategory extends BaseSearchCategory {
+	private IUpdateSearchQuery[] queries;
+	private ArrayList vids;
+	private static final String CATEGORY_ID =
+		"org.eclipse.update.core.unified-search"; //$NON-NLS-1$
+
+	private class OptionalQuery implements IUpdateSearchQuery {
+		public void run(
+			ISite site,
+			String[] categoriesToSkip,
+			IUpdateSearchFilter filter,
+			IUpdateSearchResultCollector collector,
+			IProgressMonitor monitor) {
+
+			monitor.beginTask("", vids.size()); //$NON-NLS-1$
+			for (int i = 0; i < vids.size(); i++) {
+				VersionedIdentifier vid = (VersionedIdentifier) vids.get(i);
+				monitor.subTask(vid.toString());
+				IFeature feature =
+					createFeature(
+						site,
+						vid,
+						new SubProgressMonitor(monitor, 1));
+				if (feature!=null && filter.accept(feature))
+					collector.accept(feature);
+			}
+		}
+
+		private IFeature createFeature(
+			ISite site,
+			VersionedIdentifier vid,
+			IProgressMonitor monitor) {
+			try {
+				URL siteURL = site.getURL();
+				//TODO This assumption stands only in the default case
+				// In general, feature archive URL may be mapped on site.
+				// Also, feature type may be something else (not packaged).
+				// We may need additional information (not only id and version)
+				// in order to create a feature on a site.
+				String relative = vid.toString();
+				URL featureURL = new URL(siteURL, "features/" + relative+".jar"); //$NON-NLS-1$ //$NON-NLS-2$
+				return site.createFeature(
+					"org.eclipse.update.core.packaged", //$NON-NLS-1$
+					featureURL,
+					monitor);
+			} catch (Exception e) {
+				return null;
+			}
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.update.internal.ui.search.ISearchQuery#getSearchSite()
+		 */
+		public IQueryUpdateSiteAdapter getQuerySearchSite() {
+			return null;
+		}
+	}
+
+	public void addVersionedIdentifier(VersionedIdentifier vid) {
+		vids.add(vid);
+	}
+
+	public void clear() {
+		vids.clear();
+	}
+
+	public OptionalFeatureSearchCategory() {
+		super(CATEGORY_ID);
+		vids = new ArrayList();
+		queries = new IUpdateSearchQuery[] { new OptionalQuery()};
+	}
+
+	public IUpdateSearchQuery[] getQueries() {
+		return queries;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/QueryUpdateSiteAdapter.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/QueryUpdateSiteAdapter.java
new file mode 100644
index 0000000..e30d391
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/QueryUpdateSiteAdapter.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.search;
+
+import java.net.*;
+
+import org.eclipse.update.search.*;
+
+public class QueryUpdateSiteAdapter extends UpdateSiteAdapter implements IQueryUpdateSiteAdapter {
+	private String mappingId;
+
+	public QueryUpdateSiteAdapter(String label, URL url, String mappingId) {
+		super(label, url);
+		this.mappingId = mappingId;
+	}
+	
+	public String getMappingId() {
+		return mappingId;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/SiteSearchCategory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/SiteSearchCategory.java
new file mode 100644
index 0000000..78bd7af
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/SiteSearchCategory.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2009 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
+ *     James D Miles (IBM Corp.) - bug 181375, ArrayIndexOutOfBoundsException in SiteSearchCategory$Query
+ *     James D Miles (IBM Corp.) - bug 191783, NullPointerException in FeatureDownloader
+ *******************************************************************************/
+package org.eclipse.update.internal.search;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.update.core.ICategory;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.internal.core.ExtendedSite;
+import org.eclipse.update.internal.core.LiteFeature;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.search.IQueryUpdateSiteAdapter;
+import org.eclipse.update.search.IUpdateSearchFilter;
+import org.eclipse.update.search.IUpdateSearchQuery;
+import org.eclipse.update.search.IUpdateSearchResultCollector;
+
+/**
+ * Searches an update site
+ */
+public class SiteSearchCategory extends BaseSearchCategory {
+	private IUpdateSearchQuery[] queries;
+	private boolean liteFeaturesAreOK;
+	private static final String CATEGORY_ID =
+		"org.eclipse.update.core.unified-search"; //$NON-NLS-1$
+
+	private static class Query implements IUpdateSearchQuery {
+		
+		private boolean liteFeaturesAreOK;
+		
+		
+		public Query() {
+			liteFeaturesAreOK = false;
+		}
+		
+		public Query(boolean liteFeaturesAreOK) {
+			this.liteFeaturesAreOK = liteFeaturesAreOK;
+		}
+		
+		public void setLiteFeaturesAreOK(boolean liteFeaturesAreOK) {
+			this.liteFeaturesAreOK = liteFeaturesAreOK;
+		}
+		
+		public void run(
+			ISite site,
+			String[] categoriesToSkip,
+			IUpdateSearchFilter filter,
+			IUpdateSearchResultCollector collector,
+			IProgressMonitor monitor) {
+			
+			ISiteFeatureReference[] refs = site.getFeatureReferences();
+			HashSet ignores = new HashSet();			
+			Map liteFeatures = new HashMap();
+			
+			if (categoriesToSkip != null) {
+				for (int i = 0; i < categoriesToSkip.length; i++) {
+					ignores.add(categoriesToSkip[i]);
+				}
+			}
+			List siteFeatureReferences = new ArrayList(Arrays.asList(refs));
+			
+			if (liteFeaturesAreOK && (site instanceof ExtendedSite) ) {
+				
+				ExtendedSite extendedSite = (ExtendedSite)site;
+				LiteFeature[] liteFeaturesArray =  extendedSite.getLiteFeatures();
+				if ( (liteFeaturesArray != null) && ( liteFeaturesArray.length != 0)) {
+					for(int i = 0; i < liteFeaturesArray.length; i++) {
+						liteFeatures.put(liteFeaturesArray[i].getVersionedIdentifier(), liteFeaturesArray[i]);					
+					}
+					(new FeatureDownloader(siteFeatureReferences, collector, filter, ignores, monitor, true, liteFeatures)).run();
+					return;
+				} else {
+					liteFeaturesAreOK = false;
+				}
+			}
+			
+
+			
+			monitor.beginTask("", refs.length); //$NON-NLS-1$
+			ThreadGroup featureDownloaders = new ThreadGroup("FeatureDownloader"); //$NON-NLS-1$
+			int numberOfThreads = (refs.length > 5)? 5: refs.length;
+
+			Thread[] featureDownloader = new Thread[numberOfThreads];
+			for( int i = 0; i < numberOfThreads; i++) {
+				featureDownloader[i] = new Thread(featureDownloaders, new FeatureDownloader(siteFeatureReferences, collector, filter, ignores, monitor));
+				featureDownloader[i].start();
+			}
+			
+			int i =0;
+			while(i < numberOfThreads){
+				if (monitor.isCanceled()) {
+					synchronized(siteFeatureReferences) { 
+						siteFeatureReferences.clear();
+					}
+				}
+				try	{
+					featureDownloader[i].join(250);
+					if(!featureDownloader[i].isAlive()){
+						i++;
+					}
+				} catch (InterruptedException ie) {
+				}
+			}
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.update.internal.ui.search.ISearchQuery#getSearchSite()
+		 */
+		public IQueryUpdateSiteAdapter getQuerySearchSite() {
+			return null;
+		}
+	}
+
+	public SiteSearchCategory() {
+		super(CATEGORY_ID);
+		queries = new IUpdateSearchQuery[] { new Query()};
+	}
+
+	public SiteSearchCategory(boolean liteFeaturesAreOK) {
+		this();
+		this.liteFeaturesAreOK = liteFeaturesAreOK;
+		queries = new IUpdateSearchQuery[] { new Query(liteFeaturesAreOK)};
+	}
+
+	public IUpdateSearchQuery[] getQueries() {
+		return queries;
+	}
+	
+	
+	private static class FeatureDownloader implements Runnable {
+		
+		private List siteFeatureReferences;
+		
+		private IProgressMonitor monitor;
+		
+		private IUpdateSearchFilter filter;
+		
+		private IUpdateSearchResultCollector collector;
+		
+		private HashSet ignores;
+
+		private boolean liteFeaturesAreOK;
+
+		private Map liteFeatures;
+
+		public FeatureDownloader(List siteFeatureReferences, IUpdateSearchResultCollector collector, IUpdateSearchFilter filter, HashSet ignores, IProgressMonitor monitor) {
+			super();
+
+			this.collector = collector;
+			this.filter = filter;
+			this.ignores = ignores;
+			this.monitor = monitor;
+			this.siteFeatureReferences = siteFeatureReferences;
+		}
+		
+		public FeatureDownloader(List siteFeatureReferences, IUpdateSearchResultCollector collector, IUpdateSearchFilter filter, HashSet ignores, IProgressMonitor monitor, boolean liteFeaturesAreOK, Map liteFeatures) {
+			this(siteFeatureReferences, collector, filter, ignores, monitor);
+			this.liteFeaturesAreOK = liteFeaturesAreOK && (liteFeatures != null);
+			this.liteFeatures = liteFeatures;
+		}
+
+		public void run() {
+			
+			ISiteFeatureReference siteFeatureReference = null;
+			
+			while (siteFeatureReferences.size() != 0) {
+				
+				synchronized(siteFeatureReferences) { 
+					try{
+						siteFeatureReference = (ISiteFeatureReference)siteFeatureReferences.remove(0);
+					}catch(IndexOutOfBoundsException e){
+						siteFeatureReference = null;
+						break;
+					}
+				}
+				if (siteFeatureReference != null) {
+					boolean skipFeature = false;
+					if (monitor.isCanceled())
+						break;
+					if (ignores.size() > 0) {
+						ICategory[] categories = siteFeatureReference.getCategories();
+						
+						for (int j = 0; j < categories.length; j++) {
+							ICategory category = categories[j];
+							if (ignores.contains(category.getName())) {
+								skipFeature = true;
+								break;
+							}
+						}
+					}
+					try {
+						if (!skipFeature) {
+							if (filter.accept(siteFeatureReference)) {
+								IFeature feature = null;
+								if(liteFeaturesAreOK) {
+									feature = (IFeature)liteFeatures.get(siteFeatureReference.getVersionedIdentifier());
+								}
+								if (feature == null){
+									feature = siteFeatureReference.getFeature(null);
+								}
+								synchronized(siteFeatureReferences) {
+									if ( (feature != null) && (filter.accept(siteFeatureReference)) ) {								
+										collector.accept(feature);							    
+										monitor.subTask(feature.getLabel());
+									}
+								}
+							}
+						}
+					} catch (CoreException e) {
+						UpdateCore.log(e);
+					} finally {
+						monitor.worked(1);
+					}
+				}
+			}
+			
+		}
+	}
+
+	public boolean isLiteFeaturesAreOK() {
+		return liteFeaturesAreOK;
+	}
+
+	public void setLiteFeaturesAreOK(boolean liteFeaturesAreOK) {
+		this.liteFeaturesAreOK = liteFeaturesAreOK;
+		for( int i = 0; i < queries.length; i++) {
+			((Query)queries[i]).setLiteFeaturesAreOK(liteFeaturesAreOK);
+		}
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatePolicy.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatePolicy.java
new file mode 100644
index 0000000..6e62a86
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatePolicy.java
@@ -0,0 +1,316 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *     James D Miles (IBM Corp.) - bug 191368, Policy URL doesn't support UTF-8 characters
+ *******************************************************************************/
+package org.eclipse.update.internal.search;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.core.URLEncoder;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.internal.core.connection.ConnectionFactory;
+import org.eclipse.update.internal.core.connection.IResponse;
+import org.eclipse.update.search.IUpdateSiteAdapter;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * 
+ * This class opens connection to the update map resource
+ * and parses the file to load update URL mappings.
+ * These mappings are used to redirect new updates search
+ * when the redirection pattern matches.
+ */
+
+public class UpdatePolicy {
+	private static final String TAG_POLICY = "update-policy"; //$NON-NLS-1$
+	private static final String TAG_URL_MAP = "url-map"; //$NON-NLS-1$
+	private static final String ATT_URL = "url"; //$NON-NLS-1$
+	private static final String ATT_PATTERN = "pattern"; //$NON-NLS-1$
+	private static final String ATT_TYPE = "url-type"; //$NON-NLS-1$
+	private static final String ATT_TYPE_VALUE_UPDATE = "update"; //$NON-NLS-1$
+	//private static final String ATT_TYPE_VALUE_BOTH = "both"; //$NON-NLS-1$
+	private static final String ATT_TYPE_VALUE_DISCOVERY = "discovery"; //$NON-NLS-1$
+
+	private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+
+	private static class MapSite implements IUpdateSiteAdapter {
+		private URL url;
+		public MapSite(URL url) {
+			this.url = url;
+		}
+		public String getLabel() {
+			if (url == null) {
+				return ""; //$NON-NLS-1$
+			}
+			return url.toString();
+		}
+		public URL getURL() {
+			return url;
+		}
+	}
+
+	private static class UpdateMapEntry {
+		private IUpdateSiteAdapter site;
+		private String pattern;
+
+		public UpdateMapEntry(String pattern, URL url) {
+			this.pattern = pattern;
+			this.site = new MapSite(url);
+		}
+		public IUpdateSiteAdapter getSite() {
+			return site;
+		}
+		public boolean matches(String id) {
+			return id.startsWith(pattern);
+		}
+		public String getPattern() {
+			return pattern;
+		}
+	}
+
+	private ArrayList entries;
+	private ArrayList discoveryEntries;
+	private IUpdateSiteAdapter defaultSite;
+	private IUpdateSiteAdapter defaultDiscoverySite;
+	private boolean loaded = false;
+	private boolean fallbackAllowed = true;
+
+	public UpdatePolicy() {
+		entries = new ArrayList();
+		discoveryEntries = new ArrayList();
+	}
+
+	public void load(URL mapFile, IProgressMonitor monitor)
+		throws CoreException {
+		InputStream policyStream = null;
+		try {
+			IResponse response = ConnectionFactory.get(mapFile);
+			UpdateManagerUtils.checkConnectionResult(response, mapFile);
+			policyStream = response.getInputStream(monitor);
+			// the stream can be null if the user cancels the connection
+			if (policyStream == null)
+				return;
+			
+			documentBuilderFactory.setNamespaceAware(true);
+			DocumentBuilder parser = documentBuilderFactory.newDocumentBuilder();
+			Document doc = parser.parse(new InputSource(policyStream));
+
+			processUpdatePolicy(doc);
+			loaded = true;
+		} catch (IOException e) {
+			throw Utilities.newCoreException(
+				NLS.bind(Messages.SiteURLFactory_UnableToAccessSiteStream, (new String[] { mapFile == null ? "" : mapFile.toExternalForm() })), //$NON-NLS-1$
+				ISite.SITE_ACCESS_EXCEPTION,
+				e);
+		} catch (SAXException e) {
+			throw Utilities.newCoreException(
+				Messages.UpdatePolicy_parsePolicy, 
+				0,
+				e);
+
+		} catch(ParserConfigurationException e) {
+			throw Utilities.newCoreException(
+				Messages.UpdatePolicy_parsePolicy, 
+				0,
+				e);
+		} finally {
+			if (policyStream != null) {
+				try {
+					policyStream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+	}
+
+	public boolean isLoaded() {
+		return loaded;
+	}
+	
+	/*
+	 * Given the feature ID, returns the mapped update URL if
+	 * found in the mappings. This URL will be used INSTEAD of
+	 * the update URL encoded in the feature itself during the
+	 * new update search.
+	 * <p>In case of multiple matches (e.g. org.eclipse and org.eclipse.platform)
+	 * the URL for the longer pattern will be picked (i.e. org.eclipse.platform).
+	 */
+	public IUpdateSiteAdapter getMappedSite(String id) {
+		UpdateMapEntry lastEntry = null;
+		for (int i = 0; i < entries.size(); i++) {
+			UpdateMapEntry entry = (UpdateMapEntry) entries.get(i);
+			if (entry.matches(id)) {
+				if (lastEntry == null)
+					lastEntry = entry;
+				else {
+					// Choose the match with longer pattern.
+					// For example, if two matches are found:
+					// 'org.eclipse' and 'org.eclipse.platform',
+					// pick 'org.eclipse.platform'.
+					String pattern = entry.getPattern();
+					String lastPattern = lastEntry.getPattern();
+					if (pattern.length() > lastPattern.length())
+						lastEntry = entry;
+				}
+			}
+		}
+		if (lastEntry != null)
+			return lastEntry.getSite();
+		else
+			return defaultSite;
+	}
+	
+	/*
+	 * Given the feature ID, returns the mapped discovery URL if
+	 * found in the mappings. This URL will be used INSTEAD of
+	 * the discovery URL encoded in the feature itself during the
+	 * new search.
+	 * <p>In case of multiple matches (e.g. org.eclipse and org.eclipse.platform)
+	 * the URL for the longer pattern will be picked (i.e. org.eclipse.platform).
+	 */
+	public IUpdateSiteAdapter getMappedDiscoverySite(String id) {
+		UpdateMapEntry lastEntry = null;
+		for (int i = 0; i < discoveryEntries.size(); i++) {
+			UpdateMapEntry entry = (UpdateMapEntry) discoveryEntries.get(i);
+			if (entry.matches(id)) {
+				if (lastEntry == null)
+					lastEntry = entry;
+				else {
+					// Choose the match with longer pattern.
+					// For example, if two matches are found:
+					// 'org.eclipse' and 'org.eclipse.platform',
+					// pick 'org.eclipse.platform'.
+					String pattern = entry.getPattern();
+					String lastPattern = lastEntry.getPattern();
+					if (pattern.length() > lastPattern.length())
+						lastEntry = entry;
+				}
+			}
+		}
+		if (lastEntry != null)
+			return lastEntry.getSite();
+		else
+			return defaultDiscoverySite;
+	}
+
+	public boolean isFallbackAllowed() {
+		return fallbackAllowed;
+	}
+	
+	private void reset() {
+		if (!entries.isEmpty())
+			entries.clear();
+		if (!discoveryEntries.isEmpty())
+			discoveryEntries.clear();
+	}
+
+	private void processUpdatePolicy(Document document) throws CoreException {
+		Node root = document.getDocumentElement();
+		reset();
+		
+		if (root.getNodeName().equals(TAG_POLICY)==false)
+			throwCoreException("'"+TAG_POLICY+Messages.UpdatePolicy_policyExpected, null);  //$NON-NLS-1$
+				
+		NodeList nodes = root.getChildNodes();
+		
+		for (int i=0; i<nodes.getLength(); i++) {
+			Node child = nodes.item(i);
+			if (child.getNodeType() != Node.ELEMENT_NODE)
+				continue;
+			String tag = child.getNodeName();
+			if (tag.equals(TAG_URL_MAP))
+				processMapNode(child);
+		}
+	}
+	private void processMapNode(Node node) throws CoreException {
+		String pattern = getAttribute(node, ATT_PATTERN);
+		String urlName = getAttribute(node, ATT_URL);
+		String type = getAttribute(node, ATT_TYPE);
+		
+		assertNotNull(ATT_PATTERN, pattern);
+		assertNotNull(ATT_URL, urlName);
+		
+		// empty url means feature is not updateable
+		if (urlName.trim().length() == 0) {
+			addUpdateEntry(pattern, null, type);
+			return;
+		}
+
+		try {
+			URL url = new URL(urlName);
+			URL resolvedURL = URLEncoder.encode(url);
+			addUpdateEntry(pattern, resolvedURL, type);
+		} catch (MalformedURLException e) {
+			throwCoreException(Messages.UpdatePolicy_invalidURL+urlName, null); 
+		} 
+	}
+	
+	private void assertNotNull(String name, String value) throws CoreException {
+		if (value==null)
+			throwCoreException(name+Messages.UpdatePolicy_nameNoNull, null); 
+	}
+	
+	private String getAttribute(Node node, String name) {
+		NamedNodeMap attMap = node.getAttributes();
+		Node att = attMap.getNamedItem(name);
+		if (att==null) return null;
+		return att.getNodeValue();
+	}
+
+	private void addUpdateEntry(String pattern, URL url, String type) {
+		if (pattern.equalsIgnoreCase("*")) {//$NON-NLS-1$
+			if (type == null)
+				defaultSite = new MapSite(url);
+			else if (type.equals(ATT_TYPE_VALUE_UPDATE))
+				defaultSite = new MapSite(url);
+			else if (type.equals(ATT_TYPE_VALUE_DISCOVERY))
+				defaultDiscoverySite = new MapSite(url);
+			else {
+				defaultSite = new MapSite(url);
+				defaultDiscoverySite = new MapSite(url);
+			}
+		} else {
+			if (type == null )
+				entries.add(new UpdateMapEntry(pattern, url));
+			else if (type.equals(ATT_TYPE_VALUE_UPDATE))
+				entries.add(new UpdateMapEntry(pattern, url));
+			else if (type.equals(ATT_TYPE_VALUE_DISCOVERY))
+				discoveryEntries.add(new UpdateMapEntry(pattern, url));
+			else {
+				entries.add(new UpdateMapEntry(pattern, url));
+				discoveryEntries.add(new UpdateMapEntry(pattern, url));
+			}
+		}
+	}
+	
+	private void throwCoreException(String message, Throwable e) throws CoreException {
+		String fullMessage = Messages.UpdatePolicy_UpdatePolicy+message; 
+		throw Utilities.newCoreException(fullMessage, 0, e);
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdateSiteAdapter.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdateSiteAdapter.java
new file mode 100644
index 0000000..85c1e59
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdateSiteAdapter.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.search;
+
+import java.net.*;
+
+import org.eclipse.update.search.*;
+
+/**
+ */
+public class UpdateSiteAdapter implements IUpdateSiteAdapter {
+	private String label;
+	private URL url;
+	
+	public UpdateSiteAdapter(String label, URL url) {
+		this.label = label;
+		this.url = url;
+	}
+	public URL getURL() {
+		return url;
+	}
+	public String getLabel() {
+		return label;
+	}
+/*
+	public ISite getSite(IProgressMonitor monitor) {
+		try {
+			return SiteManager.getSite(getURL(), monitor);
+		} catch (CoreException e) {
+			return null;
+		}
+	}
+*/
+	public String toString(){
+		return "" + getURL(); //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatesSearchCategory.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatesSearchCategory.java
new file mode 100644
index 0000000..c21db09
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/search/UpdatesSearchCategory.java
@@ -0,0 +1,571 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.internal.search;
+
+import java.util.ArrayList;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.PluginVersionIdentifier;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.configuration.ILocalSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IIncludedFeatureReference;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.core.IURLEntry;
+import org.eclipse.update.core.IUpdateConstants;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.operations.FeatureHierarchyElement;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.operations.IInstallFeatureOperation;
+import org.eclipse.update.operations.OperationsManager;
+import org.eclipse.update.search.IQueryUpdateSiteAdapter;
+import org.eclipse.update.search.IUpdateSearchFilter;
+import org.eclipse.update.search.IUpdateSearchQuery;
+import org.eclipse.update.search.IUpdateSearchResultCollector;
+
+public class UpdatesSearchCategory extends BaseSearchCategory {
+	private static final String CATEGORY_ID =
+		"org.eclipse.update.core.new-updates"; //$NON-NLS-1$
+	private IFeature [] features;
+	private boolean automatic;
+
+	class Candidate {
+		ArrayList children;
+		Candidate parent;
+		IFeatureReference ref;
+		public Candidate(IFeatureReference ref) {
+			this.ref = ref;
+		}
+		public Candidate(IFeatureReference ref, Candidate parent) {
+			this(ref);
+			this.parent = parent;
+		}
+		public void add(Candidate child) {
+			if (children == null)
+				children = new ArrayList();
+			child.setParent(this);
+			children.add(child);
+		}
+		void setParent(Candidate parent) {
+			this.parent = parent;
+		}
+		public IFeatureReference getReference() {
+			return ref;
+		}
+		void setReference(IFeatureReference ref) {
+			this.ref = ref;
+		}
+		public IFeature getFeature(IProgressMonitor monitor) {
+			try {
+				return ref.getFeature(monitor);
+			} catch (CoreException e) {
+				return null;
+			}
+		}
+		public Candidate getParent() {
+			return parent;
+		}
+		public Candidate getRoot() {
+			Candidate root = this;
+
+			while (root.getParent() != null) {
+				root = root.getParent();
+			}
+			return root;
+		}
+		public IURLEntry getUpdateEntry() {
+			int location = IUpdateConstants.SEARCH_ROOT;
+
+			if (ref instanceof IIncludedFeatureReference)
+				location =
+					((IIncludedFeatureReference) ref).getSearchLocation();
+			if (parent == null || location == IUpdateConstants.SEARCH_SELF) {
+				return getFeature(null).getUpdateSiteEntry();
+			}
+			return getRoot().getUpdateEntry();
+		}
+		public String toString() {
+			return ref.toString();
+		}
+		public boolean equals(Object source) {
+			if (source instanceof Candidate) {
+				return this.ref.equals(((Candidate) source).getReference());
+			}
+			if (source instanceof IFeatureReference) {
+				return this.ref.equals(source);
+			}
+			return false;
+		}
+		public void addToFlatList(ArrayList list, boolean updatableOnly) {
+			// add itself
+			if (!updatableOnly || isUpdatable())
+				list.add(this);
+			// add children
+			if (children != null) {
+				for (int i = 0; i < children.size(); i++) {
+					Candidate child = (Candidate) children.get(i);
+					child.addToFlatList(list, updatableOnly);
+				}
+			}
+		}
+		public boolean isUpdatable() {
+			return (parent == null);
+		}
+	}
+
+	private static class Hit {
+		IFeatureReference ref;
+		IInstallFeatureOperation patchFor;
+		boolean patch;
+		IInstallFeatureOperation job;
+		
+		public Hit(IFeature candidate, IFeatureReference ref) {
+			this.ref = ref;
+		}
+		public Hit(IFeature candidate, IFeatureReference ref, boolean patch) {
+			this(candidate, ref);
+			this.patch = patch;
+		}
+
+		public Hit(IFeature candidate, IFeatureReference ref, IInstallFeatureOperation patchFor) {
+			this(candidate, ref, true);
+			this.patchFor = patchFor;
+		}
+
+		public IInstallFeatureOperation getJob() {
+			if (job == null) {
+				try {
+					IFeature feature = ref.getFeature(null);
+					job = OperationsManager.getOperationFactory().createInstallOperation(null, feature, null, null, null);
+				} catch (CoreException e) {
+					UpdateCore.log(e);
+				}
+			}
+			return job;
+		}
+
+		public boolean isPatch() {
+			return patch;
+		}
+		public IInstallFeatureOperation getPatchedJob() {
+			return patchFor;
+		}
+	}
+
+	public class UpdateQuery implements IUpdateSearchQuery {
+		IFeature candidate;
+		IQueryUpdateSiteAdapter adapter;
+
+		public UpdateQuery(
+			IFeature candidate,
+			IURLEntry updateEntry) {
+			this.candidate = candidate;
+			if (updateEntry != null && updateEntry.getURL() != null)
+				adapter =
+					new QueryUpdateSiteAdapter(
+						getLabelForEntry(updateEntry),
+						updateEntry.getURL(),
+						candidate.getVersionedIdentifier().getIdentifier());
+		}
+		private String getLabelForEntry(IURLEntry entry) {
+			String label = entry.getAnnotation();
+			if (label == null || label.length() == 0)
+				label = entry.getURL().toString();
+			return label;
+		}
+
+		public IQueryUpdateSiteAdapter getQuerySearchSite() {
+			return adapter;
+		}
+		private boolean isBroken() {
+			try {
+				IStatus status =
+					SiteManager.getLocalSite().getFeatureStatus(candidate);
+				return status.getSeverity() == IStatus.ERROR;
+			} catch (CoreException e) {
+				return false;
+			}
+		}
+		private boolean isMissingOptionalChildren(IFeature feature) {
+			try {
+				IIncludedFeatureReference[] children =
+					feature.getIncludedFeatureReferences();
+				for (int i = 0; i < children.length; i++) {
+					IIncludedFeatureReference ref = children[i];
+					try {
+						IFeature child = ref.getFeature(null);
+						// If we are here, the child is not missing.
+						// Check it's children recursively.
+						if (isMissingOptionalChildren(child))
+							return true;
+					} catch (CoreException e) {
+						// Missing child. Return true if optional,
+						// otherwise it is a broken feature that we 
+						// do not care about.
+						if (ref.isOptional()) {
+							return FeatureHierarchyElement.hasOlderVersion(ref);
+						}
+					}
+				}
+			} catch (CoreException e) {
+			}
+			return false;
+		}
+		public void run(
+			ISite site,
+			String[] categoriesToSkip,
+			IUpdateSearchFilter filter,
+			IUpdateSearchResultCollector collector,
+			IProgressMonitor monitor) {
+			ArrayList hits = new ArrayList();
+			boolean broken = isBroken();
+			boolean missingOptionalChildren = false;
+
+			// Don't bother to compute missing optional children
+			// if the feature is broken - all we want is to 
+			// see if we should allow same-version re-install.
+			if (!broken)
+				missingOptionalChildren = isMissingOptionalChildren(candidate);
+			ISiteFeatureReference[] refs = site.getFeatureReferences();
+			monitor.beginTask("", refs.length + 1); //$NON-NLS-1$
+			ArrayList updateJobs = new ArrayList();
+			for (int i = 0; i < refs.length; i++) {
+				ISiteFeatureReference ref = refs[i];
+				try {
+					if (isNewerVersion(candidate.getVersionedIdentifier(),ref.getVersionedIdentifier())) {
+						Hit h = new Hit(candidate, ref);
+						hits.add(h);
+						IInstallFeatureOperation job = h.getJob();
+						if (job != null)
+							updateJobs.add(job);
+					} else {
+						// accept the same feature if the installed
+						// feature is broken
+						if ((broken || missingOptionalChildren)
+							&& candidate.getVersionedIdentifier().equals(
+								ref.getVersionedIdentifier())){
+							hits.add(new Hit(candidate, ref));
+							continue;
+						}
+						else {
+							// check for patches
+							if (isPatch(candidate, ref)){
+								hits.add(new Hit(candidate, ref, true));
+								continue;
+							}
+						}
+					}
+				} catch (CoreException e) {
+				}
+				monitor.worked(1);
+				if (monitor.isCanceled()){
+					return;
+				}
+				
+			}
+			// accept patches for updated features
+			for (int n = 0; n < updateJobs.size(); n++) {
+				IInstallFeatureOperation job = (IInstallFeatureOperation) updateJobs
+						.get(n);
+					IFeature newCandidate = job.getFeature();
+					for (int i = 0; i < refs.length; i++) {
+						ISiteFeatureReference ref = refs[i];
+						if (isPatch(newCandidate, ref)) {
+							Hit h = new Hit(newCandidate, ref, job);
+							hits.add(h);
+							continue;
+						}
+						//monitor.worked(1);
+						if (monitor.isCanceled()) {
+							return;
+						}
+					}
+			}
+			if (hits.size() > 0) {
+				collectValidHits(hits, filter, collector);
+			}
+			monitor.worked(1);
+			monitor.done();
+		}
+		
+		/**
+		 * Returns IFeature associated with the IUpdateSearchQuery
+		 */
+		public IFeature getFeature() {
+			return candidate;
+		}
+	}
+
+	private ArrayList candidates;
+
+	public UpdatesSearchCategory() {
+		this(true);
+	}
+	
+	public UpdatesSearchCategory(boolean automatic) {
+		super(CATEGORY_ID);
+		this.automatic = automatic;
+	}
+
+	private void collectValidHits(
+		ArrayList hits,
+		IUpdateSearchFilter filter,
+		IUpdateSearchResultCollector collector) {
+		//Object[] array = hits.toArray();
+		IFeature topHit = null;
+		for (int i = 0; i < hits.size(); i++) {
+			Hit hit = (Hit) hits.get(i);
+			IInstallFeatureOperation job = hit.getJob();
+			if (job == null)
+				continue;
+			// do not accept updates without a license
+			if (!UpdateUtils.hasLicense(job.getFeature())) {
+				UpdateCore.log(job.getFeature().getVersionedIdentifier() + ": " + Messages.DefaultFeatureParser_NoLicenseText, null);  //$NON-NLS-1$
+				continue;
+			}
+			IStatus status = null;
+			
+			// Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=132450
+			// Only validate for automatic updates because
+			// non-automatic once will arrive in the review wizard
+			// where additional validation will be performed
+			if (automatic) {
+				if( hit.getPatchedJob()==null){
+					status = OperationsManager.getValidator().validatePendingInstall(job.getOldFeature(), job.getFeature());
+				}else{
+					status = OperationsManager.getValidator().validatePendingChanges(new IInstallFeatureOperation[]{hit.getPatchedJob(), job});
+				}
+			}
+			if (status == null || status.getCode() == IStatus.WARNING) {
+				if (hit.isPatch()) {
+					IFeature patch = job.getFeature();
+					// Do not add the patch if already installed
+					IFeature[] sameId = UpdateUtils.getInstalledFeatures(patch, false);
+					if (sameId.length==0) {
+						if (filter.accept(patch))
+							collector.accept(patch);
+					}
+				}
+				else  {
+					topHit = job.getFeature();
+					if (filter.accept(topHit))
+						collector.accept(topHit);
+				}
+			}
+		}
+	}
+
+	private void initialize() {
+		candidates = new ArrayList();
+		try {
+			ILocalSite localSite = SiteManager.getLocalSite();
+			IInstallConfiguration config = localSite.getCurrentConfiguration();
+			IConfiguredSite[] isites = config.getConfiguredSites();
+			for (int i = 0; i < isites.length; i++) {
+				contributeCandidates(isites[i]);
+			}
+		} catch (CoreException e) {
+			UpdateCore.log(
+				Messages.UpdatesSearchCategory_errorSearchingForUpdates, 
+				e);
+		}
+	}
+
+	private void contributeCandidates(IConfiguredSite isite)
+		throws CoreException {
+		IFeatureReference[] refs = isite.getConfiguredFeatures();
+		ArrayList candidatesPerSite = new ArrayList();
+		for (int i = 0; i < refs.length; i++) {
+			IFeatureReference ref = refs[i];
+			// Don't waste time searching for updates to 
+			// patches.
+			try {
+				if (UpdateUtils.isPatch(ref.getFeature(null)))
+					continue;
+			}
+			catch (CoreException e) {
+				continue;
+			}
+			Candidate c = new Candidate(ref);
+			candidatesPerSite.add(c);
+		}
+		// Create a tree from a flat list
+		buildHierarchy(candidatesPerSite);
+		// Add the remaining root candidates to 
+		// the global list of candidates.
+		candidates.addAll(candidatesPerSite);
+	}
+
+	private void buildHierarchy(ArrayList candidates) throws CoreException {
+		Candidate[] array =
+			(Candidate[]) candidates.toArray(new Candidate[candidates.size()]);
+		// filter out included features so that only top-level features remain on the list
+		for (int i = 0; i < array.length; i++) {
+			Candidate parent = array[i];
+			IFeature feature = parent.getFeature(null);
+			IFeatureReference[] included =
+				feature.getIncludedFeatureReferences();
+			for (int j = 0; j < included.length; j++) {
+				IFeatureReference fref = included[j];
+				Candidate child = findCandidate(candidates, fref);
+				if (child != null) {
+					parent.add(child);
+					child.setReference(fref);
+					candidates.remove(child);
+				}
+			}
+		}
+	}
+	private Candidate findCandidate(ArrayList list, IFeatureReference ref) {
+		for (int i = 0; i < list.size(); i++) {
+			Candidate c = (Candidate) list.get(i);
+			if (c.ref.equals(ref))
+				return c;
+		}
+		return null;
+	}
+
+	public IUpdateSearchQuery[] getQueries() {
+		initialize();
+		ArrayList allCandidates = getAllCandidates();
+
+		IUpdateSearchQuery[] queries =
+			new IUpdateSearchQuery[allCandidates.size()];
+		for (int i = 0; i < queries.length; i++) {
+			Candidate candidate = (Candidate) allCandidates.get(i);
+			IFeature feature = candidate.getFeature(null);
+			IURLEntry updateEntry = candidate.getUpdateEntry();
+			if (feature == null) {
+				queries[i] = null;
+			} else {
+				queries[i] = new UpdateQuery(feature, updateEntry);
+			}
+		}
+		return queries;
+	}
+	
+/**
+ * Sets the features for which new updates need to be found. If
+ * not set, updates will be searched for all the installed
+ * and configured features.
+ * @param features the features to search updates for
+ */	
+	public void setFeatures(IFeature [] features) {
+		this.features = features;
+	}
+	
+/**
+ * Returns an array of features for which updates need to
+ * be found. 
+ * @return an array of features or <samp>null</samp> if not
+ * set.
+ */	
+	public IFeature [] getFeatures() {
+		return features;
+	}
+	/**
+	 * @param fvi
+	 * @param cvi
+	 * @return fvi < cvi
+	 */
+	private boolean isNewerVersion(
+		VersionedIdentifier fvi,
+		VersionedIdentifier cvi) {
+		if (!fvi.getIdentifier().equals(cvi.getIdentifier()))
+			return false;
+		PluginVersionIdentifier fv = fvi.getVersion();
+		PluginVersionIdentifier cv = cvi.getVersion();
+		String mode = getUpdateVersionsMode();
+		boolean greater = cv.isGreaterThan(fv);
+		if (!greater)
+			return false;
+		if (mode.equals(UpdateCore.EQUIVALENT_VALUE))
+			return cv.isEquivalentTo(fv);
+		else if (mode.equals(UpdateCore.COMPATIBLE_VALUE))
+			return cv.isCompatibleWith(fv);
+		else
+			return false;
+	}
+
+	private boolean isPatch(IFeature candidate, ISiteFeatureReference ref) {
+		if (ref.isPatch() == false)
+			return false;
+		try {
+			IFeature feature = ref.getFeature(null);
+			if( UpdateUtils.isPatch(candidate, feature))
+				return true;
+			// Check if patch is for children
+			try {
+				IIncludedFeatureReference[] children =
+					candidate.getIncludedFeatureReferences();
+				for (int i = 0; i < children.length; i++) {
+					IIncludedFeatureReference cref = children[i];
+					try {
+						IFeature child = cref.getFeature(null);
+						if (isPatch(child, ref))
+							return true;
+					} catch (CoreException e) {
+					}
+				}
+			} catch (CoreException e) {
+			}
+			return false;
+		} catch (CoreException e) {
+			return false;
+		}
+	}
+	
+	private String getUpdateVersionsMode() {
+		Preferences store = UpdateCore.getPlugin().getPluginPreferences();
+		return store.getString(UpdateCore.P_UPDATE_VERSIONS);
+	}
+/*
+ * This method recursively walks the list of candidates
+ * building the flat that starts with the roots but
+ * also includes all the children that are updatable
+ * (use 'include' clause with a match that is not 'perfect').
+ */
+	private ArrayList getAllCandidates() {
+		ArrayList selected = new ArrayList();
+		for (int i=0; i<candidates.size(); i++) {
+			Candidate c = (Candidate)candidates.get(i);
+			if (isOnTheList(c))
+				c.addToFlatList(selected, true);
+		}
+		return selected;
+	}
+	
+	private boolean isOnTheList(Candidate c) {
+		if (features==null) return true;
+		VersionedIdentifier vid;
+		try {
+			vid = c.getReference().getVersionedIdentifier();
+		}
+		catch (CoreException e) {
+			return false;
+		}
+		for (int i=0; i<features.length; i++) {
+			IFeature feature = features[i];
+			VersionedIdentifier fvid = feature.getVersionedIdentifier();
+			if (fvid.equals(vid))
+				return true;
+		}
+		return false;
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/CertificatePair.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/CertificatePair.java
new file mode 100644
index 0000000..9b0c4c1
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/CertificatePair.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.internal.security;
+ 
+ import java.security.cert.*;
+ 
+/**
+ *
+ */
+public class CertificatePair {
+	private Certificate root;
+	private Certificate issuer;
+	
+	
+
+	/**
+	 * Gets the root.
+	 * @return Returns a Certificate
+	 */
+	public Certificate getRoot() {
+		return root;
+	}
+
+	/**
+	 * Sets the root.
+	 * @param root The root to set
+	 */
+	public void setRoot(Certificate root) {
+		this.root = root;
+	}
+
+	/**
+	 * Gets the issuer.
+	 * @return Returns a Certificate
+	 */
+	public Certificate getIssuer() {
+		return issuer;
+	}
+
+	/**
+	 * Sets the issuer.
+	 * @param issuer The issuer to set
+	 */
+	public void setIssuer(Certificate issuer) {
+		this.issuer = issuer;
+	}
+
+	/*
+	 * @see Object#equals(Object)
+	 */
+	public boolean equals(Object obj) {
+		
+		if (obj==null) return false;
+		
+		if (!(obj instanceof CertificatePair)) return false;
+		
+		if (root==null || issuer==null) return false;
+		
+		CertificatePair pair = (CertificatePair)obj;
+		
+		return (root.equals(pair.getRoot()) && issuer.equals(pair.getIssuer()));
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerificationResult.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerificationResult.java
new file mode 100644
index 0000000..87406f7
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerificationResult.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.security;
+
+import java.security.*;
+import java.security.cert.*;
+import java.security.cert.Certificate;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.Messages;
+
+/**
+ * Result of the service
+ */
+public class JarVerificationResult implements IVerificationResult {
+
+
+	private int resultCode;
+	private int verificationCode;
+	private Exception resultException;
+	private List /*of Certificates[] */
+	certificates;
+	private CertificatePair[] rootCertificates;
+	private CertificatePair foundCertificate; // certificate found in one keystore
+	
+	private String signerInfo;
+	private String verifierInfo;
+	private ContentReference contentReference;
+	private IFeature feature;
+	private boolean featureVerification;
+	private boolean alreadySeen;
+
+	public JarVerificationResult() {
+	}
+	
+	/*
+	 * 
+	 */
+	public int getResultCode() {
+		return resultCode;
+	}
+	
+	/*
+	 * 
+	 */
+	public Exception getVerificationException() {
+		return resultException;
+	}
+	
+	/*
+	 * 
+	 */
+	public void setResultCode(int newResultCode) {
+		resultCode = newResultCode;
+	}
+	
+	/*
+	 * 
+	 */
+	public void setResultException(Exception newResultException) {
+		resultException = newResultException;
+	}
+	
+	/*
+	 * 
+	 */
+	public int getVerificationCode() {
+		return verificationCode;
+	}
+
+	/*
+	 * 
+	 */
+	public void setVerificationCode(int verificationCode) {
+		this.verificationCode = verificationCode;
+	}
+
+	/*
+	 * adds an array of Certificates to the list
+	 * force recomputation of root cert
+	 */
+	public void addCertificates(Certificate[] certs) {
+		if (certificates == null)
+			certificates = new ArrayList();
+		certificates.add(certs);
+		rootCertificates = null;
+	}
+
+	/*
+	 * Returns the list of root certificates
+	 * The list of certificates we received is an array of certificates
+	 * we have to determine 
+	 * 1) how many chain do we have (a chain stops when verifier of a cert is 
+	 * not the signer of the next cert in the list 
+	 * 2) build a cert with the leaf signer and the root verifier for each chain
+	 */
+	public CertificatePair[] getRootCertificates() {
+		if (rootCertificates == null) {
+			rootCertificates = new CertificatePair[0];			
+			List rootCertificatesList = new ArrayList();
+			if (certificates != null && certificates.size() > 0) {
+				Iterator iter = certificates.iterator();
+				while (iter.hasNext()) {
+
+					Certificate[] certs = (Certificate[]) iter.next();
+					if (certs != null && certs.length > 0) {
+
+						CertificatePair pair = new CertificatePair();
+						pair.setIssuer(certs[0]);
+
+						for (int i = 0; i < certs.length - 1; i++) {
+							X509Certificate x509certRoot = (X509Certificate) certs[i];
+							X509Certificate x509certIssuer = (X509Certificate) certs[i+1];
+							if (!x509certRoot.getIssuerDN().equals(x509certIssuer.getSubjectDN())) {
+								pair.setRoot(x509certRoot);
+								if (!rootCertificatesList.contains(pair)) {
+									rootCertificatesList.add(pair);
+								}
+								pair = new CertificatePair();
+								pair.setIssuer(x509certIssuer);
+							}
+						}
+
+						// add the latest one
+						if (pair != null) {
+							pair.setRoot(certs[certs.length - 1]);
+							if (!rootCertificatesList.contains(pair)) {
+								rootCertificatesList.add(pair);
+							}
+						}
+					}
+				}
+
+			}
+			
+			if (rootCertificatesList.size() > 0) {
+				rootCertificates = new CertificatePair[rootCertificatesList.size()];				
+				rootCertificatesList.toArray(rootCertificates);
+			}
+		}
+		return rootCertificates;
+	}
+
+	/*
+	 * 
+	 */
+	private CertificatePair getFoundCertificate() {
+		return foundCertificate;
+	}
+
+	/*
+	 * 
+	 */
+	public void setFoundCertificate(CertificatePair foundCertificate) {
+		this.foundCertificate = foundCertificate;
+	}
+
+
+	/*
+	 * Initializes the signerInfo and the VerifierInfo from the Certificate Pair
+	 */
+	private void initializeCertificates(){
+		X509Certificate certRoot = null;
+		X509Certificate certIssuer = null;
+		CertificatePair trustedCertificate;
+		if (getFoundCertificate() == null) {
+			CertificatePair[] certs = getRootCertificates();
+			if (certs.length == 0)
+				return;
+			trustedCertificate = certs[0];
+		} else {
+			trustedCertificate = getFoundCertificate();
+		}
+		certRoot = (X509Certificate) trustedCertificate.getRoot();
+		certIssuer = (X509Certificate) trustedCertificate.getIssuer();
+
+		StringBuffer strb = new StringBuffer();
+		strb.append(issuerString(certIssuer.getSubjectDN()));
+		strb.append("\r\n"); //$NON-NLS-1$
+		strb.append(NLS.bind(Messages.JarVerificationResult_ValidBetween, (new String[] { dateString(certIssuer.getNotBefore()), dateString(certIssuer.getNotAfter()) })));
+		strb.append(checkValidity(certIssuer));
+		signerInfo = strb.toString();
+		if (certIssuer != null && !certIssuer.equals(certRoot)) {
+			strb = new StringBuffer();	
+			strb.append(issuerString(certIssuer.getIssuerDN()));
+			strb.append("\r\n"); //$NON-NLS-1$
+			strb.append(NLS.bind(Messages.JarVerificationResult_ValidBetween, (new String[] { dateString(certRoot.getNotBefore()), dateString(certRoot.getNotAfter()) }))); 
+			strb.append(checkValidity(certRoot));
+			verifierInfo = strb.toString();
+		}
+
+	}
+
+	/*
+	 * Returns a String to show if the certificate is valid
+	 */
+	private String checkValidity(X509Certificate cert) {
+
+		try {
+			cert.checkValidity();
+		} catch (CertificateExpiredException e) {
+			return ("\r\n" + Messages.JarVerificationResult_ExpiredCertificate);  //$NON-NLS-1$
+		} catch (CertificateNotYetValidException e) {
+			return ("\r\n" + Messages.JarVerificationResult_CertificateNotYetValid);  //$NON-NLS-1$
+		}
+		return ("\r\n" + Messages.JarVerificationResult_CertificateValid);  //$NON-NLS-1$
+	}
+
+	/*
+	 * Returns the label String from a X50name
+	 */
+	private String issuerString(Principal principal) {
+// 19902
+//		try {
+//			if (principal instanceof X500Name) {
+//				StringBuffer buf = new StringBuffer();
+//				X500Name name = (X500Name) principal;
+//				buf.append((name.getDNQualifier() != null) ? name.getDNQualifier() + ", " : "");
+//				buf.append(name.getCommonName());
+//				buf.append((name.getOrganizationalUnit() != null) ? ", " + name.getOrganizationalUnit() : "");
+//				buf.append((name.getOrganization() != null) ? ", " + name.getOrganization() : "");
+//				buf.append((name.getLocality() != null) ? ", " + name.getLocality() : "");
+//				buf.append((name.getCountry() != null) ? ", " + name.getCountry() : "");
+//				return new String(buf);
+//			}
+//		} catch (Exception e) {
+//			UpdateCore.warn("Error parsing X500 Certificate",e);
+//		}
+		return principal.toString();
+	}
+
+	/*
+	 * 
+	 */
+	private String dateString(Date date) {
+		return DateFormat.getDateInstance().format(date);
+	}
+
+	/*
+	 *
+	 */
+	public String getSignerInfo() {
+		if (signerInfo==null) initializeCertificates();
+		return signerInfo;
+	}
+
+	/*
+	 *
+	 */
+	public String getVerifierInfo() {
+		if (signerInfo==null) initializeCertificates();		
+		return verifierInfo;
+	}
+
+	/*
+	 *
+	 */
+	public ContentReference getContentReference() {
+		return contentReference;
+	}
+
+	/*
+	 * 
+	 */
+	public void setContentReference(ContentReference ref) {
+		this.contentReference = ref;
+	}
+
+
+	/*
+	 *
+	 */
+	public IFeature getFeature() {
+		return feature;
+	}
+
+	/*
+	 * 
+	 */
+	public void setFeature(IFeature feature) {
+		this.feature = feature;
+	}
+
+	/*
+	 * 
+	 */
+	public String getText() {
+		return null;
+	}
+
+
+	/*
+	 * 
+	 */
+	public boolean isFeatureVerification() {
+		return featureVerification;
+	}
+	
+	/*
+	 * 
+	 */
+	public void isFeatureVerification(boolean featureVerification) {
+		this.featureVerification = featureVerification;
+	}
+
+	/*
+	 *
+	 */
+	public boolean alreadySeen() {
+		return alreadySeen;
+	}
+
+	/*
+	 * 
+	 */
+	public boolean alreadySeen(boolean seen) {
+		return this.alreadySeen = seen;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerifier.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerifier.java
new file mode 100644
index 0000000..d0b25b2
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/JarVerifier.java
@@ -0,0 +1,457 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.security;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.zip.ZipException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.ContentReference;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IVerificationResult;
+import org.eclipse.update.core.IVerifier;
+import org.eclipse.update.core.InstallMonitor;
+import org.eclipse.update.core.JarContentReference;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.Verifier;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.connection.ConnectionFactory;
+
+/**
+ * The JarVerifier will check the integrity of the JAR.
+ * If the Jar is signed and the integrity is validated,
+ * it will check if one of the certificate of each file
+ * is in one of the keystore.
+ *
+ */
+
+public class JarVerifier extends Verifier {
+
+	private static final String MANIFEST = "META-INF"; //$NON-NLS-1$
+
+	private JarVerificationResult result;
+	private List /*of CertificatePair*/
+	trustedCertificates;
+	private boolean acceptUnsignedFiles;
+	private List /* of KeyStore */
+	listOfKeystores;
+	private IProgressMonitor monitor;
+	private File jarFile;
+
+	private static	byte[] buffer = new byte[8192];
+	
+	/*
+	 * Default Constructor
+	 */
+	public JarVerifier() {
+		initialize();
+	}
+
+	/*
+	 * Returns the list of the keystores.
+	 */
+	private List getKeyStores() throws CoreException {
+		if (listOfKeystores == null) {
+			listOfKeystores = new ArrayList(0);
+			KeyStores listOfKeystoreHandles = new KeyStores();
+			InputStream in = null;
+			KeyStore keystore = null;
+			KeystoreHandle handle = null;
+			while (listOfKeystoreHandles.hasNext()) {
+				try {
+					handle = listOfKeystoreHandles.next();
+					in = ConnectionFactory.get(handle.getLocation()).getInputStream();
+					try {
+						keystore = KeyStore.getInstance(handle.getType());
+						keystore.load(in, null); // no password
+					} catch (NoSuchAlgorithmException e) {
+						throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_UnableToFindEncryption, (new String[] { handle.getLocation().toExternalForm() })), e);
+					} catch (CertificateException e) {
+						throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_UnableToLoadCertificate, (new String[] { handle.getLocation().toExternalForm() })), e);
+					} catch (KeyStoreException e) {
+						throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_UnableToFindProviderForKeystore, (new String[] { handle.getType() })), e);
+					} finally {
+						if (in != null) {
+							try {
+								in.close();
+							} catch (IOException e) {
+							} // nothing
+						}
+					} // try loading a keyStore
+
+					// keystore was loaded
+					listOfKeystores.add(keystore);
+				} catch (IOException e) {
+					// nothing... if the keystore doesn't exist, continue	
+				}
+
+			} // while all key stores
+
+		}
+
+		return listOfKeystores;
+	}
+
+	/*
+	 * 
+	 */
+	private void initialize() {
+		result = null;
+		trustedCertificates = null;
+		acceptUnsignedFiles = false;
+		listOfKeystores = null;
+	}
+
+	/*
+	 * init
+	 */
+	private void init(IFeature feature, ContentReference contentRef) throws CoreException {
+		jarFile = null;
+		if (contentRef instanceof JarContentReference) {
+			JarContentReference jarReference = (JarContentReference) contentRef;
+			try {
+				jarFile = jarReference.asFile();
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_INSTALL)
+					UpdateCore.debug("Attempting to read JAR file:"+jarFile); //$NON-NLS-1$
+			
+				// # of entries
+				if (!jarFile.exists()) throw new IOException();
+				JarFile jar = new JarFile(jarFile);
+				if (jar !=null){
+					try {
+						jar.close();
+					} catch (IOException ex) {
+						// unchecked
+					}
+				}
+			} catch (ZipException e){
+				throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_InvalidJar, (new String[] { jarReference.toString() })), e);				
+			} catch (IOException e) {
+				throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_UnableToAccessJar, (new String[] { jarReference.toString() })), e);
+			}
+		}
+
+		result = new JarVerificationResult();
+		result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR);
+		result.setResultException(null);
+		result.setFeature(feature);
+		result.setContentReference(contentRef);
+	}
+
+	/*
+	 * Returns true if one of the certificate exists in the keystore
+	 */
+	private boolean existsInKeystore(Certificate cert) throws CoreException {
+		try {
+			List keyStores = getKeyStores();
+			if (!keyStores.isEmpty()) {
+				Iterator listOfKeystores = keyStores.iterator();
+				while (listOfKeystores.hasNext()) {
+					KeyStore keystore = (KeyStore) listOfKeystores.next();
+
+					if (keystore.getCertificateAlias(cert) != null) {
+						return true;
+					}
+				}
+			}
+		} catch (KeyStoreException e) {
+			throw Utilities.newCoreException(Messages.JarVerifier_KeyStoreNotLoaded, e); 
+		}
+		return false;
+	}
+
+	/*
+	 * 
+	 */
+	private List readJarFile(JarFile jarFile, String identifier)
+		throws IOException, InterruptedException {
+		List list = new ArrayList();
+
+		Enumeration entries = jarFile.entries();
+		JarEntry currentEntry = null;
+		InputStream in = null;
+		if (monitor != null)
+			monitor.setTaskName(NLS.bind(Messages.JarVerifier_Verify, (new String[] { identifier == null ? jarFile.getName(): identifier }))); 
+
+		try {
+			while (entries.hasMoreElements()) {
+				currentEntry = (JarEntry) entries.nextElement();
+				list.add(currentEntry);
+				in = jarFile.getInputStream(currentEntry);
+				while ((in.read(buffer, 0, buffer.length)) != -1) {
+					// Security error thrown if tempered
+				}
+				if (in!=null)
+					in.close();
+			}
+		} catch (IOException e) {
+			result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR);
+			result.setResultException(e);
+		} finally {
+			try {
+				if (in != null)
+					in.close();
+			} catch (IOException e1) {
+				// ignore
+			}
+		}
+
+		return list;
+	}
+
+	/*
+	 * @param newMonitor org.eclipse.core.runtime.IProgressMonitor
+	 */
+	public void setMonitor(IProgressMonitor newMonitor) {
+		monitor = newMonitor;
+	}
+
+	/*
+	 * @see IVerifier#verify(IFeature,ContentReference,boolean, InstallMonitor)
+	 */
+	public IVerificationResult verify(
+		IFeature feature,
+		ContentReference reference,
+		boolean isFeatureVerification,
+		InstallMonitor monitor)
+		throws CoreException {
+
+		if (reference == null)
+			return result;
+
+		// if parent knows how to verify, ask the parent first
+		if (getParent() != null) {
+			IVerificationResult vr =
+				getParent().verify(feature, reference, isFeatureVerification, monitor);
+			if (vr.getVerificationCode() != IVerificationResult.TYPE_ENTRY_UNRECOGNIZED)
+				return vr;
+		}
+
+		// the parent couldn't verify
+		setMonitor(monitor);
+		init(feature, reference);
+		result.isFeatureVerification(isFeatureVerification);
+
+		if (jarFile!=null) {
+				result = verify(jarFile.getAbsolutePath(), reference.getIdentifier());
+		} else {
+			result.setVerificationCode(IVerificationResult.TYPE_ENTRY_UNRECOGNIZED);
+		}
+
+		return result;
+	}
+
+	/*
+	 * 
+	 */
+	private JarVerificationResult verify(String file, String identifier) {
+
+		try {
+
+			// verify integrity
+			verifyIntegrity(file, identifier);
+
+			// do not close input stream
+			// as verifyIntegrity already did it
+
+			//if user already said yes
+			result.alreadySeen(alreadyValidated());
+
+			// verify source certificate
+			if (result.getVerificationCode()
+				== IVerificationResult.TYPE_ENTRY_SIGNED_UNRECOGNIZED) {
+				verifyAuthentication();
+			}
+
+			// save the fact the file is not signed, so the user will not be prompted again 
+			if (result.getVerificationCode()
+				== IVerificationResult.TYPE_ENTRY_NOT_SIGNED) {
+				acceptUnsignedFiles = true;
+			}
+
+		} catch (Exception e) {
+			result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR);
+			result.setResultException(e);
+		}
+
+		if (monitor != null) {
+			monitor.worked(1);
+			if (monitor.isCanceled()) {
+				result.setVerificationCode(IVerificationResult.VERIFICATION_CANCELLED);
+			}
+		}
+
+		return result;
+	}
+
+	/*
+	 * Verifies that each file has at least one certificate
+	 * valid in the keystore
+	 *
+	 * At least one certificate from each Certificate Array
+	 * of the Jar file must be found in the known Certificates
+	 */
+	private void verifyAuthentication() throws CoreException {
+
+		CertificatePair[] entries = result.getRootCertificates();
+		boolean certificateFound = false;
+
+		// If all the certificate of an entry are
+		// not found in the list of known certifcate
+		// the certificate is not trusted by any keystore.
+		for (int i = 0; i < entries.length; i++) {
+			certificateFound = existsInKeystore(entries[i].getRoot());
+			if (certificateFound) {
+				result.setVerificationCode(IVerificationResult.TYPE_ENTRY_SIGNED_RECOGNIZED);
+				result.setFoundCertificate(entries[i]);
+				return;
+			}
+		}
+	}
+
+	/*
+	 * Verifies the integrity of the JAR
+	 */
+	private void verifyIntegrity(String file, String identifier) {
+
+		JarFile jarFile = null;
+
+		try {
+			// If the JAR is signed and not valid
+			// a security exception will be thrown
+			// while reading it
+			jarFile = new JarFile(file, true);
+			List filesInJar = readJarFile(jarFile, identifier);
+
+			// you have to read all the files once
+			// before getting the certificates 
+			if (jarFile.getManifest() != null) {
+				Iterator iter = filesInJar.iterator();
+				boolean certificateFound = false;
+				while (iter.hasNext()) {
+					JarEntry currentJarEntry = (JarEntry) iter.next();
+					Certificate[] certs = currentJarEntry.getCertificates();
+					if ((certs != null) && (certs.length != 0)) {
+						certificateFound = true;
+						result.addCertificates(certs);
+					} else {
+						String jarEntryName = currentJarEntry.getName();
+						if (!jarEntryName.toUpperCase().startsWith(MANIFEST)
+							&& !currentJarEntry.isDirectory()) {
+							// if the jarEntry is not in MANIFEST, consider the whole file unsigned							
+							break;
+						}
+
+					}
+				}
+
+				if (certificateFound)
+					result.setVerificationCode(IVerificationResult.TYPE_ENTRY_SIGNED_UNRECOGNIZED);
+				else
+					result.setVerificationCode(IVerificationResult.TYPE_ENTRY_NOT_SIGNED);
+			} else {
+				Exception e = new Exception(NLS.bind(Messages.JarVerifier_InvalidFile, (new String[] { file })));
+				result.setResultException(e);
+				result.setVerificationCode(IVerificationResult.TYPE_ENTRY_NOT_SIGNED);
+				UpdateCore.warn(null,e);
+			}
+		} catch (SecurityException e) {
+			// Jar file is signed
+			// but content has changed since signed
+			result.setVerificationCode(IVerificationResult.TYPE_ENTRY_CORRUPTED);
+		} catch (InterruptedException e) {
+			result.setVerificationCode(IVerificationResult.VERIFICATION_CANCELLED);
+		} catch (Exception e) {
+			result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR);
+			result.setResultException(e);
+		} finally {
+			if (jarFile!=null){
+				try {jarFile.close();} catch (IOException e){}
+			}
+		}
+
+	}
+
+	/*
+	 * 
+	 */
+	private boolean alreadyValidated() {
+
+		if (result.getVerificationCode() == IVerificationResult.TYPE_ENTRY_NOT_SIGNED)
+			return (acceptUnsignedFiles);
+
+		if (getTrustedCertificates() != null) {
+			Iterator iter = getTrustedCertificates().iterator();
+			CertificatePair[] jarPairs = result.getRootCertificates();
+
+			// check if this is not a user accepted certificate for this feature	
+			while (iter.hasNext()) {
+				CertificatePair trustedCertificate = (CertificatePair) iter.next();
+				for (int i = 0; i < jarPairs.length; i++) {
+					if (trustedCertificate.equals(jarPairs[i])) {
+						return true;
+					}
+				}
+			}
+
+			// if certificate pair not found in trusted add it for next time
+			for (int i = 0; i < jarPairs.length; i++) {
+				addTrustedCertificate(jarPairs[i]);
+			}
+		}
+
+		return false;
+	}
+
+	/*
+	 * 
+	 */
+	private void addTrustedCertificate(CertificatePair pair) {
+		if (trustedCertificates == null)
+			trustedCertificates = new ArrayList();
+		if (pair != null)
+			trustedCertificates.add(pair);
+	}
+
+	/*
+	 * 
+	 */
+	private List getTrustedCertificates() {
+		if (trustedCertificates == null)
+			trustedCertificates = new ArrayList();
+		return trustedCertificates;
+	}
+
+	/**
+	 * @see IVerifier#setParent(IVerifier)
+	 */
+	public void setParent(IVerifier parentVerifier) {
+		super.setParent(parentVerifier);
+		initialize();
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeyStores.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeyStores.java
new file mode 100644
index 0000000..9907ca6
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeyStores.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.security;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.connection.ConnectionFactory;
+/**
+ * Class to manage the different KeyStores we should
+ * check for certificates of Signed JAR
+ */
+public class KeyStores {
+
+
+	/**
+	 * java.policy files properties of the java.security file
+	 */
+	private static final String JAVA_POLICY_URL = "policy.url."; //$NON-NLS-1$
+
+	/**
+	 * Default keystore type in java.security file
+	 */	
+    private static final String DEFAULT_KEYSTORE_TYPE = "keystore.type"; //$NON-NLS-1$
+
+	/**
+	 * List of KeystoreHandle pointing of valid KeyStores
+	 * the URL of the KeystoreHandle is not tested yet...
+	 */
+	private List /* of KeystoreHandle */ listOfKeyStores;
+
+	/**
+	 * Iterator
+	 */
+	private Iterator iterator;
+	/**
+	 * KeyStores constructor comment.
+	 */
+	public KeyStores() {
+		super();
+		initializeDefaultKeyStores();
+	}
+	/**
+	 * 
+	 */
+	private Iterator getIterator() {
+		if (iterator == null)
+			iterator = listOfKeyStores.iterator();
+		return iterator;
+	}
+	/**
+	 * returns trus if there is more Keystores in the list
+	 */
+	public boolean hasNext() {
+		return getIterator().hasNext();
+	}
+	/**
+	 * populate the list of Keystores
+	 * should be done with Dialog with Cancel/Skip button if
+	 * the connection to the URL is down...
+	 */
+	private void initializeDefaultKeyStores() {
+
+		listOfKeyStores = new ArrayList(5);
+
+		// get JRE cacerts
+		try {
+			URL url = new URL("file", null, 0, System.getProperty("java.home") + File.separator + "lib" + File.separator + "security" + File.separator + "cacerts");  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+			listOfKeyStores.add(new KeystoreHandle(url,Security.getProperty(DEFAULT_KEYSTORE_TYPE)));
+		}
+		catch (MalformedURLException e) {
+			// should not happen, hardcoded...
+		}
+
+		// get java.home .keystore
+		try {
+			URL url = new URL("file", null, 0, System.getProperty("user.home") + File.separator + ".keystore"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			listOfKeyStores.add(new KeystoreHandle(url,Security.getProperty(DEFAULT_KEYSTORE_TYPE)));
+		}
+		catch (MalformedURLException e) {
+			// should not happen, hardcoded...
+		}
+
+		// get KeyStores from policy files...
+		int index = 1;
+		String java_policy = Security.getProperty(JAVA_POLICY_URL+index);
+		while (java_policy!=null){
+			// retrieve keystore url from java.policy
+			// also retrieve keystore type
+			KeystoreHandle keystore = getKeystoreFromLocation(java_policy);
+			if (keystore!=null){
+				listOfKeyStores.add(keystore);
+			}
+			index++;	
+			java_policy = Security.getProperty(JAVA_POLICY_URL+index);			
+		}
+
+	}
+	/**
+	 * returns the URL for the Next KeystoreHandle
+	 */
+	public KeystoreHandle next() {
+		return (KeystoreHandle) getIterator().next();
+	}
+	
+	/**
+	 * retrieve the keystore from java.policy file
+	 */
+	private KeystoreHandle getKeystoreFromLocation(String location){
+		
+		InputStream in = null;
+		char[] buff = new char[4096];
+		
+		
+		int indexOf$ = location.indexOf("${"); //$NON-NLS-1$
+		int indexOfCurly = location.indexOf('}',indexOf$);
+		if (indexOf$!=-1 && indexOfCurly!=-1){
+			String prop = System.getProperty(location.substring(indexOf$+2,indexOfCurly));
+			String location2 = location.substring(0,indexOf$);
+			location2 += prop;
+			location2 += location.substring(indexOfCurly+1);
+			location = location2;
+		}
+		
+		
+		try {
+			URL url = new URL(location);
+			in = ConnectionFactory.get(url).getInputStream();
+			Reader reader = new InputStreamReader(in);
+			int result = reader.read(buff);
+			StringBuffer contentBuff = new StringBuffer();
+			while (result!=-1){
+				contentBuff.append(buff,0,result);
+				result = reader.read(buff);				
+			}
+
+			if (contentBuff.length()>0){			
+				String content = new String(contentBuff);
+				int indexOfKeystore = content.indexOf("keystore"); //$NON-NLS-1$
+				if (indexOfKeystore != -1){
+					int indexOfSemiColumn = content.indexOf(';',indexOfKeystore);
+					return getKeystoreFromString(content.substring(indexOfKeystore,indexOfSemiColumn),url);
+				}
+			}
+		} catch (MalformedURLException e){
+			log(e);
+		} catch (IOException e){
+			// url.openStream, reader.read (x2)
+			// only log, the keystore may not exist
+			log(e);	
+		} finally {
+			if (in!=null){
+				try {
+					in.close();
+				} catch (IOException e){}
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * retrieve the keystore from java.policy file
+	 */
+	private KeystoreHandle getKeystoreFromString(String content,URL rootURL){
+		KeystoreHandle handle = null;
+		String keyStoreType = Security.getProperty(DEFAULT_KEYSTORE_TYPE);
+		
+		
+		int indexOfSpace = content.indexOf(' ');
+		if (indexOfSpace==-1) return null;
+		
+		int secondSpace = content.lastIndexOf(',');
+		if (secondSpace==-1) {
+			secondSpace = content.length();
+		} else {
+			keyStoreType = content.substring(secondSpace+1,content.length()).trim();
+		}
+		
+		URL url = null;
+		try {
+			url = new URL(content.substring(indexOfSpace,secondSpace));
+		} catch (MalformedURLException e){
+			log(e);
+			// the url maybe relative
+			try {
+			url = new URL(rootURL,content.substring(indexOfSpace,secondSpace));				
+			} catch (MalformedURLException e1){
+				log(e1);			
+			}
+		}
+
+		if (url!=null)
+			handle = new KeystoreHandle(url,keyStoreType);				
+			
+		return handle;
+	}	
+	
+	private void log(Exception e){
+		UpdateCore.warn("Cannot retrieve a KeyStore",e); //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeystoreHandle.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeystoreHandle.java
new file mode 100644
index 0000000..d1a7b29
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/security/KeystoreHandle.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.security;
+
+import java.net.*;
+
+
+ 
+/**
+ * Manages a handle to a keystore
+ */
+public class KeystoreHandle {
+	
+	private URL location;
+	private String type;
+	
+	public KeystoreHandle(URL url, String type){
+		this.location = url;
+		this.type = type;
+	}
+
+	/**
+	 * Gets the location.
+	 * @return Returns a URL
+	 */
+	public URL getLocation() {
+		return location;
+	}
+
+	/**
+	 * Sets the location.
+	 * @param location The location to set
+	 */
+	public void setLocation(URL location) {
+		this.location = location;
+	}
+
+	/**
+	 * Gets the type.
+	 * @return Returns a String
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * Sets the type.
+	 * @param type The type to set
+	 */
+	public void setType(String type) {
+		this.type = type;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/verifier/CertVerificationResult.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/verifier/CertVerificationResult.java
new file mode 100644
index 0000000..d8c3b9e
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/verifier/CertVerificationResult.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.verifier;
+
+import java.security.Principal;
+import java.security.cert.*;
+import java.text.DateFormat;
+import java.util.Date;
+import org.eclipse.osgi.signedcontent.SignedContent;
+import org.eclipse.osgi.signedcontent.SignerInfo;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.Messages;
+
+/**
+ * Result of the service
+ */
+public class CertVerificationResult implements IVerificationResult {
+
+
+	private int resultCode;
+	private int verificationCode;
+	private Exception resultException;
+
+	private SignedContent signedContent;
+	private String signerInfo;
+	private String verifierInfo;
+	private ContentReference contentReference;
+	private IFeature feature;
+	private boolean featureVerification;
+	private boolean alreadySeen;
+
+	public CertVerificationResult() {
+	}
+	
+	/*
+	 * 
+	 */
+	public int getResultCode() {
+		return resultCode;
+	}
+	
+	/*
+	 * 
+	 */
+	public Exception getVerificationException() {
+		return resultException;
+	}
+	
+	/*
+	 * 
+	 */
+	public void setResultCode(int newResultCode) {
+		resultCode = newResultCode;
+	}
+	
+	/*
+	 * 
+	 */
+	public void setResultException(Exception newResultException) {
+		resultException = newResultException;
+	}
+	
+	/*
+	 * 
+	 */
+	public int getVerificationCode() {
+		return verificationCode;
+	}
+
+	/*
+	 * 
+	 */
+	public void setVerificationCode(int verificationCode) {
+		this.verificationCode = verificationCode;
+	}
+
+	void setSignedContent(SignedContent signedContent) {
+		this.signedContent = signedContent;
+	}
+
+	public SignerInfo[] getSigners() {
+		return signedContent.getSignerInfos();
+	}
+
+	/*
+	 * Initializes the signerInfo and the VerifierInfo from the Certificate Pair
+	 */
+	private void initializeCertificates(){
+		X509Certificate certRoot = null;
+		X509Certificate certIssuer = null;
+		SignerInfo trustedSigner;
+		SignerInfo[] signers = getSigners();
+		if (signers.length == 0)
+			return;
+		trustedSigner = signers[0];
+		for (int i = 0; i < signers.length; i++) {
+			if (signers[i].isTrusted()) {
+				trustedSigner = signers[i];
+				break;
+			}
+		}
+		Certificate[] certs = trustedSigner.getCertificateChain();
+		if (certs == null || certs.length == 0)
+			return;
+		certRoot = (X509Certificate) certs[certs.length - 1];
+		certIssuer = (X509Certificate) certs[0];
+
+		StringBuffer strb = new StringBuffer();
+		strb.append(issuerString(certIssuer.getSubjectDN()));
+		strb.append("\r\n"); //$NON-NLS-1$
+		strb.append(NLS.bind(Messages.JarVerificationResult_ValidBetween, (new String[] { dateString(certIssuer.getNotBefore()), dateString(certIssuer.getNotAfter()) })));
+		strb.append(checkValidity(trustedSigner));
+		signerInfo = strb.toString();
+		if (certIssuer != null && !certIssuer.equals(certRoot)) {
+			strb = new StringBuffer();	
+			strb.append(issuerString(certIssuer.getIssuerDN()));
+			strb.append("\r\n"); //$NON-NLS-1$
+			strb.append(NLS.bind(Messages.JarVerificationResult_ValidBetween, (new String[] { dateString(certRoot.getNotBefore()), dateString(certRoot.getNotAfter()) }))); 
+			verifierInfo = strb.toString();
+		}
+
+	}
+
+	/*
+	 * Returns a String to show if the certificate is valid
+	 */
+	private String checkValidity(SignerInfo signer) {
+
+		try {
+			signedContent.checkValidity(signer);
+		} catch (CertificateExpiredException e) {
+			return ("\r\n" + Messages.JarVerificationResult_ExpiredCertificate);  //$NON-NLS-1$
+		} catch (CertificateNotYetValidException e) {
+			return ("\r\n" + Messages.JarVerificationResult_CertificateNotYetValid);  //$NON-NLS-1$
+		}
+		return ("\r\n" + Messages.JarVerificationResult_CertificateValid);  //$NON-NLS-1$
+	}
+
+	/*
+	 * Returns the label String from a X50name
+	 */
+	private String issuerString(Principal principal) {
+// 19902
+//		try {
+//			if (principal instanceof X500Name) {
+//				StringBuffer buf = new StringBuffer();
+//				X500Name name = (X500Name) principal;
+//				buf.append((name.getDNQualifier() != null) ? name.getDNQualifier() + ", " : "");
+//				buf.append(name.getCommonName());
+//				buf.append((name.getOrganizationalUnit() != null) ? ", " + name.getOrganizationalUnit() : "");
+//				buf.append((name.getOrganization() != null) ? ", " + name.getOrganization() : "");
+//				buf.append((name.getLocality() != null) ? ", " + name.getLocality() : "");
+//				buf.append((name.getCountry() != null) ? ", " + name.getCountry() : "");
+//				return new String(buf);
+//			}
+//		} catch (Exception e) {
+//			UpdateCore.warn("Error parsing X500 Certificate",e);
+//		}
+		return principal.toString();
+	}
+
+	/*
+	 * 
+	 */
+	private String dateString(Date date) {
+		return DateFormat.getDateInstance().format(date);
+	}
+
+	/*
+	 *
+	 */
+	public String getSignerInfo() {
+		if (signerInfo==null) initializeCertificates();
+		return signerInfo;
+	}
+
+	/*
+	 *
+	 */
+	public String getVerifierInfo() {
+		if (signerInfo==null) initializeCertificates();		
+		return verifierInfo;
+	}
+
+	/*
+	 *
+	 */
+	public ContentReference getContentReference() {
+		return contentReference;
+	}
+
+	/*
+	 * 
+	 */
+	public void setContentReference(ContentReference ref) {
+		this.contentReference = ref;
+	}
+
+
+	/*
+	 *
+	 */
+	public IFeature getFeature() {
+		return feature;
+	}
+
+	/*
+	 * 
+	 */
+	public void setFeature(IFeature feature) {
+		this.feature = feature;
+	}
+
+	/*
+	 * 
+	 */
+	public String getText() {
+		return null;
+	}
+
+
+	/*
+	 * 
+	 */
+	public boolean isFeatureVerification() {
+		return featureVerification;
+	}
+	
+	/*
+	 * 
+	 */
+	public void isFeatureVerification(boolean featureVerification) {
+		this.featureVerification = featureVerification;
+	}
+
+	/*
+	 *
+	 */
+	public boolean alreadySeen() {
+		return alreadySeen;
+	}
+
+	/*
+	 * 
+	 */
+	public boolean alreadySeen(boolean seen) {
+		return this.alreadySeen = seen;
+	}
+
+}
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/verifier/CertVerifier.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/verifier/CertVerifier.java
new file mode 100644
index 0000000..50c8440
--- /dev/null
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/verifier/CertVerifier.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.verifier;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.jar.JarFile;
+import java.util.zip.ZipException;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.osgi.signedcontent.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.core.UpdateCore;
+
+/**
+ * The JarVerifier will check the integrity of the JAR.
+ * If the Jar is signed and the integrity is validated,
+ * it will check if one of the certificate of each file
+ * is in one of the keystore.
+ *
+ */
+
+public class CertVerifier extends Verifier {
+
+	private CertVerificationResult result;
+	private boolean acceptUnsignedFiles;
+	private IProgressMonitor monitor;
+	private File jarFile;
+	private SignedContentFactory factory;
+	private List trustedSignerInfos;
+
+	/*
+	 * Default Constructor
+	 */
+	public CertVerifier(SignedContentFactory factory) {
+		this.factory = factory;
+		initialize();
+	}
+
+
+	/*
+	 * 
+	 */
+	private void initialize() {
+		result = null;
+		acceptUnsignedFiles = false;
+	}
+
+	/*
+	 * init
+	 */
+	private void init(IFeature feature, ContentReference contentRef) throws CoreException {
+		jarFile = null;
+		if (contentRef instanceof JarContentReference) {
+			JarContentReference jarReference = (JarContentReference) contentRef;
+			try {
+				jarFile = jarReference.asFile();
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_INSTALL)
+					UpdateCore.debug("Attempting to read JAR file:"+jarFile); //$NON-NLS-1$
+			
+				// # of entries
+				if (!jarFile.exists()) throw new IOException();
+				JarFile jar = new JarFile(jarFile);
+				if (jar !=null){
+					try {
+						jar.close();
+					} catch (IOException ex) {
+						// unchecked
+					}
+				}
+			} catch (ZipException e){
+				throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_InvalidJar, (new String[] { jarReference.toString() })), e);				
+			} catch (IOException e) {
+				throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_UnableToAccessJar, (new String[] { jarReference.toString() })), e);
+			}
+		}
+
+		result = new CertVerificationResult();
+		result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR);
+		result.setResultException(null);
+		result.setFeature(feature);
+		result.setContentReference(contentRef);
+	}
+
+	/*
+	 * @param newMonitor org.eclipse.core.runtime.IProgressMonitor
+	 */
+	private void setMonitor(IProgressMonitor newMonitor) {
+		monitor = newMonitor;
+	}
+
+	/*
+	 * @see IVerifier#verify(IFeature,ContentReference,boolean, InstallMonitor)
+	 */
+	public IVerificationResult verify(
+		IFeature feature,
+		ContentReference reference,
+		boolean isFeatureVerification,
+		InstallMonitor monitor)
+		throws CoreException {
+
+		if (reference == null)
+			return result;
+
+		// if parent knows how to verify, ask the parent first
+		if (getParent() != null) {
+			IVerificationResult vr =
+				getParent().verify(feature, reference, isFeatureVerification, monitor);
+			if (vr.getVerificationCode() != IVerificationResult.TYPE_ENTRY_UNRECOGNIZED)
+				return vr;
+		}
+
+		// the parent couldn't verify
+		setMonitor(monitor);
+		init(feature, reference);
+		result.isFeatureVerification(isFeatureVerification);
+
+		if (jarFile!=null) {
+			result = verify(jarFile.getAbsolutePath(), reference.getIdentifier());
+		} else {
+			result.setVerificationCode(IVerificationResult.TYPE_ENTRY_UNRECOGNIZED);
+		}
+
+		return result;
+	}
+
+	/*
+	 * 
+	 */
+	private CertVerificationResult verify(String file, String identifier) {
+
+		try {
+			SignedContent verifier = factory.getSignedContent(new File(file));
+			// verify integrity
+			verifyIntegrity(verifier, identifier);
+
+			//if user already said yes
+			result.alreadySeen(alreadyValidated());
+
+			// save the fact the file is not signed, so the user will not be prompted again 
+			if (result.getVerificationCode()
+				== IVerificationResult.TYPE_ENTRY_NOT_SIGNED) {
+				acceptUnsignedFiles = true;
+			}
+
+		} catch (Exception e) {
+			result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR);
+			result.setResultException(e);
+		}
+
+		if (monitor != null) {
+			monitor.worked(1);
+			if (monitor.isCanceled()) {
+				result.setVerificationCode(IVerificationResult.VERIFICATION_CANCELLED);
+			}
+		}
+
+		return result;
+	}
+
+	/*
+	 * Verifies the integrity of the JAR
+	 */
+	private void verifyIntegrity(SignedContent verifier, String identifier) {
+		try {
+			if (verifier.isSigned()) {
+				// If the JAR is signed and invalid then mark as corrupted
+				if (hasValidContent(verifier.getSignedEntries())) {
+					result.setSignedContent(verifier);
+					SignerInfo[] signers = verifier.getSignerInfos();
+					for (int i = 0; i < signers.length; i++)
+						if (signers[i].isTrusted()) {
+							result.setVerificationCode(IVerificationResult.TYPE_ENTRY_SIGNED_RECOGNIZED);
+							break;
+						}
+					if (result.getVerificationCode() != IVerificationResult.TYPE_ENTRY_SIGNED_RECOGNIZED)
+						result.setVerificationCode(IVerificationResult.TYPE_ENTRY_SIGNED_UNRECOGNIZED);
+				} else
+					result.setVerificationCode(IVerificationResult.TYPE_ENTRY_CORRUPTED);
+			} else {
+				result.setVerificationCode(IVerificationResult.TYPE_ENTRY_NOT_SIGNED);
+				return;
+			}
+		} catch (Exception e) {
+			result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR);
+			result.setResultException(e);
+		}
+	}
+
+	private boolean hasValidContent(SignedContentEntry[] signedEntries) {
+		try {
+			for (int i = 0; i < signedEntries.length; i++)
+				signedEntries[i].verify();
+		} catch (InvalidContentException e) {
+			return false;
+		} catch (IOException e) {
+			return false;
+		}
+		return true;
+	}
+
+
+	/*
+	 * 
+	 */
+	private boolean alreadyValidated() {
+		int verifyCode = result.getVerificationCode();
+		if (verifyCode == IVerificationResult.TYPE_ENTRY_NOT_SIGNED)
+			return (acceptUnsignedFiles);
+		if (verifyCode == IVerificationResult.UNKNOWN_ERROR)
+			return false;
+		if (result.getSigners() != null) { //getTrustedCertificates() can't be null as it is lazy initialized
+			Iterator iter = getTrustedInfos().iterator();
+			SignerInfo[] signers = result.getSigners();
+
+			// check if this is not a user accepted certificate for this feature	
+			while (iter.hasNext()) {
+				SignerInfo chain = (SignerInfo) iter.next();
+				for (int i = 0; i < signers.length; i++)
+					if (chain.equals(signers[i]))
+						return true;
+			}
+
+			// if certificate pair not found in trusted add it for next time
+			for (int i = 0; i < signers.length; i++) {
+				addTrustedSignerInfo(signers[i]);
+			}
+		}
+
+		return false;
+	}
+
+	/*
+	 * 
+	 */
+	private void addTrustedSignerInfo(SignerInfo signer) {
+		if (trustedSignerInfos == null)
+			trustedSignerInfos = new ArrayList();
+		if (signer != null)
+			trustedSignerInfos.add(signer);
+	}
+
+	/*
+	 * 
+	 */
+	private List getTrustedInfos() {
+		if (trustedSignerInfos == null)
+			trustedSignerInfos = new ArrayList();
+		return trustedSignerInfos;
+	}
+
+	/**
+	 * @see IVerifier#setParent(IVerifier)
+	 */
+	public void setParent(IVerifier parentVerifier) {
+		super.setParent(parentVerifier);
+		initialize();
+	}
+
+}
diff --git a/update/org.eclipse.update.examples/.classpath b/update/org.eclipse.update.examples/.classpath
new file mode 100644
index 0000000..0a91e8e
--- /dev/null
+++ b/update/org.eclipse.update.examples/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src/"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/update/org.eclipse.update.examples/.cvsignore b/update/org.eclipse.update.examples/.cvsignore
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/update/org.eclipse.update.examples/.cvsignore
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/update/org.eclipse.update.examples/.project b/update/org.eclipse.update.examples/.project
new file mode 100644
index 0000000..39cb54a
--- /dev/null
+++ b/update/org.eclipse.update.examples/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.update.examples</name>

+	<comment></comment>

+	<projects>

+		<project>org.apache.xerces</project>

+		<project>org.eclipse.core.boot</project>

+		<project>org.eclipse.core.runtime</project>

+		<project>org.eclipse.update.core</project>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ui.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ui.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+		<nature>org.eclipse.pde.ui.PluginNature</nature>

+		<nature>org.eclipse.team.cvs.core.cvsnature</nature>

+	</natures>

+</projectDescription>

diff --git a/update/org.eclipse.update.examples/.settings/org.eclipse.jdt.core.prefs b/update/org.eclipse.update.examples/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..5b49ff9
--- /dev/null
+++ b/update/org.eclipse.update.examples/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,64 @@
+#Wed Feb 11 13:02:57 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=ignore
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
diff --git a/update/org.eclipse.update.examples/META-INF/MANIFEST.MF b/update/org.eclipse.update.examples/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..0b39425
--- /dev/null
+++ b/update/org.eclipse.update.examples/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %name
+Bundle-SymbolicName: org.eclipse.update.examples; singleton:=true
+Bundle-Version: 2.0.0
+Bundle-ClassPath: updateexamples.jar
+Bundle-Activator: org.eclipse.core.internal.compatibility.PluginActivator
+Bundle-Vendor: %provider-name
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.core.runtime.compatibility,
+ org.eclipse.update.core,
+ org.eclipse.core.runtime;bundle-version="2.1"
+Bundle-ActivationPolicy: lazy
diff --git a/update/org.eclipse.update.examples/Scrapbook2.jpage b/update/org.eclipse.update.examples/Scrapbook2.jpage
new file mode 100644
index 0000000..b5da99a
--- /dev/null
+++ b/update/org.eclipse.update.examples/Scrapbook2.jpage
@@ -0,0 +1,111 @@
+SiteManager.getSite(URL)throws CoreException

+  String type = getTypeForprotocol(URL.getprotocol);

+  try {

+    if (type != null){

+	attemptCreationSite(type,URL);

+    } else {

+	attemptCreationSite("http",URL);

+    }

+  } catch (CoreException e){

+    throw new CoreException("Cannot create site",e.getMessage());

+  }

+

+SiteManager.attemptCreationSite(type,URL)throws CoreException

+  try {

+    createSite(type,URL);

+  } catch (InvalidTypeException e){

+    try {

+      createSite(e.getRealType(),URL);

+    } catch (InvalidSiteExeption e){

+      throw new CoreException("Wrong site type");

+    }

+  }

+

+SiteManager.createSite(type,URL) throws CoreExeption, InvalidSiteTypeException

+

+

+try {

+			

+	factory.createSite(url, forceCreation);

+	

+} catch (IOException e) {

+	// if the URL is pointing to either a file 

+// or a directory, without reference			

+if (url.getRef() != null) {

+	// 4 nothing we can do

+	throw newCoreException("Error accessing url:"+url.toExternalForm()+"\r\n"+e.getMessage(),e);

+} else if (url.getFile().endsWith("/")) {

+	// 1 try to add site.xml

+	try {

+		url = new URL(url,Site.SITE_XML);

+	} catch (MalformedURLException e1){

+		throw newCoreException("Cannot create URL:"+url.toExternalForm()+"+"+Site.SITE_XML,e1);

+	}

+	try {

+		site = factory.createSite(url, forceCreation);

+	} catch (ParsingException e1){

+		throw newCoreException("Error parsing URL:"+url.toExternalForm()+"\r\n"+e1.getMessage(),e1);					

+	} catch (IOException e1){

+		throw newCoreException("Error accessing url:"+url.toExternalForm()+"\r\n"+e1.getMessage(),e1);					

+	}

+} else if (url.getFile().endsWith(Site.SITE_XML)) {

+	// 3 nothing we can do

+	throw newCoreException("Error accessing url:"+url.toExternalForm()+"\r\n"+e.getMessage(),e);

+} else {

+	// 2 try to add /site.xml

+	try {

+		url = new URL(url.getProtocol(),url.getHost(), url.getPort(), url.getFile()+"/"+Site.SITE_XML);

+	} catch (MalformedURLException e1){

+		throw newCoreException("Cannot create URL:"+url.toExternalForm()+"+"+Site.SITE_XML,e1);

+	}

+	

+	try {

+		site = factory.createSite(url, forceCreation);

+	} catch (ParsingException e1){

+		throw newCoreException("Error parsing URL:"+url.toExternalForm()+"\r\n"+e1.getMessage()+"\r\nPrevious Input/Output Error:"+e.getMessage(),e1);					

+	} catch (IOException e1){

+		throw newCoreException("Error accessing url:"+url.toExternalForm()+"\r\n"+e1.getMessage()+"\r\nPrevious Input/Output Error:"+e.getMessage(),e1);					

+				}				

+			}

+

+		} catch (ParsingException e) {

+			

+			// if the URL is pointing to either a file 

+// or a directory, without reference			

+if (url.getRef() != null) {

+	// 4 nothing we can do

+	throw newCoreException("Error parsing URL:"+url.toExternalForm()+"\r\n"+e.getMessage(),e);

+} else if (url.getFile().endsWith("/")) {

+	// 1 try to add site.xml

+	try {

+		url = new URL(url,Site.SITE_XML);

+	} catch (MalformedURLException e1){

+		throw newCoreException("Cannot create URL:"+url.toExternalForm()+"+"+Site.SITE_XML,e1);

+	}

+	try {

+		site = factory.createSite(url, forceCreation);

+	} catch (ParsingException e1){

+		throw newCoreException("Error parsing URL:"+url.toExternalForm()+"\r\n"+e1.getMessage(),e1);					

+	} catch (IOException e1){

+		throw newCoreException("Error accessing url:"+url.toExternalForm()+"\r\n"+e1.getMessage(),e1);

+				}				

+

+			} else if (url.getFile().endsWith(Site.SITE_XML)) {

+				// 3 nothing we can do

+	throw newCoreException("Error parsing URL:"+url.toExternalForm()+"\r\n"+e.getMessage(),e);					

+} else {

+	// 2 try to add /site.xml

+	

+	try {

+		url = new URL(url.getProtocol(),url.getHost(), url.getPort(), url.getFile()+"/"+Site.SITE_XML);

+	} catch (MalformedURLException e1){

+		throw newCoreException("Cannot create URL:"+url.toExternalForm()+"+"+Site.SITE_XML,e1);

+	}

+	try {

+		site = factory.createSite(url, forceCreation);

+	} catch (ParsingException e1){

+		throw newCoreException("Error parsing URL:"+url.toExternalForm()+"\r\n"+e1.getMessage()+"\r\nPrevious Parsing error:"+e.getMessage(),e1);					

+	} catch (IOException e1){

+		throw newCoreException("Error accessing url:"+url.toExternalForm()+"\r\n"+e1.getMessage()+"\r\nPrevious Parsing error:"+e.getMessage(),e1);

+	

+

diff --git a/update/org.eclipse.update.examples/about.html b/update/org.eclipse.update.examples/about.html
new file mode 100644
index 0000000..768324e
--- /dev/null
+++ b/update/org.eclipse.update.examples/about.html
@@ -0,0 +1,42 @@
+<html>

+<head>

+<title>About</title>

+<style type="text/css">

+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}

+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}

+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}

+code { font-family: "Courier New", Courier, mono; font-size: 10pt}

+sup { font-family: arial,helvetica,geneva; font-size: 10px}

+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}

+li { font-family: arial, helvetica, geneva; font-size: 10pt}

+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}

+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect(   ); margin-top: 5mm; margin-left: 3mm}

+</style>

+</head>

+<body lang="EN-US" link="blue" vlink="purple">

+<table border="0" cellspacing="5" cellpadding="2" width="100%" >

+  <tr> 

+    <td align="LEFT" valign="TOP" colspan="2" bgcolor="#0080C0"><b><font color="#FFFFFF">About This Content</font></b></td>

+  </tr>

+  <tr> 

+    <td> 

+<p>11th December, 2001</p>	

+<h3>License</h3>

+<p>Eclipse.org 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

+<a href="http://www.eclipse.org/legal/cpl-v05.html">Common Public License Version 0.5</a> &quot;CPL&quot;.  For purposes of the CPL, &quot;Program&quot; will mean the Content.</p>

+

+<h3>Contributions</h3>

+

+<p>If this Content is licensed to you under the terms and conditions of the CPL, any Contributions, as defined in the CPL, uploaded, submitted, or otherwise

+made available to Eclipse.org, members of Eclipse.org and/or the host of Eclipse.org web site, by you that relate to such

+Content are provided under the terms and conditions of the CPL and can be made available to others under the terms of the CPL.</p>

+

+<p>If this Content is licensed to you under license terms and conditions other than the CPL &quot;Other License&quot;, any modifications, enhancements and/or

+other code and/or documentation &quot;Modifications&quot; uploaded, submitted, or otherwise made available to Eclipse.org, members of Eclipse.org and/or the

+host of Eclipse.org, by you that relate to such Content are provided under terms and conditions of the Other License and can be made available

+to others under the terms of the Other License.  In addition, with regard to Modifications for which you are the copyright holder, you are also

+providing the Modifications under the terms and conditions of the CPL and such Modifications can be made available to others under the terms of

+the CPL.</p>

+</td></tr></table>

+</body>

+</html>
\ No newline at end of file
diff --git a/update/org.eclipse.update.examples/build.properties b/update/org.eclipse.update.examples/build.properties
new file mode 100644
index 0000000..af5e2aa
--- /dev/null
+++ b/update/org.eclipse.update.examples/build.properties
@@ -0,0 +1,17 @@
+###############################################################################

+# Copyright (c) 2009 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

+###############################################################################

+source.updateexamplescore.jar = src/

+src.includes=about.html

+bin.includes = plugin.xml,\

+               plugin.properties,\

+               *.jar,\

+               about.html,\

+               META-INF/

diff --git a/update/org.eclipse.update.examples/plugin.properties b/update/org.eclipse.update.examples/plugin.properties
new file mode 100644
index 0000000..b935be4
--- /dev/null
+++ b/update/org.eclipse.update.examples/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################

+# Copyright (c) 2009 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

+###############################################################################

+

+name = Install/Update BuildZip Example

+provider-name = Eclipse.org
\ No newline at end of file
diff --git a/update/org.eclipse.update.examples/plugin.xml b/update/org.eclipse.update.examples/plugin.xml
new file mode 100644
index 0000000..f188318
--- /dev/null
+++ b/update/org.eclipse.update.examples/plugin.xml
Binary files differ
diff --git a/update/org.eclipse.update.examples/site/features/com.reddot.reddot_1.0.0.jar b/update/org.eclipse.update.examples/site/features/com.reddot.reddot_1.0.0.jar
new file mode 100644
index 0000000..06507a7
--- /dev/null
+++ b/update/org.eclipse.update.examples/site/features/com.reddot.reddot_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.examples/site/features/com.reddot.reddot_2.0.0.jar b/update/org.eclipse.update.examples/site/features/com.reddot.reddot_2.0.0.jar
new file mode 100644
index 0000000..7236815
--- /dev/null
+++ b/update/org.eclipse.update.examples/site/features/com.reddot.reddot_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.examples/site/info/images/redDot.jpg b/update/org.eclipse.update.examples/site/info/images/redDot.jpg
new file mode 100644
index 0000000..f0fb5c3
--- /dev/null
+++ b/update/org.eclipse.update.examples/site/info/images/redDot.jpg
Binary files differ
diff --git a/update/org.eclipse.update.examples/site/plugins/com.reddot.reddot_1.0.0.jar b/update/org.eclipse.update.examples/site/plugins/com.reddot.reddot_1.0.0.jar
new file mode 100644
index 0000000..c88b793
--- /dev/null
+++ b/update/org.eclipse.update.examples/site/plugins/com.reddot.reddot_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.examples/site/plugins/com.reddot.reddot_2.0.0.jar b/update/org.eclipse.update.examples/site/plugins/com.reddot.reddot_2.0.0.jar
new file mode 100644
index 0000000..da31ad3
--- /dev/null
+++ b/update/org.eclipse.update.examples/site/plugins/com.reddot.reddot_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.examples/site/site.xml b/update/org.eclipse.update.examples/site/site.xml
new file mode 100644
index 0000000..35c858b
--- /dev/null
+++ b/update/org.eclipse.update.examples/site/site.xml
Binary files differ
diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipConverter.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipConverter.java
new file mode 100644
index 0000000..0ed4a75
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipConverter.java
@@ -0,0 +1,162 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2002 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

+ *******************************************************************************/

+package org.eclipse.update.examples.buildzip;

+

+import java.io.File;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.StringBufferInputStream;

+import java.net.URL;

+import java.util.Properties;

+import java.util.jar.JarEntry;

+import java.util.jar.JarOutputStream;

+

+import org.eclipse.update.core.*;

+import org.eclipse.update.core.ContentReference;

+import org.eclipse.update.core.IFeature;

+import org.eclipse.update.core.IFeatureContentProvider;

+import org.eclipse.update.core.IPluginEntry;

+import org.eclipse.update.core.JarContentReference;

+import org.eclipse.update.core.model.InstallAbortedException;

+

+/**

+ * Converts eclipse build .zip files into packaged feature

+ */

+public class BuildZipConverter {

+

+	public static void main(String[] args) {

+		if (args.length <=0) {

+			System.out.println("Usage:     BuildZipConverter <path to the zip file>.\r\nExample: BuildZipConverter d:/download/integration-eclipse-SDK-20020109-win32.zip");

+			return;

+		}

+		try {

+			URL buildzip = new URL(("file:"+args[0]).replace(File.separatorChar, '/'));

+			BuildZipFeatureFactory factory = new BuildZipFeatureFactory();

+			IFeature feature = factory.createFeature(buildzip, null);

+			IFeatureContentProvider provider = feature.getFeatureContentProvider();

+			

+			ContentReference[] refs = provider.getFeatureEntryContentReferences(null);

+			

+			File site = new File((args[0]+".packaged/").replace('/',File.separatorChar));

+			site.mkdirs();

+			File featuresDir = new File(site,"features");

+			featuresDir.mkdirs();

+			File pluginsDir = new File(site, "plugins");

+			pluginsDir.mkdirs();

+			

+			File jarFile = new File(featuresDir,feature.getVersionedIdentifier()+".jar");

+			System.out.println("writing feature archive: "+feature.getVersionedIdentifier()+".jar");

+			writeJar(jarFile, refs, feature, null, null);

+			JarContentReference jar = new JarContentReference("build.zip",buildzip);

+			Properties manifest = getBuildManifest(jar);

+			

+			IPluginEntry[] plugins = feature.getPluginEntries();

+			for (int i=0; i<plugins.length; i++) {

+				refs = provider.getPluginEntryContentReferences(plugins[i], null);

+				jarFile = new File(pluginsDir,plugins[i].getVersionedIdentifier()+".jar");

+				System.out.println("writing plugin archive: "+plugins[i].getVersionedIdentifier()+".jar");

+				writeJar(jarFile, refs, feature, plugins[i].getVersionedIdentifier().getIdentifier(), manifest);

+			}

+			

+			writeSiteManifest(site, feature);

+		} catch(Exception e) {

+			e.printStackTrace();

+		}

+	}

+	

+	public static void writeJar(File jarFile,ContentReference[] refs, IFeature feature, String pluginId, Properties manifest) {

+			

+		JarOutputStream jos = null;

+		FileOutputStream os = null;

+		InputStream is = null;

+		

+		try {

+			os = new FileOutputStream(jarFile);

+			jos = new JarOutputStream(os);

+			JarEntry entry = null;

+			String buf = null;

+			StringBufferInputStream sbis = null;

+			

+			// write jar manifest (first entry in output stream)

+			buf = "Manifest-Version: 1.0\nCreated-By: 2.0.0 (www.eclipse.org Feature Packager)\n";

+			sbis = new StringBufferInputStream(buf);

+			entry = new JarEntry("META-INF/MANIFEST.MF");

+			jos.putNextEntry(entry);

+			Utilities.copy(sbis,jos,null);

+			sbis.close();

+			

+			// jar up the references

+			for (int i=0; i<refs.length; i++) {

+				String id = refs[i].getIdentifier();

+				entry = new JarEntry(id);

+				jos.putNextEntry(entry);

+				is = refs[i].getInputStream();

+				Utilities.copy(is,jos,null);

+				is.close(); is = null;

+			}

+			

+			// for plugin jars, write build manifest

+			if (pluginId != null && manifest != null) {

+				String key = "plugin@"+pluginId;

+				String value = manifest.getProperty(key);

+				if (value != null) {

+					if (value.equals("HEAD")) {

+						value += "-" + feature.getVersionedIdentifier().getVersion().getMajorComponent();

+					}

+					buf = key + "=" + value;

+					sbis = new StringBufferInputStream(buf);

+					entry = new JarEntry("buildmanifest.properties");

+					jos.putNextEntry(entry);

+					Utilities.copy(sbis,jos,null);

+					sbis.close();

+				}

+			}

+			

+			// close jar

+			jos.close(); jos = null; os = null;

+		} catch(Exception e) {

+			e.printStackTrace();

+		} finally {

+			if (is != null) 

+				try {is.close();} catch(IOException e) {}

+				

+			if (jos != null) 

+				try {jos.close();} catch(IOException e) {}

+			else if (os != null)

+				try {os.close();} catch(IOException e) {}

+		}		

+	}

+	

+	public static void writeSiteManifest(File site, IFeature feature) throws IOException, InstallAbortedException {

+		File manifest = new File(site, "site.xml");

+		FileOutputStream os = new FileOutputStream(manifest);

+		String siteXML = "<site>\n   <feature url=\"features/"+feature.getVersionedIdentifier().toString()+".jar\"/>\n</site>";

+		StringBufferInputStream sbis = new StringBufferInputStream(siteXML);

+		Utilities.copy(sbis,os,null);

+		os.close();

+		sbis.close();

+	}

+	

+	public static Properties getBuildManifest(JarContentReference jar) throws IOException {

+		ContentReference manifestEntry = jar.peek("eclipse/buildmanifest.properties",null/*ContentSelector*/, null/*ProgressMonitor*/);

+		InputStream is = null;

+		Properties props = null;

+		try {

+			props = new Properties();

+			is = manifestEntry.getInputStream();

+			props.load(is);

+		} finally {

+			if (is != null) try{ is.close(); } catch(IOException e) {}

+		}

+		return props;

+	}

+}

diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipFeatureContentProvider.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipFeatureContentProvider.java
new file mode 100644
index 0000000..861dd5a
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipFeatureContentProvider.java
@@ -0,0 +1,261 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2002 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

+ *******************************************************************************/

+package org.eclipse.update.examples.buildzip;

+

+import java.io.File;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.net.URL;

+import java.util.jar.JarEntry;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.update.core.*;

+import org.eclipse.update.core.ContentReference;

+import org.eclipse.update.core.FeatureContentProvider;

+import org.eclipse.update.core.IFeatureContentProvider;

+import org.eclipse.update.core.INonPluginEntry;

+import org.eclipse.update.core.IPluginEntry;

+import org.eclipse.update.core.IVerifier;

+import org.eclipse.update.core.InstallMonitor;

+import org.eclipse.update.core.JarContentReference;

+import org.eclipse.update.core.JarContentReference.ContentSelector;

+import org.eclipse.update.core.model.FeatureModel;

+import org.eclipse.update.core.model.InstallAbortedException;

+

+/**

+ * An example feature content provider. It handles features packaged as

+ * build zip's using the format used for integration and stable builds

+ * posted on the downloads pages at www.eclipse.org

+ * </p>

+ * @since 2.0

+ */

+

+public class BuildZipFeatureContentProvider extends FeatureContentProvider implements IFeatureContentProvider {

+

+	private JarContentReference baseReference;

+	private ContentReference generatedFeatureManifest;	

+	private ContentReference[] featureEntryContentReferences;

+	private IPluginEntry currentPluginEntry;

+	private INonPluginEntry currentNonPluginEntry;

+	

+	public BuildZipFeatureContentProvider(URL base) {

+		super(base);

+		this.baseReference = new JarContentReference("build.zip",base);

+	}

+	

+	/*

+	 * @see IFeatureContentProvider#getFeatureManifest()

+	 */

+	public ContentReference getFeatureManifestReference(InstallMonitor monitor) throws CoreException {

+		if (generatedFeatureManifest == null) {

+			throw newCoreException("Feature manifest is not available",null);

+		}

+		else

+			return generatedFeatureManifest;

+	}

+

+	/*

+	 * @see IFeatureContentProvider#getArchiveReferences()

+	 */

+	public ContentReference[] getArchiveReferences(InstallMonitor monitor) {

+		// the feature and all its plugins files are packaged in a single archive

+		return new ContentReference[] { baseReference };

+	}

+

+	/*

+	 * @see IFeatureContentProvider#getFeatureEntryArchiveReferences()

+	 */

+	public ContentReference[] getFeatureEntryArchiveReferences(InstallMonitor monitor) {

+		// the feature and all its plugins files are packaged in a single archive

+		return new ContentReference[] { baseReference };

+	}

+

+	/*

+	 * @see IFeatureContentProvider#getPluginEntryArchiveReferences(IPluginEntry)

+	 */

+	public ContentReference[] getPluginEntryArchiveReferences(IPluginEntry pluginEntry, InstallMonitor monitor) {

+		// the feature and all its plugins files are packaged in a single archive

+		return new ContentReference[] { baseReference };

+	}

+

+	/*

+	 * @see IFeatureContentProvider#getNonPluginEntryArchiveReferences(INonPluginEntry)

+	 */

+	public ContentReference[] getNonPluginEntryArchiveReferences(INonPluginEntry nonPluginEntry, InstallMonitor monitor) 

+		throws CoreException {

+		try {

+			return peekNonPluginEntryContent(nonPluginEntry,monitor);

+		} catch(IOException e) {

+			throw newCoreException("Unable to return content for non plugin entry "+nonPluginEntry.getIdentifier(),e);

+		}

+	}

+

+	/*

+	 * @see IFeatureContentProvider#getFeatureEntryContentReferences()

+	 */

+	public ContentReference[] getFeatureEntryContentReferences(InstallMonitor monitor) {

+		if (featureEntryContentReferences == null)

+			return new ContentReference[0];

+		else

+			return  featureEntryContentReferences;

+	}

+

+	/*

+	 * @see IFeatureContentProvider#getPluginEntryContentReferences(IPluginEntry)

+	 */

+	public ContentReference[] getPluginEntryContentReferences(IPluginEntry pluginEntry, InstallMonitor monitor)

+		throws CoreException {

+		try {

+			return peekPluginEntryContent(pluginEntry, monitor);

+		} catch(IOException e) {

+			throw newCoreException("Unable to return content for plugin entry "+pluginEntry.getVersionedIdentifier(),e);

+		}

+	}

+	

+	public URL getFeatureBaseURL() throws IOException {

+		return getWorkingDirectory().toURL();

+			

+	}

+

+	ContentReference getFeatureBuildManifest() throws Exception {

+		return baseReference.peek("eclipse/buildmanifest.properties",null/*ContentSelector*/, null/*ProgressMonitor*/);

+	}

+

+	ContentReference getPluginManifest(String pluginId, boolean isFragment) throws Exception {			

+		String manifestName = "eclipse/plugins/" + pluginId + "/" + (isFragment ? "fragment.xml" : "plugin.xml");

+		return baseReference.peek(manifestName, null/*ContentSelector*/, null/*ProgressMonitor*/);

+	}

+	

+	void unpackFeatureEntryContent(FeatureModel feature, InstallMonitor monitor) throws IOException, InstallAbortedException {

+			

+		// define selector for feature entry files

+		ContentSelector selector = new ContentSelector() {

+			public boolean include(JarEntry jarEntry) {

+				if (jarEntry.isDirectory())

+					return false;					

+				String entry = jarEntry.getName();

+				if (entry.startsWith("eclipse/readme/"))

+					return true;

+				else if (entry.startsWith("eclipse/splash/"))

+					return true;

+				else if (entry.startsWith("eclipse/") && entry.indexOf("/",8)==-1 && entry.endsWith(".html"))

+					return true;

+				else

+					return false;	

+			}

+			public String defineIdentifier(JarEntry jarEntry) {

+				String entry = jarEntry.getName();

+				if (entry.startsWith("eclipse/"))

+					return entry.substring(8);

+				else

+					return entry;

+			}

+		};

+		

+		// unpack feature entry files

+		File tmpDir = getWorkingDirectory();

+		ContentReference[] refs = baseReference.unpack(tmpDir, selector, monitor);

+		

+		// write out feature manifest (feature.xml);

+		File manifest = Utilities.createLocalFile(tmpDir,"feature.xml");

+		ContentReference manifestReference = new ContentReference("feature.xml", manifest);

+		DefaultModelWriter w = new DefaultModelWriter(feature);

+		FileOutputStream os = null;

+		try {

+			os = new FileOutputStream(manifest);

+			w.writeFeatureManifest(os);

+		} finally {

+			if (os != null) try { os.close(); } catch(IOException e) {}

+		}

+		this.generatedFeatureManifest = manifestReference;

+		

+		// save references (newly-written feature.xml plus rest of selected feature files)

+		ContentReference[] allRefs = new ContentReference[refs.length+1];

+		allRefs[0] = manifestReference;

+		System.arraycopy(refs,0,allRefs,1,refs.length);

+		featureEntryContentReferences = allRefs;

+	}

+		

+	ContentReference[] peekPluginEntryContent(IPluginEntry plugin, InstallMonitor monitor) throws IOException {

+		

+		// define selector for plugin entry files

+		ContentSelector selector = new ContentSelector() {

+			public boolean include(JarEntry jarEntry) {

+				if (jarEntry.isDirectory())

+					return false;

+				String entry = jarEntry.getName();

+				String id = currentPluginEntry.getVersionedIdentifier().getIdentifier();

+				if (id==null)

+					return false;

+				else if (entry.startsWith("eclipse/plugins/"+id+"/"))

+					return true;

+				else

+					return false;	

+			}

+			public String defineIdentifier(JarEntry jarEntry) {

+				String entry = jarEntry.getName();

+				int ix = entry.indexOf("/",16);

+				if (ix != -1) {

+					return entry.substring(ix+1);

+				} else {

+					return entry;

+				}

+			}

+		};

+		

+		// unpack plugin entry files

+		currentPluginEntry = plugin;

+		return baseReference.peek(selector, monitor);

+	}

+		

+	ContentReference[] peekNonPluginEntryContent(INonPluginEntry data, InstallMonitor monitor) throws IOException {

+		

+		// define selector for non plugin entry files

+		ContentSelector selector = new ContentSelector() {

+			public boolean include(JarEntry jarEntry) {

+				if (jarEntry.isDirectory())

+					return false;

+				String entry = jarEntry.getName();

+				String id = currentNonPluginEntry.getIdentifier();

+				if (!id.equals("root"))

+					return false;

+				else if (!entry.startsWith("eclipse/plugins/"))

+					return true;

+				else

+					return false;	

+			}

+			public String defineIdentifier(JarEntry jarEntry) {

+				String entry = jarEntry.getName();

+				if (entry.startsWith("eclipse/"))

+					return entry.substring(8);

+				else

+					return entry;

+			}

+		};

+		

+		// unpack non plugin entry files

+		currentNonPluginEntry = data;

+		return baseReference.peek(selector, monitor);

+	}

+	

+	private CoreException newCoreException(String s, Throwable e) throws CoreException {

+		return new CoreException(new Status(IStatus.ERROR,"org.eclipse.update.examples",0,s,e));

+	}

+	/*

+	 * @see IFeatureContentProvider#getVerifier()

+	 */

+	public IVerifier getVerifier() throws CoreException {

+		return null;

+	}

+

+}

diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipFeatureFactory.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipFeatureFactory.java
new file mode 100644
index 0000000..0df580d
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipFeatureFactory.java
@@ -0,0 +1,68 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2002 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

+ *******************************************************************************/

+package org.eclipse.update.examples.buildzip;

+

+import java.net.URL;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.update.core.BaseFeatureFactory;

+import org.eclipse.update.core.Feature;

+import org.eclipse.update.core.IFeature;

+import org.eclipse.update.core.IFeatureFactory;

+import org.eclipse.update.core.ISite;

+import org.eclipse.update.core.model.FeatureModel;

+

+/**

+ * An example feature factory based on the packaging 

+ * format used for integration and stable builds

+ * posted on the downloads pages at www.eclipse.org

+ * </p>

+ * @since 2.0

+ */

+

+public class BuildZipFeatureFactory

+	extends BaseFeatureFactory

+	implements IFeatureFactory {

+

+	/*

+	 * @see IFeatureFactory#createFeature(URL, ISite, IProgressMonitor)

+	 */

+	public IFeature createFeature(URL url, ISite site, IProgressMonitor monitor) throws CoreException {

+		try {

+			// create content provider for feature

+			BuildZipFeatureContentProvider cp = new BuildZipFeatureContentProvider(url);

+			Feature feature = null;

+			

+			// parse the feature

+			feature = (Feature) parseFeature(cp);

+			

+			// initialize feature

+			feature.setFeatureContentProvider(cp);

+			feature.setSite(site);

+			feature.resolve(cp.getFeatureBaseURL(), null); 

+			feature.markReadOnly();

+			return feature;

+		} catch (Exception e) {

+			throw new CoreException(new Status(IStatus.ERROR,"org.eclipse.update.examples.buildzip",0,"Unable to create feature",e));

+		}

+	}

+

+	/*

+	 * parse the build zip to reconstruct a feature model

+	 */

+	public FeatureModel parseFeature(BuildZipFeatureContentProvider cp) throws Exception {

+		return (new BuildZipFeatureParser(this)).parse(cp);

+	}

+

+}

diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipFeatureParser.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipFeatureParser.java
new file mode 100644
index 0000000..4132b3c
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipFeatureParser.java
@@ -0,0 +1,208 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2002 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

+ *******************************************************************************/

+package org.eclipse.update.examples.buildzip;

+

+import java.io.IOException;

+import java.io.InputStream;

+import java.net.URLDecoder;

+import java.util.Enumeration;

+import java.util.Properties;

+import java.util.StringTokenizer;

+

+import org.eclipse.core.runtime.PluginVersionIdentifier;

+import org.eclipse.update.core.ContentReference;

+import org.eclipse.update.core.model.FeatureModel;

+import org.eclipse.update.core.model.PluginEntryModel;

+import org.eclipse.update.core.model.URLEntryModel;

+

+/**

+ * An example feature parser. It handles features packaged as

+ * build zip's using the format used for integration and stable builds

+ * posted on the downloads pages at www.eclipse.org

+ * </p>

+ * @since 2.0

+ */

+

+public class BuildZipFeatureParser {	

+	

+	private BuildZipFeatureFactory factory;

+	private BuildZipPluginParser pluginParser;

+	

+	public BuildZipFeatureParser(BuildZipFeatureFactory factory) {

+		this.factory = factory;

+	}

+	

+	public FeatureModel parse(BuildZipFeatureContentProvider cp) throws Exception {				

+		return parseFeature(cp);

+	}

+	

+	private FeatureModel parseFeature(BuildZipFeatureContentProvider cp) throws Exception {		

+		

+		// get reference to the build manifest

+		ContentReference manifestRef = cp.getFeatureBuildManifest();

+		InputStream is = manifestRef.getInputStream();		

+		

+		// load buildmanifest.properties

+		Properties manifest = new Properties();

+		try {

+			manifest.load(is);

+		} finally {

+			if (is!=null) try { is.close(); } catch(IOException e) {}

+		}

+		

+		// populate feature model

+		FeatureModel feature = factory.createFeatureModel();

+		parseFeatureEntry(cp, feature, manifest);

+		

+		// parse plugin entries

+		parsePluginEntries(cp, feature, manifest); 

+		

+		// parse non-plugin entries

+		parseNonPluginEntries(cp, feature, manifest);

+		

+		// unpack feature entry content

+		cp.unpackFeatureEntryContent(feature, null/*IProgressMonitor*/);

+		

+		return feature;

+	}

+	

+	private void parseFeatureEntry(BuildZipFeatureContentProvider cp, FeatureModel feature, Properties manifest) throws Exception {

+		

+		// parse out build zip file name. It is assumed to be in the

+		// form <package identifier>-<build date>-<target platform>.zip,

+		// where

+		//		<package identifier> is hyphen (-) separaterd token list

+		//		<build date> is single all-numeric token

+		//		<target platform> is hyphen (-) separaterd token list

+		

+		String pkgId = "";

+		String target = "";

+		String build = "";

+		String state = "ID";

+		boolean firstToken = true;

+		String zipName = URLDecoder.decode(cp.getURL().getFile());

+		int ix = zipName.lastIndexOf("/");

+		if (ix != -1)

+			zipName = zipName.substring(ix+1);

+		if (zipName.endsWith(".zip")) {

+			zipName = zipName.substring(0,zipName.length()-4);

+		}

+		StringTokenizer tokenizer = new StringTokenizer(zipName,"-",false);

+		String token;

+		while(tokenizer.hasMoreTokens()) {

+			token = tokenizer.nextToken();

+			try {

+				Long.parseLong(token);

+				state = "TARGET";

+				target = "";

+				firstToken = true;

+				build = token+".0.0";

+			} catch (NumberFormatException e) {

+				if (state.equals("ID")) {

+					pkgId += (firstToken ? "" : " ") + token;

+				} else {

+					target += (firstToken ? "" : " ") + token;

+				}

+				firstToken = false;

+			}

+		}

+		

+		// generate base feature attributes

+		feature.setFeatureIdentifier(pkgId.replace(' ','.'));

+		feature.setFeatureVersion(build);

+		feature.setLabel(pkgId.substring(0,1).toUpperCase() + pkgId.substring(1) + " for " + target);

+		feature.setProvider("www.eclipse.org");

+		feature.setImageURLString("splash/splash_full.bmp");

+		feature.setOS(target.replace(' ','-'));	

+		

+		// add description

+		URLEntryModel description = factory.createURLEntryModel();

+		description.setURLString("readme/readme.html");

+		description.setAnnotation("x");

+		feature.setDescriptionModel(description);

+		

+		// add license

+		URLEntryModel license = factory.createURLEntryModel();

+		license.setURLString("about.html");

+		license.setAnnotation("You must view the full license by following the \"License\" link in the feature preview.\nSelecting \"Accept\" indicates that you have viewed and accepted the feature license.");

+		feature.setLicenseModel(license);

+		

+		// add copyright

+		URLEntryModel copyright = factory.createURLEntryModel();

+		copyright.setURLString("notice.html");

+		copyright.setAnnotation("x");

+		feature.setCopyrightModel(copyright);

+	}	

+	

+	private void parsePluginEntries(BuildZipFeatureContentProvider cp, FeatureModel feature, Properties manifest) throws Exception {

+		

+		Enumeration entries = manifest.keys();

+		String plugin;

+		String pluginId;

+		String pluginVersion;

+		String pluginBuildVersion;

+		PluginEntryModel pluginEntry;

+		while(entries.hasMoreElements()) {

+			plugin = (String) entries.nextElement();

+			if (plugin.startsWith("plugin@")) {

+				pluginId = plugin.substring(7);

+				pluginBuildVersion = manifest.getProperty(plugin);

+				if (pluginBuildVersion.equals("HEAD")) {

+					String featureVersion = feature.getFeatureVersion();

+					int ix = featureVersion.indexOf(".");

+					String featureMajor = ix==-1 ? featureVersion : featureVersion.substring(0,ix);

+					pluginBuildVersion += "-" + featureMajor;

+				}

+				pluginEntry = factory.createPluginEntryModel();

+				pluginVersion = parsePluginVersionInManifest(cp, pluginId, pluginEntry);

+				if (pluginVersion != null) {

+					pluginEntry.setPluginIdentifier(pluginId);

+					pluginEntry.setPluginVersion((new PluginVersionIdentifier(pluginVersion)).toString()+"."+pluginBuildVersion);

+					feature.addPluginEntryModel(pluginEntry);

+				}

+			}

+		}		

+	}

+	

+	private void parseNonPluginEntries(BuildZipFeatureContentProvider cp, FeatureModel feature, Properties manifest) throws Exception {

+	//	NonPluginEntryModel nonPluginEntry = factory.createNonPluginEntryModel();

+	//	nonPluginEntry.setIdentifier("root");

+	//	feature.addNonPluginEntryModel(nonPluginEntry);

+	}

+	

+	private String parsePluginVersionInManifest(BuildZipFeatureContentProvider cp, String pluginId, PluginEntryModel pluginEntry) {

+

+		if (pluginParser == null)

+			pluginParser = new BuildZipPluginParser();

+				

+		InputStream is = null;				

+		ContentReference pluginManifest;

+		try {

+			// try plugin.xml

+			pluginManifest  = cp.getPluginManifest(pluginId, false);

+			is = pluginManifest.getInputStream();

+			return pluginParser.parse(is);

+		} catch (Exception e) {

+			try {

+				// retry with feature.xml

+				pluginManifest  = cp.getPluginManifest(pluginId, true);

+				is = pluginManifest.getInputStream();

+				String result = pluginParser.parse(is);

+				pluginEntry.isFragment(true);

+				return result;

+			} catch (Exception e2) {

+				return null;

+			}

+		} finally {

+			if (is != null) try { is.close(); } catch (IOException e) {}

+		}

+	}

+}

diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipPluginParser.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipPluginParser.java
new file mode 100644
index 0000000..1570807
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipPluginParser.java
@@ -0,0 +1,88 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2002 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

+ *******************************************************************************/

+package org.eclipse.update.examples.buildzip;

+

+import java.io.IOException;

+import java.io.InputStream;

+

+import org.apache.xerces.parsers.SAXParser;

+import org.xml.sax.Attributes;

+import org.xml.sax.InputSource;

+import org.xml.sax.SAXException;

+import org.xml.sax.helpers.DefaultHandler;

+

+/**

+ * Parse default feature.xml

+ */

+

+public class BuildZipPluginParser extends DefaultHandler {

+

+	private SAXParser parser;

+	private String version;

+	

+	private static final String PLUGIN = "plugin";

+	private static final String FRAGMENT = "fragment";

+	

+	private class ParseCompleteException extends SAXException {

+		public ParseCompleteException(String arg0) {

+			super(arg0);

+		}

+	}

+

+	/**

+	 * Constructor for DefaultFeatureParser

+	 */

+	public BuildZipPluginParser() {

+		super();

+		this.parser = new SAXParser();

+		this.parser.setContentHandler(this);

+	}

+	

+	/**

+	 * @since 2.0

+	 */

+	public synchronized String parse(InputStream in) throws SAXException, IOException {

+		try {

+			version = null;

+			parser.parse(new InputSource(in));

+		} catch(ParseCompleteException e) {

+		}

+		return version;

+	}

+	

+	/**

+	 * @see DefaultHandler#startElement(String, String, String, Attributes)

+	 */

+	public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {

+		

+		String tag = localName.trim();

+	

+		if (tag.equalsIgnoreCase(PLUGIN)) {

+			processPlugin(attributes);

+			return;

+		}

+	

+		if (tag.equalsIgnoreCase(FRAGMENT)) {

+			processPlugin(attributes);

+			return;

+		}

+	}

+	

+	/** 

+	 * process plugin entry info

+	 */

+	private void processPlugin(Attributes attributes) throws ParseCompleteException {

+		version = attributes.getValue("version");

+		throw new ParseCompleteException("");

+	}

+}

+

+

diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipSiteContentProvider.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipSiteContentProvider.java
new file mode 100644
index 0000000..7648091
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipSiteContentProvider.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2002 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

+ *******************************************************************************/

+package org.eclipse.update.examples.buildzip;

+

+import java.net.URL;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.update.core.SiteContentProvider;

+

+public class BuildZipSiteContentProvider extends SiteContentProvider {

+

+	/**

+	 * Constructor for SiteContentProvider.

+	 */

+	public BuildZipSiteContentProvider(URL url) {

+		super(url);

+	}

+	

+	/*

+	 * @see ISiteContentProvider#getArchiveReference(String)

+	 */

+	public URL getArchiveReference(String id) throws CoreException {

+		// build zip features do not have associated archives

+		// the zip file also contains the archives files

+		return null;

+	}

+

+}

diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipSiteFactory.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipSiteFactory.java
new file mode 100644
index 0000000..8f98bf4
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/BuildZipSiteFactory.java
@@ -0,0 +1,90 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2002 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

+ *******************************************************************************/

+package org.eclipse.update.examples.buildzip;

+

+import java.io.File;

+import java.io.FileFilter;

+import java.io.IOException;

+import java.net.MalformedURLException;

+import java.net.URL;

+import java.net.URLDecoder;

+import java.util.zip.ZipEntry;

+import java.util.zip.ZipFile;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.update.core.*;

+import org.eclipse.update.core.BaseSiteFactory;

+import org.eclipse.update.core.ISite;

+import org.eclipse.update.core.Site;

+import org.eclipse.update.core.model.InvalidSiteTypeException;

+import org.eclipse.update.core.model.CategoryModel;

+

+public class BuildZipSiteFactory extends BaseSiteFactory {

+

+	/*

+	 * @see ISiteFactory#createSite(URL)

+	 */

+	public ISite createSite(URL url) throws CoreException,InvalidSiteTypeException {

+

+		Site site = null;

+

+		// create site and add category

+		site = (Site) createSiteMapModel();

+		CategoryModel category = createSiteCategoryModel();

+		category.setName("eclipse-builds");

+		category.setLabel("Eclipse Builds");

+		site.addCategoryModel(category);

+

+		// set content provider

+		BuildZipSiteContentProvider contentProvider = new BuildZipSiteContentProvider(url);

+		site.setSiteContentProvider(contentProvider);

+

+		// get all matching zip files on the site

+		FileFilter filter = new FileFilter() {

+			public boolean accept(File file) {

+				if (file.getName().endsWith(".zip")) {

+					try {

+						ZipFile zip = new ZipFile(file);

+						ZipEntry entry = zip.getEntry("eclipse/buildmanifest.properties");

+						if (entry == null)

+							return false;

+						else

+							return true;

+					} catch (IOException e) {

+						return false;

+					}

+				} else

+					return false;

+			}

+		};

+		File file = new File(URLDecoder.decode(url.getFile()));

+		File[] zips = file.listFiles(filter);

+

+		// create a reference for each matching zip

+		SiteFeatureReferenceModel ref = null;

+		for (int i = 0; zips != null && i < zips.length; i++) {

+			ref = createFeatureReferenceModel();

+			ref.setType("org.eclipse.update.examples.zip");

+			ref.setSiteModel(site);

+			ref.setURLString("file:" + zips[i].getAbsolutePath());

+			ref.setCategoryNames(new String[] { "eclipse-builds" });

+			site.addFeatureReferenceModel(ref);

+		}

+		try {

+			site.resolve(url, null); // resolve any URLs relative to the site

+		} catch (MalformedURLException e){

+			throw Utilities.newCoreException("",e);

+		}

+

+		return site;

+	}

+

+}
\ No newline at end of file
diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/DefaultModelWriter.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/DefaultModelWriter.java
new file mode 100644
index 0000000..f09e543
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/DefaultModelWriter.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2002 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
+ *******************************************************************************/
+package org.eclipse.update.examples.buildzip;
+
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+import org.eclipse.update.core.model.*;
+
+/**
+ * Write standard feature manifest (feature.xml) from model.
+ * </p>
+ * @since 2.0
+ */
+
+public class DefaultModelWriter {
+	
+	private FeatureModel feature;
+	
+	/**
+	 * @since 2.0
+	 */
+	public DefaultModelWriter(FeatureModel feature) {
+		this.feature = feature;
+	}
+	
+	/**
+	 * @since 2.0
+	 */
+	public void writeFeatureManifest(OutputStream os) {
+		PrintWriter w = new PrintWriter(os);
+		writeFeature(w,0,feature);
+		w.flush();
+	}
+	
+	private void writeFeature(PrintWriter w, int level, FeatureModel feature) {
+		if (feature == null) return;
+		
+		String in = getIndent(level);
+		w.println(in+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+		
+		w.println(in+"<feature");
+		if (feature.getFeatureIdentifier()!=null)
+			w.println(in+"   "+"id=\""+feature.getFeatureIdentifier()+"\"");
+		if (feature.getFeatureVersion()!=null)
+			w.println(in+"   "+"version=\""+feature.getFeatureVersion()+"\"");
+		if (feature.getLabelNonLocalized()!=null)
+			w.println(in+"   "+"label=\""+feature.getLabelNonLocalized()+"\"");
+		if (feature.getProviderNonLocalized()!=null)
+			w.println(in+"   "+"provider-name=\""+feature.getProviderNonLocalized()+"\"");
+		if (feature.getImageURLString()!=null)
+			w.println(in+"   "+"image=\""+feature.getImageURLString()+"\"");
+		if (feature.getOS()!=null)
+			w.println(in+"   "+"os=\""+feature.getOS()+"\"");
+		if (feature.getWS()!=null)
+			w.println(in+"   "+"ws=\""+feature.getWS()+"\"");
+		if (feature.getNL()!=null)
+			w.println(in+"   "+"nl=\""+feature.getNL()+"\"");
+		if (feature.getApplication()!=null)
+			w.println(in+"   "+"application=\""+feature.getApplication()+"\"");
+		w.println(in+"   "+">");
+		
+		writeDescription(w, level+1, feature.getDescriptionModel());
+		writeCopyright(w, level+1, feature.getCopyrightModel());
+		writeLicense(w, level+1, feature.getLicenseModel());
+		writeURLs(w, level+1, feature);
+		writePrereqs(w, level+1, feature);
+		writePluginEntries(w, level+1, feature);
+		writeNonPluginEntries(w, level+1, feature);
+         
+        w.println("");
+        w.println(in+"</feature>");
+	}
+	
+	private void writeDescription(PrintWriter w, int level, URLEntryModel ue) {
+		writeDescriptionEntry(w,level, ue, "description");
+	}
+	
+	private void writeCopyright(PrintWriter w, int level, URLEntryModel ue) {
+		writeDescriptionEntry(w,level, ue, "copyright");
+	}
+	
+	private void writeLicense(PrintWriter w, int level, URLEntryModel ue) {
+		writeDescriptionEntry(w,level, ue, "license");
+	}
+	
+	private void writeDescriptionEntry(PrintWriter w, int level, URLEntryModel ue, String tag) {
+		if (ue == null) return;
+		String url = ue.getURLString();
+		String txt = ue.getAnnotationNonLocalized();
+		if (url==null && txt==null) return;
+		
+		String in = getIndent(level);
+		w.println("");
+		if (url==null)
+			w.println(in+"<"+tag+">");
+		else {
+			w.print(in+"<"+tag+" url=\""+ue.getURLString()+"\"");
+			if (txt==null)
+				w.println("/>");
+			else
+				w.println(">");
+		}
+		if (txt!=null) {
+			w.println(in + txt);
+			w.println(in+"</"+tag+">");
+		}
+	}
+	
+	private void writeURLs(PrintWriter w, int level, FeatureModel feature) {	
+		URLEntryModel update = feature.getUpdateSiteEntryModel();
+		URLEntryModel[] discovery = feature.getDiscoverySiteEntryModels();		
+		if (update == null && (discovery == null || discovery.length==0)) return;
+		
+		String in = getIndent(level);
+		String in2 = getIndent(level+1);		
+		w.println("");
+		w.println(in+"<url>");
+		
+		if (update != null) {
+			w.println(in2+"<update");
+			if (update.getURLString()!=null)
+				w.println(in2+"   "+"url=\""+update.getURLString()+"\"");
+			if (update.getAnnotationNonLocalized()!=null)
+				w.println(in2+"   "+"label=\""+update.getAnnotationNonLocalized()+"\"");
+			w.println(in2+"   "+"/>");
+		}
+		
+		for (int i=0; discovery!=null && i<discovery.length; i++) {
+			w.println(in2+"<discovery");
+			if (discovery[i].getURLString()!=null)	
+				w.println(in2+"   "+"url=\""+discovery[i].getURLString()+"\"");
+			if (discovery[i].getAnnotationNonLocalized()!=null)
+				w.println(in2+"   "+"label=\""+discovery[i].getAnnotationNonLocalized()+"\"");
+			w.println(in2+"   "+"/>");
+		}
+		
+		w.println(in+"</url>");
+	}
+	
+	private void writePrereqs(PrintWriter w, int level, FeatureModel feature) {	
+		ImportModel[] imp = feature.getImportModels();	
+		if (imp == null || imp.length == 0) return;
+		
+		String in = getIndent(level);
+		String in2 = getIndent(level+1);
+		w.println("");
+		w.println(in+"<requires>");
+		
+		for (int i=0; imp!=null && i<imp.length; i++) {
+			w.println(in2+"<import");
+			if (imp[i].getIdentifier()!=null)
+				w.println(in2+"   "+"plugin=\""+imp[i].getIdentifier()+"\"");
+			if (imp[i].getVersion()!=null)
+				w.println(in2+"   "+"version=\""+imp[i].getVersion()+"\"");
+			if (imp[i].getMatchingRuleName()!=null)
+				w.println(in2+"   "+"match=\""+imp[i].getMatchingRuleName()+"\"");
+			w.println(in2+"   "+"/>");
+		}
+		
+		w.println(in+"</requires>");
+	}
+	
+	private void writePluginEntries(PrintWriter w, int level, FeatureModel feature) {
+		PluginEntryModel[] plugin = feature.getPluginEntryModels();
+		if (plugin == null || plugin.length == 0) return;
+		
+		String in = getIndent(level);
+		w.println("");
+		
+		for (int i=0; i<plugin.length; i++) {
+			w.println(in+"<plugin");
+			if (plugin[i].getPluginIdentifier()!=null)
+				w.println(in+"   "+"id=\""+plugin[i].getPluginIdentifier()+"\"");
+			if (plugin[i].getPluginVersion()!=null)
+				w.println(in+"   "+"version=\""+plugin[i].getPluginVersion()+"\"");
+			if (plugin[i].isFragment())
+				w.println(in+"   "+"fragment=\""+plugin[i].isFragment()+"\"");
+			if (plugin[i].getOS()!=null)
+				w.println(in+"   "+"os=\""+plugin[i].getOS()+"\"");
+			if (plugin[i].getWS()!=null)
+				w.println(in+"   "+"ws=\""+plugin[i].getWS()+"\"");
+			if (plugin[i].getNL()!=null)
+				w.println(in+"   "+"nl=\""+plugin[i].getNL()+"\"");
+			if (plugin[i].getDownloadSize()!=ContentEntryModel.UNKNOWN_SIZE)
+				w.println(in+"   "+"download-size=\""+plugin[i].getDownloadSize()+"\"");
+			if (plugin[i].getInstallSize()!=ContentEntryModel.UNKNOWN_SIZE)
+				w.println(in+"   "+"install-size=\""+plugin[i].getInstallSize()+"\"");
+			w.println(in+"   "+"/>");
+		}
+	}
+	
+	private void writeNonPluginEntries(PrintWriter w, int level, FeatureModel feature) {
+		NonPluginEntryModel[] data = feature.getNonPluginEntryModels();
+		if (data == null || data.length == 0) return;
+		
+		String in = getIndent(level);
+		w.println("");
+		
+		for (int i=0; i<data.length; i++) {
+			w.println(in+"<data");
+			if (data[i].getIdentifier()!=null)
+				w.println(in+"   "+"id=\""+data[i].getIdentifier()+"\"");
+			if (data[i].getOS()!=null)
+				w.println(in+"   "+"os=\""+data[i].getOS()+"\"");
+			if (data[i].getWS()!=null)
+				w.println(in+"   "+"ws=\""+data[i].getWS()+"\"");
+			if (data[i].getNL()!=null)
+				w.println(in+"   "+"nl=\""+data[i].getNL()+"\"");
+			if (data[i].getDownloadSize()!=ContentEntryModel.UNKNOWN_SIZE)
+				w.println(in+"   "+"download-size=\""+data[i].getDownloadSize()+"\"");
+			if (data[i].getInstallSize()!=ContentEntryModel.UNKNOWN_SIZE)
+				w.println(in+"   "+"install-size=\""+data[i].getInstallSize()+"\"");
+			w.println(in+"   "+"/>");
+		}
+	}
+	
+	
+	private String getIndent(int level) {
+		String indent = "";
+		for (int i=0; i<level; i++) 
+			indent += "   ";
+		return indent;
+	}
+}
diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/Test.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/Test.java
new file mode 100644
index 0000000..4946acc
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/Test.java
@@ -0,0 +1,60 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2002 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

+ *******************************************************************************/

+package org.eclipse.update.examples.buildzip;

+

+import java.net.URL;

+

+import org.eclipse.update.core.*;

+ 

+/**

+ * unit test harness

+ */

+

+public class Test {

+

+	public static void main(String[] args) {

+		

+		try {

+			URL url = new URL("file:d:/downloads/eclipse 2.0/integration-eclipse-SDK-20020109-win32.zip");

+			BuildZipFeatureFactory factory = new BuildZipFeatureFactory();

+			Feature feature = (Feature) factory.createFeature(url,null/*ISite*/);

+			DefaultModelWriter w = new DefaultModelWriter(feature);

+			w.writeFeatureManifest(System.out);

+			

+			System.out.println("");

+			System.out.println("Feature entry references");

+			ContentReference[] refs = feature.getFeatureContentProvider().getFeatureEntryContentReferences(null);

+			for (int i=0; i< refs.length; i++) {

+				System.out.println("   "+refs[i].getIdentifier());

+			}

+			

+			System.out.println("");

+			System.out.println("Plug-in entry references");

+			IPluginEntry[] entry = feature.getPluginEntries();

+			refs = feature.getFeatureContentProvider().getPluginEntryContentReferences(entry[0], null);

+			for (int i=0; i< refs.length; i++) {

+				System.out.println("   "+refs[i].getIdentifier());

+			}			

+			

+			System.out.println("");

+			System.out.println("Non-plug-in entry references");

+			INonPluginEntry[] data = feature.getNonPluginEntries();

+			refs = feature.getFeatureContentProvider().getNonPluginEntryArchiveReferences(data[0], null);

+			for (int i=0; i< refs.length; i++) {

+				System.out.println("   "+refs[i].getIdentifier());

+			}			

+			

+			System.out.println("Done ...");

+		} catch (Exception e) {

+			e.printStackTrace();

+		}		

+	}

+}

diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/java.page.jpage b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/java.page.jpage
new file mode 100644
index 0000000..6cb24bd
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/buildzip/java.page.jpage
@@ -0,0 +1,45 @@
+

+

+java.util.Properties p = System.getProperties();

+java.util.Enumeration keys = p.keys();

+while (keys.hasMoreElements()) {

+	String key = (String)keys.nextElement();

+	System.out.println(key + " = " + (String)p.get(key));

+}

+

+

+

+

+

+String fileName = "d:\\downloads\\eclipse 2.0\\integration-eclipse-SDK-20020109-win32.zip";

+java.io.File archiveFile = new java.io.File(fileName);

+java.util.jar.JarFile jarArchive = new java.util.jar.JarFile(archiveFile);

+java.util.jar.JarEntry entry;

+java.util.Enumeration entries = jarArchive.entries();

+while(entries.hasMoreElements()) {

+	entry = (java.util.jar.JarEntry) entries.nextElement();

+	System.out.println(entry.getName());

+}

+

+

+String a = "223";

+String b = "123";

+a.compareTo(b);

+

+

+org.eclipse.update.core.Version v1 = 

+	new org.eclipse.update.core.Version(1,2,3,"build 127J");

+org.eclipse.update.core.Version v2 = 

+	new org.eclipse.update.core.Version(1,2,3,"build 127J");

+v1.compare(v2);

+

+

+java.io.File f = new java.io.File("d:\\downloads\\eclipse 2.0\\x\\");

+f.isDirectory();

+

+

+String s = "hello";

+Object a = java.lang.reflect.Array.newInstance(s.getClass(),0);

+System.out.println(a.getClass().getName());

+

+

diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/freeform/FreeFormSiteContentProvider.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/freeform/FreeFormSiteContentProvider.java
new file mode 100644
index 0000000..506e33c
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/freeform/FreeFormSiteContentProvider.java
@@ -0,0 +1,44 @@
+/*******************************************************************************

+ * Copyright (c) 2009 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

+ *******************************************************************************/

+package org.eclipse.update.examples.freeform;

+import java.net.MalformedURLException;

+import java.net.URL;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.update.core.SiteContentProvider;

+

+public class FreeFormSiteContentProvider extends SiteContentProvider {

+

+	/**

+	 * Constructor for SiteContentProvider.

+	 */

+	public FreeFormSiteContentProvider(URL url) {

+		super(url);

+	}

+	

+	/*

+	 * @see ISiteContentProvider#getArchiveReference(String)

+	 */

+	public URL getArchiveReference(String id) throws CoreException {

+		try {

+			return new URL(getURL(),id);

+		} catch(MalformedURLException e) {

+			throw newCoreException("Unable to return archive URL",e);

+		}

+	}

+	

+	private CoreException newCoreException(String s, Throwable e) throws CoreException {

+		return new CoreException(new Status(IStatus.ERROR,"org.eclipse.update.examples",0,s,e));

+	}

+

+}

diff --git a/update/org.eclipse.update.examples/src/org/eclipse/update/examples/freeform/FreeFormSiteFactory.java b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/freeform/FreeFormSiteFactory.java
new file mode 100644
index 0000000..ae4603c
--- /dev/null
+++ b/update/org.eclipse.update.examples/src/org/eclipse/update/examples/freeform/FreeFormSiteFactory.java
@@ -0,0 +1,79 @@
+/*******************************************************************************

+ * Copyright (c) 2009 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

+ *******************************************************************************/

+package org.eclipse.update.examples.freeform;

+import java.io.IOException;

+import java.io.InputStream;

+import java.net.MalformedURLException;

+import java.net.URL;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.update.core.*;

+import org.eclipse.update.core.BaseSiteFactory;

+import org.eclipse.update.core.ISite;

+import org.eclipse.update.core.Site;

+import org.eclipse.update.core.model.InvalidSiteTypeException;

+import org.eclipse.update.core.model.URLEntryModel;

+

+public class FreeFormSiteFactory extends BaseSiteFactory {

+

+	/*

+	 * @see ISiteFactory#createSite(URL)

+	 */

+	public ISite createSite(URL url)

+		throws CoreException, InvalidSiteTypeException {

+

+		// Create site

+		Site site = null;

+		InputStream is = null;

+		try {

+			is = url.openStream();

+			site = (Site) parseSite(is);

+

+			URLEntryModel realSiteRef = site.getDescriptionModel();

+			if (realSiteRef == null)

+				throw Utilities.newCoreException(

+					"Unable to obtain update site reference",

+					null);

+			String siteURLString = realSiteRef.getURLString();

+			if (siteURLString == null)

+				throw Utilities.newCoreException(

+					"Unable to obtain update site reference",

+					null);

+			URL siteURL = new URL(siteURLString);

+			FreeFormSiteContentProvider contentProvider =

+				new FreeFormSiteContentProvider(siteURL);

+			site.setSiteContentProvider(contentProvider);

+			site.resolve(siteURL, null); // resolve any URLs relative to the site

+

+		} catch (MalformedURLException e){

+			throw Utilities.newCoreException("Unable to create URL",e);

+		} catch (IOException e){

+			throw Utilities.newCoreException("Unable to access URL",e);

+		} finally {

+			if (is != null)

+				try {

+					is.close();

+				} catch (IOException e) {

+				}

+		}

+

+		return site;

+	}

+

+	/*

+	 * @see SiteModelFactory#canParseSiteType(String)

+	 */

+	public boolean canParseSiteType(String type) {

+		return type != null

+			&& type.equals("org.eclipse.update.examples.site.freeform");

+	}

+

+}
\ No newline at end of file
diff --git a/update/org.eclipse.update.scheduler/.classpath b/update/org.eclipse.update.scheduler/.classpath
new file mode 100644
index 0000000..ce0c7a5
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/.classpath
@@ -0,0 +1,7 @@
+<?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/CDC-1.0%Foundation-1.0"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/update/org.eclipse.update.scheduler/.cvsignore b/update/org.eclipse.update.scheduler/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/update/org.eclipse.update.scheduler/.project b/update/org.eclipse.update.scheduler/.project
new file mode 100644
index 0000000..7421364
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/.project
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.update.scheduler</name>
+	<comment></comment>
+	<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.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update.scheduler/.settings/org.eclipse.jdt.core.prefs b/update/org.eclipse.update.scheduler/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d5346c3
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Wed Apr 26 14:34:03 EDT 2006
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.1
+org.eclipse.jdt.core.compiler.compliance=1.3
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=ignore
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/update/org.eclipse.update.scheduler/about.html b/update/org.eclipse.update.scheduler/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</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
+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/update/org.eclipse.update.scheduler/build.properties b/update/org.eclipse.update.scheduler/build.properties
new file mode 100644
index 0000000..1ffcaa7
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/build.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+bin.includes = plugin.properties,\
+               .,\
+               plugin.xml,\
+               about.html,\
+               META-INF/
+src.includes = about.html
+source.. = src/
diff --git a/update/org.eclipse.update.scheduler/plugin.properties b/update/org.eclipse.update.scheduler/plugin.properties
new file mode 100644
index 0000000..529b080
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/plugin.properties
@@ -0,0 +1,18 @@
+###############################################################################
+# 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
+###############################################################################
+#
+# Update Scheduler plugin.xml resources
+#
+pluginName = Automatic Updates Scheduler
+providerName = Eclipse.org
+automaticUpdatesPrefPage = Automatic Updates
+preferences = Updates Scheduler Preferences
+preferenceKeywords.general=automatic update schedule download
diff --git a/update/org.eclipse.update.scheduler/plugin.xml b/update/org.eclipse.update.scheduler/plugin.xml
new file mode 100644
index 0000000..31ee733
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/plugin.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+
+    	<extension id="preferences" point="org.eclipse.core.runtime.preferences" name="%preferences">
+		<initializer class="org.eclipse.update.internal.scheduler.preferences.PreferenceInitializer"/>
+	</extension>
+   <extension
+         point="org.eclipse.ui.startup">
+      <startup class="org.eclipse.update.internal.scheduler.SchedulerStartup">
+      </startup>
+   </extension>
+   <extension
+         point="org.eclipse.ui.startup">
+      <startup class="org.eclipse.update.internal.scheduler.ScheduledPluginUninstall">
+      </startup>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            name="%automaticUpdatesPrefPage"
+            category="org.eclipse.update.internal.ui.preferences.MainPreferencePage"
+            class="org.eclipse.update.internal.scheduler.preferences.AutomaticUpdatesPreferencePage"
+            id="org.eclipse.update.scheduler.AutomaticUpdatesPreferencePage">
+            <keywordReference id="org.eclipse.update.scheduler.general"/>
+      </page>
+   </extension>
+
+      <extension
+   		point="org.eclipse.ui.keywords">
+      <keyword
+            label="%preferenceKeywords.general"
+            id="org.eclipse.update.scheduler.general"/>
+      </extension>
+</plugin>
diff --git a/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/AutomaticUpdateJob.java b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/AutomaticUpdateJob.java
new file mode 100644
index 0000000..e6afd9a
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/AutomaticUpdateJob.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.scheduler;
+
+import org.eclipse.update.search.UpdateSearchRequest;
+import org.eclipse.update.ui.UpdateJob;
+
+class AutomaticUpdateJob extends UpdateJob {
+
+	public AutomaticUpdateJob(String name, boolean isAutomatic, boolean download) {
+		super(name, isAutomatic, download);
+	}
+
+	public AutomaticUpdateJob(String name, UpdateSearchRequest searchRequest) {
+		super(name, searchRequest);
+	}
+
+	public boolean belongsTo(Object family) {
+		return SchedulerStartup.automaticJobFamily == family;
+	}
+}
\ No newline at end of file
diff --git a/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/ScheduledPluginUninstall.java b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/ScheduledPluginUninstall.java
new file mode 100644
index 0000000..b192f68
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/ScheduledPluginUninstall.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.scheduler;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.ui.IStartup;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.internal.operations.OperationFactory;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class ScheduledPluginUninstall implements IStartup {
+
+	public void earlyStartup() {
+		URL platformXML = ConfiguratorUtils.getCurrentPlatformConfiguration().getConfigurationLocation();
+		
+		File f = new File(platformXML.getFile());
+
+		f = new File(f.getParentFile(), "toBeUninstalled"); //$NON-NLS-1$
+		try {
+			if (!f.exists()) {
+				return;
+			}
+			FileInputStream fis = new FileInputStream(f);
+			Properties toBeUninstalled = new Properties();
+			toBeUninstalled.load(fis);
+			fis.close();
+
+			IFeature[] features = new IFeature[toBeUninstalled.size()];
+			IConfiguredSite[] configuredSites = new IConfiguredSite[toBeUninstalled.size()];
+
+			IConfiguredSite[] sites = SiteManager.getLocalSite().getCurrentConfiguration().getConfiguredSites();
+
+			Enumeration featuresToBeDeleted = toBeUninstalled.elements();
+			int i = 0;
+			while(featuresToBeDeleted.hasMoreElements()) {
+				String temp = (String)featuresToBeDeleted.nextElement();
+				StringTokenizer stk = new StringTokenizer( temp, ";"); //$NON-NLS-1$
+				String targetSite = stk.nextToken();
+				String featureName = stk.nextToken();
+				for(int j = 0; j < sites.length; j++) {
+					if (sites[j].getSite().getURL().toString().equals(targetSite)) {
+						configuredSites[i] = sites[j];
+						IFeatureReference[] siteFeatures = configuredSites[i].getFeatureReferences();
+						for(int k = 0; k < siteFeatures.length; k++) {
+							if (siteFeatures[k].getVersionedIdentifier().toString().equals(featureName)) {
+								features[i] = siteFeatures[k].getFeature(null);
+								
+								break;
+							}
+						}
+						
+					}
+				}
+				i++;
+			}
+			
+
+			IOperation uninstallFeaturesOperation =
+				((OperationFactory)OperationsManager.getOperationFactory()).createUninstallFeaturesOperation( configuredSites, features);
+
+			uninstallFeaturesOperation.execute(null, null);
+			
+			f.delete();
+		} catch (IOException ioe) {
+			
+		} catch (CoreException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (InvocationTargetException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+
+}
diff --git a/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/SchedulerStartup.java b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/SchedulerStartup.java
new file mode 100644
index 0000000..69401b7
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/SchedulerStartup.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.scheduler;
+
+import java.lang.reflect.Constructor;
+import java.util.Calendar;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.ui.IStartup;
+
+/**
+ * This plug-in is loaded on startup to fork a job that searches for new
+ * plug-ins.
+ */
+public class SchedulerStartup implements IStartup {
+	// Preferences
+	public static final String P_ENABLED = "enabled"; //$NON-NLS-1$
+
+	public static final String P_SCHEDULE = "schedule"; //$NON-NLS-1$
+
+	public static final String VALUE_ON_STARTUP = "on-startup"; //$NON-NLS-1$
+
+	public static final String VALUE_ON_SCHEDULE = "on-schedule"; //$NON-NLS-1$
+
+	public static final String P_DOWNLOAD = "download"; // value is true or false, default isfalse //$NON-NLS-1$
+
+	// values are to be picked up from the arryas DAYS and HOURS
+	public static final String P_DAY = "day"; //$NON-NLS-1$
+
+	public static final String P_HOUR = "hour"; //$NON-NLS-1$
+
+	// Keeps track of the running job
+	private Job job;
+
+	static final Object automaticJobFamily = new Object();
+
+	// Listener for job changes
+	private IJobChangeListener jobListener;
+
+	public static final String[] DAYS = {
+			UpdateSchedulerMessages.SchedulerStartup_day,
+			UpdateSchedulerMessages.SchedulerStartup_Monday,
+			UpdateSchedulerMessages.SchedulerStartup_Tuesday,
+			UpdateSchedulerMessages.SchedulerStartup_Wednesday,
+			UpdateSchedulerMessages.SchedulerStartup_Thursday,
+			UpdateSchedulerMessages.SchedulerStartup_Friday,
+			UpdateSchedulerMessages.SchedulerStartup_Saturday,
+			UpdateSchedulerMessages.SchedulerStartup_Sunday };
+
+	public static final String[] HOURS = {
+			UpdateSchedulerMessages.SchedulerStartup_1AM,
+			UpdateSchedulerMessages.SchedulerStartup_2AM,
+			UpdateSchedulerMessages.SchedulerStartup_3AM,
+			UpdateSchedulerMessages.SchedulerStartup_4AM,
+			UpdateSchedulerMessages.SchedulerStartup_5AM,
+			UpdateSchedulerMessages.SchedulerStartup_6AM,
+			UpdateSchedulerMessages.SchedulerStartup_7AM,
+			UpdateSchedulerMessages.SchedulerStartup_8AM,
+			UpdateSchedulerMessages.SchedulerStartup_9AM,
+			UpdateSchedulerMessages.SchedulerStartup_10AM,
+			UpdateSchedulerMessages.SchedulerStartup_11AM,
+			UpdateSchedulerMessages.SchedulerStartup_12PM,
+			UpdateSchedulerMessages.SchedulerStartup_1PM,
+			UpdateSchedulerMessages.SchedulerStartup_2PM,
+			UpdateSchedulerMessages.SchedulerStartup_3PM,
+			UpdateSchedulerMessages.SchedulerStartup_4PM,
+			UpdateSchedulerMessages.SchedulerStartup_5PM,
+			UpdateSchedulerMessages.SchedulerStartup_6PM,
+			UpdateSchedulerMessages.SchedulerStartup_7PM,
+			UpdateSchedulerMessages.SchedulerStartup_8PM,
+			UpdateSchedulerMessages.SchedulerStartup_9PM,
+			UpdateSchedulerMessages.SchedulerStartup_10PM,
+			UpdateSchedulerMessages.SchedulerStartup_11PM,
+			UpdateSchedulerMessages.SchedulerStartup_12AM, };
+
+	/**
+	 * The constructor.
+	 */
+	public SchedulerStartup() {
+		UpdateSchedulerPlugin.setScheduler(this);
+	}
+
+	public void earlyStartup() {
+		scheduleUpdateJob();
+	}
+
+	public void scheduleUpdateJob() {
+		Preferences pref = UpdateSchedulerPlugin.getDefault()
+				.getPluginPreferences();
+		// See if automatic search is enabled at all
+		if (pref.getBoolean(P_ENABLED) == false)
+			return;
+
+		String schedule = pref.getString(P_SCHEDULE);
+		long delay = -1L;
+		if (schedule.equals(VALUE_ON_STARTUP))
+			// have we already started a job ?
+			if (job == null)
+				delay = 0L;
+			else
+				delay = -1L;
+		else
+			delay = computeDelay(pref);
+		if (delay == -1L)
+			return;
+		startSearch(delay);
+	}
+
+	private int getDay(Preferences pref) {
+		String day = pref.getString(P_DAY);
+		for (int d = 0; d < DAYS.length; d++)
+			if (DAYS[d].equals(day))
+				switch (d) {
+				case 0:
+					return -1;
+				case 1:
+					return Calendar.MONDAY;
+				case 2:
+					return Calendar.TUESDAY;
+				case 3:
+					return Calendar.WEDNESDAY;
+				case 4:
+					return Calendar.THURSDAY;
+				case 5:
+					return Calendar.FRIDAY;
+				case 6:
+					return Calendar.SATURDAY;
+				case 7:
+					return Calendar.SUNDAY;
+				}
+		return -1;
+	}
+
+	private int getHour(Preferences pref) {
+		String hour = pref.getString(P_HOUR);
+		for (int h = 0; h < HOURS.length; h++)
+			if (HOURS[h].equals(hour))
+				return h + 1;
+		return 1;
+	}
+
+	/*
+	 * Computes the number of milliseconds from this moment to the next
+	 * scheduled search. If that moment has already passed, returns 0L (start
+	 * immediately).
+	 */
+	private long computeDelay(Preferences pref) {
+
+		int target_d = getDay(pref);
+		int target_h = getHour(pref);
+
+		Calendar calendar = Calendar.getInstance();
+		// may need to use the BootLoader locale
+		int current_d = calendar.get(Calendar.DAY_OF_WEEK);
+		// starts with SUNDAY
+		int current_h = calendar.get(Calendar.HOUR_OF_DAY);
+		int current_m = calendar.get(Calendar.MINUTE);
+		int current_s = calendar.get(Calendar.SECOND);
+		int current_ms = calendar.get(Calendar.MILLISECOND);
+
+		long delay = 0L; // milliseconds
+
+		if (target_d == -1) {
+			// Compute the delay for "every day at x o'clock"
+			// Is it now ?
+			if (target_h == current_h && current_m == 0 && current_s == 0)
+				return delay;
+
+			int delta_h = target_h - current_h;
+			if (target_h <= current_h)
+				delta_h += 24;
+			delay = ((delta_h * 60 - current_m) * 60 - current_s) * 1000
+					- current_ms;
+			return delay;
+		} else {
+			// Compute the delay for "every Xday at x o'clock"
+			// Is it now ?
+			if (target_d == current_d && target_h == current_h
+					&& current_m == 0 && current_s == 0)
+				return delay;
+
+			int delta_d = target_d - current_d;
+			if (target_d < current_d
+					|| target_d == current_d
+					&& (target_h < current_h || target_h == current_h
+							&& current_m > 0))
+				delta_d += 7;
+
+			delay = (((delta_d * 24 + target_h - current_h) * 60 - current_m) * 60 - current_s)
+					* 1000 - current_ms;
+
+			return delay;
+		}
+		// return -1L;
+	}
+
+	private void startSearch(long delay) {
+		if (job != null) {
+			// cancel old job.
+			// We need to deregister the listener first,so we won't
+			// automatically start another job
+			if (jobListener != null)
+				Job.getJobManager().removeJobChangeListener(jobListener);
+			Job.getJobManager().cancel(automaticJobFamily);
+		}
+		if (jobListener == null) {
+			// using reflection to avoid premature class loading
+			jobListener = createJobChangeAdapter();
+			if (jobListener == null)
+				return;
+		}
+		Job.getJobManager().addJobChangeListener(jobListener);
+		String jobName = UpdateSchedulerMessages.AutomaticUpdatesJob_AutomaticUpdateSearch; //);
+		boolean download = UpdateSchedulerPlugin.getDefault()
+				.getPluginPreferences().getBoolean(
+						UpdateSchedulerPlugin.P_DOWNLOAD);
+		job = createUpdateJob(jobName, download);
+		if (job != null)
+			job.schedule(delay);
+
+	}
+
+	/*
+	 * Loads the update job using reflection to avoid premature startup of the
+	 * Update UI plug-in.
+	 */
+
+	private Job createUpdateJob(String name, boolean download) {
+		try {
+			Class theClass = Class
+					.forName("org.eclipse.update.internal.scheduler.AutomaticUpdateJob"); //$NON-NLS-1$
+			Constructor constructor = theClass.getConstructor(new Class[] {
+					String.class, Boolean.TYPE, Boolean.TYPE });
+			return (Job) constructor.newInstance(new Object[] { name,
+					Boolean.TRUE, new Boolean(download) });
+		} catch (Exception e) {
+			UpdateSchedulerPlugin.logException(e, false);
+			return null;
+		}
+	}
+
+	/*
+	 * Loads the job listener using reflection to avoid premature startup of the
+	 * Update UI plug-in.
+	 */
+	private IJobChangeListener createJobChangeAdapter() {
+		try {
+			Class theClass = Class
+					.forName("org.eclipse.update.internal.scheduler.UpdateJobChangeAdapter"); //$NON-NLS-1$
+			Constructor constructor = theClass
+					.getConstructor(new Class[] { SchedulerStartup.class });
+			return (IJobChangeListener) constructor
+					.newInstance(new Object[] { this });
+		} catch (Exception e) {
+			UpdateSchedulerPlugin.logException(e, false);
+			return null;
+		}
+	}
+
+	Job getJob() {
+		return job;
+	}
+}
diff --git a/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateJobChangeAdapter.java b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateJobChangeAdapter.java
new file mode 100644
index 0000000..94473c4
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateJobChangeAdapter.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.scheduler;
+
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.wizards.InstallWizard;
+import org.eclipse.update.internal.ui.wizards.InstallWizard2;
+import org.eclipse.update.internal.ui.wizards.ResizableInstallWizardDialog;
+
+class UpdateJobChangeAdapter extends JobChangeAdapter {
+	private SchedulerStartup startup;
+
+	public UpdateJobChangeAdapter(SchedulerStartup startup) {
+		this.startup = startup;
+	}
+
+	public void done(IJobChangeEvent event) {
+		if (event.getJob() == startup.getJob()) {
+
+			// prompt the user
+			if (((AutomaticUpdateJob) startup.getJob()).getUpdates().length > 0
+					&& !InstallWizard.isRunning()) {
+				if (UpdateSchedulerPlugin.getDefault().getPluginPreferences()
+						.getBoolean(UpdateSchedulerPlugin.P_DOWNLOAD)) {
+					UpdateUI.getStandardDisplay().asyncExec(new Runnable() {
+						public void run() {
+							asyncNotifyDownloadUser();
+							startup.scheduleUpdateJob();
+						}
+					});
+				} else {
+					UpdateUI.getStandardDisplay().asyncExec(new Runnable() {
+						public void run() {
+							asyncNotifyUser();
+							startup.scheduleUpdateJob();
+						}
+					});
+				}
+			}
+		}
+	}
+
+	private void asyncNotifyUser() {
+		// ask the user to install updates
+		UpdateUI.getStandardDisplay().beep();
+		if (MessageDialog.openQuestion(UpdateUI.getActiveWorkbenchShell(),
+				UpdateUIMessages.AutomaticUpdatesJob_EclipseUpdates1,
+				UpdateUIMessages.AutomaticUpdatesJob_UpdatesAvailable)) {
+			BusyIndicator.showWhile(UpdateUI.getStandardDisplay(),
+					new Runnable() {
+						public void run() {
+							openInstallWizard2();
+						}
+					});
+		}
+		// notify the manager that the job is done
+		// job.done(Status.OK_STATUS);
+	}
+
+	private void asyncNotifyDownloadUser() {
+		// ask the user to install updates
+		UpdateUI.getStandardDisplay().beep();
+		if (MessageDialog.openQuestion(UpdateUI.getActiveWorkbenchShell(),
+				UpdateUIMessages.AutomaticUpdatesJob_EclipseUpdates2,
+				UpdateUIMessages.AutomaticUpdatesJob_UpdatesDownloaded)) {
+			BusyIndicator.showWhile(UpdateUI.getStandardDisplay(),
+					new Runnable() {
+						public void run() {
+							openInstallWizard2();
+						}
+					});
+		} else {
+			// Don't discard downloaded data, as next time we compare
+			// timestamps.
+
+			// discard all the downloaded data from cache (may include old
+			// data as well)
+			// Utilities.flushLocalFile();
+		}
+		// notify the manager that the job is done
+		// job.done(Status.OK_STATUS);
+	}
+
+	private void openInstallWizard2() {
+		if (InstallWizard.isRunning())
+			// job ends and a new one is rescheduled
+			return;
+		AutomaticUpdateJob ujob = (AutomaticUpdateJob) startup.getJob();
+		InstallWizard2 wizard = new InstallWizard2(ujob.getSearchRequest(),
+				ujob.getUpdates(), true);
+		WizardDialog dialog = new ResizableInstallWizardDialog(UpdateUI
+				.getActiveWorkbenchShell(), wizard,
+				UpdateUIMessages.AutomaticUpdatesJob_Updates);
+		dialog.create();
+		dialog.open();
+	}
+
+}
diff --git a/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateSchedulerMessages.java b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateSchedulerMessages.java
new file mode 100644
index 0000000..606fde8
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateSchedulerMessages.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.scheduler;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class UpdateSchedulerMessages extends NLS {
+
+	private static final String BUNDLE_NAME = "org.eclipse.update.internal.scheduler.UpdateSchedulerResources";//$NON-NLS-1$
+
+	private UpdateSchedulerMessages() {
+		// Do not instantiate
+	}
+
+	public static String SchedulerStartup_day;
+	public static String SchedulerStartup_Monday;
+	public static String SchedulerStartup_Tuesday;
+	public static String SchedulerStartup_Wednesday;
+	public static String SchedulerStartup_Thursday;
+	public static String SchedulerStartup_Friday;
+	public static String SchedulerStartup_Saturday;
+	public static String SchedulerStartup_Sunday;
+	public static String SchedulerStartup_1AM;
+	public static String SchedulerStartup_2AM;
+	public static String SchedulerStartup_3AM;
+	public static String SchedulerStartup_4AM;
+	public static String SchedulerStartup_5AM;
+	public static String SchedulerStartup_6AM;
+	public static String SchedulerStartup_7AM;
+	public static String SchedulerStartup_8AM;
+	public static String SchedulerStartup_9AM;
+	public static String SchedulerStartup_10AM;
+	public static String SchedulerStartup_11AM;
+	public static String SchedulerStartup_12PM;
+	public static String SchedulerStartup_1PM;
+	public static String SchedulerStartup_2PM;
+	public static String SchedulerStartup_3PM;
+	public static String SchedulerStartup_4PM;
+	public static String SchedulerStartup_5PM;
+	public static String SchedulerStartup_6PM;
+	public static String SchedulerStartup_7PM;
+	public static String SchedulerStartup_8PM;
+	public static String SchedulerStartup_9PM;
+	public static String SchedulerStartup_10PM;
+	public static String SchedulerStartup_11PM;
+	public static String SchedulerStartup_12AM;
+	public static String AutomaticUpdatesJob_AutomaticUpdateSearch;
+	public static String AutomaticUpdatesPreferencePage_findUpdates;
+	public static String AutomaticUpdatesPreferencePage_UpdateSchedule;
+	public static String AutomaticUpdatesPreferencePage_findOnStart;
+	public static String AutomaticUpdatesPreferencePage_findOnSchedule;
+	public static String AutomaticUpdatesPreferencePage_downloadOptions;
+	public static String AutomaticUpdatesPreferencePage_searchAndNotify;
+	public static String AutomaticUpdatesPreferencePage_downloadAndNotify;
+	public static String AutomaticUpdatesPreferencePage_at;
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, UpdateSchedulerMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateSchedulerPlugin.java b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateSchedulerPlugin.java
new file mode 100644
index 0000000..0d80fbc
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateSchedulerPlugin.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.scheduler;
+
+import java.lang.reflect.*;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.plugin.*;
+import org.osgi.framework.*;
+
+/**
+ * This plug-in is loaded on startup to fork a job that
+ * searches for new plug-ins.
+ */
+public class UpdateSchedulerPlugin extends AbstractUIPlugin{
+	// Preferences
+	public static final String P_ENABLED = "enabled"; //$NON-NLS-1$
+	public static final String P_SCHEDULE = "schedule"; //$NON-NLS-1$
+	public static final String VALUE_ON_STARTUP = "on-startup"; //$NON-NLS-1$
+	public static final String VALUE_ON_SCHEDULE = "on-schedule"; //$NON-NLS-1$
+	public static final String P_DOWNLOAD = "download"; // value is true or false, default is false //$NON-NLS-1$
+
+	//The shared instance.
+	private static UpdateSchedulerPlugin plugin;
+	//Resource bundle.
+	private ResourceBundle resourceBundle;
+	
+	// singleton
+	private static SchedulerStartup scheduler;
+
+	/**
+	 * The constructor.
+	 */
+	public UpdateSchedulerPlugin() {
+		plugin = this;
+	}
+
+
+	public ResourceBundle getResourceBundle() {
+		if (resourceBundle == null)
+			try {
+				resourceBundle = ResourceBundle.getBundle("org.eclipse.update.internal.scheduler.UpdateSchedulerResources"); //$NON-NLS-1$
+			} catch (MissingResourceException x) {
+				resourceBundle = null;
+			}
+		return resourceBundle;
+	}
+
+	/**
+	 * Returns the shared instance.
+	 */
+	public static UpdateSchedulerPlugin getDefault() {
+		return plugin;
+	}
+
+	public static String getPluginId() {
+		return getDefault().getBundle().getSymbolicName();
+	}
+
+	public static void logException(Throwable e) {
+		logException(e, true);
+	}
+
+	public static void logException(Throwable e, boolean showErrorDialog) {
+		if (e instanceof InvocationTargetException) {
+			e = ((InvocationTargetException) e).getTargetException();
+		}
+
+		IStatus status = null;
+		if (e instanceof CoreException) {
+			status = ((CoreException) e).getStatus();
+		} else {
+			String message = e.getMessage();
+			if (message == null)
+				message = e.toString();
+			status =
+				new Status(
+					IStatus.ERROR,
+					getPluginId(),
+					IStatus.OK,
+					message,
+					e);
+		}
+		log(status, showErrorDialog);
+	}
+
+	public static void log(IStatus status, boolean showErrorDialog) {
+		if (status.getSeverity() != IStatus.INFO) {
+			if (showErrorDialog)
+				ErrorDialog.openError(
+					getActiveWorkbenchShell(),
+					null,
+					null,
+					status);
+//			 Should log on the update plugin's log
+//			Platform.getPlugin("org.eclipse.core.runtime").getLog().log(status); //$NON-NLS-1$
+			Bundle bundle = Platform.getBundle("org.eclipse.update.scheduler");  //$NON-NLS-1$
+			Platform.getLog(bundle).log(status);
+		} else {
+			MessageDialog.openInformation(
+				getActiveWorkbenchShell(),
+				null,
+				status.getMessage());
+		}
+	}
+
+	public static IWorkbenchPage getActivePage() {
+		UpdateSchedulerPlugin plugin = getDefault();
+		IWorkbenchWindow window =
+			plugin.getWorkbench().getActiveWorkbenchWindow();
+		if (window != null)
+			return window.getActivePage();
+		return null;
+	}
+
+	public static Shell getActiveWorkbenchShell() {
+		IWorkbenchWindow window = getActiveWorkbenchWindow();
+		return window != null ? window.getShell() : null;
+	}
+
+	public static IWorkbenchWindow getActiveWorkbenchWindow() {
+		return getDefault().getWorkbench().getActiveWorkbenchWindow();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+	}
+	
+	public static SchedulerStartup getScheduler() {
+		// If the scheduler was disabled, it does not get initialized
+		if (scheduler == null)
+			scheduler = new SchedulerStartup();
+		return scheduler;
+	}
+	
+	static void setScheduler(SchedulerStartup scheduler) {
+		UpdateSchedulerPlugin.scheduler = scheduler;
+	}
+}
diff --git a/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateSchedulerResources.properties b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateSchedulerResources.properties
new file mode 100644
index 0000000..694a811
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/UpdateSchedulerResources.properties
@@ -0,0 +1,53 @@
+###############################################################################
+# Copyright (c) 2003, 2008 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
+###############################################################################
+#Messages for Update Scheduler plug-in
+
+SchedulerStartup_day=Every day
+SchedulerStartup_Monday=Every Monday
+SchedulerStartup_Tuesday=Every Tuesday
+SchedulerStartup_Wednesday=Every Wednesday
+SchedulerStartup_Thursday=Every Thursday
+SchedulerStartup_Friday=Every Friday
+SchedulerStartup_Saturday=Every Saturday
+SchedulerStartup_Sunday=Every Sunday
+SchedulerStartup_1AM=1:00 AM
+SchedulerStartup_2AM=2:00 AM
+SchedulerStartup_3AM=3:00 AM
+SchedulerStartup_4AM=4:00 AM
+SchedulerStartup_5AM=5:00 AM
+SchedulerStartup_6AM=6:00 AM
+SchedulerStartup_7AM=7:00 AM
+SchedulerStartup_8AM=8:00 AM
+SchedulerStartup_9AM=9:00 AM
+SchedulerStartup_10AM=10:00 AM
+SchedulerStartup_11AM=11:00 AM
+SchedulerStartup_12PM=12:00 PM
+SchedulerStartup_1PM=1:00 PM
+SchedulerStartup_2PM=2:00 PM
+SchedulerStartup_3PM=3:00 PM
+SchedulerStartup_4PM=4:00 PM
+SchedulerStartup_5PM=5:00 PM
+SchedulerStartup_6PM=6:00 PM
+SchedulerStartup_7PM=7:00 PM
+SchedulerStartup_8PM=8:00 PM
+SchedulerStartup_9PM=9:00 PM
+SchedulerStartup_10PM=10:00 PM
+SchedulerStartup_11PM=11:00 PM
+SchedulerStartup_12AM=12:00 AM
+AutomaticUpdatesJob_AutomaticUpdateSearch=Automatic Update Search
+AutomaticUpdatesPreferencePage_findUpdates=Automatically &find new updates and notify me
+AutomaticUpdatesPreferencePage_UpdateSchedule=Update &Schedule
+AutomaticUpdatesPreferencePage_findOnStart=Look for updates each time &platform is started
+AutomaticUpdatesPreferencePage_findOnSchedule=&Look for updates on the following schedule:
+AutomaticUpdatesPreferencePage_downloadOptions=Download &Options
+AutomaticUpdatesPreferencePage_searchAndNotify=Search for updates and &notify me when they are available
+AutomaticUpdatesPreferencePage_downloadAndNotify=Download new &updates automatically and notify me when ready to install them
+AutomaticUpdatesPreferencePage_at=at
diff --git a/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/preferences/AutomaticUpdatesPreferencePage.java b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/preferences/AutomaticUpdatesPreferencePage.java
new file mode 100644
index 0000000..670cced
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/preferences/AutomaticUpdatesPreferencePage.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.scheduler.preferences;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.update.internal.scheduler.*;
+import org.eclipse.update.internal.scheduler.UpdateSchedulerPlugin;
+
+public class AutomaticUpdatesPreferencePage
+	extends PreferencePage
+	implements IWorkbenchPreferencePage {
+
+	private Button enabledCheck;
+	private Button onStartupRadio;
+	private Button onScheduleRadio;
+	private Combo dayCombo;
+	private Label atLabel;
+	private Combo hourCombo;
+	private Button searchOnlyRadio;
+	private Button searchAndDownloadRadio;
+	private Group updateScheduleGroup;
+	private Group downloadGroup;
+
+	public void init(IWorkbench workbench) {
+	}
+
+	protected Control createContents(Composite parent) {
+		Composite container = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.marginWidth = layout.marginHeight = 0;
+		container.setLayout(layout);
+
+		enabledCheck = new Button(container, SWT.CHECK);
+		enabledCheck.setText(UpdateSchedulerMessages.AutomaticUpdatesPreferencePage_findUpdates); 
+
+		createSpacer(container, 1);
+
+		updateScheduleGroup = new Group(container, SWT.NONE);
+		updateScheduleGroup.setText(UpdateSchedulerMessages.AutomaticUpdatesPreferencePage_UpdateSchedule); 
+		layout = new GridLayout();
+		layout.numColumns = 3;
+		updateScheduleGroup.setLayout(layout);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		updateScheduleGroup.setLayoutData(gd);
+
+		onStartupRadio = new Button(updateScheduleGroup, SWT.RADIO);
+		onStartupRadio.setText(
+			UpdateSchedulerMessages.AutomaticUpdatesPreferencePage_findOnStart); 
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		onStartupRadio.setLayoutData(gd);
+		onStartupRadio.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				pageChanged();
+			}
+		});
+
+		onScheduleRadio = new Button(updateScheduleGroup, SWT.RADIO);
+		onScheduleRadio.setText(UpdateSchedulerMessages.AutomaticUpdatesPreferencePage_findOnSchedule); 
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		onScheduleRadio.setLayoutData(gd);
+		onScheduleRadio.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				pageChanged();
+			}
+		});
+
+		dayCombo = new Combo(updateScheduleGroup, SWT.READ_ONLY);
+		dayCombo.setItems(SchedulerStartup.DAYS);
+		gd = new GridData();
+		gd.widthHint = 200;
+		gd.horizontalIndent = 30;
+		dayCombo.setLayoutData(gd);
+		
+		atLabel = new Label(updateScheduleGroup, SWT.NULL);
+		atLabel.setText(UpdateSchedulerMessages.AutomaticUpdatesPreferencePage_at); 
+		
+		hourCombo = new Combo(updateScheduleGroup, SWT.READ_ONLY);
+		hourCombo.setItems(SchedulerStartup.HOURS);
+		gd = new GridData();
+		//gd.widthHint = 100;
+		hourCombo.setLayoutData(gd);
+	
+		createSpacer(container, 1);
+		
+		downloadGroup = new Group(container, SWT.NONE);
+		downloadGroup.setText(UpdateSchedulerMessages.AutomaticUpdatesPreferencePage_downloadOptions); 
+		layout = new GridLayout();
+		layout.numColumns = 3;
+		downloadGroup.setLayout(layout);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		downloadGroup.setLayoutData(gd);
+
+		searchOnlyRadio = new Button(downloadGroup, SWT.RADIO);
+		searchOnlyRadio.setText(
+			UpdateSchedulerMessages.AutomaticUpdatesPreferencePage_searchAndNotify); 
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		searchOnlyRadio.setLayoutData(gd);
+		searchOnlyRadio.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				pageChanged();
+			}
+		});
+
+		searchAndDownloadRadio = new Button(downloadGroup, SWT.RADIO);
+		searchAndDownloadRadio.setText(UpdateSchedulerMessages.AutomaticUpdatesPreferencePage_downloadAndNotify); 
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		searchAndDownloadRadio.setLayoutData(gd);
+		searchAndDownloadRadio.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				pageChanged();
+			}
+		});
+			
+		initialize();
+
+		enabledCheck.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				pageChanged();
+			}
+		});
+
+		Dialog.applyDialogFont(container);
+		return container;
+	}
+
+	protected void createSpacer(Composite composite, int columnSpan) {
+		Label label = new Label(composite, SWT.NONE);
+		GridData gd = new GridData();
+		gd.horizontalSpan = columnSpan;
+		label.setLayoutData(gd);
+	}
+
+	private void initialize() {
+		Preferences pref = UpdateSchedulerPlugin.getDefault().getPluginPreferences();
+		enabledCheck.setSelection(pref.getBoolean(UpdateSchedulerPlugin.P_ENABLED));
+		setSchedule(pref.getString(UpdateSchedulerPlugin.P_SCHEDULE));
+
+		dayCombo.setText(SchedulerStartup.DAYS[getDay(pref, false)]);
+		hourCombo.setText(SchedulerStartup.HOURS[getHour(pref, false)]);
+		
+		searchOnlyRadio.setSelection(!pref.getBoolean(UpdateSchedulerPlugin.P_DOWNLOAD));
+		searchAndDownloadRadio.setSelection(pref.getBoolean(UpdateSchedulerPlugin.P_DOWNLOAD));
+
+		pageChanged();
+	}
+
+	private void setSchedule(String value) {
+		if (value.equals(UpdateSchedulerPlugin.VALUE_ON_STARTUP))
+			onStartupRadio.setSelection(true);
+		else
+			onScheduleRadio.setSelection(true);
+	}
+
+	private void pageChanged() {
+		boolean master = enabledCheck.getSelection();
+		updateScheduleGroup.setEnabled(master);
+		onStartupRadio.setEnabled(master);
+		onScheduleRadio.setEnabled(master);
+		dayCombo.setEnabled(master && onScheduleRadio.getSelection());
+		atLabel.setEnabled(master && onScheduleRadio.getSelection());
+		hourCombo.setEnabled(master && onScheduleRadio.getSelection());
+		downloadGroup.setEnabled(master);
+		searchOnlyRadio.setEnabled(master);
+		searchAndDownloadRadio.setEnabled(master);
+	}
+
+	protected void performDefaults() {
+		super.performDefaults();
+		Preferences pref = UpdateSchedulerPlugin.getDefault().getPluginPreferences();
+		enabledCheck.setSelection(pref.getDefaultBoolean(UpdateSchedulerPlugin.P_ENABLED));		
+		
+		setSchedule(pref.getDefaultString(UpdateSchedulerPlugin.P_SCHEDULE));
+		onScheduleRadio.setSelection(pref.getDefaultBoolean(UpdateSchedulerPlugin.P_SCHEDULE));
+		
+		dayCombo.setText(SchedulerStartup.DAYS[getDay(pref, true)]);
+		hourCombo.setText(SchedulerStartup.HOURS[getHour(pref, true)]);
+		
+		searchOnlyRadio.setSelection(!pref.getDefaultBoolean(UpdateSchedulerPlugin.P_DOWNLOAD));
+		searchAndDownloadRadio.setSelection(pref.getDefaultBoolean(UpdateSchedulerPlugin.P_DOWNLOAD));
+		pageChanged();
+	}
+
+	/** 
+	 * Method declared on IPreferencePage.
+	 * Subclasses should override
+	 */
+	public boolean performOk() {
+		Preferences pref = UpdateSchedulerPlugin.getDefault().getPluginPreferences();
+		pref.setValue(UpdateSchedulerPlugin.P_ENABLED, enabledCheck.getSelection());
+		if (onStartupRadio.getSelection())
+			pref.setValue(UpdateSchedulerPlugin.P_SCHEDULE, UpdateSchedulerPlugin.VALUE_ON_STARTUP);
+		else 
+			pref.setValue(UpdateSchedulerPlugin.P_SCHEDULE, UpdateSchedulerPlugin.VALUE_ON_SCHEDULE);
+			
+		pref.setValue(SchedulerStartup.P_DAY, dayCombo.getText());
+		pref.setValue(SchedulerStartup.P_HOUR, hourCombo.getText());
+		
+		pref.setValue(UpdateSchedulerPlugin.P_DOWNLOAD, searchAndDownloadRadio.getSelection());
+		
+		UpdateSchedulerPlugin.getDefault().savePluginPreferences();
+		
+		UpdateSchedulerPlugin.getScheduler().scheduleUpdateJob();
+		return true;
+	}
+	
+	private int getDay(Preferences pref, boolean useDefault) {
+		String day = useDefault? pref.getDefaultString(SchedulerStartup.P_DAY): pref.getString(SchedulerStartup.P_DAY);
+		for (int i=0; i<SchedulerStartup.DAYS.length; i++)
+			if (SchedulerStartup.DAYS[i].equals(day))
+				return i;
+		return 0;
+	}
+	
+	private int getHour(Preferences pref, boolean useDefault) {
+		String hour = useDefault? pref.getDefaultString(SchedulerStartup.P_HOUR): pref.getString(SchedulerStartup.P_HOUR);
+		for (int i=0; i<SchedulerStartup.HOURS.length; i++)
+			if (SchedulerStartup.HOURS[i].equals(hour))
+				return i;
+		return 0;
+	}
+}
diff --git a/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/preferences/PreferenceInitializer.java b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..72c7750
--- /dev/null
+++ b/update/org.eclipse.update.scheduler/src/org/eclipse/update/internal/scheduler/preferences/PreferenceInitializer.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ *******************************************************************************/
+package org.eclipse.update.internal.scheduler.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.update.internal.scheduler.UpdateSchedulerPlugin;
+import org.osgi.service.prefs.Preferences;
+
+
+/**
+ * @since 3.1
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+	 */
+	public void initializeDefaultPreferences() {
+		Preferences node = new DefaultScope().getNode("org.eclipse.update.scheduler"); //$NON-NLS-1$
+		node.putBoolean(UpdateSchedulerPlugin.P_ENABLED, false);
+		node.put(UpdateSchedulerPlugin.P_SCHEDULE, UpdateSchedulerPlugin.VALUE_ON_STARTUP);
+		node.putBoolean(UpdateSchedulerPlugin.P_DOWNLOAD, false);
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/.classpath b/update/org.eclipse.update.tests.core/.classpath
new file mode 100644
index 0000000..4848249
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/update/org.eclipse.update.tests.core/.cvsignore b/update/org.eclipse.update.tests.core/.cvsignore
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/.cvsignore
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/.project b/update/org.eclipse.update.tests.core/.project
new file mode 100644
index 0000000..5042624
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/.project
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.update.tests.core</name>

+	<comment></comment>

+	<projects>

+		<project>org.eclipse.core.boot</project>

+		<project>org.eclipse.core.resources</project>

+		<project>org.eclipse.core.runtime</project>

+		<project>org.eclipse.core.runtime.compatibility</project>

+		<project>org.eclipse.help.appserver</project>

+		<project>org.eclipse.tomcat</project>

+		<project>org.eclipse.update.configurator</project>

+		<project>org.eclipse.update.core</project>

+		<project>org.eclipse.update.core.linux</project>

+		<project>org.junit</project>

+	</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.jdt.core.javanature</nature>

+		<nature>org.eclipse.pde.PluginNature</nature>

+	</natures>

+</projectDescription>

diff --git a/update/org.eclipse.update.tests.core/.settings/org.eclipse.jdt.core.prefs b/update/org.eclipse.update.tests.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..5d00398
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,64 @@
+#Wed Feb 25 10:06:41 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=ignore
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
diff --git a/update/org.eclipse.update.tests.core/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..420c8ce
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/META-INF/MANIFEST.MF
@@ -0,0 +1,38 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %name
+Bundle-SymbolicName: org.eclipse.update.tests.core; singleton:=true
+Bundle-Version: 3.3.0.qualifier
+Bundle-ClassPath: updatetests.jar
+Bundle-Activator: org.eclipse.update.tests.UpdateTestsPlugin
+Bundle-Vendor: %provider-name
+Bundle-Localization: plugin
+Export-Package: org.eclipse.update.tests,
+ org.eclipse.update.tests.api,
+ org.eclipse.update.tests.branding,
+ org.eclipse.update.tests.configurations,
+ org.eclipse.update.tests.core.boot,
+ org.eclipse.update.tests.implementation,
+ org.eclipse.update.tests.mirror,
+ org.eclipse.update.tests.model,
+ org.eclipse.update.tests.nativeTests,
+ org.eclipse.update.tests.nestedfeatures,
+ org.eclipse.update.tests.parser,
+ org.eclipse.update.tests.perfms,
+ org.eclipse.update.tests.reconciliation,
+ org.eclipse.update.tests.regularInstall,
+ org.eclipse.update.tests.regularRemove,
+ org.eclipse.update.tests.sitevalidation,
+ org.eclipse.update.tests.standalone,
+ org.eclipse.update.tests.types,
+ org.eclipse.update.tests.uivalues
+Require-Bundle: org.eclipse.core.runtime,
+ org.junit,
+ org.eclipse.update.core,
+ org.eclipse.help.appserver,
+ org.eclipse.update.configurator,
+ org.eclipse.test.performance,
+ org.eclipse.equinox.http.registry
+Eclipse-LazyStart: true
+Import-Package: org.eclipse.equinox.http.jetty,
+ org.osgi.service.http;version="1.2.0"
diff --git a/update/org.eclipse.update.tests.core/about.html b/update/org.eclipse.update.tests.core/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</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
+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/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/features/feature3/feature.xml b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/features/feature3/feature.xml
new file mode 100644
index 0000000..5fc8899
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/features/feature3/feature.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature id="org.eclipse.update.core.tests.feature3" image="feature1.gif" label="Third Feature" provider-name="Smart Company" version="1.0.0" >
+  <description>Description</description>
+  <copyright>copyright</copyright>
+  <license>license</license>
+  <url>
+    <update label="URL to update the feature" url="http://www.eclipse.org/path/feature1/"/>
+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>
+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>
+  </url>
+  <plugin download-size="1500" id="org.eclipse.update.core.tests.feature1.plugin1" install-size="1000" fragment="false" nl="en" os="WIN32,LINUX,HPUX,MACOSX,AIX,SOLARIS,QNX,UNKNOWN" version="3.5.6" ws="WIN32,MOTIF,GTK,CARBON,PHOTON,COCOA,UNKNOWN"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/Pde_core.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/Pde_core.jar
new file mode 100644
index 0000000..f107217
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/Pde_core.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/help.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/help.jar
new file mode 100644
index 0000000..7584f66
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/help.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/junit_3.7.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/junit_3.7.jar
new file mode 100644
index 0000000..67587b2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/junit_3.7.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
new file mode 100644
index 0000000..7f05d82
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.feature1.plugin1" version="3.5.6" vendor-name="junit.org">

+  <runtime>

+    <library name="junit.jar">

+      <export name="*"/>

+    </library>

+  </runtime>

+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/org.eclipse.update.plugin1_1.1.1/src.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
new file mode 100644
index 0000000..2d4d609
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/features/feature3/feature.xml b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/features/feature3/feature.xml
new file mode 100644
index 0000000..8bf1485
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/features/feature3/feature.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature id="org.eclipse.update.core.tests.feature3" image="feature1.gif" label="Third Feature" provider-name="Smart Company" version="1.0.0" >
+  <description>Description</description>
+  <copyright>copyright</copyright>
+  <license>license</license>
+  <url>
+    <update label="URL to update the feature" url="http://www.eclipse.org/path/feature1/"/>
+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>
+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>
+  </url>
+  <plugin download-size="1500" id="org.eclipse.update.plugin1" install-size="1000" fragment="false" nl="en,fr" os="WIN32,LINUX,HPUX,MACOSX,AIX,SOLARIS,QNX,UNKNOWN" version="1.1.1" ws="WIN32,MOTIF,GTK,CARBON,PHOTON,COCOA,UNKNOWN"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/features/helpFeature.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/features/helpFeature.jar
new file mode 100644
index 0000000..2ee8e8f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/features/helpFeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/features/org.eclipse.pde.feature_1.0.0.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/features/org.eclipse.pde.feature_1.0.0.jar
new file mode 100644
index 0000000..7e23cab
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/features/org.eclipse.pde.feature_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/info/img/top_titlsm.gif b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/info/img/top_titlsm.gif
new file mode 100644
index 0000000..3917bb6
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/info/img/top_titlsm.gif
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/info/img/wel_ml.jpg b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/info/img/wel_ml.jpg
new file mode 100644
index 0000000..01e33df
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/info/img/wel_ml.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/info/siteInfo.html b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/info/siteInfo.html
new file mode 100644
index 0000000..b065aa3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/info/siteInfo.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

+<html>

+<head>

+</head>

+  <body>

+<img src="img/top_titlsm.gif" alt="" width="460" height="50">

+<br>

+<br>

+     It started with Smalltalk<br>

+    OTI has been building tools for platform-independent OO development since

+  1988. Our ENVY&reg; technology first brought collaborative software development,

+  version management and shared repositories to Smalltalk. IBM is one of

+many   companies to license ENVY, which continues to be the foundation of

+VisualAge&reg;   Smalltalk.<br>

+<br>

+<br>

+<br>

+      Next came Java&#8482;<br>

+    Because of our expertise in OO technology, IBM turned to OTI for a next-generation

+  development environment for Java. The result is VisualAge for Java, which

+  continues to win awards for its innovative IDE and team support. InfoWorld

+  has chosen VisualAge for Java as development tool of the year - year after

+  year after year!<br>

+<br>

+<br>

+<br>

+      Then pervasive computing<br>

+    OTI continues its development of IBM's VisualAge Micro Edition, a state-of-the-art

+  platform for collaborative development of embedded applications and systems

+  that are very lean. As the steady stream of press releases attests, VisualAge

+  Micro Edition is already licensed to the leading microchip manufacturers,

+  microkernel developers, and producers of handheld and consumer devices.<br>

+<br>

+<br>

+<br>

+      Now it's Eclipse<br>

+    OTI has built the next generation IBM application development tools platform.

+  Eclipse is a kind of universal tool platform - an open extensible IDE for

+  anything and nothing in particular. The real value comes from tool plug-ins

+  that "teach" Eclipse how to work with things - java files, web content,

+graphics,  video - almost anything you can imagine. Eclipse allows you to

+independently  develop tools that integrate with other people's tools so

+seamlessly you won't know where one tool ends and another starts. The IBM

+supported version of this technology, WebSphere Studio Workbench, will be

+the core of the next  generation of IBM and IBM Business Partner e-business

+tools optimized for  the WebSphere software platform.<br>

+<br>

+<br>

+<br>

+      So what's next?<br>

+    OTI continues to deliver object-oriented technology that scales across

+ platforms,  across teams and across project size. From a mainframe to a

+watch  - we're  closing in on that vision.<br>

+<br>

+<img src="img/wel_ml.jpg" width="460" height="460" alt="">

+<br>

+<br>

+<br>

+<br>

+<br>

+<br>

+</body>

+</html>

diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/Pde_core.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/Pde_core.jar
new file mode 100644
index 0000000..f107217
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/Pde_core.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/help.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/help.jar
new file mode 100644
index 0000000..7584f66
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/help.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/junit_3.7.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/junit_3.7.jar
new file mode 100644
index 0000000..67587b2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/junit_3.7.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
new file mode 100644
index 0000000..7f05d82
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.feature1.plugin1" version="3.5.6" vendor-name="junit.org">

+  <runtime>

+    <library name="junit.jar">

+      <export name="*"/>

+    </library>

+  </runtime>

+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/org.eclipse.update.plugin1_1.1.1/src.jar b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
new file mode 100644
index 0000000..2d4d609
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/site.xml b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/site.xml
new file mode 100644
index 0000000..b6211a8
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/ExecutableFeaturePackagedSite/data2/site.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.core.file">

+<description url="info/siteInfo.html"/>

+  <feature url="features/helpFeature.jar" type="org.eclipse.update.core.packaged">

+    <category name="eclipse/UML"/>

+  </feature>

+  <feature url="features/org.eclipse.pde.feature_1.0.0.jar" type="org.eclipse.update.core.packaged">

+    <category name="eclipse/J2EE"/>

+  </feature>

+  <feature url="features/feature3/" os="LINUX">

+    <category name="eclipse"/>

+  </feature>

+  <archive path="plugins/org.eclipse.help_1.0.0.jar" url="plugins/help.jar"/>

+  <archive path="plugins/org.eclipse.pde.core_1.0.0.jar" url="plugins/Pde_core.jar"/>

+  <archive path="plugins/org.junit_3.5.0.jar" url="plugins/junit_3.7.jar"/>

+  <archive path="plugins/org.eclipse.update.plugin1_1.1.1.jar" url="plugins/org.eclipse.update.plugin1_1.1.1"/>  

+  <category-def label="IBM WSAD Tools" name="eclipse"/>

+  <category-def label="J2EE tools" name="eclipse/J2EE"/>

+  <category-def label="EJB Tools" name="eclipse/J2EE/EJB"/>

+  <category-def label="UML tools" name="eclipse/UML"/>

+  <category-def label="Messaging Tools" name="B2B"/>  

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/FTPLikeSite/site.xml b/update/org.eclipse.update.tests.core/data/FTPLikeSite/site.xml
new file mode 100644
index 0000000..da62e2e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/FTPLikeSite/site.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.tests.core.ftp">

+  <feature url="features/feature3/features2.jarfile"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site1/features/feature3/feature.xml b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site1/features/feature3/feature.xml
new file mode 100644
index 0000000..2c98f42
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site1/features/feature3/feature.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature id="org.eclipse.update.core.tests.feature3" image="feature1.gif" label="Third Feature" provider-name="Smart Company" version="1.0.0">

+  <description>Description</description>

+  <copyright>copyright</copyright>

+  <license>license</license>

+  <url>

+    <update label="URL to update the feature" url="http://www.eclipse.org/path/feature1/"/>

+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>

+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>

+  </url>

+  <plugin download-size="1500" id="org.eclipse.update.plugin1" install-size="1000" fragment="false" os="WIN32,LINUX" version="1.1.1" ws="WIN32,MOTIF,GTK"/>

+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site1/site.xml b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site1/site.xml
new file mode 100644
index 0000000..486d119
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site1/site.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.core.file">

+  <feature url="features/feature3" type="org.eclipse.update.tests.core.feature1"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site2/features/feature3/features2.jarfile b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site2/features/feature3/features2.jarfile
new file mode 100644
index 0000000..240ab4f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site2/features/feature3/features2.jarfile
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site2/site.xml b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site2/site.xml
new file mode 100644
index 0000000..fb5fe0e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site2/site.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.core.file">

+  <feature url="features/feature3/features2.jarfile" type="org.eclipse.update.core.packaged"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site3/features/feature3/features2.jarfile b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site3/features/feature3/features2.jarfile
new file mode 100644
index 0000000..240ab4f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site3/features/feature3/features2.jarfile
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site3/site.xml b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site3/site.xml
new file mode 100644
index 0000000..daf372d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/FeatureTypeExamples/site3/site.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.core.file">

+  <feature url="features/feature3/features2.jarfile" type="org.eclipse.update.core.unknowntype.jar"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/features space/helpFeature.jar b/update/org.eclipse.update.tests.core/data/Site with space/features space/helpFeature.jar
new file mode 100644
index 0000000..56afef6
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/features space/helpFeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/features space/space feature.jar b/update/org.eclipse.update.tests.core/data/Site with space/features space/space feature.jar
new file mode 100644
index 0000000..0fc1a6e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/features space/space feature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/info/img/top_titlsm.gif b/update/org.eclipse.update.tests.core/data/Site with space/info/img/top_titlsm.gif
new file mode 100644
index 0000000..3917bb6
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/info/img/top_titlsm.gif
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/info/img/wel_ml.jpg b/update/org.eclipse.update.tests.core/data/Site with space/info/img/wel_ml.jpg
new file mode 100644
index 0000000..01e33df
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/info/img/wel_ml.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/info/siteInfo.html b/update/org.eclipse.update.tests.core/data/Site with space/info/siteInfo.html
new file mode 100644
index 0000000..b065aa3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/info/siteInfo.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

+<html>

+<head>

+</head>

+  <body>

+<img src="img/top_titlsm.gif" alt="" width="460" height="50">

+<br>

+<br>

+     It started with Smalltalk<br>

+    OTI has been building tools for platform-independent OO development since

+  1988. Our ENVY&reg; technology first brought collaborative software development,

+  version management and shared repositories to Smalltalk. IBM is one of

+many   companies to license ENVY, which continues to be the foundation of

+VisualAge&reg;   Smalltalk.<br>

+<br>

+<br>

+<br>

+      Next came Java&#8482;<br>

+    Because of our expertise in OO technology, IBM turned to OTI for a next-generation

+  development environment for Java. The result is VisualAge for Java, which

+  continues to win awards for its innovative IDE and team support. InfoWorld

+  has chosen VisualAge for Java as development tool of the year - year after

+  year after year!<br>

+<br>

+<br>

+<br>

+      Then pervasive computing<br>

+    OTI continues its development of IBM's VisualAge Micro Edition, a state-of-the-art

+  platform for collaborative development of embedded applications and systems

+  that are very lean. As the steady stream of press releases attests, VisualAge

+  Micro Edition is already licensed to the leading microchip manufacturers,

+  microkernel developers, and producers of handheld and consumer devices.<br>

+<br>

+<br>

+<br>

+      Now it's Eclipse<br>

+    OTI has built the next generation IBM application development tools platform.

+  Eclipse is a kind of universal tool platform - an open extensible IDE for

+  anything and nothing in particular. The real value comes from tool plug-ins

+  that "teach" Eclipse how to work with things - java files, web content,

+graphics,  video - almost anything you can imagine. Eclipse allows you to

+independently  develop tools that integrate with other people's tools so

+seamlessly you won't know where one tool ends and another starts. The IBM

+supported version of this technology, WebSphere Studio Workbench, will be

+the core of the next  generation of IBM and IBM Business Partner e-business

+tools optimized for  the WebSphere software platform.<br>

+<br>

+<br>

+<br>

+      So what's next?<br>

+    OTI continues to deliver object-oriented technology that scales across

+ platforms,  across teams and across project size. From a mainframe to a

+watch  - we're  closing in on that vision.<br>

+<br>

+<img src="img/wel_ml.jpg" width="460" height="460" alt="">

+<br>

+<br>

+<br>

+<br>

+<br>

+<br>

+</body>

+</html>

diff --git a/update/org.eclipse.update.tests.core/data/Site with space/install/features space/feature3/feature.xml b/update/org.eclipse.update.tests.core/data/Site with space/install/features space/feature3/feature.xml
new file mode 100644
index 0000000..5cb89fc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/install/features space/feature3/feature.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature id="org.eclipse.update.core.tests.feature3" image="feature1.gif" label="Third Feature" provider-name="Smart Company" version="1.0.0" >
+  <description>Description</description>
+  <copyright>copyright</copyright>
+  <license>license</license>
+  <url>
+    <update label="URL to update the feature" url="http://www.eclipse.org/path/feature1/"/>
+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>
+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>
+  </url>
+  <plugin download-size="1500" id="org.eclipse.update.plugin1" install-size="1000" fragment="false" nl="en,fr" os="WIN32,LINUX,HPUX,MACOSX" version="1.1.1" ws="WIN32,MOTIF,GTK,CARBON,COCOA"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/plugins space/Pde_core.jar b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/Pde_core.jar
new file mode 100644
index 0000000..f107217
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/Pde_core.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/plugins space/help.jar b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/help.jar
new file mode 100644
index 0000000..7584f66
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/help.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/plugins space/junit_3.7.jar b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/junit_3.7.jar
new file mode 100644
index 0000000..67587b2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/junit_3.7.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/plugins space/org.eclipse.update.plugin1_1.1.1/plugin.xml b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/org.eclipse.update.plugin1_1.1.1/plugin.xml
new file mode 100644
index 0000000..e01846c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/org.eclipse.update.plugin1_1.1.1/plugin.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.feature1.plugin1" version="3.5.6" vendor-name="junit.org">
+  <runtime>
+    <library name="junit.jar">
+      <export name="*"/>
+    </library>
+  </runtime>
+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/plugins space/org.eclipse.update.plugin1_1.1.1/src.jar b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/org.eclipse.update.plugin1_1.1.1/src.jar
new file mode 100644
index 0000000..2d4d609
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/plugins space/org.eclipse.update.plugin1_1.1.1/src.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/Site with space/site.xml b/update/org.eclipse.update.tests.core/data/Site with space/site.xml
new file mode 100644
index 0000000..54928fb
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/Site with space/site.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.core.file">

+<description url="info/siteInfo.html"/>

+  <feature url="features space/helpFeature.jar" type="org.eclipse.update.core.packaged">

+    <category name="eclipse/UML"/>

+  </feature>

+  <feature url="features space/space feature.jar" type="org.eclipse.update.core.packaged">

+    <category name="eclipse/J2EE"/>

+  </feature>

+  <feature url="install/features space/feature3/">

+    <category name="eclipse"/>

+  </feature>

+  <archive path="plugins/org.eclipse.help_1.0.0.jar" url="plugins space/help.jar"/>

+  <archive path="plugins/org.eclipse.pde.core_1.0.0.jar" url="plugins space/Pde_core.jar"/>

+  <archive path="plugins/org.junit_3.5.0.jar" url="plugins space/junit_3.7.jar"/>

+  <archive path="plugins/org.eclipse.update.plugin1_1.1.1.jar" url="plugins space/org.eclipse.update.plugin1_1.1.1"/>  

+  <category-def label="IBM WSAD Tools" name="eclipse"/>

+  <category-def label="J2EE tools" name="eclipse/J2EE"/>

+  <category-def label="EJB Tools" name="eclipse/J2EE/EJB"/>

+  <category-def label="UML tools" name="eclipse/UML"/>

+  <category-def label="Messaging Tools" name="B2B"/>  

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/SiteTypeExamples/site1/features/feature3/features2.jarfile b/update/org.eclipse.update.tests.core/data/SiteTypeExamples/site1/features/feature3/features2.jarfile
new file mode 100644
index 0000000..240ab4f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteTypeExamples/site1/features/feature3/features2.jarfile
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/SiteTypeExamples/site1/site.xml b/update/org.eclipse.update.tests.core/data/SiteTypeExamples/site1/site.xml
new file mode 100644
index 0000000..6f7165a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteTypeExamples/site1/site.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.core.http">

+  <feature url="features/feature3/features2.jarfile"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/features/helpFeature.jar b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/features/helpFeature.jar
new file mode 100644
index 0000000..9809713
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/features/helpFeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/features/org.eclipse.pde.feature_1.0.0.jar b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/features/org.eclipse.pde.feature_1.0.0.jar
new file mode 100644
index 0000000..f592c1d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/features/org.eclipse.pde.feature_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/plugins/Pde_core.jar b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/plugins/Pde_core.jar
new file mode 100644
index 0000000..f107217
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/plugins/Pde_core.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/plugins/help.jar b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/plugins/help.jar
new file mode 100644
index 0000000..7584f66
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/plugins/help.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/plugins/junit_3.7.jar b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/plugins/junit_3.7.jar
new file mode 100644
index 0000000..67587b2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/artifacts/plugins/junit_3.7.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/SiteURLTest/data/info/img/top_titlsm.gif b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/info/img/top_titlsm.gif
new file mode 100644
index 0000000..3917bb6
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/info/img/top_titlsm.gif
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/SiteURLTest/data/info/img/wel_ml.jpg b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/info/img/wel_ml.jpg
new file mode 100644
index 0000000..01e33df
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/info/img/wel_ml.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/SiteURLTest/data/info/siteInfo.html b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/info/siteInfo.html
new file mode 100644
index 0000000..b065aa3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/info/siteInfo.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

+<html>

+<head>

+</head>

+  <body>

+<img src="img/top_titlsm.gif" alt="" width="460" height="50">

+<br>

+<br>

+     It started with Smalltalk<br>

+    OTI has been building tools for platform-independent OO development since

+  1988. Our ENVY&reg; technology first brought collaborative software development,

+  version management and shared repositories to Smalltalk. IBM is one of

+many   companies to license ENVY, which continues to be the foundation of

+VisualAge&reg;   Smalltalk.<br>

+<br>

+<br>

+<br>

+      Next came Java&#8482;<br>

+    Because of our expertise in OO technology, IBM turned to OTI for a next-generation

+  development environment for Java. The result is VisualAge for Java, which

+  continues to win awards for its innovative IDE and team support. InfoWorld

+  has chosen VisualAge for Java as development tool of the year - year after

+  year after year!<br>

+<br>

+<br>

+<br>

+      Then pervasive computing<br>

+    OTI continues its development of IBM's VisualAge Micro Edition, a state-of-the-art

+  platform for collaborative development of embedded applications and systems

+  that are very lean. As the steady stream of press releases attests, VisualAge

+  Micro Edition is already licensed to the leading microchip manufacturers,

+  microkernel developers, and producers of handheld and consumer devices.<br>

+<br>

+<br>

+<br>

+      Now it's Eclipse<br>

+    OTI has built the next generation IBM application development tools platform.

+  Eclipse is a kind of universal tool platform - an open extensible IDE for

+  anything and nothing in particular. The real value comes from tool plug-ins

+  that "teach" Eclipse how to work with things - java files, web content,

+graphics,  video - almost anything you can imagine. Eclipse allows you to

+independently  develop tools that integrate with other people's tools so

+seamlessly you won't know where one tool ends and another starts. The IBM

+supported version of this technology, WebSphere Studio Workbench, will be

+the core of the next  generation of IBM and IBM Business Partner e-business

+tools optimized for  the WebSphere software platform.<br>

+<br>

+<br>

+<br>

+      So what's next?<br>

+    OTI continues to deliver object-oriented technology that scales across

+ platforms,  across teams and across project size. From a mainframe to a

+watch  - we're  closing in on that vision.<br>

+<br>

+<img src="img/wel_ml.jpg" width="460" height="460" alt="">

+<br>

+<br>

+<br>

+<br>

+<br>

+<br>

+</body>

+</html>

diff --git a/update/org.eclipse.update.tests.core/data/SiteURLTest/data/site.xml b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/site.xml
new file mode 100644
index 0000000..e3ea684
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/SiteURLTest/data/site.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site url = "artifacts/">
+<description url="info/siteInfo.html"/>
+  <feature url="features/helpFeature.jar" type="org.eclipse.update.core.packaged">
+    <category name="eclipse/UML"/>
+  </feature>
+  <feature url="features/org.eclipse.pde.feature_1.0.0.jar" type="org.eclipse.update.core.packaged">
+    <category name="eclipse/J2EE"/>
+  </feature>
+  <archive path="plugins/org.eclipse.help_1.0.0.jar" url="plugins/help.jar"/>
+  <archive path="plugins/org.eclipse.pde.core_1.0.0.jar" url="plugins/Pde_core.jar"/>
+  <archive path="plugins/org.junit_3.5.0.jar" url="plugins/junit_3.7.jar"/>
+  <category-def label="IBM WSAD Tools" name="eclipse"/>
+  <category-def label="J2EE tools" name="eclipse/J2EE"/>
+  <category-def label="EJB Tools" name="eclipse/J2EE/EJB"/>
+  <category-def label="UML tools" name="eclipse/UML"/>
+  <category-def label="Messaging Tools" name="B2B"/>  
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site1/file1.zip b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site1/file1.zip
new file mode 100644
index 0000000..1a70b7e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site1/file1.zip
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site1/install/features/feature3/feature.xml b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site1/install/features/feature3/feature.xml
new file mode 100644
index 0000000..6b454ec
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site1/install/features/feature3/feature.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature id="org.eclipse.update.core.tests.feature3" image="feature1.gif" label="Third Feature" provider-name="Smart Company" version="1.0.0">

+	<install-handler handler="org.eclipse.update.core.DefaultInstallHandler"/>

+  	<data download-size="1500" id="file.zip" install-size="1000"/>

+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site1/site.xml b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site1/site.xml
new file mode 100644
index 0000000..c41f21d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site1/site.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.core.file">

+<description url="info/siteInfo.html"/>

+  <feature url="install/features/feature3">

+  </feature>

+  <archive path="features/org.eclipse.update.core.tests.feature3_1.0.0/file.zip" url="file1.zip"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site2/features/features3.jar b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site2/features/features3.jar
new file mode 100644
index 0000000..74c6eca
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site2/features/features3.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site2/non data/another file.zip b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site2/non data/another file.zip
new file mode 100644
index 0000000..1a70b7e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site2/non data/another file.zip
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site2/site.xml b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site2/site.xml
new file mode 100644
index 0000000..040943c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/dataEntrySiteTest/site2/site.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.core.file">

+<description url="info/siteInfo.html"/>

+  <feature url="features/features3.jar" type="org.eclipse.update.core.packaged">

+  </feature>

+  <archive path="features/org.eclipse.update.core.tests.feature3_1.0.0/file.zip" url="non data/another file.zip"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/features/features2.jar b/update/org.eclipse.update.tests.core/data/features/features2.jar
new file mode 100644
index 0000000..e8d004d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/features/features2.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/features/org.eclipse.test.feature_1.0.0.jar b/update/org.eclipse.update.tests.core/data/features/org.eclipse.test.feature_1.0.0.jar
new file mode 100644
index 0000000..870a70d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/features/org.eclipse.test.feature_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/features/org.eclipse.update.core.tests.feature1_1.0.4.jar b/update/org.eclipse.update.tests.core/data/features/org.eclipse.update.core.tests.feature1_1.0.4.jar
new file mode 100644
index 0000000..f1c7153
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/features/org.eclipse.update.core.tests.feature1_1.0.4.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/features/org.eclipse_test_feature.jar b/update/org.eclipse.update.tests.core/data/features/org.eclipse_test_feature.jar
new file mode 100644
index 0000000..938ddc4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/features/org.eclipse_test_feature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/.project b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/.project
new file mode 100644
index 0000000..5d52069
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>update-site1</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.UpdateSiteBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.UpdateSiteNature</nature>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/.sitebuild/build.log b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/.sitebuild/build.log
new file mode 100644
index 0000000..3bce194
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/.sitebuild/build.log
@@ -0,0 +1,318 @@
+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin3.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: javac

+Message logged: Compile failed; see the compiler error output for details.

+Task finished: javac

+Task started: copy

+Task finished: copy

+Task started: mkdir

+Task finished: mkdir

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: plugin3.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin4.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: javac

+Message logged: Compile failed; see the compiler error output for details.

+Task finished: javac

+Task started: copy

+Task finished: copy

+Task started: mkdir

+Task finished: mkdir

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: plugin4.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature3_1.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Build finished.

diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/.sitebuild/sitebuild.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/.sitebuild/sitebuild.xml
new file mode 100644
index 0000000..1e700b9
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/.sitebuild/sitebuild.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site-build
+      feature-location="features"
+      plugin-location="plugins"
+      autobuild="false"
+      scrub-output="false"
+      use-console="true">
+   <feature id="update.feature1" version="1.0.0"/>
+   <feature id="update.feature2" version="1.0.0"/>
+   <feature id="update.feature3" version="1.0.0"/>
+</site-build>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/features/update.feature1_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/features/update.feature1_1.0.0.jar
new file mode 100644
index 0000000..c812b0b
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/features/update.feature1_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/features/update.feature2_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/features/update.feature2_1.0.0.jar
new file mode 100644
index 0000000..fbf1754
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/features/update.feature2_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/features/update.feature3_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/features/update.feature3_1.0.0.jar
new file mode 100644
index 0000000..8682a62
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/features/update.feature3_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin1_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin1_1.0.0.jar
new file mode 100644
index 0000000..8bbc7f3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin1_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin2_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin2_1.0.0.jar
new file mode 100644
index 0000000..5d42583
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin2_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin3_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin3_1.0.0.jar
new file mode 100644
index 0000000..aa94e52
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin3_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin4_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin4_1.0.0.jar
new file mode 100644
index 0000000..c8cca28
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/plugins/com.plugin4_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site1/site.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/site.xml
new file mode 100644
index 0000000..163f7bb
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site1/site.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <feature url="features/update.feature1_1.0.0.jar" id="update.feature1" version="1.0.0">
+      <category name="Site1-Category1"/>
+   </feature>
+   <feature url="features/update.feature2_1.0.0.jar" id="update.feature2" version="1.0.0">
+      <category name="Site1-Category2"/>
+   </feature>
+   <feature url="features/update.feature3_1.0.0.jar" id="update.feature3" version="1.0.0">
+      <category name="Site1-Category3"/>
+   </feature>
+   <category-def name="Site1-Category1" label="Site1-Category1-Label">
+      <description>
+         ecetera.
+      </description>
+   </category-def>
+   <category-def name="Site1-Category2" label="Site1-Category2-Label">
+      <description>
+         ecetera.
+      </description>
+   </category-def>
+   <category-def name="Site1-Category3" label="Site1-Category3-Label">
+      <description>
+         ecetera.
+      </description>
+   </category-def>
+</site>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site2/.project b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/.project
new file mode 100644
index 0000000..a4b687e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>update-site2</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.UpdateSiteBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.UpdateSiteNature</nature>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site2/.sitebuild/build.log b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/.sitebuild/build.log
new file mode 100644
index 0000000..e977850
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/.sitebuild/build.log
@@ -0,0 +1,203 @@
+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin2.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: javac

+Message logged: Compile failed; see the compiler error output for details.

+Task finished: javac

+Task started: copy

+Task finished: copy

+Task started: mkdir

+Task finished: mkdir

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: plugin2.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature2_1.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Build finished.

diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site2/.sitebuild/sitebuild.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/.sitebuild/sitebuild.xml
new file mode 100644
index 0000000..2258820
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/.sitebuild/sitebuild.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site-build
+      feature-location="features"
+      plugin-location="plugins"
+      autobuild="false"
+      scrub-output="false"
+      use-console="true">
+   <feature id="update.feature1" version="1.0.1"/>
+   <feature id="update.feature2" version="1.0.1"/>
+</site-build>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site2/features/update.feature1_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/features/update.feature1_1.0.0.jar
new file mode 100644
index 0000000..5175b4a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/features/update.feature1_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site2/features/update.feature2_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/features/update.feature2_1.0.0.jar
new file mode 100644
index 0000000..d1660b9
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/features/update.feature2_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site2/plugins/com.plugin1_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/plugins/com.plugin1_1.0.0.jar
new file mode 100644
index 0000000..d815f20
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/plugins/com.plugin1_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site2/plugins/com.plugin2_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/plugins/com.plugin2_1.0.0.jar
new file mode 100644
index 0000000..dec5f4c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/plugins/com.plugin2_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site2/site.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/site.xml
new file mode 100644
index 0000000..f1d4b71
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site2/site.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <feature url="features/update.feature1_1.0.1.jar" id="update.feature1" version="1.0.1"/>
+   <feature url="features/update.feature2_1.0.1.jar" id="update.feature2" version="1.0.1"/>
+</site>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/.project b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/.project
new file mode 100644
index 0000000..0ddb6b7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>update-site3</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.UpdateSiteBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.UpdateSiteNature</nature>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/.sitebuild/build.log b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/.sitebuild/build.log
new file mode 100644
index 0000000..4a2ee01
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/.sitebuild/build.log
@@ -0,0 +1,318 @@
+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin2a.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: javac

+Message logged: Compile failed; see the compiler error output for details.

+Task finished: javac

+Task started: copy

+Task finished: copy

+Task started: mkdir

+Task finished: mkdir

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: plugin2a.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin2.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: javac

+Message logged: Compile failed; see the compiler error output for details.

+Task finished: javac

+Task started: copy

+Task finished: copy

+Task started: mkdir

+Task finished: mkdir

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: plugin2.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature2b_2.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Build finished.

diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/.sitebuild/sitebuild.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/.sitebuild/sitebuild.xml
new file mode 100644
index 0000000..e3510b0
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/.sitebuild/sitebuild.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site-build
+      feature-location="features"
+      plugin-location="plugins"
+      autobuild="false"
+      scrub-output="false"
+      use-console="true">
+   <feature id="update.feature1b" version="2.0.0"/>
+   <feature id="update.feature2b" version="2.0.0"/>
+</site-build>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/features/update.feature1b_2.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/features/update.feature1b_2.0.0.jar
new file mode 100644
index 0000000..6b9a876
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/features/update.feature1b_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/features/update.feature2b_2.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/features/update.feature2b_2.0.0.jar
new file mode 100644
index 0000000..97bb70f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/features/update.feature2b_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin1_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin1_1.0.0.jar
new file mode 100644
index 0000000..ee2d41d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin1_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin1a_1.0.1.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin1a_1.0.1.jar
new file mode 100644
index 0000000..97183c7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin1a_1.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin2_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin2_1.0.0.jar
new file mode 100644
index 0000000..e31b28e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin2_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin2a_1.0.1.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin2a_1.0.1.jar
new file mode 100644
index 0000000..557ba5d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/plugins/com.plugin2a_1.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site3/site.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/site.xml
new file mode 100644
index 0000000..e28506b
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site3/site.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <feature url="features/update.feature1b_2.0.0.jar" id="update.feature1b" version="2.0.0">
+      <category name="Site3-Category1"/>
+   </feature>
+   <feature url="features/update.feature2b_2.0.0.jar" id="update.feature2b" version="2.0.0">
+      <category name="Site3-Category2"/>
+   </feature>
+   <category-def name="Site3-Category1" label="Site3-Category1-Label">
+      <description>
+         ecetera.
+      </description>
+   </category-def>
+   <category-def name="Site3-Category2" label="Site3-Category2-Label">
+      <description>
+         ecetera.
+      </description>
+   </category-def>
+</site>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/.project b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/.project
new file mode 100644
index 0000000..8a07aaf
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>update-site4</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.UpdateSiteBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.UpdateSiteNature</nature>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/.sitebuild/build.log b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/.sitebuild/build.log
new file mode 100644
index 0000000..1cfe8e3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/.sitebuild/build.log
@@ -0,0 +1,791 @@
+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin1.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: javac

+Message logged: Compile failed; see the compiler error output for details.

+Task finished: javac

+Task started: copy

+Task finished: copy

+Task started: mkdir

+Task finished: mkdir

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: plugin1.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin1.jar

+Target finished: plugin1.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin1.jar

+Target finished: plugin1.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin1a.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: javac

+Message logged: Compile failed; see the compiler error output for details.

+Task finished: javac

+Task started: copy

+Task finished: copy

+Task started: mkdir

+Task finished: mkdir

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: plugin1a.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.features

+Target started: all.plugins

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature1c_3.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature1_1.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Task finished: ant

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature1_1.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Task finished: ant

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature1b_2.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Task finished: ant

+Target finished: all.features

+Target started: all.plugins

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Build finished.

diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/.sitebuild/sitebuild.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/.sitebuild/sitebuild.xml
new file mode 100644
index 0000000..47cb017
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/.sitebuild/sitebuild.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site-build
+      feature-location="features"
+      plugin-location="plugins"
+      autobuild="false"
+      scrub-output="false"
+      use-console="true">
+   <feature id="update.feature1c" version="3.0.0"/>
+</site-build>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1_1.0.0.jar
new file mode 100644
index 0000000..78d2f28
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1_1.0.1.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1_1.0.1.jar
new file mode 100644
index 0000000..eeb0b6f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1_1.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1b_2.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1b_2.0.0.jar
new file mode 100644
index 0000000..31b6bcb
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1b_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1c_3.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1c_3.0.0.jar
new file mode 100644
index 0000000..3753305
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/features/update.feature1c_3.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/plugins/com.plugin1_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/plugins/com.plugin1_1.0.0.jar
new file mode 100644
index 0000000..3e0760f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/plugins/com.plugin1_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/plugins/com.plugin1a_1.0.1.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/plugins/com.plugin1a_1.0.1.jar
new file mode 100644
index 0000000..634eb07
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/plugins/com.plugin1a_1.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site4/site.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/site.xml
new file mode 100644
index 0000000..2c73cbe
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site4/site.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <feature url="features/update.feature1c_3.0.0.jar" id="update.feature1c" version="3.0.0">
+      <category name="Site4-Category1"/>
+   </feature>
+   <category-def name="Site4-Category1" label="Site4-Category1-Label">
+      <description>
+         ecetera.
+      </description>
+   </category-def>
+</site>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/.project b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/.project
new file mode 100644
index 0000000..0a93302
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>update-site5</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.UpdateSiteBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.UpdateSiteNature</nature>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/.sitebuild/build.log b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/.sitebuild/build.log
new file mode 100644
index 0000000..db44faa
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/.sitebuild/build.log
@@ -0,0 +1,791 @@
+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin2.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: javac

+Message logged: Compile failed; see the compiler error output for details.

+Task finished: javac

+Task started: copy

+Task finished: copy

+Task started: mkdir

+Task finished: mkdir

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: plugin2.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin2.jar

+Target finished: plugin2.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin2a.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: javac

+Message logged: Compile failed; see the compiler error output for details.

+Task finished: javac

+Task started: copy

+Task finished: copy

+Task started: mkdir

+Task finished: mkdir

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: plugin2a.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.update.jar

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: build.jars

+Task started: available

+Task finished: available

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: plugin2.jar

+Target finished: plugin2.jar

+Task finished: antcall

+Target finished: build.jars

+Task finished: antcall

+Task started: antcall

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: copy

+Task finished: copy

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: zip

+Task finished: zip

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Task finished: ant

+Target finished: all.features

+Target started: all.plugins

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Task started: property

+Task finished: property

+Task started: delete

+Task finished: delete

+Task started: mkdir

+Task finished: mkdir

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: gather.bin.parts

+Task started: antcall

+Target started: children

+Target finished: children

+Task finished: antcall

+Task started: mkdir

+Task finished: mkdir

+Task started: copy

+Task finished: copy

+Task started: eclipse.idReplacer

+Task finished: eclipse.idReplacer

+Task started: antcall

+Target started: ROOTFILES*_*_*

+Target finished: ROOTFILES*_*_*

+Task finished: antcall

+Target finished: gather.bin.parts

+Task finished: antcall

+Task started: jar

+Task finished: jar

+Task started: delete

+Task finished: delete

+Target finished: build.update.jar

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature2c_3.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature2_1.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Task finished: ant

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature2_1.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Task finished: ant

+Task started: ant

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Message logged: Project ${update.feature2b_2.0.0} does not exist and cannot be refreshed.

+Task finished: eclipse.refreshLocal

+Task started: antcall

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: all.features

+Target finished: all.features

+Target started: all.plugins

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Task started: ant

+Target started: properties

+Task started: property

+Task finished: property

+Target finished: properties

+Target started: init

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Task started: property

+Task finished: property

+Target finished: init

+Target started: refresh

+Task started: eclipse.convertPath

+Task finished: eclipse.convertPath

+Task started: eclipse.refreshLocal

+Task finished: eclipse.refreshLocal

+Target finished: refresh

+Task finished: ant

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Task finished: ant

+Target finished: all.features

+Target started: all.plugins

+Target finished: all.plugins

+Target started: update.feature

+Target finished: update.feature

+Target started: all.children

+Target finished: all.children

+Task finished: antcall

+Target finished: refresh

+Build finished.

diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/.sitebuild/sitebuild.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/.sitebuild/sitebuild.xml
new file mode 100644
index 0000000..49243d3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/.sitebuild/sitebuild.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site-build
+      feature-location="features"
+      plugin-location="plugins"
+      autobuild="false"
+      scrub-output="false"
+      use-console="true">
+   <feature id="update.feature1c" version="3.0.0"/>
+   <feature id="update.feature2c" version="3.0.0"/>
+</site-build>
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1_1.0.0.jar
new file mode 100644
index 0000000..152d9e2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1_1.0.1.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1_1.0.1.jar
new file mode 100644
index 0000000..eeb0b6f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1_1.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1b_2.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1b_2.0.0.jar
new file mode 100644
index 0000000..49b0764
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1b_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1c_3.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1c_3.0.0.jar
new file mode 100644
index 0000000..d426f86
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature1c_3.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature2_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature2_1.0.0.jar
new file mode 100644
index 0000000..b070ccd
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature2_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature2b_2.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature2b_2.0.0.jar
new file mode 100644
index 0000000..e48ac05
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature2b_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature2c_3.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature2c_3.0.0.jar
new file mode 100644
index 0000000..00037df
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/features/update.feature2c_3.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin1_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin1_1.0.0.jar
new file mode 100644
index 0000000..3543749
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin1_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin1a_1.0.1.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin1a_1.0.1.jar
new file mode 100644
index 0000000..632cc3f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin1a_1.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin2_1.0.0.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin2_1.0.0.jar
new file mode 100644
index 0000000..dbc8a88
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin2_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin2a_1.0.1.jar b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin2a_1.0.1.jar
new file mode 100644
index 0000000..a3cd0fb
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/plugins/com.plugin2a_1.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/mirrors/update-site5/site.xml b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/site.xml
new file mode 100644
index 0000000..6e26db1
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/mirrors/update-site5/site.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <feature url="features/update.feature1c_3.0.0.jar" id="update.feature1c" version="3.0.0">
+      <category name="Site5-Category1"/>
+   </feature>
+   <feature url="features/update.feature2c_3.0.0.jar" id="update.feature2c" version="3.0.0">
+      <category name="Site5-Category2"/>
+   </feature>
+   <category-def name="Site5-Category1" label="Site5-Category1-Label">
+      <description>
+         ecetera.
+      </description>
+   </category-def>
+   <category-def name="Site5-Category2" label="Site5-Category2-Label">
+      <description>
+         ecetera.
+      </description>
+   </category-def>
+</site>
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/features/org.eclipse.update.core.tests.childrenfeature_2.0.0.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/features/org.eclipse.update.core.tests.childrenfeature_2.0.0.jar
new file mode 100644
index 0000000..6658034
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/features/org.eclipse.update.core.tests.childrenfeature_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/features/rootfeature.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/features/rootfeature.jar
new file mode 100644
index 0000000..b011050
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/features/rootfeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
new file mode 100644
index 0000000..5d9f5bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
new file mode 100644
index 0000000..8b4b04a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar
new file mode 100644
index 0000000..52208fe
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/site.xml b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/site.xml
new file mode 100644
index 0000000..623cb1a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest/site.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+  <feature url="features/rootfeature.jar"/>
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/features/childrenfeature.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/features/childrenfeature.jar
new file mode 100644
index 0000000..7e057e6
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/features/childrenfeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/features/rootfeature.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/features/rootfeature.jar
new file mode 100644
index 0000000..38a0a3c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/features/rootfeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
new file mode 100644
index 0000000..5d9f5bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
new file mode 100644
index 0000000..8b4b04a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar
new file mode 100644
index 0000000..52208fe
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/site.xml b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/site.xml
new file mode 100644
index 0000000..1752da2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest2/site.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+  <feature url="features/rootfeature.jar"/>
+  <feature url="features/childrenfeature.jar"/>  
+  
+  <archive path="features/org.eclipse.update.core.tests.childrenfeature_2.1.0.jar" url="features/childrenfeature.jar"/>  
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/features/childrenfeature.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/features/childrenfeature.jar
new file mode 100644
index 0000000..12ee4ba
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/features/childrenfeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/features/rootfeature.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/features/rootfeature.jar
new file mode 100644
index 0000000..899bdda
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/features/rootfeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
new file mode 100644
index 0000000..5d9f5bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
new file mode 100644
index 0000000..8b4b04a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar
new file mode 100644
index 0000000..52208fe
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/site.xml b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/site.xml
new file mode 100644
index 0000000..4f696ba
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/nestedFeatureSiteTest3/site.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+  <feature url="features/rootfeature.jar"/>
+  
+  <archive path="features/org.eclipse.update.core.tests.childrenfeature_2.1.0.jar" url="features/childrenfeature.jar"/>  
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/feature1.xml b/update/org.eclipse.update.tests.core/data/parsertests/feature1.xml
new file mode 100644
index 0000000..93d7080
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/feature1.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+   id="org.eclipse.platform"
+   version="2.1.0"
+   label="Eclipse Platform"
+   provider-name="www.eclipse.org"
+   image="splash/splash_full.bmp"
+   >
+
+	<license>
+    	 license
+	</license>
+
+   <copyright url="notice.html"/>
+   x
+	
+   <license url="about.html">
+   x
+   </license>
+
+   <url>
+      <update url="file:/D:/" label="Eclipse Update Site"/>
+   </url>
+
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/feature1bis.xml b/update/org.eclipse.update.tests.core/data/parsertests/feature1bis.xml
new file mode 100644
index 0000000..e855f97
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/feature1bis.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+   id="org.eclipse.platform"
+   version="2.1.0"
+   label="Eclipse Platform"
+   provider-name="www.eclipse.org"
+   image="splash/splash_full.bmp"
+   >
+
+   <description>
+   Eclipse platform feature.
+   </description>
+
+   <copyright url="notice.html"/>
+   <blah />
+	
+   <license url="about.html">
+
+   </license>
+
+   <url>
+      <update url="file:/D:/" label="Eclipse Update Site"/>
+   </url>
+
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/feature2.xml b/update/org.eclipse.update.tests.core/data/parsertests/feature2.xml
new file mode 100644
index 0000000..9c2df9b
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/feature2.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+   id="org.eclipse.platform"
+   version="2.1.0"
+   label="Eclipse Platform"
+   provider-name="www.eclipse.org"
+   image="splash/splash_full.bmp"
+   blah="blah"
+   >
+
+   <description blah="blah">
+   Eclipse platform feature.
+   </description>
+
+   <copyright url="notice.html" blah="blah"/>
+	
+   <license url="about.html" blah="blah">
+   </license>
+
+   <url blah="blah">
+      <update url="file:/D:/" label="Eclipse Update Site" blah="blah"/>
+   </url>
+
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/feature3.xml b/update/org.eclipse.update.tests.core/data/parsertests/feature3.xml
new file mode 100644
index 0000000..ca660be
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/feature3.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+   id="org.eclipse.platform"
+   version="2.1.0"
+   label="Eclipse Platform"
+   provider-name="www.eclipse.org"
+   image="splash/splash_full.bmp"
+   >
+
+   <description>
+   Eclipse platform feature.
+   </description>
+
+   <copyright url="$os$/$ws$/notice.html"/>
+   x
+	
+   <license url="about.html">
+   x
+   </license>
+
+   <url>
+      <update url="file:/D:/" label="Eclipse Update Site"/>
+   </url>
+
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/feature4.xml b/update/org.eclipse.update.tests.core/data/parsertests/feature4.xml
new file mode 100644
index 0000000..17187c9
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/feature4.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+   id="org.eclipse.platform"
+   version="2.1.0"
+   label="Eclipse Platform"
+   provider-name="www.eclipse.org"
+   image="splash/splash_full.bmp"
+   >
+
+   <description>
+   Eclipse platform feature.
+   </description>
+
+   <copyright url="$os$/$ws$/notice.html"/>
+   x
+	
+   <license url="about.html">
+   x
+   </license>
+
+   <url>
+      <update url="file:/D:/" label="Eclipse Update Site"/>
+      <discovery url="file:/c:/" label = "Discovery" type="web"/>
+   </url>
+
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/reddot.xml b/update/org.eclipse.update.tests.core/data/parsertests/reddot.xml
new file mode 100644
index 0000000..f3f1701
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/reddot.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>

+<site url="info/siteInfo.html">

+<feature url="features/reddot_1.0.0.jar"> 

+<category name="reddot"/>

+</feature>

+<feature url="features/reddot_2.1.0.jar">

+<category name="reddot"/>

+</feature>

+<archive path="com.reddot.redot_1.0.0" url="plugins/com.reddot.reddot_1.0.0.jar"/>

+<archive path="com.reddot.redot_2.1.0" url="plugins/com.reddot.reddot_2.1.0.jar"/>

+<category-def label="Red Dot Versions" name="reddot">

+<description url="RedDotVersions.html">

+This category contains all of the &lt;currently&gt; available versions of Red Dot feature.

+<![CDATA[<greeting>Hello, world!</greeting>]]>

+</description>

+</category-def>

+</site>

+

+

diff --git a/update/org.eclipse.update.tests.core/data/parsertests/reddot1.xml b/update/org.eclipse.update.tests.core/data/parsertests/reddot1.xml
new file mode 100644
index 0000000..074490e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/reddot1.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>

+<site url="info/siteInfo.html">

+<feature url="features/reddot_1.0.0.jar"> 

+<category name="reddot"/>

+</feature>

+<feature url="features/reddot_2.1.0.jar">

+<category name="reddot"/>

+</feature>

+<archive path="com.reddot.redot_1.0.0" url="plugins/com.reddot.reddot_1.0.0.jar"/>

+<archive path="com.reddot.redot_2.1.0" url="plugins/com.reddot.reddot_2.1.0.jar"/>

+<category-def label="Red Dot Versions" name="reddot">

+<description url="RedDotVersions.html">

+This category contains all of the &lt;currently&gt; available versions of Red Dot feature.

+</description>

+</category-def>

+</site>

+

+

diff --git a/update/org.eclipse.update.tests.core/data/parsertests/site.xml b/update/org.eclipse.update.tests.core/data/parsertests/site.xml
new file mode 100644
index 0000000..b40d831
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/site.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site id="org.eclipse.update.core.tests" name="Tests" version="0.0.1" type="org.eclipse.update.core.file">

+  <handler>

+  	<boo class ="unknown"/>

+  </handler>

+  

+  <feature url="features/org.eclipse.test.feature_1.0.0.jar">

+    <category name="category1"/>

+  </feature>

+  

+  <feature url="features/features2.jar">

+    <category name="category1/subcat1"/>

+    <category name="category2"/>

+  </feature>

+  

+  <feature url="features/org.eclipse.update.core.tests.feature1_1.0.4.jar">

+    <category name="category1"/>

+    <category name="category2"/>

+    <blah/>

+  </feature>

+  

+  <feature url="features/org.eclipse_test_feature.jar"/>

+  

+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">

+    <category name="category1"/>

+  </feature>

+  

+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">

+  </feature>

+  

+  <archive path="plugins/hello" >

+  	<default/>

+  </archive>

+

+  <category-def name="category2" label="%security"/>

+  <category-def name="category1/subcat1" label="Special Fix"/>

+  <category-def name="category1" label="%drivers"/>  

+

+

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/site10.xml b/update/org.eclipse.update.tests.core/data/parsertests/site10.xml
new file mode 100644
index 0000000..e42680d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/site10.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site id="org.eclipse.update.core.tests" name="Tests" version="0.0.1" type="org.eclipse.update.core.file" blah="blah">
+  
+  <feature url="features/org.eclipse.test.feature_1.0.0.jar" blah="blah" id="org.eclipse.test.feature" version="1.0.0"/>
+  
+  <feature url="features/features2.jar" id="unknwon.id" version="bad version"/>
+  
+  <feature url="features/org.eclipse.update.core.tests.feature1_1.0.4.jar" id="only.id"/>
+    
+  <feature url="features/org.eclipse_test_feature.jar" version="1.0.0"/>
+  
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/site2.xml b/update/org.eclipse.update.tests.core/data/parsertests/site2.xml
new file mode 100644
index 0000000..007550e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/site2.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+  <feature id="com.ibm.jdt" url="http://www.not-eclipse.org/feature3" version="1.0.0"/>
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/site3.xml b/update/org.eclipse.update.tests.core/data/parsertests/site3.xml
new file mode 100644
index 0000000..dbbb682
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/site3.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+  <feature id="com.ibm.jdt" url="feature3/feature.jar" version="1.0.0">
+        <category name="unknown"/>
+  </feature>
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/site4.xml b/update/org.eclipse.update.tests.core/data/parsertests/site4.xml
new file mode 100644
index 0000000..41b7d16
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/site4.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<site>
+   <description url="info/siteInfo.html"/>
+
+  <category-def label="Red Dot Versions" name="reddot">
+      <description url="RedDotVersions.html">
+         This category contains all of the currently available versions of Red Dot feature.
+      </description>
+   </category-def>
+   
+   <feature url="features/com.reddot.reddot_1.0.0.jar">
+      <category name="reddot"/>
+   </feature>
+
+   <feature url="features/com.reddot.reddot_2.1.0.jar">
+      <category name="reddot"/>
+   </feature>
+
+ 
+</site>   
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/site7.xml b/update/org.eclipse.update.tests.core/data/parsertests/site7.xml
new file mode 100644
index 0000000..2190d70
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/site7.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site id="org.eclipse.update.core.tests" name="Tests" version="0.0.1" type="org.eclipse.update.core.file">
+  <handler>
+  	<boo class ="unknown"/>
+  </handler>
+  
+  <feature url="features/org.eclipse.test.feature_1.0.0.jar">
+    <category name="category1"/>
+  </feature>
+  
+  <feature url="features/features2.jar">
+    <category name="category1/subcat1"/>
+    <category name="category2"/>
+  </feature>
+  
+  <blah/>
+  
+  <feature url="features/org.eclipse.update.core.tests.feature1_1.0.4.jar">
+    <category name="category1"/>
+    <category name="category2"/>
+    <blah/>
+  </feature>
+  
+  <feature url="features/org.eclipse_test_feature.jar"/>
+  
+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">
+    <category name="category1"/>
+  </feature>
+  
+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">
+  </feature>
+  
+  <archive path="plugins/hello" >
+  	<default/>
+  </archive>
+
+  <category-def name="category2" label="%security"/>
+  <category-def name="category1/subcat1" label="Special Fix"/>
+  <category-def name="category1" label="%drivers"/>  
+
+
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/site8.xml b/update/org.eclipse.update.tests.core/data/parsertests/site8.xml
new file mode 100644
index 0000000..afcbaa1
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/site8.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site id="org.eclipse.update.core.tests" name="Tests" version="0.0.1" type="org.eclipse.update.core.file">
+  <handler>
+  	<boo class ="unknown"/>
+  </handler>
+  
+  <feature url="features/org.eclipse.test.feature_1.0.0.jar">
+    <category name="category1"/>
+  </feature>
+  
+  <feature url="features/features2.jar">
+    <category name="category1/subcat1"/>
+    <category name="category2"/>
+  </feature>
+  xcxgfsdfgsdsd
+  
+  <feature url="features/org.eclipse.update.core.tests.feature1_1.0.4.jar">
+    <category name="category1"/>
+    <category name="category2"/>
+    <blah/>
+  </feature>
+  
+  <feature url="features/org.eclipse_test_feature.jar"/>
+  
+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">
+    <category name="category1"/>
+  </feature>
+  
+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">
+  </feature>
+  
+  <archive path="plugins/hello" >
+  	<default/>
+  </archive>
+
+  <category-def name="category2" label="%security"/>
+  <category-def name="category1/subcat1" label="Special Fix"/>
+  <category-def name="category1" label="%drivers"/>  
+
+
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/site9.xml b/update/org.eclipse.update.tests.core/data/parsertests/site9.xml
new file mode 100644
index 0000000..f38c5a4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/site9.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site id="org.eclipse.update.core.tests" name="Tests" version="0.0.1" type="org.eclipse.update.core.file" blah="blah">
+  <handler blah="blah">
+  	<boo class ="unknown" blah="blah"/>
+  </handler>
+  
+  <feature url="features/org.eclipse.test.feature_1.0.0.jar" blah="blah">
+    <category name="category1" blah="blah" />
+  </feature>
+  
+  <feature url="features/features2.jar">
+    <category name="category1/subcat1"/>
+    <category name="category2"/>
+  </feature>
+  
+  <feature url="features/org.eclipse.update.core.tests.feature1_1.0.4.jar">
+    <category name="category1"/>
+    <category name="category2"/>
+    <blah/>
+  </feature>
+  
+  <feature url="features/org.eclipse_test_feature.jar"/>
+  
+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">
+    <category name="category1"/>
+  </feature>
+  
+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">
+  </feature>
+  
+  <archive path="plugins/hello" blah="blah">
+  	<default blah="blah"/>
+  </archive>
+
+  <category-def name="category2" label="%security" blah="blah"/>
+  <category-def name="category1/subcat1" label="Special Fix" blah="blah"/>
+  <category-def name="category1" label="%drivers"/>  
+
+
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/parsertests/siteftp.xml b/update/org.eclipse.update.tests.core/data/parsertests/siteftp.xml
new file mode 100644
index 0000000..f883ec0
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/parsertests/siteftp.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site type="org.eclipse.update.tests.core.ftp">
+  <feature url="features/feature3/features2.jarfile"/>
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/.classpath b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/.classpath
new file mode 100644
index 0000000..88acb39
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="/org.eclipse.update.core"/>
+	<classpathentry kind="src" path="/org.eclipse.core.runtime"/>
+	<classpathentry kind="src" path="/org.eclipse.ui"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/.project b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/.project
new file mode 100644
index 0000000..1ebc505
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>FeatureWithInstallHandler</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/FeatureWithInstallHandler_1.0.0.jar b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/FeatureWithInstallHandler_1.0.0.jar
new file mode 100644
index 0000000..695b722
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/FeatureWithInstallHandler_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/bin/HandlerWithUI$1.class b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/bin/HandlerWithUI$1.class
new file mode 100644
index 0000000..57291b0
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/bin/HandlerWithUI$1.class
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/bin/HandlerWithUI.class b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/bin/HandlerWithUI.class
new file mode 100644
index 0000000..fe8e881
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/bin/HandlerWithUI.class
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/build.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/build.properties
new file mode 100644
index 0000000..8fb7cc5
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/build.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+source.handler.jar = src/,\
+                     bin/
+output.handler.jar = bin/
+bin.includes = feature.xml,\
+               handler.jar
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/feature.xml
new file mode 100644
index 0000000..8b90ea7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/feature.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="FeatureWithInstallHandler"
+      label="FeatureWithInstallHandler"
+      version="1.0.0">
+
+   <install-handler library="handler.jar" handler="HandlerWithUI" />
+
+   <description url="[Enter Feature URL here.]">
+      [Enter Feature Description here.]
+   </description>
+
+   <copyright url="[Enter Copyright URL here.]">
+      [Enter Copyright Description here.]
+   </copyright>
+
+   <license url="[Enter License URL here.]">
+      [Enter License Description here.]
+   </license>
+
+   <plugin
+         id="org.apache.lucene"
+         download-size="0"
+         install-size="0"
+         version="1.3.0"/>
+
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/handler.jar b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/handler.jar
new file mode 100644
index 0000000..87bc244
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/handler.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/src/HandlerWithUI.java b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/src/HandlerWithUI.java
new file mode 100644
index 0000000..88dfbc0
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/FeatureWithInstallHandler/src/HandlerWithUI.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.core.*;
+/*
+ * Created on Oct 1, 2004
+ *
+ * TODO To change the template for this generated file go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+
+/**
+ * @author birsan
+ *
+ * TODO To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+public class HandlerWithUI implements IInstallHandler {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#completeConfigure()
+	 */
+	public void completeConfigure() throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("completeConfigure()");
+
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#completeInstall(org.eclipse.update.core.IFeatureContentConsumer)
+	 */
+	public void completeInstall(IFeatureContentConsumer consumer)
+			throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("completeInstall()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#completeUnconfigure()
+	 */
+	public void completeUnconfigure() throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("completeInstall()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#completeUninstall()
+	 */
+	public void completeUninstall() throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("completeUninstall()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#configureCompleted(boolean)
+	 */
+	public void configureCompleted(boolean success) throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("configureCompleted()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#configureInitiated()
+	 */
+	public void configureInitiated() throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("configureInitiated()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#initialize(int, org.eclipse.update.core.IFeature, org.eclipse.update.core.IInstallHandlerEntry, org.eclipse.update.core.InstallMonitor)
+	 */
+	public void initialize(int type, IFeature feature,
+			IInstallHandlerEntry entry, InstallMonitor monitor)
+			throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("initialize()");
+		Display.getDefault().asyncExec( new Runnable() {
+			public void run() {
+				MessageDialog.openInformation(Display.getDefault().getActiveShell(), "InstallHandler", "This is a dummy message");
+			}
+		});
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#installCompleted(boolean)
+	 */
+	public void installCompleted(boolean success) throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("installCompleted()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#installInitiated()
+	 */
+	public void installInitiated() throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("installInitiated()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#nonPluginDataDownloaded(org.eclipse.update.core.INonPluginEntry[], org.eclipse.update.core.IVerificationListener)
+	 */
+	public void nonPluginDataDownloaded(INonPluginEntry[] nonPluginData,
+			IVerificationListener listener) throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("nonPluginDataDownloaded()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#pluginsDownloaded(org.eclipse.update.core.IPluginEntry[])
+	 */
+	public void pluginsDownloaded(IPluginEntry[] plugins) throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("pluginsDownloaded()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#unconfigureCompleted(boolean)
+	 */
+	public void unconfigureCompleted(boolean success) throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("unconfigureCompleted()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#unconfigureInitiated()
+	 */
+	public void unconfigureInitiated() throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("unconfigureInitiated()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#uninstallCompleted(boolean)
+	 */
+	public void uninstallCompleted(boolean success) throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("uninstallCompleted()");
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.IInstallHandler#uninstallInitiated()
+	 */
+	public void uninstallInitiated() throws CoreException {
+		// TODO Auto-generated method stub
+		System.out.println("uninstallInitiated()");
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..95416c1
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/cpl-v10.html
@@ -0,0 +1,266 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy, see www.w3.org" />
+<title>Common Public License - v 1.0</title>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1" />
+</head>
+<body bgcolor="#FFFFFF" vlink="#800000">
+<p style="font-weight: bold; text-align: center">Common Public
+License - v 1.0</p>
+
+<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS
+COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF
+THIS AGREEMENT.</p>
+
+<p style="font-weight: bold">1. DEFINITIONS</p>
+
+<p>"Contribution" means:</p>
+
+<div style="margin-left: 2em">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:</div>
+
+<div style="margin-left: 2em">i) changes to the Program, and</div>
+
+<div style="margin-left: 2em">ii) additions to the Program;</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p>"Contributor" means any person or entity that distributes the
+Program.</p>
+
+<p>"Licensed Patents " 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.</p>
+
+<p>"Program" means the Contributions distributed in accordance with
+this Agreement.</p>
+
+<p>"Recipient" means anyone who receives the Program under this
+Agreement, including all Contributors.</p>
+
+<p style="font-weight: bold">2. GRANT OF RIGHTS</p>
+
+<div style="margin-left: 2em">a) Subject to the terms of this
+Agreement, each Contributor hereby grants Recipient a
+non-exclusive, worldwide, royalty-free copyright license to
+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.</div>
+
+<div style="margin-left: 2em">b) Subject to the terms of this
+Agreement, each Contributor hereby grants Recipient a
+non-exclusive, worldwide, 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.</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p style="font-weight: bold">3. REQUIREMENTS</p>
+
+<p>A Contributor may choose to distribute the Program in object
+code form under its own license agreement, provided that:</p>
+
+<div style="margin-left: 2em">a) it complies with the terms and
+conditions of this Agreement; and</div>
+
+<div style="margin-left: 2em">b) its license agreement:</div>
+
+<div style="margin-left: 2em">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;</div>
+
+<div style="margin-left: 2em">ii) effectively excludes on behalf of
+all Contributors all liability for damages, including direct,
+indirect, special, incidental and consequential damages, such as
+lost profits;</div>
+
+<div style="margin-left: 2em">iii) states that any provisions which
+differ from this Agreement are offered by that Contributor alone
+and not by any other party; and</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p>When the Program is made available in source code form:</p>
+
+<div style="margin-left: 2em">a) it must be made available under
+this Agreement; and</div>
+
+<div style="margin-left: 2em">b) a copy of this Agreement must be
+included with each copy of the Program.</div>
+
+<p>Contributors may not remove or alter any copyright notices
+contained within the Program.</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">4. COMMERCIAL DISTRIBUTION</p>
+
+<p>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 ("Commercial Contributor")
+hereby agrees to defend and indemnify every other Contributor
+("Indemnified Contributor") against any losses, damages and costs
+(collectively "Losses") 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.</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">5. NO WARRANTY</p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 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.</p>
+
+<p style="font-weight: bold">6. DISCLAIMER OF LIABILITY</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">7. GENERAL</p>
+
+<p>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.</p>
+
+<p>If Recipient institutes patent litigation against a Contributor
+with respect to a patent applicable to software (including a
+cross-claim or counterclaim in a lawsuit), then any patent licenses
+granted by that Contributor to such Recipient under this Agreement
+shall terminate as of the date such litigation is filed. In
+addition, 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.</p>
+
+<p>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.</p>
+
+<p>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. IBM is the initial Agreement Steward. IBM 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.</p>
+
+<p>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.</p>
+</body>
+</html>
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/feature.properties
new file mode 100644
index 0000000..c4d2224
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/feature.properties
@@ -0,0 +1,151 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $Id: feature.properties,v 1.1 2004/10/18 15:50:42 dbirsan Exp $
+#  */
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+# This file 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=Eclipse Modeling Framework (EMF) Documentation
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=Eclipse Modeling Framework. (documentation)
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/feature.xml
new file mode 100644
index 0000000..09363e7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/feature.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2002-2004 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *   IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: feature.xml,v 1.1 2004/03/06 17:31:31 marcelop Exp $
+ */
+-->
+
+<feature
+	id="org.eclipse.emf.doc"
+    label="%featureName"
+    version="2.0.0"
+    image= "eclipse_update_120.jpg"
+    provider-name="%providerName">
+
+	<description>
+    	%description
+	</description>
+
+    <license url="%licenseURL">
+		%license
+	</license>
+
+	<url>
+		<update url="http://update.eclipse.org/updates" label="%updateSiteName"/>
+	</url>
+
+	<plugin
+		id="org.eclipse.emf.doc"
+        download-size="0"
+        install-size="0"   		
+		version="2.0.0"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/license.html
new file mode 100644
index 0000000..07a5e18
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.doc_2.0.0/license.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy, see www.w3.org" />
+<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.org Software User Agreement</h2>
+
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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
+Eclipse.org is provided to you under the terms and conditions of
+the Common Public License Version 1.0 ("CPL"). A copy of the CPL is
+provided with this Content and is also available at <a
+href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+For purposes of the CPL, "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>
+
+<li>Plug-in and Fragment directories</li>
+
+<li>Subdirectories of the directory named "src" of certain
+Plug-ins</li>
+
+<li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by Eclipse.org 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 CPL 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>Apache Software License 1.1 (available at <a
+href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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
+Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..3a4d639
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/feature.properties
new file mode 100644
index 0000000..dda7d1d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/feature.properties
@@ -0,0 +1,151 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $Id: feature.properties,v 1.1 2004/10/18 15:50:42 dbirsan Exp $ 
+#  */
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+# This file 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=EMF Service Data Objects (SDO) Documentation
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=EMF Service Data Objects (SDO) Documentation
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/feature.xml
new file mode 100644
index 0000000..1dfb44a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/feature.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2003-2004 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *   IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: feature.xml,v 1.2 2004/03/26 15:32:13 marcelop Exp $
+ */
+-->
+
+<feature
+	id="org.eclipse.emf.ecore.sdo.doc"
+    label="%featureName"
+    version="2.0.0"
+    image= "eclipse_update_120.jpg"
+    provider-name="%providerName">
+
+	<description>
+    	%description
+	</description>
+
+    <license url="%licenseURL">
+		%license
+	</license>
+
+	<url>
+		<update url="http://update.eclipse.org/updates" label="%updateSiteName"/>
+	</url>
+
+	<plugin
+		id="org.eclipse.emf.ecore.sdo.doc"
+        download-size="0"
+        install-size="0"   		
+		version="2.0.0"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/license.html
new file mode 100644
index 0000000..af8c380
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.doc_2.0.0/license.html
@@ -0,0 +1,71 @@
+<!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.org Software User Agreement</h2>
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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 Eclipse.org 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>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..3a4d639
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/feature.properties
new file mode 100644
index 0000000..2cbb1cb
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/feature.properties
@@ -0,0 +1,151 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $Id: feature.properties,v 1.1 2004/10/18 15:50:42 dbirsan Exp $ 
+#  */
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+# This file 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=EMF Service Data Objects (SDO) Source
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=EMF Service Data Objects (SDO) Source
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/feature.xml
new file mode 100644
index 0000000..ba5d87d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/feature.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature primary="false"  provider-name="%providerName"    label="%featureName"  image="eclipse_update_120.jpg" id="org.eclipse.emf.ecore.sdo.source"  version="2.0.0">
+	<description >
+		%description
+	</description>
+	<copyright url="http://www.eclipse.org/legal/cpl-v10.html">
+		Copyright (c) 2002-2004 IBM Corporation and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+	</copyright>
+	<license url="%licenseURL">
+		%license
+	</license>
+	<url>
+		<update label="%updateSiteName" url="http://update.eclipse.org/updates/"/>
+		<discovery label="%secondaryUpdateSiteName" url="http://download.eclipse.org/tools/emf/updates/"/>
+	</url>
+	<plugin    fragment="false"  download-size="0" install-size="0" id="org.eclipse.emf.ecore.sdo.source" version="2.0.0"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/license.html
new file mode 100644
index 0000000..af8c380
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo.source_2.0.0/license.html
@@ -0,0 +1,71 @@
+<!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.org Software User Agreement</h2>
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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 Eclipse.org 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>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..3a4d639
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/feature.properties
new file mode 100644
index 0000000..a42f3b9
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/feature.properties
@@ -0,0 +1,154 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $id$
+#  */
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+# This file 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=EMF Service Data Objects (SDO)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=EMF Service Data Objects (SDO).
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
+
+# "secondaryUpdateSiteName" property - label for the secondary update site (on download.eclipse.org)
+secondaryUpdateSiteName=EMF/SDO/XSD Secondary Update Site
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/feature.xml
new file mode 100644
index 0000000..f04662b
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/feature.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.emf.ecore.sdo"
+      label="%featureName"
+      version="2.0.0"
+      provider-name="%providerName"
+      image="eclipse_update_120.jpg">
+
+   <description>
+      %description
+   </description>
+
+   <copyright url="http://www.eclipse.org/legal/cpl-v10.html">
+      Copyright (c) 2002-2004 IBM Corporation and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <url>
+      <update label="%updateSiteName" url="http://update.eclipse.org/updates/"/>
+      <discovery label="%secondaryUpdateSiteName" url="http://download.eclipse.org/tools/emf/updates/"/>
+   </url>
+
+   <requires>
+      <import plugin="org.eclipse.core.resources" version="3.0.0" match="compatible"/>
+      <import plugin="org.eclipse.emf.ecore" version="2.0.0" match="compatible"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.emf.commonj.sdo"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.ecore.sdo"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.ecore.sdo.edit"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.ecore.sdo.editor"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/license.html
new file mode 100644
index 0000000..af8c380
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.ecore.sdo_2.0.0/license.html
@@ -0,0 +1,71 @@
+<!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.org Software User Agreement</h2>
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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 Eclipse.org 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>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..95416c1
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/cpl-v10.html
@@ -0,0 +1,266 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy, see www.w3.org" />
+<title>Common Public License - v 1.0</title>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1" />
+</head>
+<body bgcolor="#FFFFFF" vlink="#800000">
+<p style="font-weight: bold; text-align: center">Common Public
+License - v 1.0</p>
+
+<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS
+COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF
+THIS AGREEMENT.</p>
+
+<p style="font-weight: bold">1. DEFINITIONS</p>
+
+<p>"Contribution" means:</p>
+
+<div style="margin-left: 2em">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:</div>
+
+<div style="margin-left: 2em">i) changes to the Program, and</div>
+
+<div style="margin-left: 2em">ii) additions to the Program;</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p>"Contributor" means any person or entity that distributes the
+Program.</p>
+
+<p>"Licensed Patents " 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.</p>
+
+<p>"Program" means the Contributions distributed in accordance with
+this Agreement.</p>
+
+<p>"Recipient" means anyone who receives the Program under this
+Agreement, including all Contributors.</p>
+
+<p style="font-weight: bold">2. GRANT OF RIGHTS</p>
+
+<div style="margin-left: 2em">a) Subject to the terms of this
+Agreement, each Contributor hereby grants Recipient a
+non-exclusive, worldwide, royalty-free copyright license to
+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.</div>
+
+<div style="margin-left: 2em">b) Subject to the terms of this
+Agreement, each Contributor hereby grants Recipient a
+non-exclusive, worldwide, 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.</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p style="font-weight: bold">3. REQUIREMENTS</p>
+
+<p>A Contributor may choose to distribute the Program in object
+code form under its own license agreement, provided that:</p>
+
+<div style="margin-left: 2em">a) it complies with the terms and
+conditions of this Agreement; and</div>
+
+<div style="margin-left: 2em">b) its license agreement:</div>
+
+<div style="margin-left: 2em">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;</div>
+
+<div style="margin-left: 2em">ii) effectively excludes on behalf of
+all Contributors all liability for damages, including direct,
+indirect, special, incidental and consequential damages, such as
+lost profits;</div>
+
+<div style="margin-left: 2em">iii) states that any provisions which
+differ from this Agreement are offered by that Contributor alone
+and not by any other party; and</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p>When the Program is made available in source code form:</p>
+
+<div style="margin-left: 2em">a) it must be made available under
+this Agreement; and</div>
+
+<div style="margin-left: 2em">b) a copy of this Agreement must be
+included with each copy of the Program.</div>
+
+<p>Contributors may not remove or alter any copyright notices
+contained within the Program.</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">4. COMMERCIAL DISTRIBUTION</p>
+
+<p>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 ("Commercial Contributor")
+hereby agrees to defend and indemnify every other Contributor
+("Indemnified Contributor") against any losses, damages and costs
+(collectively "Losses") 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.</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">5. NO WARRANTY</p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 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.</p>
+
+<p style="font-weight: bold">6. DISCLAIMER OF LIABILITY</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">7. GENERAL</p>
+
+<p>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.</p>
+
+<p>If Recipient institutes patent litigation against a Contributor
+with respect to a patent applicable to software (including a
+cross-claim or counterclaim in a lawsuit), then any patent licenses
+granted by that Contributor to such Recipient under this Agreement
+shall terminate as of the date such litigation is filed. In
+addition, 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.</p>
+
+<p>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.</p>
+
+<p>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. IBM is the initial Agreement Steward. IBM 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.</p>
+
+<p>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.</p>
+</body>
+</html>
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/feature.properties
new file mode 100644
index 0000000..194775c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/feature.properties
@@ -0,0 +1,140 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $Id: feature.properties,v 1.1 2004/10/18 15:50:42 dbirsan Exp $
+#  */
+
+# 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=EMF SDK
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=Binaries and API documentation and source zips for EMF.
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/feature.xml
new file mode 100644
index 0000000..6418de2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/feature.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2002-2004 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *   IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: feature.xml,v 1.2 2004/03/25 14:06:34 marcelop Exp $
+ */
+-->
+
+<feature
+    id="org.eclipse.emf.sdk"
+    label="%featureName"
+    version="2.0.0"
+    image= "eclipse_update_120.jpg"
+    provider-name="%providerName">
+
+	<description>
+        %description
+    </description>
+   
+	<license url="%licenseURL">
+        %license
+    </license>
+
+    <url>
+      <update url="http://update.eclipse.org/updates" label="%updateSiteName"/>
+    </url>
+
+    <includes
+        id="org.eclipse.emf"
+        version="2.0.0"
+        match="compatible"/> 
+        
+    <includes
+        id="org.eclipse.emf.source"
+        version="2.0.0"
+        match="compatible"/> 
+
+    <includes
+        id="org.eclipse.emf.doc"
+        version="2.0.0"
+        match="compatible"/>   
+
+    <includes
+        id="org.eclipse.xsd"
+        version="2.0.0"
+        match="compatible"/> 
+
+    <includes
+        id="org.eclipse.xsd.source"
+        version="2.0.0"
+        match="compatible"/> 
+
+    <includes
+        id="org.eclipse.xsd.doc"
+        version="2.0.0"
+        match="compatible"/> 
+
+    <includes
+        id="org.eclipse.emf.ecore.sdo"
+        version="2.0.0"
+        match="compatible"/> 
+
+    <includes
+        id="org.eclipse.emf.ecore.sdo.source"
+        version="2.0.0"
+        match="compatible"/> 
+
+    <includes
+        id="org.eclipse.emf.ecore.sdo.doc"
+        version="2.0.0"
+        match="compatible"/> 
+       
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/license.html
new file mode 100644
index 0000000..07a5e18
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.sdk_2.0.0/license.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy, see www.w3.org" />
+<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.org Software User Agreement</h2>
+
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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
+Eclipse.org is provided to you under the terms and conditions of
+the Common Public License Version 1.0 ("CPL"). A copy of the CPL is
+provided with this Content and is also available at <a
+href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+For purposes of the CPL, "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>
+
+<li>Plug-in and Fragment directories</li>
+
+<li>Subdirectories of the directory named "src" of certain
+Plug-ins</li>
+
+<li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by Eclipse.org 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 CPL 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>Apache Software License 1.1 (available at <a
+href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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
+Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..95416c1
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/cpl-v10.html
@@ -0,0 +1,266 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy, see www.w3.org" />
+<title>Common Public License - v 1.0</title>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1" />
+</head>
+<body bgcolor="#FFFFFF" vlink="#800000">
+<p style="font-weight: bold; text-align: center">Common Public
+License - v 1.0</p>
+
+<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS
+COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF
+THIS AGREEMENT.</p>
+
+<p style="font-weight: bold">1. DEFINITIONS</p>
+
+<p>"Contribution" means:</p>
+
+<div style="margin-left: 2em">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:</div>
+
+<div style="margin-left: 2em">i) changes to the Program, and</div>
+
+<div style="margin-left: 2em">ii) additions to the Program;</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p>"Contributor" means any person or entity that distributes the
+Program.</p>
+
+<p>"Licensed Patents " 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.</p>
+
+<p>"Program" means the Contributions distributed in accordance with
+this Agreement.</p>
+
+<p>"Recipient" means anyone who receives the Program under this
+Agreement, including all Contributors.</p>
+
+<p style="font-weight: bold">2. GRANT OF RIGHTS</p>
+
+<div style="margin-left: 2em">a) Subject to the terms of this
+Agreement, each Contributor hereby grants Recipient a
+non-exclusive, worldwide, royalty-free copyright license to
+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.</div>
+
+<div style="margin-left: 2em">b) Subject to the terms of this
+Agreement, each Contributor hereby grants Recipient a
+non-exclusive, worldwide, 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.</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p style="font-weight: bold">3. REQUIREMENTS</p>
+
+<p>A Contributor may choose to distribute the Program in object
+code form under its own license agreement, provided that:</p>
+
+<div style="margin-left: 2em">a) it complies with the terms and
+conditions of this Agreement; and</div>
+
+<div style="margin-left: 2em">b) its license agreement:</div>
+
+<div style="margin-left: 2em">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;</div>
+
+<div style="margin-left: 2em">ii) effectively excludes on behalf of
+all Contributors all liability for damages, including direct,
+indirect, special, incidental and consequential damages, such as
+lost profits;</div>
+
+<div style="margin-left: 2em">iii) states that any provisions which
+differ from this Agreement are offered by that Contributor alone
+and not by any other party; and</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p>When the Program is made available in source code form:</p>
+
+<div style="margin-left: 2em">a) it must be made available under
+this Agreement; and</div>
+
+<div style="margin-left: 2em">b) a copy of this Agreement must be
+included with each copy of the Program.</div>
+
+<p>Contributors may not remove or alter any copyright notices
+contained within the Program.</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">4. COMMERCIAL DISTRIBUTION</p>
+
+<p>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 ("Commercial Contributor")
+hereby agrees to defend and indemnify every other Contributor
+("Indemnified Contributor") against any losses, damages and costs
+(collectively "Losses") 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.</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">5. NO WARRANTY</p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 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.</p>
+
+<p style="font-weight: bold">6. DISCLAIMER OF LIABILITY</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">7. GENERAL</p>
+
+<p>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.</p>
+
+<p>If Recipient institutes patent litigation against a Contributor
+with respect to a patent applicable to software (including a
+cross-claim or counterclaim in a lawsuit), then any patent licenses
+granted by that Contributor to such Recipient under this Agreement
+shall terminate as of the date such litigation is filed. In
+addition, 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.</p>
+
+<p>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.</p>
+
+<p>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. IBM is the initial Agreement Steward. IBM 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.</p>
+
+<p>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.</p>
+</body>
+</html>
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/feature.properties
new file mode 100644
index 0000000..33f07ed
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/feature.properties
@@ -0,0 +1,151 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $Id: feature.properties,v 1.1 2004/10/18 15:50:42 dbirsan Exp $
+#  */
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+# This file 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=Eclipse Modeling Framework (EMF) Source
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=Eclipse Modeling Framework. (source code)
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/feature.xml
new file mode 100644
index 0000000..2200214
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/feature.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature primary="false"  provider-name="%providerName"    label="%featureName"  image="eclipse_update_120.jpg" id="org.eclipse.emf.source"  version="2.0.0">
+	<description >
+		%description
+	</description>
+	<copyright url="http://www.eclipse.org/legal/cpl-v10.html">
+		Copyright (c) 2002-2004 IBM Corporation and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+	</copyright>
+	<license url="%licenseURL">
+		%license
+	</license>
+	<url>
+		<update label="%updateSiteName" url="http://update.eclipse.org/updates/"/>
+		<discovery label="%secondaryUpdateSiteName" url="http://download.eclipse.org/tools/emf/updates/"/>
+	</url>
+	<plugin    fragment="false"  download-size="0" install-size="0" id="org.eclipse.emf.source" version="2.0.0"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/license.html
new file mode 100644
index 0000000..07a5e18
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf.source_2.0.0/license.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy, see www.w3.org" />
+<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.org Software User Agreement</h2>
+
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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
+Eclipse.org is provided to you under the terms and conditions of
+the Common Public License Version 1.0 ("CPL"). A copy of the CPL is
+provided with this Content and is also available at <a
+href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+For purposes of the CPL, "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>
+
+<li>Plug-in and Fragment directories</li>
+
+<li>Subdirectories of the directory named "src" of certain
+Plug-ins</li>
+
+<li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by Eclipse.org 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 CPL 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>Apache Software License 1.1 (available at <a
+href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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
+Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..95416c1
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/cpl-v10.html
@@ -0,0 +1,266 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy, see www.w3.org" />
+<title>Common Public License - v 1.0</title>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1" />
+</head>
+<body bgcolor="#FFFFFF" vlink="#800000">
+<p style="font-weight: bold; text-align: center">Common Public
+License - v 1.0</p>
+
+<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS
+COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF
+THIS AGREEMENT.</p>
+
+<p style="font-weight: bold">1. DEFINITIONS</p>
+
+<p>"Contribution" means:</p>
+
+<div style="margin-left: 2em">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:</div>
+
+<div style="margin-left: 2em">i) changes to the Program, and</div>
+
+<div style="margin-left: 2em">ii) additions to the Program;</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p>"Contributor" means any person or entity that distributes the
+Program.</p>
+
+<p>"Licensed Patents " 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.</p>
+
+<p>"Program" means the Contributions distributed in accordance with
+this Agreement.</p>
+
+<p>"Recipient" means anyone who receives the Program under this
+Agreement, including all Contributors.</p>
+
+<p style="font-weight: bold">2. GRANT OF RIGHTS</p>
+
+<div style="margin-left: 2em">a) Subject to the terms of this
+Agreement, each Contributor hereby grants Recipient a
+non-exclusive, worldwide, royalty-free copyright license to
+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.</div>
+
+<div style="margin-left: 2em">b) Subject to the terms of this
+Agreement, each Contributor hereby grants Recipient a
+non-exclusive, worldwide, 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.</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p style="font-weight: bold">3. REQUIREMENTS</p>
+
+<p>A Contributor may choose to distribute the Program in object
+code form under its own license agreement, provided that:</p>
+
+<div style="margin-left: 2em">a) it complies with the terms and
+conditions of this Agreement; and</div>
+
+<div style="margin-left: 2em">b) its license agreement:</div>
+
+<div style="margin-left: 2em">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;</div>
+
+<div style="margin-left: 2em">ii) effectively excludes on behalf of
+all Contributors all liability for damages, including direct,
+indirect, special, incidental and consequential damages, such as
+lost profits;</div>
+
+<div style="margin-left: 2em">iii) states that any provisions which
+differ from this Agreement are offered by that Contributor alone
+and not by any other party; and</div>
+
+<div style="margin-left: 2em">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.</div>
+
+<p>When the Program is made available in source code form:</p>
+
+<div style="margin-left: 2em">a) it must be made available under
+this Agreement; and</div>
+
+<div style="margin-left: 2em">b) a copy of this Agreement must be
+included with each copy of the Program.</div>
+
+<p>Contributors may not remove or alter any copyright notices
+contained within the Program.</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">4. COMMERCIAL DISTRIBUTION</p>
+
+<p>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 ("Commercial Contributor")
+hereby agrees to defend and indemnify every other Contributor
+("Indemnified Contributor") against any losses, damages and costs
+(collectively "Losses") 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.</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">5. NO WARRANTY</p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 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.</p>
+
+<p style="font-weight: bold">6. DISCLAIMER OF LIABILITY</p>
+
+<p>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.</p>
+
+<p style="font-weight: bold">7. GENERAL</p>
+
+<p>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.</p>
+
+<p>If Recipient institutes patent litigation against a Contributor
+with respect to a patent applicable to software (including a
+cross-claim or counterclaim in a lawsuit), then any patent licenses
+granted by that Contributor to such Recipient under this Agreement
+shall terminate as of the date such litigation is filed. In
+addition, 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.</p>
+
+<p>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.</p>
+
+<p>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. IBM is the initial Agreement Steward. IBM 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.</p>
+
+<p>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.</p>
+</body>
+</html>
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/feature.properties
new file mode 100644
index 0000000..7c947a4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/feature.properties
@@ -0,0 +1,154 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $Id: feature.properties,v 1.1 2004/10/18 15:50:42 dbirsan Exp $
+#  */
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+# This file 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=Eclipse Modeling Framework (EMF)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=Eclipse Modeling Framework. (Binary runtime)
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
+
+# "secondaryUpdateSiteName" property - label for the secondary update site (on download.eclipse.org)
+secondaryUpdateSiteName=EMF/SDO/XSD Secondary Update Site
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/feature.xml
new file mode 100644
index 0000000..6d59f37
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/feature.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.emf"
+      label="%featureName"
+      version="2.0.0"
+      provider-name="%providerName"
+      image="eclipse_update_120.jpg">
+
+   <description>
+      %description
+   </description>
+
+   <copyright url="http://www.eclipse.org/legal/cpl-v10.html">
+      Copyright (c) 2002-2004 IBM Corporation and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <url>
+      <update label="%updateSiteName" url="http://update.eclipse.org/updates/"/>
+      <discovery label="%secondaryUpdateSiteName" url="http://download.eclipse.org/tools/emf/updates/"/>
+   </url>
+
+   <requires>
+      <import plugin="org.eclipse.core.resources" version="3.0.0" match="compatible"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.emf"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.codegen"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.codegen.ui"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.codegen.ecore"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.codegen.ecore.ui"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.common"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.common.ui"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.ecore"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.ecore.edit"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.ecore.editor"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.ecore.change"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.ecore.change.edit"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.ecore.xmi"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.edit"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.edit.ui"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.mapping"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.mapping.ui"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.mapping.ecore2ecore"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.mapping.ecore2ecore.editor"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/license.html
new file mode 100644
index 0000000..07a5e18
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.emf_2.0.0/license.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta name="generator" content="HTML Tidy, see www.w3.org" />
+<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.org Software User Agreement</h2>
+
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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
+Eclipse.org is provided to you under the terms and conditions of
+the Common Public License Version 1.0 ("CPL"). A copy of the CPL is
+provided with this Content and is also available at <a
+href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+For purposes of the CPL, "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>
+
+<li>Plug-in and Fragment directories</li>
+
+<li>Subdirectories of the directory named "src" of certain
+Plug-ins</li>
+
+<li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by Eclipse.org 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 CPL 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>Apache Software License 1.1 (available at <a
+href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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
+Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/.project b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/.project
new file mode 100644
index 0000000..472b822
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jdt-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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/feature.xml
new file mode 100644
index 0000000..cb0b530
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/feature.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.jdt"
+      label="%featureName"
+      version="3.1.0"
+      image= "eclipse_update_120.jpg"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+
+   <license url="%licenseURL">
+     %license
+   </license>
+
+   <url>
+      <update label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+      <discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+   </url>
+
+  <requires>
+      <import plugin="org.eclipse.platform" version="3.1.0" match="compatible" />
+  </requires>
+  
+   <plugin
+         id="org.eclipse.jdt"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.ant.ui"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.ltk.core.refactoring"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.ltk.ui.refactoring"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.jdt.core"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.jdt.debug.ui"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.jdt.debug"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.jdt.junit"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.jdt.junit.runtime"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.jdt.launching"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.eclipse.jdt.ui"
+         download-size="0"
+         install-size="0"
+         version="3.1.0">
+   </plugin>
+
+   <plugin
+         id="org.junit"
+         download-size="0"
+         install-size="0"
+         version="3.8.1">
+   </plugin>
+
+   <plugin id="org.eclipse.jdt.doc.user" version="3.1.0"/>
+
+   <plugin id="org.eclipse.jdt.launching.macosx" version="3.1.0"  os="macosx" ws="carbon"/>  
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/license.html
new file mode 100644
index 0000000..e7d8500
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt-feature/license.html
@@ -0,0 +1,72 @@
+<!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.org Software User Agreement</h2>
+<p>15<sup>th</sup> June, 2004</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Eclipse Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-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>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>
+</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 Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/.project b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/.project
new file mode 100644
index 0000000..35af184
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jdt.source-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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/cpl-v10.html
new file mode 100644
index 0000000..158d99c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/feature.xml
new file mode 100644
index 0000000..336ac86
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/feature.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature primary="false"  provider-name="%providerName"    label="%featureName"  image="eclipse_update_120.jpg" id="org.eclipse.jdt.source"  version="3.1.0">
+	<description >
+		%description
+	</description>
+	<license url="%licenseURL">
+		%license
+	</license>
+	<url>
+		<update label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+		<discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+	</url>
+	<plugin    fragment="false"  download-size="0" install-size="0" id="org.eclipse.jdt.doc.isv" version="3.1.0"/>
+	<plugin    fragment="false"  download-size="0" install-size="0" id="org.eclipse.jdt.source" version="3.1.0"/>
+	<plugin ws="carbon"  os="macosx" fragment="true" arch="ppc" download-size="0" install-size="0" id="org.eclipse.jdt.source.macosx.carbon.ppc" version="3.1.0"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/license.html
new file mode 100644
index 0000000..e7d8500
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.jdt.source-feature/license.html
@@ -0,0 +1,72 @@
+<!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.org Software User Agreement</h2>
+<p>15<sup>th</sup> June, 2004</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Eclipse Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-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>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>
+</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 Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/.project b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/.project
new file mode 100644
index 0000000..223a24d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.pde-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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/feature.xml
new file mode 100644
index 0000000..5d22266
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/feature.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.pde"
+      label="%featureName"
+      version="3.1.0"
+      provider-name="%providerName"
+      image="eclipse_update_120.jpg">
+
+   <description>
+      %description
+   </description>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <url>
+      <update label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+      <discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+   </url>
+
+   <requires>
+      <import plugin="org.eclipse.jdt" version="3.0.0" match="compatible"/>
+      <import plugin="org.eclipse.platform" version="3.0.0" match="compatible"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.pde"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.pde.build"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.pde.core"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.pde.junit.runtime"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+         
+   <plugin
+         id="org.eclipse.pde.runtime"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.pde.ui"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.pde.doc.user"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/license.html
new file mode 100644
index 0000000..e7d8500
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde-feature/license.html
@@ -0,0 +1,72 @@
+<!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.org Software User Agreement</h2>
+<p>15<sup>th</sup> June, 2004</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Eclipse Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-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>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>
+</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 Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/.project b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/.project
new file mode 100644
index 0000000..f4bce7b
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.pde.source-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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/feature.xml
new file mode 100644
index 0000000..5abbbc7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/feature.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature primary="false"  provider-name="%providerName"    label="%featureName"  image="eclipse_update_120.jpg" id="org.eclipse.pde.source"  version="3.1.0">
+	<description >
+		%description
+	</description>
+	<license url="%licenseURL">
+		%license
+	</license>
+	<url>
+		<update label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+		<discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+	</url>
+	<plugin    fragment="false"  download-size="0" install-size="0" id="org.eclipse.pde.source" version="3.1.0"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/license.html
new file mode 100644
index 0000000..e7d8500
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.pde.source-feature/license.html
@@ -0,0 +1,72 @@
+<!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.org Software User Agreement</h2>
+<p>15<sup>th</sup> June, 2004</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Eclipse Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-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>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>
+</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 Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/.project b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/.project
new file mode 100644
index 0000000..9f53c70
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.platform-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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/feature.xml
new file mode 100644
index 0000000..872f5cb
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/feature.xml
@@ -0,0 +1,387 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+In the following markup, ignore the "primary" and "application" attributes.
+See https://bugs.eclipse.org/bugs/show_bug.cgi?id=68351 for more details.
+-->
+<feature
+      id="org.eclipse.platform"
+      label="%featureName"
+      version="3.1.0"
+      provider-name="%providerName"
+      plugin=""
+      image="eclipse_update_120.jpg"
+      primary="true"
+      application="org.eclipse.ui.ide.workbench">
+
+   <description>
+      %description
+   </description>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <url>
+      <update label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+      <discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+   </url>
+
+   <plugin
+         id="org.apache.ant"
+         download-size="0"
+         install-size="0"
+         version="1.6.2"/>
+
+   <plugin
+         id="org.apache.lucene"
+         download-size="0"
+         install-size="0"
+         version="1.3.0"/>
+
+   <plugin
+         id="org.eclipse.ant.core"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.compare"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.core.boot"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+         
+   <plugin
+   		 id="org.eclipse.core.filebuffers"
+   		 download-size="0"
+   		 install-size="0"
+   		 version="3.1.0"/>
+   
+   <plugin
+   		 id="org.eclipse.core.expressions"
+   		 download-size="0"
+   		 install-size="0"
+   		 version="3.1.0"/>
+   
+   <plugin
+         id="org.eclipse.core.resources"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.core.runtime"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.core.runtime.compatibility"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.osgi"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.osgi.services"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.osgi.util"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.core.variables"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+         
+   <plugin
+         id="org.eclipse.debug.core"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.debug.ui"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.help"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.help.webapp"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.help.base"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.help.ui"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.help.appserver"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.help.ide"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.platform"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.platform.doc.user"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.search"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.swt"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.team.core"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.team.cvs.core"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.team.cvs.ssh"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.team.cvs.ssh2"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.team.cvs.ui"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.team.ui"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.tomcat"
+         download-size="0"
+         install-size="0"
+         version="4.1.30"/>
+
+   <plugin
+         id="org.eclipse.text"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.jface"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.jface.text"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+	
+   <plugin
+         id="org.eclipse.ui.console"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.ui.presentations.r21"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+            
+   <plugin
+         id="org.eclipse.ui.intro"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.ui.cheatsheets"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+            
+   <plugin
+         id="org.eclipse.ui.workbench"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.ui.workbench.texteditor"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.ui.views"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.ui.editors"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+         
+   <plugin
+         id="org.eclipse.ui.forms"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+         
+   <plugin
+         id="org.eclipse.ui"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.ui.externaltools"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.ui.ide"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"/>
+
+   <plugin
+         id="org.eclipse.update.configurator"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.update.core"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.update.scheduler"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+
+   <plugin
+         id="org.eclipse.update.ui"
+         download-size="0"
+         install-size="0"
+         version="3.0.0"/>
+        
+  <!-- Pre-3.0 binary compatibility -->
+   <plugin
+         id="org.eclipse.ui.workbench.compatibility"
+         download-size="0"
+         install-size="0"
+         version="3.1.0"
+         fragment="true"/>
+
+  <!--Aix platform inclusion -->
+  <plugin id="org.eclipse.swt.motif" download-size="0" install-size="0" version="3.1.0" fragment="true" os="aix" ws="motif"/>
+  
+  <!-- HPUX Platform specifics -->
+  <plugin id="org.eclipse.swt.motif" download-size="0" install-size="0" version="3.1.0" fragment="true" os="hpux" ws="motif"/>
+  <plugin id="org.eclipse.core.resources.hpux" download-size="0" install-size="0" version="3.0.0" fragment="true" os="hpux"/>
+
+  <!-- LINUX GTK-->  
+  <plugin id="org.eclipse.swt.gtk" download-size="0" install-size="0" version="3.1.0"  fragment="true" os="linux" ws="gtk" arch="x86" />
+  <plugin id="org.eclipse.swt.gtk" download-size="0" install-size="0" version="3.1.0"  fragment="true" os="linux" ws="gtk" arch="ppc" />
+  <plugin id="org.eclipse.core.resources.linux" download-size="0" install-size="0" version="3.0.0" fragment="true" os="linux"/>
+  <plugin id="org.eclipse.update.core.linux" download-size="0" install-size="0" version="3.0.0" fragment="true" os="linux" />
+
+  <!-- LINUX GTK AMD64-->
+  <plugin id="org.eclipse.swt.gtk64" download-size="0" install-size="0" version="3.1.0"  fragment="true" os="linux" ws="gtk" arch="amd64" />
+
+  <!-- LINUX Motif-->    
+  <plugin id="org.eclipse.swt.motif" download-size="0" install-size="0" version="3.1.0" fragment="true" os="linux" ws="motif"/>
+  <plugin id="org.eclipse.core.resources.linux" download-size="0" install-size="0" version="3.0.0" fragment="true" os="linux"/>
+  <plugin id="org.eclipse.update.core.linux" download-size="0" install-size="0" version="3.0.0" fragment="true" os="linux" />
+
+  <!-- MacOS X Carbon -->  
+  <plugin id="org.eclipse.swt.carbon" download-size="0" install-size="0" version="3.1.0"  fragment="true" os="macosx" ws="carbon"/> 
+  <plugin id="org.eclipse.core.resources.macosx" download-size="0" install-size="0" version="3.0.0" fragment="true" os="macosx" ws="carbon"/>
+  <plugin id="org.eclipse.ui.carbon" download-size="0" install-size="0" version="3.1.0" fragment="true" os="macosx" ws="carbon"/>
+  
+  <!-- QNX Photon -->
+  <plugin id="org.eclipse.swt.photon" download-size="0" install-size="0" version="3.1.0" fragment="true" os="qnx" ws="photon"/>
+  <plugin id="org.eclipse.core.resources.qnx" download-size="0" install-size="0" version="3.0.0" fragment="true" os="qnx" ws="photon"/>
+  
+  <!-- Solaris Motif -->
+  <plugin id="org.eclipse.swt.motif" download-size="0" install-size="0" version="3.1.0" fragment="true" os="solaris" ws="motif"/>
+  
+  <!-- Win32 -->
+  <plugin id="org.eclipse.swt.win32" download-size="0" install-size="0" version="3.1.0" fragment="true" ws="win32"/>
+  <plugin id="org.eclipse.core.resources.win32" download-size="0" install-size="0" version="3.0.0" fragment="true" os="win32"/>
+  <plugin id="org.eclipse.ui.win32" download-size="0" install-size="0" version="3.1.0" fragment="true" ws="win32"/>
+  <plugin id="org.eclipse.update.core.win32" download-size="0" install-size="0" version="3.0.0" fragment="true" os="win32"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/license.html
new file mode 100644
index 0000000..e7d8500
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform-feature/license.html
@@ -0,0 +1,72 @@
+<!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.org Software User Agreement</h2>
+<p>15<sup>th</sup> June, 2004</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Eclipse Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-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>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>
+</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 Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/.project b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/.project
new file mode 100644
index 0000000..d7ca40c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.platform.source-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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/feature.xml
new file mode 100644
index 0000000..3bdee40
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/feature.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature primary="false"  provider-name="%providerName"    label="%featureName"  image="eclipse_update_120.jpg" id="org.eclipse.platform.source"  version="3.1.0">
+	<description >
+		%description
+	</description>
+	<license url="%licenseURL">
+		%license
+	</license>
+	<url>
+		<update label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+		<discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+	</url>
+	<plugin    fragment="false"  download-size="0" install-size="0" id="org.eclipse.platform.doc.isv" version="3.1.0"/>
+	<plugin    fragment="false"  download-size="0" install-size="0" id="org.eclipse.platform.source" version="3.1.0"/>
+	<plugin ws="gtk"  os="linux" fragment="true" arch="ia64" download-size="0" install-size="0" id="org.eclipse.platform.source.linux.gtk.ia64" version="3.1.0"/>
+	<plugin ws="carbon"  os="macosx" fragment="true" arch="ppc" download-size="0" install-size="0" id="org.eclipse.platform.source.macosx.carbon.ppc" version="3.1.0"/>
+	<plugin ws="photon"  os="qnx" fragment="true" arch="x86" download-size="0" install-size="0" id="org.eclipse.platform.source.qnx.photon.x86" version="3.1.0"/>
+	<plugin ws="gtk"  os="linux" fragment="true" arch="ppc" download-size="0" install-size="0" id="org.eclipse.platform.source.linux.gtk.ppc" version="3.1.0"/>
+	<plugin ws="motif"  os="hpux" fragment="true" arch="PA_RISC" download-size="0" install-size="0" id="org.eclipse.platform.source.hpux.motif.PA_RISC" version="3.1.0"/>
+	<plugin ws="motif"  os="aix" fragment="true" arch="ppc" download-size="0" install-size="0" id="org.eclipse.platform.source.aix.motif.ppc" version="3.1.0"/>
+	<plugin ws="gtk"  os="linux" fragment="true" arch="x86" download-size="0" install-size="0" id="org.eclipse.platform.source.linux.gtk.x86" version="3.1.0"/>
+	<plugin ws="win32"  os="win32" fragment="true" arch="x86" download-size="0" install-size="0" id="org.eclipse.platform.source.win32.win32.x86" version="3.1.0"/>
+	<plugin ws="motif"  os="solaris" fragment="true" arch="sparc" download-size="0" install-size="0" id="org.eclipse.platform.source.solaris.motif.sparc" version="3.1.0"/>
+	<plugin ws="gtk"  os="linux" fragment="true" arch="amd64" download-size="0" install-size="0" id="org.eclipse.platform.source.linux.gtk.amd64" version="3.1.0"/>
+	<plugin ws="motif"  os="linux" fragment="true" arch="x86" download-size="0" install-size="0" id="org.eclipse.platform.source.linux.motif.x86" version="3.1.0"/>
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/license.html
new file mode 100644
index 0000000..e7d8500
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.platform.source-feature/license.html
@@ -0,0 +1,72 @@
+<!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.org Software User Agreement</h2>
+<p>15<sup>th</sup> June, 2004</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Eclipse Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-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>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>
+</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 Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/.project b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/.project
new file mode 100644
index 0000000..49f7d79
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/feature.xml
new file mode 100644
index 0000000..f29904c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/feature.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.sdk"
+      label="%featureName"
+      version="3.1.0"
+      image= "eclipse_update_120.jpg"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+   
+   <license url="%licenseURL">
+     %license
+   </license>
+
+   <url>
+      <update label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+      <discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.0"/>
+   </url>
+
+  <includes id="org.eclipse.platform" version="3.1.0" /> 
+  <includes id="org.eclipse.platform.source" version="3.1.0" /> 
+  <includes id="org.eclipse.jdt" version="3.1.0" />
+  <includes id="org.eclipse.jdt.source" version="3.1.0" /> 
+  <includes id="org.eclipse.pde" version="3.1.0" /> 
+  <includes id="org.eclipse.pde.source" version="3.1.0" /> 
+  <plugin id="org.eclipse.sdk" version="3.1.0"/>
+  
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/license.html
new file mode 100644
index 0000000..e7d8500
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.sdk-feature/license.html
@@ -0,0 +1,72 @@
+<!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.org Software User Agreement</h2>
+<p>15<sup>th</sup> June, 2004</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Eclipse Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-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>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>
+</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 Eclipse.org 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/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/feature.properties
new file mode 100644
index 0000000..f4c1d56
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/feature.properties
@@ -0,0 +1,151 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $Id: feature.properties,v 1.1 2004/10/18 15:50:42 dbirsan Exp $
+#  */
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+# This file 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=XML Schema Infoset Model (XSD) Documentation
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=Eclipse Modeling Framework. (documentation)
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/feature.xml
new file mode 100644
index 0000000..fe4f380
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/feature.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2002-2004 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ *   IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: feature.xml,v 1.1 2004/03/06 18:00:09 marcelop Exp $
+ */
+-->
+
+<feature
+      id="org.eclipse.xsd.doc"
+      label="%featureName"
+      version="2.0.0"
+      image= "eclipse_update_120.jpg"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+
+   <license url="%licenseURL">
+     %license
+   </license>
+
+   <url>
+      <update url="http://update.eclipse.org/updates" label="%updateSiteName"/>
+   </url>
+
+   <plugin
+         id="org.eclipse.xsd.doc"
+         download-size="0"
+         install-size="0"
+         version="2.0.0">
+   </plugin>
+   		
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/license.html
new file mode 100644
index 0000000..af8c380
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.doc_2.0.0/license.html
@@ -0,0 +1,71 @@
+<!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.org Software User Agreement</h2>
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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 Eclipse.org 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>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/feature.properties
new file mode 100644
index 0000000..b806af2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/feature.properties
@@ -0,0 +1,151 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $Id: feature.properties,v 1.1 2004/10/18 15:50:42 dbirsan Exp $
+#  */
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+# This file 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=XML Schema Infoset Model (XSD) Source
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=Eclipse Modeling Framework. (source code)
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/feature.xml
new file mode 100644
index 0000000..d5f2b77
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/feature.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2002-2004 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ *   IBM - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: feature.xml,v 1.1 2004/03/06 18:00:11 marcelop Exp $
+ */
+-->
+
+<feature
+      id="org.eclipse.xsd.source"
+      label="%featureName"
+      version="2.0.0"
+      image= "eclipse_update_120.jpg"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+
+   <license url="%licenseURL">
+     %license
+   </license>
+
+   <url>
+      <update url="http://update.eclipse.org/updates" label="%updateSiteName"/>
+   </url>
+
+   <plugin
+         id="org.eclipse.xsd.source"
+         download-size="0"
+         install-size="0"
+         version="2.0.0">
+   </plugin>
+   
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/license.html
new file mode 100644
index 0000000..af8c380
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd.source_2.0.0/license.html
@@ -0,0 +1,71 @@
+<!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.org Software User Agreement</h2>
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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 Eclipse.org 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>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/cpl-v10.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/cpl-v10.html
new file mode 100644
index 0000000..36aa208
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/cpl-v10.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+<HEAD>
+<TITLE>Common Public License - v 1.0</TITLE>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" VLINK="#800000">
+
+
+<P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
+<P><B></B><FONT SIZE="3"></FONT>
+<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").  ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>1.  DEFINITIONS</B></FONT>
+<P><FONT SIZE="2">"Contribution" means:</FONT>
+
+<UL><FONT SIZE="2">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:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	 	changes to the Program, and</FONT></UL>
+
+
+<UL><FONT SIZE="2">ii)		additions to the Program;</FONT></UL>
+
+
+<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor.  </FONT><FONT SIZE="2">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.  </FONT><FONT SIZE="2">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.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Licensed Patents " 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.  </FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
+<P><FONT SIZE="2"><B></B></FONT>
+<P><FONT SIZE="2"><B>2.  GRANT OF RIGHTS</B></FONT>
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a)	</FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) 	Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">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.   </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+
+<UL><FONT SIZE="2">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. </FONT></UL>
+
+
+<UL><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2"><B>3.  REQUIREMENTS</B></FONT>
+<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
+
+<UL><FONT SIZE="2">a)	it complies with the terms and conditions of this Agreement; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	its license agreement:</FONT></UL>
+
+
+<UL><FONT SIZE="2">i)	effectively disclaims</FONT><FONT SIZE="2"> 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; </FONT></UL>
+
+
+<UL><FONT SIZE="2">ii) 	effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
+
+
+<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2">	states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL>
+
+
+<UL><FONT SIZE="2">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.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
+
+
+<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
+
+<P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
+
+<UL><FONT SIZE="2">a)	it must be made available under this Agreement; and </FONT></UL>
+
+
+<UL><FONT SIZE="2">b)	a copy of this Agreement must be included with each copy of the Program.  </FONT></UL>
+
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>4.  COMMERCIAL DISTRIBUTION</B></FONT>
+<P><FONT SIZE="2">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 ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") 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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
+<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5.  NO WARRANTY</B></FONT>
+<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6.  DISCLAIMER OF LIABILITY</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> 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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"><B>7.  GENERAL</B></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed.  In addition, 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. </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.  </FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward.   IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity.  </FONT><FONT SIZE="2">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 </FONT><FONT SIZE="2">version.  </FONT><FONT SIZE="2">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, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2">  All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
+<P><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2">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.</FONT>
+<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
+<P><FONT SIZE="2"></FONT>
+
+</BODY>
+
+</HTML>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/eclipse_update_120.jpg b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/eclipse_update_120.jpg
new file mode 100644
index 0000000..68e3e02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/eclipse_update_120.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/feature.properties b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/feature.properties
new file mode 100644
index 0000000..3f0ded5
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/feature.properties
@@ -0,0 +1,154 @@
+###############################################################################
+# Copyright (c) 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
+###############################################################################
+# /**
+#  * <copyright>
+#  *
+#  * Copyright (c) 2002-2004 IBM Corporation and others.
+#  * All rights reserved.   This program and the accompanying materials
+#  * are made available under the terms of the Common Public License v1.0
+#  * which accompanies this distribution, and is available at
+#  * http://www.eclipse.org/legal/cpl-v10.html
+#  * 
+#  * Contributors: 
+#  *   IBM - Initial API and implementation
+#  *
+#  * </copyright>
+#  *
+#  * $Id: feature.properties,v 1.1 2004/10/18 15:50:42 dbirsan Exp $ 
+#  */
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+# This file 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=XSD Schema Infoset Model
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=Eclipse.org update site
+
+# "description" property - description of the feature
+description=XML Schema Infoset Model
+
+# "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.ORG SOFTWARE USER AGREEMENT\n\
+14th August, 2003\n\
+\n\
+Usage Of Content\n\
+\n\
+ECLIPSE.ORG 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 Eclipse.org\n\
+is provided to you under the terms and conditions of the Common Public\n\
+License Version 1.0 ("CPL"). A copy of the CPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/cpl-v10.html.\n\
+For purposes of the CPL, "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 apportioned into plug-ins ("Plug-ins"), plug-in fragments\n\
+("Fragments"), and features ("Features"). A Feature is a bundle of one or\n\
+more Plug-ins and/or Fragments and associated material. Files named\n\
+"feature.xml" may contain a list of the names and version numbers of the\n\
+Plug-ins and/or Fragments associated with a Feature. Plug-ins and Fragments\n\
+are located in directories named "plugins" and Features are located in\n\
+directories named "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\
+   - Subdirectories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by Eclipse.org 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 CPL 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\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\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 Eclipse.org 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
+########### end of license property ##########################################
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
+
+# "secondaryUpdateSiteName" property - label for the secondary update site (on download.eclipse.org)
+secondaryUpdateSiteName=EMF/SDO/XSD Secondary Update Site
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/feature.xml
new file mode 100644
index 0000000..3e51342
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/feature.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.xsd"
+      label="%featureName"
+      version="2.0.0"
+      provider-name="%providerName"
+      image="eclipse_update_120.jpg">
+
+   <description>
+      %description
+   </description>
+
+   <copyright url="http://www.eclipse.org/legal/cpl-v10.html">
+      Copyright (c) 2002-2004 IBM Corporation and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <url>
+      <update label="%updateSiteName" url="http://update.eclipse.org/updates/"/>
+      <discovery label="%secondaryUpdateSiteName" url="http://download.eclipse.org/tools/emf/updates/"/>
+   </url>
+
+   <requires>
+      <import plugin="org.eclipse.core.resources" version="3.0.0" match="compatible"/>
+      <import plugin="org.eclipse.emf.ecore" version="2.0.0" match="compatible"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.xsd"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.xsd.edit"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.xsd.editor"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.xsd.test"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.mapping.xsd2ecore"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+   <plugin
+         id="org.eclipse.emf.mapping.xsd2ecore.editor"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+</feature>
diff --git a/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/license.html b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/license.html
new file mode 100644
index 0000000..af8c380
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/eclipse/features/org.eclipse.xsd_2.0.0/license.html
@@ -0,0 +1,71 @@
+<!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.org Software User Agreement</h2>
+<p>14th August, 2003</p>
+
+<h3>Usage Of Content</h3>
+
+<p>ECLIPSE.ORG 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 Eclipse.org is provided to you under the terms and conditions of the Common Public License Version 1.0
+   (&quot;CPL&quot;).  A copy of the CPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+   For purposes of the CPL, &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>
+
+<p>Content may be apportioned into plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;). A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. 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 a Feature.   Plug-ins and Fragments are located in directories
+   named &quot;plugins&quot; and Features are located in directories named &quot;features&quot;.</p>
+  
+<p>Features may also include other Features (&quot;Included Features&quot;). Files named &quot;feature.xml&quot; 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 &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>Subdirectories 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 Eclipse.org 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;.
+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 CPL 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>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</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>
+</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 Eclipse.org 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>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/perf/platform.xml b/update/org.eclipse.update.tests.core/data/perf/platform.xml
new file mode 100644
index 0000000..983e5c4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/perf/platform.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Created on Mon Aug 23 15:05:43 EDT 2004-->
+<config date="1093287943134" transient="false" version="3.0">
+<site enabled="true" policy="USER-EXCLUDE" updateable="true" url="platform:/base/">
+<feature id="org.eclipse.barrup.rad.feature" url="features/org.eclipse.barrup.rad.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barupdate.dev.product" url="features/org.eclipse.barupdate.dev.product_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barupdate.dev" url="features/org.eclipse.barupdate.dev_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.uml2" url="features/org.eclipse.uml2_1.0.1/" version="1.0.1"/>
+<feature id="org.eclipse.barxtools.comparemerge.ejbddfeature" url="features/org.eclipse.barxtools.comparemerge.ejbdd-feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.serverattach.v5" url="features/org.eclipse.foo.serverattach.v5_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardebug.xsl" url="features/org.eclipse.bardebug.xsl_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barxtools.platform.feature" url="features/org.eclipse.barxtools.platform.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barsupport.rad.doc" url="features/org.eclipse.barsupport.rad.doc_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.barr2a.rdj.feature" url="features/org.eclipse.barr2a.rdj.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barupdate.test.ct.feature" url="features/org.eclipse.barupdate.test.ct.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barxtools.eDataviz.feature" url="features/org.eclipse.barxtools.eDataviz.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barrad.welcome.feature" url="features/org.eclipse.barrad.welcome.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardebug.wsa.launch.load" url="features/org.eclipse.bardebug.wsa.launch.load_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barrup.feature" url="features/org.eclipse.barrup.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barxtools.visualization.feature" url="features/org.eclipse.barxtools.visualization.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barrad.nav.doc.feature" url="features/org.eclipse.barrad.nav.doc.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y.test" primary="true" url="features/org.eclipse.y.test_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.bardebug.activescript.win32" url="features/org.eclipse.bardebug.activescript.win32_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barxtools.platform.win32.feature" url="features/org.eclipse.barxtools.platform.win32.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.portal.tools.feature" url="features/org.eclipse.foo.portal.tools.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.serverattach" url="features/org.eclipse.foo.serverattach_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y.test.examples" primary="true" url="features/org.eclipse.y.test.examples_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.barz.common.ui" url="features/org.eclipse.barz.common.ui_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.ejb" url="features/org.eclipse.barz.ejb_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y.profiling" primary="true" url="features/org.eclipse.y.profiling_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.foo.ejbdeploy.feature.nl1" url="features/org.eclipse.foo.ejbdeploy.feature.nl1_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.emf.integration" url="features/org.eclipse.barz.emf.integration_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardebug.javascript" url="features/org.eclipse.bardebug.javascript_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardebug.ast.feature" url="features/org.eclipse.bardebug.ast.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.wsvt-feature" url="features/org.eclipse.wsvt-feature_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.foo.sib.mediation.develop.feature" url="features/org.eclipse.foo.sib.mediation.develop.feature_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.foo.webservice.was.creation.ejb.feature.nl1" url="features/org.eclipse.foo.webservice.was.creation.ejb.feature.nl1_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.webedit.editor.feature" url="features/org.eclipse.foo.webedit.editor.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.data" url="features/org.eclipse.barz.data_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.sib.mediation.deploy.feature" url="features/org.eclipse.foo.sib.mediation.deploy.feature_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.foo.e" url="features/org.eclipse.foo.e_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.webservice.was.creation.ejb.feature" url="features/org.eclipse.foo.webservice.was.creation.ejb.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.siteedit.feature" url="features/org.eclipse.foo.siteedit.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.profiling.server.compatible" url="features/org.eclipse.foo.profiling.server.compatible_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.ws" url="features/org.eclipse.barz.ws_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.ejb.samples-feature" url="features/org.eclipse.foo.ejb.samples-feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.activities.feature" url="features/org.eclipse.barz.activities.feature_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.foo.examples" url="features/org.eclipse.foo.examples_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barx.sdk" url="features/org.eclipse.barx.sdk_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardebug.pdt.win32" url="features/org.eclipse.bardebug.pdt.win32_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardebug.wsa" url="features/org.eclipse.bardebug.wsa_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.jve.express" url="features/org.eclipse.foo.jve.express_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardata.linux" url="features/org.eclipse.bardata.linux_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barsse.xmlmarkup" url="features/org.eclipse.barsse.xmlmarkup_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.validation" url="features/org.eclipse.barz.validation_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y.gla" primary="true" url="features/org.eclipse.y.gla_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.barz.ws.model" url="features/org.eclipse.barz.ws.model_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barx.ast" url="features/org.eclipse.barx.ast_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barws.ast.st.ext.nl1" url="features/org.eclipse.barws.ast.st.ext.nl1_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.common.utilities" url="features/org.eclipse.barz.common.utilities_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.barz.common" url="features/org.eclipse.barz.common_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.xml.model" url="features/org.eclipse.barz.xml.model_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardebug.pdt" url="features/org.eclipse.bardebug.pdt_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.navigator" url="features/org.eclipse.barz.navigator_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.webtools.feature" url="features/org.eclipse.foo.webtools.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.emf.integration.core" url="features/org.eclipse.barz.emf.integration.core_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.foo.struts.feature" url="features/org.eclipse.foo.struts.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barsse.base" url="features/org.eclipse.barsse.base_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardebug.help.doc" url="features/org.eclipse.bardebug.help.doc_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y.models" url="features/org.eclipse.y.models_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.y.logging" url="features/org.eclipse.y.logging_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.bardebug.javascript.nl1.feature" url="features/org.eclipse.bardebug.javascript.nl1.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barws.ast.st.batch" url="features/org.eclipse.barws.ast.st.batch_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barsse.snippets" url="features/org.eclipse.barsse.snippets_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barws.rapiddeploy" plugin-identifier="org.eclipse.barws.rapiddeploy.core" url="features/org.eclipse.barws.rapiddeploy_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.bardata" url="features/org.eclipse.bardata_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.security" url="features/org.eclipse.foo.security_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.probekit" url="features/org.eclipse.foo.probekit_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.jsf.feature" url="features/org.eclipse.foo.jsf.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.analysis" url="features/org.eclipse.foo.analysis_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.ac-tech" url="features/org.eclipse.foo.ac-tech_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.webservice.was.creation.feature" url="features/org.eclipse.foo.webservice.was.creation.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.ejb" url="features/org.eclipse.foo.ejb_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.ejbdeploy.feature" url="features/org.eclipse.foo.ejbdeploy.feature_5.1.1/" version="5.1.1"/>
+<feature id="org.eclipse.barz.e" url="features/org.eclipse.barz.e_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.ftp" url="features/org.eclipse.foo.ftp_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y.examples" url="features/org.eclipse.y.examples_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.foo.jve.core" url="features/org.eclipse.foo.jve.core_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y.core" url="features/org.eclipse.y.core_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.barz.ws.axis" url="features/org.eclipse.barz.ws.axis_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.jve.e" url="features/org.eclipse.foo.jve.e_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.resources.common.feature" url="features/org.eclipse.foo.resources.common.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barws" url="features/org.eclipse.barws_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y" url="features/org.eclipse.y_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.bardebug.ast.nl1.feature" url="features/org.eclipse.bardebug.ast.nl1.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz" url="features/org.eclipse.barz_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barlpex" url="features/org.eclipse.barlpex_3.0.0/" version="3.0.0"/>
+<feature id="org.eclipse.barxml" url="features/org.eclipse.barxml_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.ws.consumption" url="features/org.eclipse.barz.ws.consumption_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.egl.feature" url="features/org.eclipse.foo.egl.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.server.tomcat" url="features/org.eclipse.barz.server.tomcat_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barws.rapiddeploy.cmdframework" url="features/org.eclipse.barws.rapiddeploy.cmdframework_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.foo.ejb.sbf.feature" url="features/org.eclipse.foo.ejb.sbf.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.qev" url="features/org.eclipse.foo.qev_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.ws.ext.feature" url="features/org.eclipse.foo.ws.ext.feature_5.9.0/" version="5.9.0"/>
+<feature id="org.eclipse.barz.xml" url="features/org.eclipse.barz.xml_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barupdate.web.developer" url="features/org.eclipse.barupdate.web.developer_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barws.ast.st.base.nl1" url="features/org.eclipse.barws.ast.st.base.nl1_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.jdt.integration" url="features/org.eclipse.barz.jdt.integration_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y.source" url="features/org.eclipse.y.source_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.foo.gla" url="features/org.eclipse.foo.gla_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.ws.ejb.nl1.feature" url="features/org.eclipse.foo.ws.ejb.nl1.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barws.ast.st.base" url="features/org.eclipse.barws.ast.st.base_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barsupport.rwd.doc" url="features/org.eclipse.barsupport.rwd.doc_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.barupdate.pd.prof" url="features/org.eclipse.barupdate.pd.prof_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.webservice.was.creation.feature.nl1" url="features/org.eclipse.foo.webservice.was.creation.feature.nl1_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.wsvtvalidatorfeature" url="features/org.eclipse.wsvtvalidatorfeature_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.barws.ast.st.batch.nl1" url="features/org.eclipse.barws.ast.st.batch.nl1_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barws.ast.doc.feature" url="features/org.eclipse.barws.ast.doc.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.ws.ejb.feature" url="features/org.eclipse.foo.ws.ejb.feature_5.9.0/" version="5.9.0"/>
+<feature id="org.eclipse.barws.rapiddeploy.nl1" url="features/org.eclipse.barws.rapiddeploy.nl1_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.barz.jca" url="features/org.eclipse.barz.jca_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.xml.validate" url="features/org.eclipse.barz.xml.validate_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.extension" url="features/org.eclipse.barz.extension_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.env.ui" url="features/org.eclipse.barz.env.ui_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.env" url="features/org.eclipse.barz.env_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barupdate.jscrib.framework" url="features/org.eclipse.barupdate.jscrib.framework_1.2.0/" version="1.2.0"/>
+<feature id="org.eclipse.bardebug.pdt.nl1.feature" url="features/org.eclipse.bardebug.pdt.nl1.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barrwd.doc.feature" url="features/org.eclipse.barrwd.doc.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barupdate.orphans" url="features/org.eclipse.barupdate.orphans_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.foo.profiling" url="features/org.eclipse.foo.profiling_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.y.probekit" url="features/org.eclipse.y.probekit_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.barsse.webmarkup" url="features/org.eclipse.barsse.webmarkup_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardata.win32" url="features/org.eclipse.bardata.win32_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.server" url="features/org.eclipse.barz.server_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.jem" url="features/org.eclipse.jem_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.foo.project.interchange" url="features/org.eclipse.foo.project.interchange_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.ve" url="features/org.eclipse.ve_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.bardebug.wsa.nl1.feature" url="features/org.eclipse.bardebug.wsa.nl1.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.webservice.was.deploy.feature.nl1" url="features/org.eclipse.foo.webservice.was.deploy.feature.nl1_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.ws.ext.nl1.feature" url="features/org.eclipse.foo.ws.ext.nl1.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.bardebug.helpas.doc" url="features/org.eclipse.bardebug.helpas.doc_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.emf.ui.integration" url="features/org.eclipse.foo.emf.ui.integration_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.webservice.was.deploy.feature" url="features/org.eclipse.foo.webservice.was.deploy.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barz.web" url="features/org.eclipse.barz.web_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.foo.profiling.server" url="features/org.eclipse.foo.profiling.server_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barws.ast.st.ext" url="features/org.eclipse.barws.ast.st.ext_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barrup.updatezone.feature" url="features/org.eclipse.barrup.updatezone.feature_1.0.0/" version="1.0.0"/>
+<feature id="org.eclipse.barsamplegallery-feature" url="features/org.eclipse.barsamplegallery-feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.jdt.source" url="features/org.eclipse.jdt.source_3.0.1/" version="3.0.1"/>
+<feature application="org.eclipse.ui.ide.workbench" id="org.eclipse.barupdate.sdp.feature" primary="true" url="features/org.eclipse.barupdate.sdp.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.pde.source" url="features/org.eclipse.pde.source_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.foo.lum.utils.feature" url="features/org.eclipse.foo.lum.utils.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.baresupport.client.nl1" url="features/org.eclipse.baresupport.client/" version="0.9.14"/>
+<feature id="org.eclipse.y.logging" url="features/org.eclipse.y.logging_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.emf.ecore.sdo.doc" url="features/org.eclipse.emf.ecore.sdo.doc_2.0.0/" version="2.0.0"/>
+<feature id="org.eclipse.foo.logging" url="features/org.eclipse.foo.logging_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barupdate.welcome.feature.nl1" url="features/org.eclipse.barupdate.welcome.feature.nl1/" version="6.0.0"/>
+<feature application="org.eclipse.ui.ide.workbench" id="org.eclipse.platform" primary="true" url="features/org.eclipse.platform_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.barcommon.doc.feature" url="features/org.eclipse.barcommon.doc.feature/" version="6.0.0"/>
+<feature id="org.eclipse.jdt" url="features/org.eclipse.jdt_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.barsupport.core.doc" url="features/org.eclipse.barsupport.core.doc/" version="1.0.0"/>
+<feature id="org.eclipse.xyz.clearcase" url="features/org.eclipse.xyz.clearcase_6.0.11/" version="6.0.11"/>
+<feature id="org.eclipse.bartutorialgallery-feature" url="features/org.eclipse.bartutorialgallery-feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barupdate.welcome.feature" url="features/org.eclipse.barupdate.welcome.feature/" version="6.0.0"/>
+<feature id="org.eclipse.emf" url="features/org.eclipse.emf_2.0.1/" version="2.0.1"/>
+<feature id="org.eclipse.platform.source" url="features/org.eclipse.platform.source_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.barupdate.common.activities.feature" url="features/org.eclipse.barupdate.common.activities.feature_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barupdate.cdi.itlm" url="features/org.eclipse.barupdate.cdi.itlm_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.pde" url="features/org.eclipse.pde_3.0.1/" version="3.0.1"/>
+<feature id="org.eclipse.emf.doc" url="features/org.eclipse.emf.doc_2.0.1/" version="2.0.1"/>
+<feature id="org.eclipse.emf.ecore.sdo" url="features/org.eclipse.emf.ecore.sdo_2.0.1/" version="2.0.1"/>
+<feature id="org.eclipse.barsupport.core.doc.nl1" url="features/org.eclipse.barsupport.core.doc.nl1/" version="1.0.0"/>
+<feature id="org.eclipse.barxtools.comparemerge" url="features/org.eclipse.barxtools.comparemerge_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.barxtools.common.ui.properties" url="features/org.eclipse.barxtools.common.ui.properties_6.0.0/" version="6.0.0"/>
+<feature id="org.eclipse.xsd" url="features/org.eclipse.xsd_2.0.1/" version="2.0.1"/>
+<feature id="org.eclipse.gef" url="features/org.eclipse.gef_3.0.0/" version="3.0.0"/>
+</site>
+</config>
diff --git a/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.feature1.plugin1_1.1.1.jar b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.feature1.plugin1_1.1.1.jar
new file mode 100644
index 0000000..0c995d5
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.feature1.plugin1_1.1.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.feature2.plugin2_2.2.2.jar b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.feature2.plugin2_2.2.2.jar
new file mode 100644
index 0000000..0c995d5
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.feature2.plugin2_2.2.2.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.tests.dummy_7.9.8.jar b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.tests.dummy_7.9.8.jar
new file mode 100644
index 0000000..78f193d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.tests.dummy_7.9.8.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
new file mode 100644
index 0000000..2275ade
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
new file mode 100644
index 0000000..ea958c7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
new file mode 100644
index 0000000..7f05d82
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.feature1.plugin1" version="3.5.6" vendor-name="junit.org">

+  <runtime>

+    <library name="junit.jar">

+      <export name="*"/>

+    </library>

+  </runtime>

+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.plugin1_1.1.1/src.jar b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
new file mode 100644
index 0000000..2d4d609
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/reconciliationSites/site1/install/features/feature3/feature.xml b/update/org.eclipse.update.tests.core/data/reconciliationSites/site1/install/features/feature3/feature.xml
new file mode 100644
index 0000000..3141af8
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/reconciliationSites/site1/install/features/feature3/feature.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature id="org.eclipse.update.core.tests.feature3" image="feature1.gif" label="Third Feature" provider-name="Smart Company" version="1.0.0" >
+  <description>Description</description>
+  <copyright>copyright</copyright>
+  <license>license</license>
+  <url>
+    <update label="URL to update the feature" url="http://www.eclipse.org/"/>
+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>
+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>
+  </url>
+  <plugin download-size="1500" id="org.eclipse.update.plugin1" install-size="1000" fragment="false" nl="us" os="OS_WIN32" version="1.1.1" ws="WS_WIN32"/>
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/reconciliationSites/site1/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml b/update/org.eclipse.update.tests.core/data/reconciliationSites/site1/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
new file mode 100644
index 0000000..e01846c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/reconciliationSites/site1/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.feature1.plugin1" version="3.5.6" vendor-name="junit.org">
+  <runtime>
+    <library name="junit.jar">
+      <export name="*"/>
+    </library>
+  </runtime>
+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/reconciliationSites/site1/plugins/org.eclipse.update.plugin1_1.1.1/src.jar b/update/org.eclipse.update.tests.core/data/reconciliationSites/site1/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
new file mode 100644
index 0000000..2d4d609
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/reconciliationSites/site1/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/reconciliationSites/site2/install/features/feature3/feature.xml b/update/org.eclipse.update.tests.core/data/reconciliationSites/site2/install/features/feature3/feature.xml
new file mode 100644
index 0000000..68a7de8
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/reconciliationSites/site2/install/features/feature3/feature.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature id="org.eclipse.update.core.tests.feature3" image="feature1.gif" label="Third Feature" provider-name="Smart Company" version="1.0.0" >
+  <description>Description</description>
+  <copyright>copyright</copyright>
+  <license>license</license>
+  <url>
+    <update label="URL to update the feature" url="http://www.eclipse.org/"/>
+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>
+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>
+  </url>
+  <plugin download-size="1500" id="org.eclipse.update.core" install-size="1000" fragment="false" nl="us" os="OS_WIN32" version="2.1.0" ws="WS_WIN32"/>
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/reconciliationSites/site2/plugins/org.eclipse.update.core_2.0.0/plugin.xml b/update/org.eclipse.update.tests.core/data/reconciliationSites/site2/plugins/org.eclipse.update.core_2.0.0/plugin.xml
new file mode 100644
index 0000000..e01846c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/reconciliationSites/site2/plugins/org.eclipse.update.core_2.0.0/plugin.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.feature1.plugin1" version="3.5.6" vendor-name="junit.org">
+  <runtime>
+    <library name="junit.jar">
+      <export name="*"/>
+    </library>
+  </runtime>
+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/reconciliationSites/site2/plugins/org.eclipse.update.core_2.0.0/src.jar b/update/org.eclipse.update.tests.core/data/reconciliationSites/site2/plugins/org.eclipse.update.core_2.0.0/src.jar
new file mode 100644
index 0000000..2d4d609
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/reconciliationSites/site2/plugins/org.eclipse.update.core_2.0.0/src.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/site.xml b/update/org.eclipse.update.tests.core/data/site.xml
new file mode 100644
index 0000000..3fc60c7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/site.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site type="org.eclipse.update.core.file">

+<description url="info/siteInfo.html"/>

+  <feature url="testAPI/features/feature3">

+    <category name="eclipse/UML"/>

+  </feature>

+  <feature url="http://www.eclipse.org/feature2">

+    <category name="eclipse/J2EE"/>

+  </feature>

+  <feature url="http://www.eclipse.org/feature1">

+    <category name="eclipse/J2EE"/>

+  </feature>

+  <archive path="plugins/org.eclipse.update.plugin1_1.1.1.jar" url="plugins/org.eclipse.update.plugin1_1.1.1"/>    

+  <category-def label="J2EE tools" name="eclipse/J2EE"/>

+  <category-def label="EJB Tools" name="eclipse/J2EE/EJB"/>

+  <category-def label="UML tools" name="eclipse/UML"/>

+  <category-def label="Messaging Tools" name="B2B"/>

+  <category-def label="Eclipse Tools" name="eclipse"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/site2/site.xml b/update/org.eclipse.update.tests.core/data/site2/site.xml
new file mode 100644
index 0000000..39d1c11
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/site2/site.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site url="Info.html" type="org.eclipse.update.core.file">

+  <feature url="features/feature1"/>

+  <archive path="org.eclipse.update.plugin1" url="plugins/plugin1"/>

+  <archive path="org.eclipse.update.archive2" url="plugins/plugin2"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/bundleAndPluginManifests_1.0.3/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/bundleAndPluginManifests_1.0.3/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..c3f0f0f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/bundleAndPluginManifests_1.0.3/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Generated-from: 1077062603708
+Bundle-Name: Test
+Bundle-Version: 1.0.3
+Bundle-SymbolicName: org.eclipse.update.core.tests.bundleAndPluginManifestsBUNDLEPARSED
+Bundle-Vendor: Eclipse.org
+Bundle-ClassPath: plugin.jar
+Legacy: true
+Bundle-Activator: org.eclipse.update.core.tests.bundleAndPluginManifests.Activator
+Require-Bundle: 
+ org.eclipse.core.runtime,
+ org.eclipse.ui
diff --git a/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/bundleAndPluginManifests_1.0.3/plugin.xml b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/bundleAndPluginManifests_1.0.3/plugin.xml
new file mode 100644
index 0000000..6b59ddb
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/bundleAndPluginManifests_1.0.3/plugin.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.bundleAndPluginManifests" version="1.0.3" vendor-name="Eclipse.org">
+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/bundleManifest_1.0.1/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/bundleManifest_1.0.1/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..fb22dc8
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/bundleManifest_1.0.1/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Generated-from: 1077062603708
+Bundle-Name: Test
+Bundle-Version: 1.0.1
+Bundle-SymbolicName: org.eclipse.update.core.tests.bundleManifest; singleton=true
+Bundle-Vendor: Eclipse.org
+Bundle-ClassPath: plugin.jar
+Legacy: true
+Bundle-Activator: org.eclipse.update.core.tests.bundleManifest.Activator
+Require-Bundle: 
+ org.eclipse.core.runtime,
+ org.eclipse.ui
diff --git a/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.0/plugin.xml b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.0/plugin.xml
new file mode 100644
index 0000000..7f81c46
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.0/plugin.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.feature1.plugin2" version="5.0.0" vendor-name="junit.org">

+  <runtime>

+    <library name="junit.jar">

+      <export name="*"/>

+    </library>

+  </runtime>

+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.0/src.jar b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.0/src.jar
new file mode 100644
index 0000000..2d4d609
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.0/src.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.1/plugin.xml b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.1/plugin.xml
new file mode 100644
index 0000000..efb3c26
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.1/plugin.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.feature1.plugin2" version="5.0.1" vendor-name="junit.org">

+  <runtime>

+    <library name="junit.jar">

+      <export name="*"/>

+    </library>

+  </runtime>

+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.1/src.jar b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.1/src.jar
new file mode 100644
index 0000000..2d4d609
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/feature1_plugin2_5.0.1/src.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/notBundleManifest_1.0.2/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/notBundleManifest_1.0.2/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ac24295
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/siteTestLocalSite/plugins/notBundleManifest_1.0.2/META-INF/MANIFEST.MF
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Generated-from: 1077062603708
+Bundle-Name: Not Valid Bundle Manifest
+Bundle-Version: 1.0.2
+Bundle-Vendor: Eclipse.org
+Bundle-ClassPath: plugin.jar
+Require-Bundle: 
+ org.eclipse.core.runtime,
+ org.eclipse.ui
diff --git a/update/org.eclipse.update.tests.core/data/testAPI/features/feature3/feature.xml b/update/org.eclipse.update.tests.core/data/testAPI/features/feature3/feature.xml
new file mode 100644
index 0000000..f878d60
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/testAPI/features/feature3/feature.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature id="org.eclipse.update.core.tests.feature3" image="feature1.gif" label="Third Feature" provider-name="Smart Company" version="1.0.0" >
+  <description>Description</description>
+  <copyright>copyright</copyright>
+  <license>license</license>
+  <url>
+    <update label="URL to update the feature" url="http://www.eclipse.org/"/>
+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>
+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>
+  </url>
+  <plugin download-size="1500" id="org.eclipse.update.plugin1" install-size="1000" fragment="false" nl="us" os="WIN32,LINUX" version="1.1.1"/>
+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/testAPI/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml b/update/org.eclipse.update.tests.core/data/testAPI/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
new file mode 100644
index 0000000..e01846c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/testAPI/plugins/org.eclipse.update.plugin1_1.1.1/plugin.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin name="JUnit Test Framework" id="org.eclipse.update.core.tests.feature1.plugin1" version="3.5.6" vendor-name="junit.org">
+  <runtime>
+    <library name="junit.jar">
+      <export name="*"/>
+    </library>
+  </runtime>
+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/testAPI/plugins/org.eclipse.update.plugin1_1.1.1/src.jar b/update/org.eclipse.update.tests.core/data/testAPI/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
new file mode 100644
index 0000000..2d4d609
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/testAPI/plugins/org.eclipse.update.plugin1_1.1.1/src.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/testAPI/site.xml b/update/org.eclipse.update.tests.core/data/testAPI/site.xml
new file mode 100644
index 0000000..4c15d43
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/testAPI/site.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site type="org.eclipse.update.core.file">
+<description url="info/siteInfo.html"/>
+  <feature url="features/feature3">
+    <category name="eclipse/UML"/>
+  </feature>
+  <feature url="http://www.eclipse.org/feature2">
+    <category name="eclipse/J2EE"/>
+  </feature>
+  <feature url="http://www.eclipse.org/feature1">
+    <category name="eclipse/J2EE"/>
+  </feature>
+  <archive path="plugins/org.eclipse.update.plugin1_1.1.1.jar" url="plugins/org.eclipse.update.plugin1_1.1.1"/>    
+  <category-def label="J2EE tools" name="eclipse/J2EE"/>
+  <category-def label="EJB Tools" name="eclipse/J2EE/EJB"/>
+  <category-def label="UML tools" name="eclipse/UML"/>
+  <category-def label="Messaging Tools" name="B2B"/>
+  <category-def label="Eclipse Tools" name="eclipse"/>
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/validation/site2/.eclipseproduct b/update/org.eclipse.update.tests.core/data/validation/site2/.eclipseproduct
new file mode 100644
index 0000000..8b829aa
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/validation/site2/.eclipseproduct
@@ -0,0 +1,3 @@
+id=another.product.id

+name=Name of the product

+ver=1.2.4
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/validation/site3/.eclipseextension b/update/org.eclipse.update.tests.core/data/validation/site3/.eclipseextension
new file mode 100644
index 0000000..6d72df7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/validation/site3/.eclipseextension
@@ -0,0 +1 @@
+id=id.of.extended.product
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/validation/site4/eclipse/.eclipseextension b/update/org.eclipse.update.tests.core/data/validation/site4/eclipse/.eclipseextension
new file mode 100644
index 0000000..acc84e9
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/validation/site4/eclipse/.eclipseextension
@@ -0,0 +1 @@
+id=different.product.id
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/validation/site5/.eclipseUM b/update/org.eclipse.update.tests.core/data/validation/site5/.eclipseUM
new file mode 100644
index 0000000..196c522
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/validation/site5/.eclipseUM
@@ -0,0 +1,3 @@
+id=org.eclipse.platform

+name=a Product 

+version=3.5.6
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/validation/site5/eclipse/.eclipseextension b/update/org.eclipse.update.tests.core/data/validation/site5/eclipse/.eclipseextension
new file mode 100644
index 0000000..fff40a3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/validation/site5/eclipse/.eclipseextension
@@ -0,0 +1,3 @@
+id=org.eclipse.platform
+name=Eclipse Platform
+version=3.1.0
diff --git a/update/org.eclipse.update.tests.core/data/validation/site6/.eclipseUM b/update/org.eclipse.update.tests.core/data/validation/site6/.eclipseUM
new file mode 100644
index 0000000..597f9f8
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/validation/site6/.eclipseUM
@@ -0,0 +1 @@
+id=org.eclipse.sdk
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/validation/site6/children/children/eclipse/.eclipseextension b/update/org.eclipse.update.tests.core/data/validation/site6/children/children/eclipse/.eclipseextension
new file mode 100644
index 0000000..597f9f8
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/validation/site6/children/children/eclipse/.eclipseextension
@@ -0,0 +1 @@
+id=org.eclipse.sdk
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/xmls/apitests/org.eclipse.test.feature_1.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/xmls/apitests/org.eclipse.test.feature_1.0.0/feature.xml
new file mode 100644
index 0000000..1511800
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/xmls/apitests/org.eclipse.test.feature_1.0.0/feature.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature id="org.test1.ident1" label="Feature One" nl="en_us,fr,de" os="OS_WIN32,OS_LINUX" provider-name="Object Technology International" version="1.0.0" ws="WS_WIN32,WS_MOTIF,WS_GTK">

+  <description>Test feature for testIdentifier test</description>

+  <copyright>Copyright (c) the company</copyright>

+  <license>Do you accept the license ?</license>

+  <url>

+    <update label="URL to update teh feature" url="http://www.eclipse.org"/>

+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>

+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>

+  </url>

+  <plugin download-size="1500" id="org.eclipse.update.core.tests.feature1.plugin1" install-size="1000" fragment="false" nl="us" os="OS_WIN32" version="3.5.6" ws="WS_WIN32"/>

+  <plugin download-size="1200" id="org.eclipse.update.core.tests.feature1.plugin2" install-size="978" fragment="false" version="5.0.0"/>

+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/xmls/apitests/org.eclipse_test_feature/feature.xml b/update/org.eclipse.update.tests.core/data/xmls/apitests/org.eclipse_test_feature/feature.xml
new file mode 100644
index 0000000..9f05cda
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/xmls/apitests/org.eclipse_test_feature/feature.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature id="org.test1.ident2" label="Feature One" nl="en_us,fr,de" os="OS_WIN32,OS_LINUX" provider-name="Object Technology International" version="1.0.0" ws="WS_WIN32,WS_MOTIF,WS_GTK">

+  <description>Test feature for testIdentifier test</description>

+  <copyright>Copyright (c) the company</copyright>

+  <license>Do you accept the license ?</license>

+  <url>

+    <update label="URL to update teh feature" url="http://www.eclipse.org"/>

+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>

+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>

+  </url>

+  <plugin download-size="1500" url="org.eclipse.update.core.tests.feature1.plugin1" id="org.eclipse.update.core.tests.feature1.plugin1" install-size="1000" fragment="false" nl="us" os="OS_WIN32" version="3.5.6" ws="WS_WIN32"/>

+  <plugin download-size="1200" id="org.eclipse.update.core.tests.feature1.plugin2" install-size="978" fragment="false" version="5.0.0"/>

+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/xmls/feature_1.0.0/feature.xml b/update/org.eclipse.update.tests.core/data/xmls/feature_1.0.0/feature.xml
new file mode 100644
index 0000000..c4ee139
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/xmls/feature_1.0.0/feature.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature id="org.eclipse.update.core.tests.feature1" image="feature1.gif" label="Feature One" nl="en,fr,de" os="OS_WIN32,OS_LINUX" provider-name="Object Technology International" version="1.0.4" ws="WS_WIN32,WS_MOTIF,WS_GTK">

+  <description>I believe this is the description of feature 1, well, feature 1 is an exceptional feature that you should install right NOW on your machine... try it.</description>

+  <copyright>Ok, now, this is a very very complex Copyright  not prepared by a lawyer Copyright (c) the company</copyright>

+  <license>#1 Do you accept it #2 you do nto accept it ...Do you accpt it ?</license>

+  <url>

+    <update label="URL to update the feature" url="http://www.eclipse.org/path/feature1/"/>

+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>

+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>

+  </url>

+  <plugin download-size="1500" id="org.eclipse.update.core.tests.feature1.plugin1" install-size="1000" fragment="false" nl="us" os="OS_WIN32" version="3.5.6" ws="WS_WIN32"/>

+  <plugin download-size="1200" id="org.eclipse.update.core.tests.feature1.plugin2" install-size="978" fragment="false" version="5.0.0"/>

+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/data/xmls/feature_1.0.0/feature1.gif b/update/org.eclipse.update.tests.core/data/xmls/feature_1.0.0/feature1.gif
new file mode 100644
index 0000000..03e30a2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/xmls/feature_1.0.0/feature1.gif
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/data/xmls/site1/site.xml b/update/org.eclipse.update.tests.core/data/xmls/site1/site.xml
new file mode 100644
index 0000000..44823c0
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/data/xmls/site1/site.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site url="info" type="org.eclipse.update.core.file">

+  <feature id="org.isv.feature3" url="www.eclipse.org/feature3" version="3.4.5">

+    <category name="eclipse/UML"/>

+  </feature>

+  <feature id="org.eclipse.update.core.tests.feature2" url="www.eclipse.org/feature2" version="3.4.6">

+    <category name="eclipse/J2EE"/>

+  </feature>

+  <feature id="org.eclipse.update.core.tests.fature1" url="www.eclipse.org/feature1" version="2.3.5">

+    <category name="eclipse/J2EE"/>

+  </feature>

+  <archive path="org.eclipse.update.plugin1" url="www.eclipse.org/pluign1"/>

+  <archive path="org.eclipse.update.archive2" url="www.eclipse.org/plugin2"/>

+  <archive path="org.eclipse.update.plugin3" url="www.eclipse.org/plugin3"/>

+  <archive path="org.eclipse.unknown.plugin" url="www.eclipse.org/plugins/plugin4"/>

+  <archive path="org.eclipse.update.core.tests.feature1.foo1" url="www.eclipse.org/plugin1"/>

+  <category-def label="J2EE tools" name="eclipse/J2EE"/>

+  <category-def label="EJB Tools" name="eclipse/J2EE/EJB"/>

+  <category-def label="UML tools" name="eclipse/UML"/>

+  <category-def label="Messaging Tools" name="B2B"/>

+  <category-def label="Eclipse tools" name="eclipse"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/plugin.xml b/update/org.eclipse.update.tests.core/plugin.xml
new file mode 100644
index 0000000..5554365
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/plugin.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.0"?>

+<plugin>

+

+     <extension

+         id="feature1"

+         point="org.eclipse.update.core.featureTypes">

+      <feature-factory

+            class="org.eclipse.update.internal.core.FeatureExecutableFactory">

+      </feature-factory>

+   </extension>

+   <extension

+         id="ftp"

+         point="org.eclipse.update.core.siteTypes">

+      <site-factory

+            class="org.eclipse.update.tests.implementation.SiteFTPFactory">

+      </site-factory>

+   </extension>

+   <extension

+         point="org.eclipse.equinox.http.registry.resources">

+      <resource

+            alias="/org.eclipse.update.tests.core.updatetests"

+            base-name="/webserver">

+      </resource>

+   </extension>

+

+</plugin>

diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/AllTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/AllTests.java
new file mode 100644
index 0000000..67fb45d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/AllTests.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.update.tests.api.AllAPITests;
+import org.eclipse.update.tests.branding.*;
+//import org.eclipse.update.tests.configurations.AllConfigurationsTests;
+import org.eclipse.update.tests.core.TestErrorRecoveryLog;
+import org.eclipse.update.tests.core.boot.AllPlatformConfigurationTests;
+import org.eclipse.update.tests.mirror.*;
+import org.eclipse.update.tests.model.AllModelTests;
+import org.eclipse.update.tests.nestedfeatures.AllNestedTests;
+import org.eclipse.update.tests.parser.AllParserTests;
+//import org.eclipse.update.tests.perfms.*;
+import org.eclipse.update.tests.reconciliation.AllReconciliationTests;
+import org.eclipse.update.tests.regularInstall.AllRegularInstallTests;
+//import org.eclipse.update.tests.regularRemove.AllRegularRemoveTests;
+import org.eclipse.update.tests.sitevalidation.AllSiteValidationTests;
+//import org.eclipse.update.tests.standalone.*;
+import org.eclipse.update.tests.types.AllTypesTests;
+import org.eclipse.update.tests.uivalues.AllCoreUITests;
+
+public class AllTests extends TestSuite {
+	public AllTests(String name) {
+		super(name);
+	}
+	public static Test suite() throws Exception {
+		TestSuite suite = new TestSuite();
+		suite.setName("All Update Manager Tests");
+		suite.addTest(new TestSuite(TestErrorRecoveryLog.class));
+		suite.addTest(AllMirrorTests.suite());	
+		suite.addTest(AllSiteValidationTests.suite());
+		suite.addTest(AllPlatformConfigurationTests.suite());
+		suite.addTest(AllRegularInstallTests.suite());
+		suite.addTest(AllAPITests.suite());
+		suite.addTest(AllParserTests.suite());
+		suite.addTest(AllCoreUITests.suite());
+//		suite.addTest(AllConfigurationsTests.suite());
+		suite.addTest(AllTypesTests.suite());
+//		suite.addTest(AllRegularRemoveTests.suite());
+		suite.addTest(AllNestedTests.suite());	
+		suite.addTest(AllReconciliationTests.suite());					
+		suite.addTest(AllModelTests.suite());
+		suite.addTest(AllBrandingTests.suite());
+		//suite.addTest(AllStandaloneTests.suite());
+		//suite.addTest(AllPerformanceTests.suite());
+		return suite;
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/UpdateManagerTestCase.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/UpdateManagerTestCase.java
new file mode 100644
index 0000000..23cc2ed
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/UpdateManagerTestCase.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ *******************************************************************************/
+package org.eclipse.update.tests;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.net.*;
+import java.util.*;
+
+import junit.framework.TestCase;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+/**
+ * All Update Manager Test cases must subclass this base test case.
+ */
+public abstract class UpdateManagerTestCase extends TestCase {
+
+	protected static ResourceBundle bundle;
+	protected static String dataPath;
+
+	protected static URL SOURCE_FILE_SITE;
+	protected static URL SOURCE_FILE_SITE_INSTALLED;
+	protected static URL SOURCE_HTTP_SITE;
+	protected static URL TARGET_FILE_SITE;
+
+	private static final String DATA_PATH = "data/";
+
+	/**
+	 * Default Constructor
+	 */
+	public UpdateManagerTestCase(String name) {
+		super(name);
+		try {
+			init();
+		} catch (Exception e) {
+			fail(e.toString());
+			e.printStackTrace();
+		}
+	}
+
+	protected static void init() throws MissingResourceException, IOException, MalformedURLException {
+
+		IPluginDescriptor dataDesc = Platform.getPluginRegistry().getPluginDescriptor("org.eclipse.update.tests.core");
+		URL resolvedURL = Platform.asLocalURL(Platform.resolve(dataDesc.getInstallURL()));
+		URL dataURL = new URL(resolvedURL, DATA_PATH);
+		dataPath = dataURL.getFile();
+		String homePath = (System.getProperty("java.io.tmpdir")).replace(File.separatorChar, '/');
+
+		if (bundle == null) {
+			ClassLoader l = new URLClassLoader(new URL[] { dataURL }, null);
+			bundle = ResourceBundle.getBundle("resources", Locale.getDefault(), l);
+		}
+
+		try {
+			SOURCE_FILE_SITE = new File(dataPath).toURL();
+			SOURCE_FILE_SITE_INSTALLED = new File(dataPath + "testAPI/").toURL();
+			SOURCE_HTTP_SITE = new URL("http", getHttpHost(), getHttpPort(), bundle.getString("HTTP_PATH_1"));
+			TARGET_FILE_SITE = new URL("file", null, homePath + "/target/");
+		} catch (Exception e) {
+			fail(e.toString());
+			e.printStackTrace();
+		}
+
+		//cleanup target 
+		File target = new File(homePath + "/target/");
+		UpdateManagerUtils.removeFromFileSystem(target);
+		// cleanup info about just installed plugins
+		InstallRegistry.cleanup();
+		
+		// setup cache site to false. 
+		// Note: the stand-alone tests will set it back to true
+		InternalSiteManager.globalUseCache = false;
+	}
+
+	/**
+	 * Simple implementation of setUp. Subclasses are prevented 
+	 * from overriding this method to maintain logging consistency.
+	 * umSetUp() should be overridden instead.
+	 */
+	protected final void setUp() throws Exception {
+		System.out.println("----- " + this.getName());
+		System.out.println(this.getName() + ": setUp...");
+		umSetUp();
+	}
+
+	/**
+	 * Sets up the fixture, for example, open a network connection.
+	 * This method is called before a test is executed.
+	 */
+	protected void umSetUp() throws Exception {
+		// do nothing.
+	}
+
+	/**
+	 * Simple implementation of tearDown.  Subclasses are prevented 
+	 * from overriding this method to maintain logging consistency.
+	 * umTearDown() should be overridden instead.
+	 */
+	protected final void tearDown() throws Exception {
+		System.out.println(this.getName() + ": tearDown...\n");
+		umTearDown();
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection.
+	 * This method is called after a test is executed.
+	 */
+	protected void umTearDown() throws Exception {
+		// do nothing.
+	}
+
+	protected static String getHttpHost() {
+		return UpdateTestsPlugin.getWebAppServerHost();
+	}
+
+	protected static int getHttpPort() {
+		return UpdateTestsPlugin.getWebAppServerPort();
+	}
+
+	protected void remove(IFeature feature, IConfiguredSite configSite) throws CoreException {
+		ISite site = configSite.getSite();
+		remove(feature, site);
+	}
+
+	protected void remove(IFeature feature, ISite site) throws CoreException {
+		site.getFeatureReference(feature);
+		// remove the plugins and features dir
+		String sitePath = site.getURL().getFile();
+		File file = null;
+
+		String featureName = feature.getVersionedIdentifier().getIdentifier().toString() + "_" + feature.getVersionedIdentifier().getVersion().toString();
+		file = new File(sitePath, "features" + File.separator + featureName);
+		System.out.println("****************************************Removing :" + file);
+		UpdateManagerUtils.removeFromFileSystem(file);
+
+		IPluginEntry[] entries = feature.getPluginEntries();
+		for (int i = 0; i < entries.length; i++) {
+			String name = entries[i].getVersionedIdentifier().getIdentifier().toString() + "_" + entries[i].getVersionedIdentifier().getVersion().toString() + File.separator;
+			file = new File(sitePath, "plugins" + File.separator + name);
+			System.out.println("****************************************Removing :" + file);
+			UpdateManagerUtils.removeFromFileSystem(file);
+			InstallRegistry.unregisterPlugin(entries[i]);
+		}
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/UpdateTestsPlugin.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/UpdateTestsPlugin.java
new file mode 100644
index 0000000..79570e2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/UpdateTestsPlugin.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.tests;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.http.jetty.JettyConfigurator;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.HttpService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * manages the startup and shutown of the 
+ * web server
+ */
+public class UpdateTestsPlugin extends Plugin {
+
+	private static String appServerHost = null;
+	private static int appServerPort = 0;
+	private static UpdateTestsPlugin plugin;
+	private static boolean initialized=false;
+	private static ServiceTracker httpServiceTracker;
+
+	public static UpdateTestsPlugin getPlugin() {
+		return plugin;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+		
+		httpServiceTracker = new ServiceTracker(context, HttpService.class.getName(), null);
+		httpServiceTracker.open();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		
+		if(httpServiceTracker != null)
+			httpServiceTracker.close();
+		
+		httpServiceTracker = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the host identifier for the web app server
+	 */
+	public static String getWebAppServerHost() {
+		if (!initialized) initialize();
+		return appServerHost;
+	}
+
+	/**
+	 * Returns the port identifier for the web app server
+	 */
+	public static int getWebAppServerPort() {
+		if (!initialized) initialize();		
+		return appServerPort;
+	}
+	/**
+	 * Method initialize.
+	 */
+	private static void initialize() {
+		String text = null;
+		try {
+
+			// ensure that the http stuff is started
+			Dictionary d = new Hashtable();
+			d.put("http.port", new Integer(0)); //$NON-NLS-1$
+			JettyConfigurator.startServer("updateTests", d);
+			ensureBundleStarted("org.eclipse.equinox.http.registry"); //$NON-NLS-1$
+			
+			ServiceReference reference = 
+				httpServiceTracker.getServiceReference();
+			
+			String port = (String) reference.getProperty("http.port"); //$NON-NLS-1$
+			
+			appServerHost = "localhost"; //$NON-NLS-1$
+			appServerPort = Integer.parseInt(port);
+
+			text = "The webServer did start ip:" + appServerHost + ":" + appServerPort;
+		} catch (Exception e) {
+			text = "The webServer didn't start ";
+			IStatus status = new Status(IStatus.ERROR, "org.eclipse.update.tests.core", IStatus.OK, "WebServer not started. Update Tests results are invalid", null);
+			UpdateCore.warn("",new CoreException(status));
+		} finally {
+			System.out.println(text);
+			initialized = true;
+		}
+	}
+	
+	private static void ensureBundleStarted(String symbolicName) throws BundleException {
+		Bundle bundle = Platform.getBundle(symbolicName);
+		if (bundle != null) {
+			if (bundle.getState() == Bundle.RESOLVED || bundle.getState() == Bundle.STARTING) {
+				bundle.start();
+			}
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/AllAPITests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/AllAPITests.java
new file mode 100644
index 0000000..b066f9d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/AllAPITests.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+/**
+ * Manages the API tests
+ */
+public class AllAPITests extends UpdateManagerTestCase {
+	/**
+	 * Constructor
+	 */
+	public AllAPITests(String name) {
+		super(name);
+	}
+	
+	/**
+	 * List of API tests
+	 */
+	public static Test suite() throws Exception {
+		TestSuite suite = new TestSuite();
+		suite.setName("API Tests");
+
+		suite.addTest(new TestSuite(TestSiteAPI.class));
+		suite.addTest(new TestSuite(TestLocalSiteAPI.class));		
+		suite.addTest(new TestSuite(TestUpdateManagerUtilsAPI.class));		
+		suite.addTest(new TestSuite(TestDefaultExecutableFeatureAPI.class));
+		suite.addTest(new TestSuite(TestDefaultPackageFeatureAPI.class));
+		suite.addTest(new TestSuite(TestPluginContainerAPI.class));
+		suite.addTest(new TestSuite(TestSiteManagerAPI.class));		
+		suite.addTest(new TestSuite(TestNestedFeatureAPI.class));
+		suite.addTest(new TestSuite(TestFeatureContentProvider_FileFilterAPI.class));
+		return suite;
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/DefaultFeature.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/DefaultFeature.java
new file mode 100644
index 0000000..880cce5
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/DefaultFeature.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.FeatureExecutableContentProvider;
+/**
+ * Abstract Class that implements most of the behavior of a feature
+ * A feature ALWAYS belongs to an ISite
+ */
+public class DefaultFeature extends Feature {
+
+
+	/**
+	 * Copy constructor
+	 */
+	public DefaultFeature(IFeature sourceFeature, ISite targetSite) throws CoreException {
+		this(targetSite);
+		this.setFeatureContentProvider(sourceFeature.getFeatureContentProvider());
+		this.setIdentifier(sourceFeature.getVersionedIdentifier());
+		this.setLabel(sourceFeature.getLabel());
+		this.setUpdateSiteEntry(sourceFeature.getUpdateSiteEntry());
+		this.setDiscoverySiteEntries(sourceFeature.getDiscoverySiteEntries());
+		this.setProvider(sourceFeature.getProvider());
+		this.setDescription(sourceFeature.getDescription());
+		this.setCopyright(sourceFeature.getCopyright());
+		this.setLicense(sourceFeature.getLicense());
+		this.setPluginEntries(sourceFeature.getPluginEntries());
+		this.setImage(sourceFeature.getImage());
+	}
+	
+	/**
+	 * Constructor
+	 */
+	public DefaultFeature(ISite targetSite) throws CoreException {
+		super();
+		this.setSite(targetSite);		
+	}	
+	
+	
+	/**
+	 * Sets the identifier
+	 * @param identifier The identifier to set
+	 */
+	public void setIdentifier(VersionedIdentifier identifier) {
+		setFeatureIdentifier(identifier.getIdentifier());
+		setFeatureVersion(identifier.getVersion().toString());
+	}
+
+	/**
+	 * Sets the discoverySiteEntries
+	 * @param discoveryInfos The discoveryInfos to set
+	 */
+	public void setDiscoverySiteEntries(IURLEntry[] discoveryInfos) {
+		setDiscoverySiteEntryModels((URLEntryModel[]) discoveryInfos);
+	}
+
+	/**
+	 * Sets the updateSiteEntry
+	 * @param updateInfo The updateInfo to set
+	 */
+	public void setUpdateSiteEntry(IURLEntry updateInfo) {
+		setUpdateSiteEntryModel((URLEntryModel) updateInfo);
+	}
+
+	/**
+	 * Adds a discoveryInfo
+	 * @param discoveryInfo The discoveryInfo to add
+	 */
+	public void addDiscoverySiteEntry(IURLEntry discoveryInfo) {
+		addDiscoverySiteEntryModel((URLEntryModel) discoveryInfo);
+	}
+
+	/**
+	 * Sets the description
+	 * @param description The description to set
+	 */
+	public void setDescription(IURLEntry description) {
+		setDescriptionModel((URLEntryModel) description);
+	}
+
+	/**
+	 * Sets the copyright
+	 * @param copyright The copyright to set
+	 */
+	public void setCopyright(IURLEntry copyright) {
+		setCopyrightModel((URLEntryModel) copyright);
+	}
+
+	/**
+	 * Sets the license
+	 * @param license The license to set
+	 */
+	public void setLicense(IURLEntry license) {
+		setLicenseModel((URLEntryModel) license);
+	}
+
+	/**
+	 * Sets the image
+	 * @param image The image to set
+	 */
+	public void setImage(URL image) {
+		if (image==null) return;
+		setImageURLString(image.toExternalForm());
+	}
+
+	/**
+	 * Adds an import
+	 * @param anImport The import to add
+	 */
+	public void addImport(IImport anImport) {
+		if (anImport != null) {
+			addImportModel((ImportModel) anImport);
+		}
+	}
+
+
+	/**
+	 * Sets the pluginEntries
+	 * @param pluginEntries The pluginEntries to set
+	 */
+	public void setPluginEntries(IPluginEntry[] pluginEntries) {
+		if (pluginEntries != null) {
+			for (int i = 0; i < pluginEntries.length; i++) {
+				addPluginEntry(pluginEntries[i]);
+			}
+		}
+	}
+
+
+	/**
+	 * sets teh URL isf not already present
+	 */
+	public void setURL(URL url) throws CoreException{
+		//if (getFeatureContentProvider()==null){
+			FeatureContentProvider contentProvider = new FeatureExecutableContentProvider(url);
+			this.setFeatureContentProvider(contentProvider);
+			contentProvider.setFeature(this);
+		//}
+	}
+	
+	
+	/*
+	 * @see IPluginContainer#addPluginEntry(IPluginEntry)
+	 */
+	public void addPluginEntry(IPluginEntry pluginEntry) {
+		if (pluginEntry != null) {
+			addPluginEntryModel((PluginEntryModel) pluginEntry);
+		}
+	}
+
+	/*
+	 * @see IFeature#addNonPluginEntry(INonPluginEntry)
+	 */
+	public void addNonPluginEntry(INonPluginEntry dataEntry) {
+		if (dataEntry != null) {
+			addNonPluginEntryModel((NonPluginEntryModel) dataEntry);
+		}
+	}	
+
+	}
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/MyURLEntry.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/MyURLEntry.java
new file mode 100644
index 0000000..745a9f2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/MyURLEntry.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.update.core.URLEntry;
+
+/**
+ * Wrapper around URLEntry
+ */
+public class MyURLEntry extends URLEntry {
+	
+	public MyURLEntry(String annotation, URL url) throws MalformedURLException {
+		super();
+		setAnnotation(annotation);
+		if (url!=null) {
+			setURLString(url.toExternalForm());
+			resolve(null,null);
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestDefaultExecutableFeatureAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestDefaultExecutableFeatureAPI.java
new file mode 100644
index 0000000..7498a02
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestDefaultExecutableFeatureAPI.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+
+
+public class TestDefaultExecutableFeatureAPI extends UpdateManagerTestCase {
+	
+	private DefaultFeature remoteFeature=null;
+	
+	/**
+	 * Test the testFeatures()
+	 */
+	public TestDefaultExecutableFeatureAPI(String arg0) {
+		super(arg0);
+	}
+	
+	/**
+	 * the feature to test
+	 */
+	private DefaultFeature getFeature() throws MalformedURLException, CoreException {
+		if (remoteFeature == null){
+
+		ISite site = SiteManager.getSite(SOURCE_FILE_SITE, null);
+		URL url = UpdateManagerUtils.getURL(site.getURL(),"testAPI/"+Site.DEFAULT_INSTALLED_FEATURE_PATH+"feature3/",null);
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(site);
+		ref.setURL(url);
+		IFeature feature = ref.getFeature(null);
+		remoteFeature = new DefaultFeature(feature,site);
+
+		}
+		return remoteFeature;
+	}
+
+	public void testIdentifier() throws CoreException, MalformedURLException {
+		String id1 = "xmls/apitests/org.eclipse.test.feature_1.0.0/";
+		String id2 = "xmls/apitests/org.eclipse_test_feature";
+		VersionedIdentifier ident1 = new VersionedIdentifier("org.test1.ident1","1.0.0");
+		VersionedIdentifier ident2 = new VersionedIdentifier("org.test1.ident2","1.0.0");		
+		
+
+			ISite site = SiteManager.getSite(SOURCE_FILE_SITE,null);
+			
+			URL url1 = UpdateManagerUtils.getURL(site.getURL(),id1,null);			
+			remoteFeature = new DefaultFeature(site);
+			remoteFeature.setURL(url1);
+			remoteFeature.setIdentifier(ident1);
+			assertEquals(ident1.toString(),remoteFeature.getVersionedIdentifier().toString());
+	 	
+			 URL url2 = UpdateManagerUtils.getURL(site.getURL(),id2,null);		
+			remoteFeature = new DefaultFeature(site);
+			remoteFeature.setURL(url2);
+			remoteFeature.setIdentifier(ident2);
+			assertEquals(ident2.toString(),remoteFeature.getVersionedIdentifier().toString());
+		
+
+	}
+
+
+
+	public void testSite() throws MalformedURLException, CoreException{
+		String ident1 = Site.DEFAULT_INSTALLED_FEATURE_PATH+"feature3/";		
+
+			ISite site = SiteManager.getSite(SOURCE_FILE_SITE,null);
+			
+			URL id = UpdateManagerUtils.getURL(site.getURL(),ident1,null);			
+			remoteFeature = new DefaultFeature(site);
+			remoteFeature.setURL(id);
+			assertEquals(site,remoteFeature.getSite());
+
+	}
+
+
+	public void testLabel() throws CoreException,MalformedURLException {
+		String label = "dummy label";
+		Feature feature = getFeature();
+		feature.setLabel(label);
+		assertEquals(label,feature.getLabel());
+	}
+
+
+	public void testUpdateURL() throws CoreException,MalformedURLException {
+		URL url = null;
+		String label = "OTI Site";
+		try {
+			url = new URL("http://www.oti.com/");
+			
+		} catch (java.net.MalformedURLException e){} // impossible eh !
+		DefaultFeature feature = getFeature();
+		feature.setUpdateSiteEntry(new MyURLEntry(label, url));
+		assertEquals(url,feature.getUpdateSiteEntry().getURL());
+		assertEquals(label,feature.getUpdateSiteEntry().getAnnotation());
+
+	} 
+
+
+	
+	public void testDiscoveryURLs() throws CoreException,MalformedURLException {
+		IURLEntry[] urlInfo = new MyURLEntry[2];
+		URL[] url = new URL[2];
+		String[] label = new String[2];
+		try {
+			url[0] = new URL("http://www.oti.com/");
+			url[1] = new URL("http://eclipse.org/");
+			label[0] = "OTI Site";
+			label[1] = "Eclipse Site";
+		} catch (java.net.MalformedURLException e){} // impossible eh !
+		DefaultFeature feature = getFeature();
+		for (int i=0;i<2;i++){
+				urlInfo[i] = new MyURLEntry(label[i],url[i]);
+		}
+		feature.setDiscoverySiteEntries(urlInfo);
+		for (int i=0; i<feature.getDiscoverySiteEntries().length;i++){
+			assertEquals(urlInfo[i],feature.getDiscoverySiteEntries()[i]);
+		}
+
+	}
+
+
+	public void testProvider() throws CoreException,MalformedURLException {
+		String provider = "not so dummy provider";
+		IFeature feature = getFeature();
+		((Feature)feature).setProvider(provider);
+		assertEquals(provider,feature.getProvider());
+	}
+
+
+
+	public void testDescription() throws CoreException,MalformedURLException {
+		String desc = "pretty long description as a string with \r\n and \t and \n";
+		IURLEntry info = new MyURLEntry(desc,null);
+		DefaultFeature feature = getFeature();
+		feature.setDescription(info);
+		assertEquals(desc,feature.getDescription().getAnnotation());
+	}
+	
+
+	public void testDescription1() throws CoreException, MalformedURLException {
+		URL url = null;
+		try {
+			url = new URL("http://www.oti.com");
+		} catch (MalformedURLException e){/*pretty impossible*/}
+		IURLEntry info = new MyURLEntry(null,url);
+		DefaultFeature feature = getFeature();
+		feature.setDescription(info);
+		assertEquals(url,feature.getDescription().getURL());
+	}	
+	
+
+	public void testDescription2() throws CoreException, MalformedURLException {
+		
+ 	 URL url = null;
+		try {
+			url = new URL("http://www.oti.com");
+		} catch (MalformedURLException e){/*pretty impossible*/}
+		String desc = "pretty long description as a string with \r\n and \t and \n";
+		IURLEntry info = new MyURLEntry(desc,url);
+		DefaultFeature feature = getFeature();
+		feature.setDescription(info);
+		String result = feature.getDescription().getAnnotation();
+		assertEquals(desc,result);
+		assertEquals(url,feature.getDescription().getURL());
+	}	
+
+
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestDefaultPackageFeatureAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestDefaultPackageFeatureAPI.java
new file mode 100644
index 0000000..aeb660c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestDefaultPackageFeatureAPI.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+
+
+public class TestDefaultPackageFeatureAPI extends UpdateManagerTestCase {
+	
+	private	DefaultFeature remoteFeature=null;
+	
+	/**
+	 * Test the testFeatures()
+	 */
+	public TestDefaultPackageFeatureAPI(String arg0) {
+		super(arg0);
+	}
+	
+	/**
+	 * the feature to test
+	 */
+	private DefaultFeature getFeature() throws MalformedURLException, CoreException {
+		if (remoteFeature == null){
+		ISite site = SiteManager.getSite(SOURCE_FILE_SITE, null);
+		URL id = UpdateManagerUtils.getURL(site.getURL(),"org.eclipse.update.core.feature1_1.0.0.jar",null);	
+		remoteFeature = new DefaultFeature(site);
+		remoteFeature.setURL(id);
+		}
+		return remoteFeature;
+	}
+
+	public void testIdentifier() throws CoreException, MalformedURLException {
+		
+		String id1 = "features/org.eclipse.test.feature_1.0.0.jar";
+		String id2 = "features/org.eclipse_test_feature.jar";
+		VersionedIdentifier ident1 = new VersionedIdentifier("org.test1.ident1","1.0.0");
+		VersionedIdentifier ident2 = new VersionedIdentifier("org.test1.ident2","1.0.0");		
+		
+
+			ISite site = SiteManager.getSite(SOURCE_FILE_SITE, null);
+			
+			URL url1 = UpdateManagerUtils.getURL(site.getURL(),id1,null);			
+			remoteFeature = new DefaultFeature(site);
+			remoteFeature.setURL(url1);
+			remoteFeature.setIdentifier(ident1);
+			assertEquals(ident1.toString(),remoteFeature.getVersionedIdentifier().toString());
+		
+			 URL url2 = UpdateManagerUtils.getURL(site.getURL(),id2,null);		
+			remoteFeature = new DefaultFeature(site);
+			remoteFeature.setURL(url2);
+			remoteFeature.setIdentifier(ident2);			
+			assertEquals(ident2.toString(),remoteFeature.getVersionedIdentifier().toString());
+	}
+
+
+	public void testSite() throws MalformedURLException, CoreException {
+		String ident1 = "org.eclipse.test.feature_1.0.0.jar";		
+
+			ISite site = SiteManager.getSite(SOURCE_FILE_SITE, null);
+			
+			URL id = UpdateManagerUtils.getURL(site.getURL(),ident1,null);		
+			remoteFeature = new DefaultFeature(site);
+			remoteFeature.setURL(id);	
+			assertEquals(site,remoteFeature.getSite());
+
+	}
+
+
+	public void testLabel() throws CoreException, MalformedURLException {
+		String label = "dummy label";
+		Feature feature = getFeature();
+		feature.setLabel(label);
+		assertEquals(label,feature.getLabel());
+	}
+
+	public void testUpdateURL() throws CoreException, MalformedURLException {
+		URL url = null;
+		String label = "OTI Site";
+		try {
+			url = new URL("http://www.oti.com/");
+			
+		} catch (java.net.MalformedURLException e){} // impossible eh !
+		DefaultFeature feature = getFeature();
+		feature.setUpdateSiteEntry(new MyURLEntry(label, url));
+		assertEquals(url,feature.getUpdateSiteEntry().getURL());
+		assertEquals(label,feature.getUpdateSiteEntry().getAnnotation());
+
+	} 
+
+
+	
+	public void testDiscoveryURLs() throws CoreException, MalformedURLException {
+		IURLEntry[] urlInfo = new URLEntry[2];
+		URL[] url = new URL[2];
+		String[] label = new String[2];
+		try {
+			url[0] = new URL("http://www.oti.com/");
+			url[1] = new URL("http://eclipse.org/");
+			label[0] = "OTI Site";
+			label[1] = "Eclipse Site";
+		} catch (java.net.MalformedURLException e){} // impossible eh !
+		DefaultFeature feature = getFeature();
+		for (int i=0;i<2;i++){
+				urlInfo[i] = new MyURLEntry(label[i],url[i]);
+		}
+		feature.setDiscoverySiteEntries(urlInfo);
+		for (int i=0; i<feature.getDiscoverySiteEntries().length;i++){
+			assertEquals(urlInfo[i],feature.getDiscoverySiteEntries()[i]);
+		}
+
+
+	}
+
+
+	public void testProvider() throws CoreException, MalformedURLException {
+		String provider = "not so dummy provider";
+		Feature feature = getFeature();
+		feature.setProvider(provider);
+		assertEquals(provider,feature.getProvider());
+	}
+
+
+
+	public void testDescription() throws CoreException, MalformedURLException {
+		String desc = "pretty long description as a string with \r\n and \t and \n";
+		IURLEntry info = new MyURLEntry(desc,null);
+		DefaultFeature feature = getFeature();
+		feature.setDescription(info);
+		assertEquals(desc,feature.getDescription().getAnnotation());
+	}
+	
+
+	public void testDescription1() throws CoreException, MalformedURLException {
+		URL url = null;
+		try {
+			url = new URL("http://www.oti.com");
+		} catch (MalformedURLException e){/*pretty impossible*/}
+		IURLEntry info = new MyURLEntry(null,url);
+		DefaultFeature feature = getFeature();
+		feature.setDescription(info);
+		assertEquals(url,feature.getDescription().getURL());
+	}	
+	
+	public void testDescription2() throws CoreException, MalformedURLException {
+		
+		URL url = null;
+		try {
+			url = new URL("http://www.oti.com");
+		} catch (MalformedURLException e){/*pretty impossible*/}
+		String desc = "pretty long description as a string with \r\n and \t and \n";
+		IURLEntry info = new MyURLEntry(desc,url);
+		DefaultFeature feature = getFeature();
+		feature.setDescription(info);
+		assertEquals(desc,feature.getDescription().getAnnotation());
+		assertEquals(url,feature.getDescription().getURL());
+	}
+
+
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestFeatureContentProvider_FileFilterAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestFeatureContentProvider_FileFilterAPI.java
new file mode 100644
index 0000000..beb218c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestFeatureContentProvider_FileFilterAPI.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import org.eclipse.update.core.FeatureContentProvider;
+import org.eclipse.update.internal.core.FeatureExecutableContentProvider;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+
+
+public class TestFeatureContentProvider_FileFilterAPI extends UpdateManagerTestCase {
+	
+	
+	/**
+	 * Test the testFeatures()
+	 */
+	public TestFeatureContentProvider_FileFilterAPI(String arg0) {
+		super(arg0);
+	}
+	
+	public void testFileFilter(){
+		
+		String p1 = "/p1/p2/a.*";
+		String p2 = "p1/p2/b.*";
+		String p3 = "/p1/p2/a.txt";
+		String p4 = "/p1/p2/*.txt";
+		
+		String name1 = "/p1/p2/a.txt";
+		String name2 = "/p1/p2/b.txt";
+		String name3 = "/p3/p2/a.txt";
+		String name4 = "p1/p2/a.txt";
+		String name5 = "/p1/p2/b.txt";
+		String name6 = "/p1/p2/c.txt";
+		String name7 = "/p1/p2/p3/a.txt";
+		
+		
+		FeatureContentProvider cp = new FeatureExecutableContentProvider(null);
+		
+		FeatureContentProvider.FileFilter filter1 = cp.new FileFilter(p1);
+		FeatureContentProvider.FileFilter filter2 = cp.new FileFilter(p2);
+		FeatureContentProvider.FileFilter filter3 = cp.new FileFilter(p3);
+		FeatureContentProvider.FileFilter filter4 = cp.new FileFilter(p4);
+
+		assertTrue("1.1",filter1.accept(name1));		
+		assertTrue("1.2",!filter1.accept(name2));		
+		assertTrue("1.3",!filter1.accept(name3));	
+		assertTrue("1.4",!filter1.accept(name4));		
+		assertTrue("1.5",!filter1.accept(name5));		
+		assertTrue("1.6",!filter1.accept(name6));		
+		assertTrue("1.7",!filter1.accept(name7));
+	
+		assertTrue("2.1",!filter2.accept(name1));		
+		assertTrue("2.2",!filter2.accept(name2));		
+		assertTrue("2.3",!filter2.accept(name3));	
+		assertTrue("2.4",!filter2.accept(name4));		
+		assertTrue("2.5",!filter2.accept(name5));		
+		assertTrue("2.6",!filter2.accept(name6));		
+		assertTrue("2.7",!filter2.accept(name7));
+
+		assertTrue("3.1",filter3.accept(name1));		
+		assertTrue("3.2",!filter3.accept(name2));		
+		assertTrue("3.3",!filter3.accept(name3));	
+		assertTrue("3.4",!filter3.accept(name4));		
+		assertTrue("3.5",!filter3.accept(name5));		
+		assertTrue("3.6",!filter3.accept(name6));		
+		assertTrue("3.7",!filter3.accept(name7));
+		
+		assertTrue("4.1",filter4.accept(name1));		
+		assertTrue("4.2",filter4.accept(name2));		
+		assertTrue("4.3",!filter4.accept(name3));	
+		assertTrue("4.4",!filter4.accept(name4));		
+		assertTrue("4.5",filter4.accept(name5));		
+		assertTrue("4.6",filter4.accept(name6));		
+		assertTrue("4.7",!filter4.accept(name7));								
+					
+	}
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestLocalSiteAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestLocalSiteAPI.java
new file mode 100644
index 0000000..be4aa2e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestLocalSiteAPI.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import java.net.URL;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.CategoryModel;
+import org.eclipse.update.core.model.SiteModel;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestLocalSiteAPI extends UpdateManagerTestCase {
+	
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestLocalSiteAPI(String arg0) {
+		super(arg0);
+	}
+	
+	public void testFileParsing() throws Exception {
+
+		ISite site = SiteManager.getSite(new URL(SOURCE_FILE_SITE,"siteTestLocalSite/"), null);
+		IArchiveReference[] info = site.getArchives();
+		
+		if (info.length<=0){
+			fail("no plugins in site: "+site.getURL().toExternalForm());
+		}
+		 
+		boolean found1 = false;
+		boolean found2 = false;
+		String name1= "plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar";
+		String name2 = "plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar";
+		
+		for (int i =0; i<info.length; i++){
+			if (info[i].getPath().equals(name1)) found1 = true;
+			if (info[i].getPath().equals(name2)) found2 = true;
+		}
+		
+		if (!found1 || !found2){
+			fail("Cannot find plugin : org.eclipse.update.core.tests.feature1.plugin2 version 5.0.0 and 5.0.1 on the site, by parsing file system");
+		}
+		
+
+	}
+	
+	public void testBundleManifestParsing() throws Exception {
+
+		ISite site = SiteManager.getSite(new URL(SOURCE_FILE_SITE,"siteTestLocalSite/"),null);
+		IArchiveReference[] info = site.getArchives();
+		
+		if (info.length<=0){
+			fail("no plugins in site: "+site.getURL().toExternalForm());
+		}
+		 
+		boolean found1 = false;
+		boolean found2 = false;
+		boolean found3 = false;
+		String name1= "plugins/org.eclipse.update.core.tests.bundleManifest_1.0.1.jar";
+		String name2 = "plugins/org.eclipse.update.core.tests.bundleAndPluginManifestsBUNDLEPARSED_1.0.3.jar";
+		String name3 = "plugins/org.eclipse.update.core.tests.bundleAndPluginManifests_1.0.3.jar";
+		
+		for (int i =0; i<info.length; i++){
+			if (info[i].getPath().equals(name1)) found1 = true;
+			if (info[i].getPath().equals(name2)) found2 = true;
+			if (info[i].getPath().equals(name3)) found3 = true;
+		}
+		
+		if (!found1 || !found2){
+			fail("Cannot find plugin : org.eclipse.update.core.tests.feature1.plugin2 version 5.0.0 and 5.0.1 on the site, by parsing file system");
+		}
+		if (found3){
+			fail("Plugin manifest parsed instead of bundle manifest.");
+		}
+		
+
+	}
+	
+	
+	public void testCategories() throws Exception {
+
+		ISite site = SiteManager.getSite(SOURCE_FILE_SITE, null);
+		
+		ICategory category = new Category("category","Label of category");
+		
+		((SiteModel)site).addCategoryModel((CategoryModel)category);
+		
+		ICategory[] categories = site.getCategories();
+		boolean found = false;
+		for (int index = 0; index < categories.length; index++) {
+			ICategory element = categories[index];
+			if (element.getName().equals("category")) found = true;
+		}
+		if (!found) fail("cannot find category 'category' in site");
+
+		ISiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(site);
+		ref.addCategory(category);		
+		categories = ref.getCategories();
+		found = false;
+		for (int index = 0; index < categories.length; index++) {
+			ICategory element = categories[index];
+			if (element.getName().equals("category")) found = true;
+		}
+		if (!found) fail("cannot find category 'category' in feature");
+		
+			}
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestNestedFeatureAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestNestedFeatureAPI.java
new file mode 100644
index 0000000..89e3061
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestNestedFeatureAPI.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestNestedFeatureAPI extends UpdateManagerTestCase {
+
+	/**
+	 * Test the testFeatures()
+	 */
+	public TestNestedFeatureAPI(String arg0) {
+		super(arg0);
+	}
+
+	/**
+	 * the feature to test
+	 */
+	private IFeature getRootFeature() throws MalformedURLException, CoreException {
+		ISite site = SiteManager.getSite(new URL(SOURCE_FILE_SITE, "nestedFeatureSiteTest/site.xml"),null);
+		URL url = UpdateManagerUtils.getURL(site.getURL(), Site.DEFAULT_INSTALLED_FEATURE_PATH + "rootfeature.jar", null);
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(site);
+		ref.setURL(url);
+		ref.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+		IFeature feature = ref.getFeature(null);
+		return feature;
+	}
+
+	/**
+	 * the feature to test
+	 */
+	private IFeature getChildFeature() throws MalformedURLException, CoreException {
+
+		ISite site = SiteManager.getSite(new URL(SOURCE_FILE_SITE, "nestedFeatureSiteTest/"), null);
+		URL url = UpdateManagerUtils.getURL(site.getURL(), Site.DEFAULT_INSTALLED_FEATURE_PATH + "org.eclipse.update.core.tests.childrenfeature_2.0.0.jar", null);
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(site);
+		ref.setURL(url);
+		ref.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+		IFeature feature = ref.getFeature(null);
+		return feature;
+	}
+
+	/*
+	 * 
+	 */
+	public void testNested() throws Exception {
+
+		IFeature rootFeature = getRootFeature();
+		IFeatureReference[] ref = rootFeature.getIncludedFeatureReferences();
+		IFeature childFeature = getChildFeature();
+		assertEquals("Children feature are not equal", childFeature, ref[0].getFeature(null));
+	}
+
+	/**
+	 * the feature to test
+	 */
+	private IFeature getRootFeature2() throws MalformedURLException, CoreException {
+		ISite site = SiteManager.getSite(new URL(SOURCE_FILE_SITE, "nestedFeatureSiteTest2/site.xml"),null);
+		URL url = UpdateManagerUtils.getURL(site.getURL(), Site.DEFAULT_INSTALLED_FEATURE_PATH + "rootfeature.jar", null);
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(site);
+		ref.setURL(url);
+		ref.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+		IFeature feature = ref.getFeature(null);
+		return feature;
+	}
+
+	/**
+	 * the feature to test
+	 */
+	private IFeature getChildFeature2() throws MalformedURLException, CoreException {
+
+		ISite site = SiteManager.getSite(new URL(SOURCE_FILE_SITE, "nestedFeatureSiteTest2/site.xml"),null);
+		URL url = UpdateManagerUtils.getURL(site.getURL(), Site.DEFAULT_INSTALLED_FEATURE_PATH + "childrenfeature.jar", null);
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(site);
+		ref.setURL(url);
+		ref.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+		IFeature feature = ref.getFeature(null);
+		return feature;
+	}
+
+	/*
+	 * 
+	 */
+	public void testNested2() throws Exception {
+
+		IFeature rootFeature = getRootFeature2();
+		IFeatureReference[] ref = rootFeature.getIncludedFeatureReferences();
+		IFeature childFeature = getChildFeature2();
+		assertEquals("Children feature are not equal", childFeature, ref[0].getFeature(null));
+	}
+
+//	/**
+//	 * the feature to test
+//	 */
+//	private IFeature getRootFeature3() throws MalformedURLException, CoreException {
+//		ISite site = SiteManager.getSite(new URL(SOURCE_FILE_SITE, "nestedFeatureSiteTest3/site.xml"), null);
+//		URL url = UpdateManagerUtils.getURL(site.getURL(), Site.DEFAULT_INSTALLED_FEATURE_PATH + "rootfeature.jar", null);
+//		SiteFeatureReference ref = new SiteFeatureReference();
+//		ref.setSite(site);
+//		ref.setURL(url);
+//		ref.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+//		IFeature feature = ref.getFeature(null);
+//		return feature;
+//	}
+
+//	/**
+//	 * the feature to test
+//	 */
+//	private IFeature getChildFeature3() throws MalformedURLException, CoreException {
+//
+//		ISite site = SiteManager.getSite(new URL(SOURCE_FILE_SITE, "nestedFeatureSiteTest3/site.xml"));
+//		URL url = UpdateManagerUtils.getURL(site.getURL(), Site.DEFAULT_INSTALLED_FEATURE_PATH + "childrenfeature.jar", null);
+//		SiteFeatureReference ref = new SiteFeatureReference();
+//		ref.setSite(site);
+//		ref.setURL(url);
+//		ref.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+//		IFeature feature = ref.getFeature(null);
+//		return feature;
+//	}
+
+	/*
+	 * 
+	 */
+	/*	public void testNested3() throws Exception {
+	
+			IFeature rootFeature = getRootFeature3();
+			IFeatureReference[] ref = rootFeature.getIncludedFeatureReferences();
+			IFeature childFeature = getChildFeature3();
+			assertEquals(
+				"Children feature are not equal",
+				childFeature,
+				ref[0].getFeature());
+		}
+	*/
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestPluginContainerAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestPluginContainerAPI.java
new file mode 100644
index 0000000..6555525
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestPluginContainerAPI.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestPluginContainerAPI extends UpdateManagerTestCase {
+
+	private Site site;
+	private DefaultFeature feature;
+
+	/**
+	 * the Site to test
+	 */
+	private Site getSite() throws CoreException, MalformedURLException {
+		if (site == null) {
+
+			site = (Site)SiteManager.getSite(new URL(SOURCE_FILE_SITE,"testAPI/"), null);
+
+		}
+		return site;
+	}
+
+	/**
+	 * the feature to test
+	 */
+	private DefaultFeature getFeature() throws MalformedURLException, CoreException {
+		if (feature == null) {
+			ISite site = getSite();
+			URL id = UpdateManagerUtils.getURL(site.getURL(),"org.eclipse.update.core.feature1_1.0.0.jar",null);						
+			feature = new DefaultFeature(site);
+			feature.setURL(id);	
+		}
+		return feature;
+	}
+
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestPluginContainerAPI(String arg0) throws CoreException {
+		super(arg0);
+	}
+
+	public void testAbstractFeature() throws CoreException, MalformedURLException {
+		PluginEntry pluginEntry = new PluginEntry();
+		pluginEntry.setVersionedIdentifier(new VersionedIdentifier("id", "6"));
+		Feature _feature = getFeature();
+		((DefaultFeature)_feature).addPluginEntry(pluginEntry);
+		assertEquals(_feature.getPluginEntryCount(), 1);
+		assertEquals(_feature.getPluginEntries()[0], pluginEntry);
+
+	}
+
+	public void testAbstactSite() throws CoreException, MalformedURLException {
+		PluginEntry pluginEntry = new PluginEntry();
+		pluginEntry.setVersionedIdentifier(new VersionedIdentifier("id", "6"));
+		Site _site = getSite();
+		_site.addPluginEntry(pluginEntry);
+		assertEquals(_site.getPluginEntryCount(), 1);
+		assertEquals(_site.getPluginEntries()[0], pluginEntry);
+
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestSiteAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestSiteAPI.java
new file mode 100644
index 0000000..9014178
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestSiteAPI.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestSiteAPI extends UpdateManagerTestCase {
+	
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestSiteAPI(String arg0) {
+		super(arg0);
+	}
+	
+	public void testURL() throws Exception {
+
+		ISite site = SiteManager.getSite(SOURCE_FILE_SITE, null);
+		assertEquals(new File(site.getURL().getFile()),new File(SOURCE_FILE_SITE.getFile()));
+		
+		ISite site2 = SiteManager.getSite(SOURCE_HTTP_SITE, null);
+		assertEquals(site2.getURL(),new URL("http", getHttpHost(),getHttpPort(), bundle.getString("HTTP_PATH_1")+"site.xml"));
+
+	}
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestSiteManagerAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestSiteManagerAPI.java
new file mode 100644
index 0000000..9bc9613
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestSiteManagerAPI.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestSiteManagerAPI extends UpdateManagerTestCase {
+	
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestSiteManagerAPI(String arg0) {
+		super(arg0);
+	}
+	
+	public void testFile() throws Exception {
+		ISite fileSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		String site = fileSite.getURL().toExternalForm();		
+		assertEquals(TARGET_FILE_SITE.toExternalForm(), site);
+	}
+	
+	public void testUnknown() throws Exception {
+		URL url = new URL("ftp://255.255.255.255/");
+		try {
+		ISite site = SiteManager.getSite(url,null);
+		if (site!=null) 
+			fail("Connected to ftp://255.255.255.255/, should not happen");
+		} catch (CoreException e){
+			// expected
+		} catch (IllegalArgumentException e){
+			// expected as the version of the WebDav HTTP Connection returns so
+		}
+	}
+	
+	public void testLocalSite() throws Exception {
+		
+		ILocalSite site = SiteManager.getLocalSite();
+		IConfiguredSite[] instSites = site.getCurrentConfiguration().getConfiguredSites();
+		assertTrue(instSites.length>0);
+		System.out.println("Local Site:"+instSites[0].getSite().getURL().toExternalForm());
+		
+		ISite remoteSite = SiteManager.getSite(SOURCE_FILE_SITE_INSTALLED,null);
+		IFeature remoteFeature = remoteSite.getFeatureReferences()[0].getFeature(null);
+		remove(remoteFeature,instSites[0].getSite());		
+		instSites[0].getSite().install(remoteFeature,null,null);
+		
+		IFeatureReference[] features = site.getCurrentConfiguration().getConfiguredSites()[0].getSite().getFeatureReferences();
+		assertTrue(features.length>0);
+
+		//cleanup
+		assertNotNull(remoteFeature);		
+		File file = new File(instSites[0].getSite().getURL().getFile()+File.separator+Site.DEFAULT_INSTALLED_FEATURE_PATH+remoteFeature.getVersionedIdentifier());
+		UpdateManagerUtils.removeFromFileSystem(file);
+		file = new File(instSites[0].getSite().getURL().getFile()+File.separator+Site.DEFAULT_PLUGIN_PATH+"org.eclipse.update.plugin1_1.1.1");
+		UpdateManagerUtils.removeFromFileSystem(file);		
+		File localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);	
+
+	}
+	
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestUpdateManagerUtilsAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestUpdateManagerUtilsAPI.java
new file mode 100644
index 0000000..a097e48
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/api/TestUpdateManagerUtilsAPI.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.api;
+import java.net.URL;
+
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestUpdateManagerUtilsAPI extends UpdateManagerTestCase {
+	
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestUpdateManagerUtilsAPI(String arg0) {
+		super(arg0);
+	}
+	
+	public void testgetURL() throws Exception {
+		URL url1 = new URL("http://www.eclipse.org");
+		URL url2 = new URL("file://c:/hello");
+		URL url3 = new URL("file:/home/eclipse/");
+		URL url4 = new URL("ftp:/host:8080/path/");
+		URL url5 = new URL("jar:file:/tmp/100100!/");
+		
+		String default1 = "default1/default";
+		String default2 = "/default2/";
+		
+		String str1 = "http://dev.eclipse.org";
+		String str2 = "relative1/path/";
+		String str3 = "/relative2/path";
+		
+		String result1=null;
+		String result2=null;
+		
+		//****************************************************************************************
+		// 1.0
+		result1 = UpdateManagerUtils.getURL(url1,str1,default1).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("1.0",result2,result1);
+		
+		// 1.1
+		 result1 = UpdateManagerUtils.getURL(null,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("1.1",result2,result1);
+		
+		// 1.2
+		 result1 = UpdateManagerUtils.getURL(url1,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("1.2",result2,result1);
+		
+		// 1.3
+		 result1 = UpdateManagerUtils.getURL(url1,str2,default1).toExternalForm();
+		 result2 = "http://www.eclipse.org/relative1/path/";
+		assertEquals("1.3",result2,result1);
+		
+		// 1.4
+		 result1 = UpdateManagerUtils.getURL(url1,str3,default1).toExternalForm();
+		 result2 = "http://www.eclipse.org/relative2/path";
+		assertEquals("1.4",result2,result1);
+		
+		// 1.5
+		 result1 = UpdateManagerUtils.getURL(url1,null,default1).toExternalForm();
+		 result2 = "http://www.eclipse.org/default1/default";
+		assertEquals("1.5",result2,result1);
+		
+		// 1.6
+		 result1 = UpdateManagerUtils.getURL(url1,null,default2).toExternalForm();
+		 result2 = "http://www.eclipse.org/default2/";
+		assertEquals("1.6",result2,result1);
+		
+		//****************************************************************************************
+		// 2.0
+		 result1 = UpdateManagerUtils.getURL(url2,str1,default1).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("2.0",result2,result1);
+		
+		// 2.1
+		 result1 = UpdateManagerUtils.getURL(null,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("2.1",result2,result1);
+		
+		// 2.2
+		 result1 = UpdateManagerUtils.getURL(url2,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("2.2",result2,result1);
+		
+		// 2.3
+		 result1 = UpdateManagerUtils.getURL(url2,str2,default1).toExternalForm();
+		 result2 = "file://c:/relative1/path/";
+		assertEquals("2.3",result2,result1);
+		
+		// 2.4
+		 result1 = UpdateManagerUtils.getURL(url2,str3,default1).toExternalForm();
+		 result2 = "file://c:/relative2/path";
+		assertEquals("2.4",result2,result1);
+		
+		// 2.5
+		 result1 = UpdateManagerUtils.getURL(url2,null,default1).toExternalForm();
+		 result2 = "file://c:/default1/default";
+		assertEquals("2.5",result2,result1);
+		
+		// 2.6
+		 result1 = UpdateManagerUtils.getURL(url2,null,default2).toExternalForm();
+		 result2 = "file://c:/default2/";
+		assertEquals("2.6",result2,result1);
+		
+
+		//****************************************************************************************
+		// 3.0
+		 result1 = UpdateManagerUtils.getURL(url3,str1,default1).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("3.0",result2,result1);
+		
+		// 3.1
+		 result1 = UpdateManagerUtils.getURL(null,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("3.1",result2,result1);
+		
+		// 3.2
+		 result1 = UpdateManagerUtils.getURL(url3,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("3.2",result2,result1);
+		
+		// 3.3
+		 result1 = UpdateManagerUtils.getURL(url3,str2,default1).toExternalForm();
+		 result2 = "file:/home/eclipse/relative1/path/";
+		assertEquals("3.3",result2,result1);
+		
+		// 3.4
+		 result1 = UpdateManagerUtils.getURL(url3,str3,default1).toExternalForm();
+		 result2 = "file:/home/eclipse/relative2/path";
+		assertEquals("3.4",result2,result1);
+		
+		// 3.5
+		 result1 = UpdateManagerUtils.getURL(url3,null,default1).toExternalForm();
+		 result2 = "file:/home/eclipse/default1/default";
+		assertEquals("3.5",result2,result1);
+		
+		// 3.6
+		 result1 = UpdateManagerUtils.getURL(url3,null,default2).toExternalForm();
+		 result2 = "file:/home/eclipse/default2/";
+		assertEquals("3.6",result2,result1);
+				
+		//****************************************************************************************
+		// 4.0
+		 result1 = UpdateManagerUtils.getURL(url4,str1,default1).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("4.0",result2,result1);
+		
+		// 4.1
+		 result1 = UpdateManagerUtils.getURL(null,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("4.1",result2,result1);
+		
+		// 4.2
+		 result1 = UpdateManagerUtils.getURL(url4,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("4.2",result2,result1);
+		
+		// 4.3
+		 result1 = UpdateManagerUtils.getURL(url4,str2,default1).toExternalForm();
+		 result2 = "ftp:/host:8080/path/relative1/path/";
+		assertEquals("4.3",result2,result1);
+		
+		// 4.4
+		 result1 = UpdateManagerUtils.getURL(url4,str3,default1).toExternalForm();
+		 result2 = "ftp:/host:8080/path/relative2/path";
+		assertEquals("4.4",result2,result1);
+		
+		// 4.5
+		 result1 = UpdateManagerUtils.getURL(url4,null,default1).toExternalForm();
+		 result2 = "ftp:/host:8080/path/default1/default";
+		assertEquals("4.5",result2,result1);
+		
+		// 4.6
+		 result1 = UpdateManagerUtils.getURL(url4,null,default2).toExternalForm();
+		 result2 = "ftp:/host:8080/path/default2/";
+		assertEquals("4.6",result2,result1);
+		
+		//****************************************************************************************
+		// 5.0
+		 result1 = UpdateManagerUtils.getURL(url5,str1,default1).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("5.0",result2,result1);
+		
+		// 5.1
+		 result1 = UpdateManagerUtils.getURL(null,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("5.1",result2,result1);
+		
+		// 5.2
+		 result1 = UpdateManagerUtils.getURL(url5,str1,null).toExternalForm();
+		 result2 = "http://dev.eclipse.org";
+		assertEquals("5.2",result2,result1);
+		
+		// 5.3
+		 result1 = UpdateManagerUtils.getURL(url5,str2,default1).toExternalForm();
+		 result2 = "jar:file:/tmp/100100!/relative1/path/";
+		assertEquals("5.3",result2,result1);
+		
+		// 5.4
+		 result1 = UpdateManagerUtils.getURL(url5,str3,default1).toExternalForm();
+		 result2 = "jar:file:/tmp/100100!/relative2/path";
+		assertEquals("5.4",result2,result1);
+		
+		// 5.5
+		 result1 = UpdateManagerUtils.getURL(url5,null,default1).toExternalForm();
+		 result2 = "jar:file:/tmp/100100!/default1/default";
+		assertEquals("5.5",result2,result1);
+		
+		// 5.6
+		 result1 = UpdateManagerUtils.getURL(url5,null,default2).toExternalForm();
+		 result2 = "jar:file:/tmp/100100!/default2/";
+		assertEquals("5.6",result2,result1);				
+
+	}
+	
+	
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/branding/AllBrandingTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/branding/AllBrandingTests.java
new file mode 100644
index 0000000..14aa1c2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/branding/AllBrandingTests.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.branding;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+/**
+ * Manages the API tests
+ */
+public class AllBrandingTests extends UpdateManagerTestCase {
+	/**
+	 * Constructor
+	 */
+	public AllBrandingTests(String name) {
+		super(name);
+	}
+	
+	/**
+	 * List of API tests
+	 */
+	public static Test suite() throws Exception {
+		TestSuite suite = new TestSuite();
+		suite.setName("Branding Tests");
+
+		suite.addTest(new TestSuite(BundleProviderTest.class));	
+		suite.addTest(new TestSuite(ProductTest.class));	
+
+		return suite;
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/branding/BundleProviderTest.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/branding/BundleProviderTest.java
new file mode 100644
index 0000000..df9a264
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/branding/BundleProviderTest.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.branding;
+
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.internal.configurator.branding.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import org.osgi.framework.*;
+
+public class BundleProviderTest extends UpdateManagerTestCase {
+
+	public BundleProviderTest(String testcase){
+		super(testcase);
+	}
+
+	public void testMain() throws Exception {
+		
+		IBundleGroupProvider[] bundleGroupProviders = Platform.getBundleGroupProviders();
+		for (int i=0; i<bundleGroupProviders.length; i++) {
+			System.out.println("BundleGroupProvider:"+bundleGroupProviders[i].getName());
+			IBundleGroup[] bundleGroups = bundleGroupProviders[i].getBundleGroups();
+			for (int j=0; j<bundleGroups.length; j++) {
+				System.out.println("BundleGroup name:"+bundleGroups[j].getName() +"\n" +
+						"description:" + bundleGroups[j].getDescription() + "\n"+
+						"id:" + bundleGroups[j].getIdentifier() + "\n" +
+						"provider:" + bundleGroups[j].getProviderName() + "\n" +
+						"version:" + bundleGroups[j].getVersion() + "\n" +
+						"license:" + bundleGroups[j].getProperty(IBundleGroupConstants.LICENSE_HREF) + "\n" +
+						"featureImage:" + bundleGroups[j].getProperty(IBundleGroupConstants.FEATURE_IMAGE) + "\n" +
+						"tips and tricks:" + bundleGroups[j].getProperty(IBundleGroupConstants.TIPS_AND_TRICKS_HREF) + "\n" +
+						"welcomePage:" + bundleGroups[j].getProperty(IBundleGroupConstants.WELCOME_PAGE) + "\n" +
+						"welcomePerspective:" + bundleGroups[j].getProperty(IBundleGroupConstants.WELCOME_PERSPECTIVE));
+				System.out.println("bundles:");
+				Bundle[] bundles = bundleGroups[j].getBundles();
+				for (int b=0; b<bundles.length; b++)
+					System.out.println(bundles[b].getSymbolicName());
+				System.out.println();
+			}
+		}
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/branding/ProductTest.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/branding/ProductTest.java
new file mode 100644
index 0000000..7f0d396
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/branding/ProductTest.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.branding;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.internal.configurator.branding.*;
+import org.eclipse.update.tests.*;
+
+public class ProductTest extends UpdateManagerTestCase {
+
+	public ProductTest(String testcase){
+		super(testcase);
+	}
+
+	public void testMain() throws Exception {
+		
+		IProduct product = Platform.getProduct();
+		if (product == null)
+			System.out.println("No product defined");
+		else
+			System.out.println("Product is: \n" +
+					"name=" + product.getName() + "\n" +
+					"application=" + product.getApplication() + "\n" +
+					"description=" + product.getDescription() + "\n" +
+					"id="+ product.getId() + "\n" +
+					"about_text:"+product.getProperty(IProductConstants.ABOUT_TEXT) +"\n" +
+					"about_image:"+product.getProperty(IProductConstants.ABOUT_IMAGE) +"\n" +
+					"app_name:"+product.getProperty(IProductConstants.APP_NAME) +"\n" +
+					"window_image:"+product.getProperty(IProductConstants.WINDOW_IMAGE) +"\n" +
+					"window_images:"+product.getProperty(IProductConstants.WINDOW_IMAGES) );
+				
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/configurations/AllConfigurationsTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/configurations/AllConfigurationsTests.java
new file mode 100644
index 0000000..2e2600b
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/configurations/AllConfigurationsTests.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.configurations;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+
+public class AllConfigurationsTests extends UpdateManagerTestCase {
+public AllConfigurationsTests(String name) {
+	super(name);
+}
+public static Test suite() {
+	TestSuite suite = new TestSuite();
+	suite.setName("Regular Install Tests");
+	
+//	suite.addTest(new TestSuite(TestRevert.class));
+	suite.addTest(new TestSuite(TestBackward.class));
+		
+	return suite;
+}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/configurations/TestBackward.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/configurations/TestBackward.java
new file mode 100644
index 0000000..31420be
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/configurations/TestBackward.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.configurations;
+import java.io.File;
+
+
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestBackward extends UpdateManagerTestCase {
+	
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestBackward(String arg0) {
+		super(arg0);
+	}
+	
+	public void testSimpleBackward() throws Exception {
+
+		// cleanup
+		LocalSite siteLocal = ((LocalSite)SiteManager.getLocalSite());
+		File localFile = new File((siteLocal).getLocationURL().getFile());
+		InternalSiteManager.localSite=null;		
+
+		ILocalSite site = SiteManager.getLocalSite();
+		ISite remoteSite = SiteManager.getSite(SOURCE_HTTP_SITE,null);
+		IFeatureReference featureRef = remoteSite.getFeatureReferences()[0];
+		
+		IInstallConfiguration oldInstallConfig = site.getCurrentConfiguration();
+		IConfiguredSite oldConfigSite = oldInstallConfig.getConfiguredSites()[0];
+		
+		((ConfiguredSite)oldConfigSite).setUpdatable(true);	
+		assertNotNull("Reference is null",featureRef);
+		remove(featureRef.getFeature(null),oldConfigSite);	
+		oldConfigSite.install(featureRef.getFeature(null),null,null);
+		site.save();
+	
+		
+		// Activity -> InstallConfig
+		IInstallConfiguration current = site.getCurrentConfiguration();
+//		IActivity activity = current.getActivities()[0];	
+//		assertTrue(activity.getInstallConfiguration().equals(current));
+		
+		// ConfigSite->InstallConfig
+		IConfiguredSite newConfigSite = current.getConfiguredSites()[0];
+		assertTrue(newConfigSite.getInstallConfiguration().equals(current));
+		
+		// cleanup
+		localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);			
+	}
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/configurations/TestRevert.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/configurations/TestRevert.java
new file mode 100644
index 0000000..15a9dfe
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/configurations/TestRevert.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.configurations;
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.model.ConfiguredSiteModel;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestRevert extends UpdateManagerTestCase {
+	
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestRevert(String arg0) {
+		super(arg0);
+	}
+	
+	public void testSimpleRevertInstall() throws Exception {
+
+		// cleanup
+		LocalSite siteLocal = ((LocalSite)SiteManager.getLocalSite());
+		File localFile = new File(siteLocal.getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);		
+		InternalSiteManager.localSite=null;		
+
+		ILocalSite site = SiteManager.getLocalSite();
+		ISite remoteSite = SiteManager.getSite(SOURCE_HTTP_SITE,null);
+		IFeatureReference featureRef = remoteSite.getFeatureReferences()[0];
+		IFeatureReference featureRef2 = remoteSite.getFeatureReferences()[1];
+		IFeature feature = featureRef.getFeature(null);
+		
+		// old config, no features installed
+		IInstallConfiguration old = site.getCurrentConfiguration();
+		ConfigurationPolicy excludepolicy = new ConfigurationPolicy();
+		excludepolicy.setPolicy(IPlatformConfiguration.ISitePolicy.USER_EXCLUDE);
+		IConfiguredSite oldConfigSite = old.getConfiguredSites()[0];
+		excludepolicy.setConfiguredSiteModel((ConfiguredSiteModel)oldConfigSite);		
+		((ConfiguredSiteModel)oldConfigSite).setConfigurationPolicyModel(excludepolicy);
+		
+		// install one feature
+		IInstallConfiguration newConfig = site.cloneCurrentConfiguration();
+		IConfiguredSite configSite = newConfig.getConfiguredSites()[0];
+		if (!configSite.getSite().equals(oldConfigSite.getSite())) fail("Config sites are not equals");
+		site.addConfiguration(newConfig);	
+		
+		((ConfiguredSite)configSite).setUpdatable(true);			
+		IFeatureReference installedFeature = configSite.install(feature,null,null);
+		site.save();
+
+		// unconfigure it
+		configSite.unconfigure(installedFeature.getFeature(null));
+
+		// install another feature
+		IFeature feature2 = featureRef2.getFeature(null);
+		IInstallConfiguration newConfig2 = site.cloneCurrentConfiguration();
+		IConfiguredSite anotherConfigSite = newConfig2.getConfiguredSites()[0];
+		if (!anotherConfigSite.getSite().equals(oldConfigSite.getSite())) fail("Config sites are not equals");		
+		site.addConfiguration(newConfig2);		
+		anotherConfigSite.install(feature2,null,null);
+		site.save();
+
+		// revert to old state where no feature where configured
+		site.revertTo(old,null,null);
+		site.save();
+		
+		// check
+		String time = ""+site.getCurrentConfiguration().getCreationDate().getTime();
+		File file = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		assertTrue("new configuration does not exist", file.exists());
+		
+		
+		//find configured site
+		IConfiguredSite newConfigSite = null;
+		IConfiguredSite[] sites = site.getCurrentConfiguration().getConfiguredSites();
+		for (int i = 0; i < sites.length; i++) {
+			if (sites[i].getSite().equals(oldConfigSite.getSite())){
+				 newConfigSite = sites[i];
+				 break;
+			}
+		}
+		if (newConfigSite==null) fail("Cannot find configuration site");
+
+		int oldNumber = oldConfigSite.getConfiguredFeatures().length;
+		int newNumber = newConfigSite.getConfiguredFeatures().length;
+		
+		//
+		IFeatureReference[] configFeatures = newConfigSite.getConfiguredFeatures();
+		for (int i = 0; i < configFeatures.length; i++) {
+			System.out.println(configFeatures[i]);
+		}		
+		assertTrue("Wrong number of configured features old:"+oldNumber+" new:"+newNumber,oldNumber==newNumber);
+		
+		// test only 2 install config in local site
+		int newNumberUnconfiguredFeatures = ((ConfiguredSite)newConfigSite).getConfigurationPolicy().getUnconfiguredFeatures().length;
+		int oldNumberUnconfiguredFeatures = ((ConfiguredSite)oldConfigSite).getConfigurationPolicy().getUnconfiguredFeatures().length;		
+		assertEquals("wrong number of unconfigured features",oldNumberUnconfiguredFeatures+2,newNumberUnconfiguredFeatures);
+		
+		// cleanup
+		localFile = new File(siteLocal.getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);		
+		localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);				
+		UpdateManagerUtils.removeFromFileSystem(file);	
+		time = ""+newConfig.getCreationDate().getTime();
+		file = new File(new URL(((LocalSite)SiteManager.getLocalSite()).getLocationURL(),"DefaultConfig"+time+".xml").getFile());	
+		UpdateManagerUtils.removeFromFileSystem(file);	
+		time = ""+newConfig2.getCreationDate().getTime();
+		file = new File(new URL(((LocalSite)SiteManager.getLocalSite()).getLocationURL(),"DefaultConfig"+time+".xml").getFile());	
+		UpdateManagerUtils.removeFromFileSystem(file);	
+	}
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/TestErrorRecoveryLog.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/TestErrorRecoveryLog.java
new file mode 100644
index 0000000..f24bff6
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/TestErrorRecoveryLog.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 The Eclipse Foundation.
+ * 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:
+ *    The Eclipse Foundation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.tests.core;
+
+import java.io.File;
+
+import org.eclipse.update.internal.core.ErrorRecoveryLog;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestErrorRecoveryLog extends UpdateManagerTestCase {
+	
+	public TestErrorRecoveryLog(String name) {
+		super(name);
+		// TODO Auto-generated constructor stub
+	}
+
+	public void testGetLocalRandomIdentifier() throws Exception {
+		for (int i = 0; i < 10; i++) {
+			String fname = ErrorRecoveryLog.getLocalRandomIdentifier(System.getProperty("java.io.tmpdir") + "/feature.xml");
+			File f = new File(fname);
+			assertTrue(f.createNewFile());
+		}
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/AllPlatformConfigurationTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/AllPlatformConfigurationTests.java
new file mode 100644
index 0000000..9450f54
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/AllPlatformConfigurationTests.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.core.boot;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllPlatformConfigurationTests
+	extends PlatformConfigurationTestCase {
+	/**
+	 * Constructor
+	 */
+	public AllPlatformConfigurationTests(String name) {
+		super(name);
+	}
+	
+	/**
+	 * List of API tests
+	 */
+	public static Test suite() throws Exception {
+		TestSuite suite = new TestSuite();
+		suite.setName("PlatformConfiguration Tests");
+
+		suite.addTest(new TestSuite(TestPlatCfgAPI.class));
+
+		return suite;
+	}
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/PlatformConfigurationTestCase.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/PlatformConfigurationTestCase.java
new file mode 100644
index 0000000..47acb3e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/PlatformConfigurationTestCase.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.core.boot;
+
+import java.io.File;
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+public class PlatformConfigurationTestCase extends TestCase {
+	
+	protected String tempDir;
+	
+	public PlatformConfigurationTestCase(String name) {
+		super(name);
+		try {
+			init();
+		} catch (Exception e) {
+			fail(e.toString());
+			e.printStackTrace();
+		}
+	}
+	
+	protected void init() {
+	}
+	
+	protected void setUp() {
+		// get new temp directory for testcase
+		String root = getTempDirectoryName();
+		setupDirectory(root);
+		tempDir = root;
+	}
+	
+	protected void tearDown() {
+		// cleanup testcase temp directory
+		if (tempDir != null)
+			cleanupDirectory(tempDir);
+	}
+	
+	protected String getTempDirectoryName() {
+		String tmp = System.getProperty("java.io.tmpdir");
+		if (!tmp.endsWith(File.separator))
+			tmp += File.separator;
+		return tmp+"eclipse"+File.separator+(new Date().getTime()+File.separator);
+	}
+	
+	protected void setupDirectory(String name) {
+		File dir = new File(name);
+		dir.mkdirs();
+	}
+	
+	protected void cleanupDirectory(String name) {
+		File dir = new File(name);
+		deleteDirectory(dir);
+	}
+	
+	private void deleteDirectory(File dir) {
+		File[] list = dir.listFiles();
+		if (list == null)
+			return;
+			
+		for (int i=0; i<list.length; i++) {
+			if (list[i].isDirectory()) 
+				deleteDirectory(list[i]);
+			if (!list[i].delete())
+				System.out.println("Unable to delete "+list[i].toString());
+		}
+	}
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/TestPlatCfgAPI.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/TestPlatCfgAPI.java
new file mode 100644
index 0000000..9e3ca7c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/TestPlatCfgAPI.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.core.boot;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import junit.framework.Assert;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.configurator.IPlatformConfiguration.*;
+
+public class TestPlatCfgAPI extends PlatformConfigurationTestCase {
+			
+	public TestPlatCfgAPI(String arg0) {
+		super(arg0);
+	}
+	
+	public void testBasic() throws Exception {
+		
+		// get new config object
+		IPlatformConfiguration cfig = null;
+		try {
+			cfig = ConfiguratorUtils.getPlatformConfiguration(null);
+		} catch (IOException e) {
+			Assert.fail("0.0.0 "+e.toString());
+		}
+		ISiteEntry[] dflt = cfig.getConfiguredSites();
+		Assert.assertEquals("0.0.1",dflt.length,0);
+		
+		// policy tests
+		ISitePolicy p1 = cfig.createSitePolicy(ISitePolicy.USER_INCLUDE, null);
+		Assert.assertEquals("1.0.0",p1.getType(),ISitePolicy.USER_INCLUDE);
+		Assert.assertEquals("1.0.1",p1.getList().length,0);
+		p1.setList(new String[] {"first"});
+		Assert.assertEquals("1.0.2",p1.getList().length,1);
+		Assert.assertEquals("1.0.3",p1.getList()[0],"first");
+		
+		ISitePolicy p2 = cfig.createSitePolicy(ISitePolicy.USER_EXCLUDE, new String[0]);
+		Assert.assertEquals("1.1.0",p2.getType(),ISitePolicy.USER_EXCLUDE);
+		Assert.assertEquals("1.1.1",p2.getList().length,0);
+		p2.setList(new String[] {"first", "second"});
+		Assert.assertEquals("1.1.2",p2.getList().length,2);
+		Assert.assertEquals("1.1.3",p2.getList()[1],"second");
+		
+		// create some urls
+		URL u1 = null;
+
+		URL u4 = null;
+		try {
+			u1 = new URL("file:/d:/temp_test_dummy");
+			new URL("http://some.server/temp/");
+			u4 = new URL("http://bad.url");
+		} catch (MalformedURLException e) {
+			Assert.fail("2.0.0 unable to create URL "+e);
+		}
+				
+		// site creation tests
+		ISiteEntry s1 = cfig.createSiteEntry(u1,p2);
+		Assert.assertEquals("3.0.0",s1.getURL(),u1);
+		Assert.assertEquals("3.0.1",s1.getSitePolicy(),p2);
+		s1.setSitePolicy(p1);
+		Assert.assertEquals("3.0.2",s1.getSitePolicy(),p1);
+		
+//		ISiteEntry s2 = cfig.createSiteEntry(u2,p1);
+//		Assert.assertEquals("3.1.0",s2.getURL(),u2);
+//		Assert.assertEquals("3.1.1",s2.getSitePolicy(),p1);
+//		s2.setSitePolicy(p2);
+//		Assert.assertEquals("3.1.2",s2.getSitePolicy(),p2);
+		
+		// configure site tests
+		Assert.assertEquals("3.3.0",cfig.getConfiguredSites().length,0);
+		cfig.configureSite(s1);
+		Assert.assertEquals("3.3.1",cfig.getConfiguredSites().length,1);
+//		cfig.configureSite(s2);
+//		Assert.assertEquals("3.3.2",cfig.getConfiguredSites().length,2);
+//		
+		// lookup site tests
+		Assert.assertEquals("3.4.0",cfig.findConfiguredSite(u1),s1);
+//		Assert.assertEquals("3.4.1",cfig.findConfiguredSite(u2),s2);
+		Assert.assertNull("3.4.3",cfig.findConfiguredSite(u4));
+		
+		// unconfigure site tests
+		cfig.unconfigureSite(s1);
+		Assert.assertEquals("3.5.0",cfig.getConfiguredSites().length,0);
+		Assert.assertNull("3.5.1",cfig.findConfiguredSite(u1));		
+//		cfig.unconfigureSite(s2);
+//		Assert.assertEquals("3.5.2",cfig.getConfiguredSites().length,0);
+//		Assert.assertNull("3.5.3",cfig.findConfiguredSite(u2));	
+	}
+	
+	public void testSaveRestore() throws Exception {
+				
+		Assert.assertNotNull("0.0 Unable to obtain temp directory",tempDir);
+		
+		// get new config object
+		IPlatformConfiguration cfig = null;
+		try {
+			cfig = ConfiguratorUtils.getPlatformConfiguration(null);
+		} catch (IOException e) {
+			Assert.fail("0.0.0 "+e.toString());
+		}
+		ISiteEntry[] sites = cfig.getConfiguredSites();
+		Assert.assertEquals("0.0.1",sites.length,0);
+				
+		// create policies
+		ISitePolicy p1 = cfig.createSitePolicy(ISitePolicy.USER_INCLUDE, null);
+		ISitePolicy p2 = cfig.createSitePolicy(ISitePolicy.USER_EXCLUDE, new String[0]);		
+		ISitePolicy p3 = cfig.createSitePolicy(ISitePolicy.USER_INCLUDE, new String[] {"first"});
+		ISitePolicy p4 = cfig.createSitePolicy(ISitePolicy.USER_EXCLUDE, new String[] {"first", "second"});
+						
+		// create some urls
+		URL u1 = null;
+		URL u2 = null;
+		URL u3 = null;
+		URL u4 = null;
+
+		try {
+			u1 = new URL("file:d:/temp/");
+			u2 = new URL("file:/localhost/temp/");
+			u3 = new URL("http://some.server/temp/");
+			u4 = new URL("http://another.server/temp/");
+			new URL("http://one.more.server/temp/");
+		} catch (MalformedURLException e) {
+			Assert.fail("1.0 unable to create URL "+e);
+		}
+		
+		// create and configure sites
+		ISiteEntry s1 = cfig.createSiteEntry(u1,p1);
+		cfig.configureSite(s1);
+		ISiteEntry s2 = cfig.createSiteEntry(u2,p2);
+		cfig.configureSite(s2);
+		ISiteEntry s3 = cfig.createSiteEntry(u3,p3);
+		cfig.configureSite(s3);
+		ISiteEntry s4 = cfig.createSiteEntry(u4,p4);
+		cfig.configureSite(s4);
+		sites = cfig.getConfiguredSites();
+		Assert.assertEquals("1.1",sites.length,4);
+		
+		// do save
+		try {
+			cfig.save();
+			Assert.fail("2.0 was expecting IOException");
+		} catch (IOException e) {
+		}
+		
+		URL cfigURL = null;
+		try {
+			cfigURL = new URL("file:"+tempDir+ "platform.xml");
+		} catch(MalformedURLException e) {
+			Assert.fail("2.1 unable to create URL "+e);
+		}
+		
+		try {
+			cfig.save(cfigURL);
+		} catch (IOException e) {
+			Assert.fail("2.2 "+e);
+		}
+		
+		// reload configuration	
+		try {
+			ConfiguratorUtils.getPlatformConfiguration(cfigURL);
+		} catch (IOException e) {
+			Assert.fail("2.3 "+e.toString());
+		}
+		ISiteEntry[] newSites = cfig.getConfiguredSites();
+		Assert.assertEquals("2.4",newSites.length,4);
+		
+		// check what we've got
+		Assert.assertEquals("3.0.1",sites[0].getURL(),newSites[0].getURL());
+		Assert.assertEquals("3.0.2",sites[0].getSitePolicy().getType(),newSites[0].getSitePolicy().getType());
+		Assert.assertEquals("3.0.3",sites[0].getSitePolicy().getList(),newSites[0].getSitePolicy().getList());
+		
+		Assert.assertEquals("3.1.1",sites[1].getURL(),newSites[1].getURL());
+		Assert.assertEquals("3.1.2",sites[1].getSitePolicy().getType(),newSites[1].getSitePolicy().getType());
+		Assert.assertEquals("3.1.3",sites[1].getSitePolicy().getList(),newSites[1].getSitePolicy().getList());
+		
+		Assert.assertEquals("3.2.1",sites[2].getURL(),newSites[2].getURL());
+		Assert.assertEquals("3.2.2",sites[2].getSitePolicy().getType(),newSites[2].getSitePolicy().getType());
+		Assert.assertEquals("3.2.3",sites[2].getSitePolicy().getList(),newSites[2].getSitePolicy().getList());
+		
+		Assert.assertEquals("3.3.1",sites[3].getURL(),newSites[3].getURL());
+		Assert.assertEquals("3.3.2",sites[3].getSitePolicy().getType(),newSites[3].getSitePolicy().getType());
+		Assert.assertEquals("3.3.3",sites[3].getSitePolicy().getList(),newSites[3].getSitePolicy().getList());
+		
+	}
+	
+	public void testCurrentConfiguration() throws Exception {
+				
+		Assert.assertNotNull("0.0 Unable to obtain temp directory",tempDir);
+		
+		// get new config object
+		IPlatformConfiguration cfig = null;
+		cfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		cfig.getPluginPath();
+		cfig.save();
+	}
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/TestPlatCfgDefault.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/TestPlatCfgDefault.java
new file mode 100644
index 0000000..a35d031
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/core/boot/TestPlatCfgDefault.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.core.boot;
+
+import org.eclipse.update.configurator.*;
+
+
+public class TestPlatCfgDefault
+	extends PlatformConfigurationTestCase {
+		
+	public TestPlatCfgDefault(String arg0) {
+		super(arg0);
+	}
+	
+	public void testInitial() throws Exception {
+		IPlatformConfiguration cfig = null;
+		cfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		IPlatformConfiguration.ISiteEntry se = cfig.getConfiguredSites()[0];
+		IPlatformConfiguration.ISitePolicy sp = cfig.createSitePolicy(IPlatformConfiguration.ISitePolicy.USER_EXCLUDE, new String[] {"1", "2","3","4","5","6","7","8","9","10","11","12"});
+		se.setSitePolicy(sp);
+		cfig.save();
+		System.out.println("done ...");
+	}
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/implementation/SiteFTP.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/implementation/SiteFTP.java
new file mode 100644
index 0000000..d7db0a9
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/implementation/SiteFTP.java
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.implementation;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.IURLEntry;
+import org.eclipse.update.core.model.InstallAbortedException;
+import org.eclipse.update.internal.core.*;
+
+public class SiteFTP implements ISite {
+
+	private URL url;
+	public SiteFTP(URL url){
+		this.url = url;
+	}
+
+	/*
+	 * @see ISite#getFeatureReferences()
+	 */
+	public ISiteFeatureReference[] getFeatureReferences() {
+		return null;
+	}
+
+	/*
+	 * @see ISite#install(IFeature, FeatureVerification verifier,IProgressMonitor)
+	 */
+	public IFeatureReference install(IFeature feature,IVerificationListener verificationListener, IProgressMonitor monitor) throws CoreException {
+		return null;
+	}
+
+	/*
+	 * @see ISite#remove(IFeature, IProgressMonitor)
+	 */
+	public void remove(IFeature feature, IProgressMonitor monitor) throws CoreException {
+	}
+
+	/*
+	 * @see ISite#addSiteChangedListener(IConfiguredSiteChangedListener)
+	 */
+	public void addSiteChangedListener(IConfiguredSiteChangedListener listener) {
+	}
+
+	/*
+	 * @see ISite#removeSiteChangedListener(IConfiguredSiteChangedListener)
+	 */
+	public void removeSiteChangedListener(IConfiguredSiteChangedListener listener) {
+	}
+
+	/*
+	 * @see ISite#getURL()
+	 */
+	public URL getURL() {
+		return url;
+	}
+
+	/*
+	 * @see ISite#getType()
+	 */
+	public String getType() {
+		return "org.eclipse.update.tests.ftp";
+	}
+
+	/*
+	 * @see ISite#getCategories()
+	 */
+	public ICategory[] getCategories() {
+		return null;
+	}
+
+	/*
+	 * @see ISite#getArchives()
+	 */
+	public IArchiveReference[] getArchives() {
+		return null;
+	}
+ 
+	/*
+	 * @see ISite#addCategory(ICategory)
+	 */
+	public void addCategory(ICategory category) {
+	}
+
+	/*
+	 * @see ISite#save()
+	 */
+	public void save() throws CoreException {
+	}
+
+	/*
+	 * @see IPluginContainer#getPluginEntries()
+	 */
+	public IPluginEntry[] getPluginEntries() {
+		return null;
+	}
+
+	/*
+	 * @see IPluginContainer#getPluginEntryCount()
+	 */
+	public int getPluginEntryCount() {
+		return 0;
+	}
+
+	/*
+	 * @see ISite#getDownloadSizeFor(IFeature)
+	 */
+	public long getDownloadSizeFor(IFeature feature) {
+		return 0;
+	}
+
+	/*
+	 * @see ISite#getInstallSizeFor(IFeature)
+	 */
+	public long getInstallSizeFor(IFeature feature) {
+		return 0;
+	}
+
+
+	/*
+	 * @see IPluginContainer#store(IPluginEntry, String, InputStream)
+	 */
+	public void store(IPluginEntry entry, String name, InputStream inStream) throws CoreException {
+	}
+
+	/*
+	 * @see IAdaptable#getAdapter(Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		return null;
+	}
+
+	/*
+	 * @see IPluginContainer#remove(IPluginEntry)
+	 */
+	public void remove(IPluginEntry entry) throws CoreException {
+	}
+
+	/*
+	 * @see ISite#setSiteContentConsumer(ISiteContentConsumer)
+	 */
+	public void setSiteContentConsumer(ISiteContentConsumer contentConsumer) {
+	}
+
+	/*
+	 * @see ISite#setSiteContentProvider(ISiteContentProvider)
+	 */
+	public void setSiteContentProvider(ISiteContentProvider siteContentProvider) {
+	}
+
+	/*
+	 * @see ISite#getSiteContentProvider()
+	 */
+	public ISiteContentProvider getSiteContentProvider() {
+		return null;
+	}
+
+	/*
+	 * @see ISite#getDefaultPackagedFeatureType()
+	 */
+	public String getDefaultPackagedFeatureType() {
+		return null;
+	}
+
+	/*
+	 * @see ISite#store(IFeature, String, InputStream, IProgressMonitor)
+	 */
+	public void store(IFeature feature, String name, InputStream inStream, IProgressMonitor monitor) throws CoreException {
+	}
+
+
+	/*
+	 * @see IPluginContainer#remove(IPluginEntry, IProgressMonitor)
+	 */
+	public void remove(IPluginEntry entry, IProgressMonitor monitor) throws CoreException {
+	}
+
+	/*
+	 * @see ISite#getCategory(String)
+	 */
+	public ICategory getCategory(String key) {
+		return null;
+	}
+
+	/*
+	 * @see ISite#createSiteContentConsumer(IFeature)
+	 */
+	public ISiteContentConsumer createSiteContentConsumer(IFeature feature) throws CoreException {
+		return null;
+	}
+
+	/*
+	 * @see ISite#getFeatureReference(IFeature)
+	 */
+	public ISiteFeatureReference getFeatureReference(IFeature feature) {
+		return null;
+	}
+
+	/*
+	 * @see ISite#getDescription()
+	 */
+	public IURLEntry getDescription() {
+		return null;
+	}
+
+	/*
+	 * @see ISite#getPluginEntriesOnlyReferencedBy(IFeature)
+	 */
+	public IPluginEntry[] getPluginEntriesOnlyReferencedBy(IFeature feature) throws CoreException {
+		return null;
+	}
+
+	/**
+	 * @see ISite#addPluginEntry(IPluginEntry)
+	 */
+	public void addPluginEntry(IPluginEntry pluginEntry) {
+	}
+
+	/**
+	 * @see org.eclipse.update.core.ISite#install(IFeature, IFeatureReference[], IVerificationListener, IProgressMonitor)
+	 */
+	public IFeatureReference install(IFeature feature, IFeatureReference[] optionalfeatures, IVerificationListener verificationListener, IProgressMonitor monitor) throws InstallAbortedException, CoreException {
+		return null;
+	}
+
+
+	public IConfiguredSite getCurrentConfiguredSite() {
+		return null;
+	}
+
+	public IFeature createFeature(String type, URL url) throws CoreException {
+		return null;
+	}
+
+	/**
+	 * @see org.eclipse.update.core.ISite#createFeature(java.lang.String, java.net.URL, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public IFeature createFeature(String type, URL url, IProgressMonitor monitor) throws CoreException {
+		return null;
+	}
+
+
+	/**
+	 * @see org.eclipse.update.core.ISite#getRawFeatureReferences()
+	 */
+	public ISiteFeatureReference[] getRawFeatureReferences() {
+		return null;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.core.ISite#getMirrorSiteEntries()
+	 */
+	public IURLEntry[] getMirrorSiteEntries() throws CoreException {
+		return null;
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/implementation/SiteFTPFactory.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/implementation/SiteFTPFactory.java
new file mode 100644
index 0000000..9734a24
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/implementation/SiteFTPFactory.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.implementation;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.URLEncoder;
+
+public class SiteFTPFactory extends SiteModelFactory implements ISiteFactory {
+
+	public static final String FILE = "a/b/c/";
+
+	/*
+	 * @see ISiteFactory#createSite(URL, boolean)
+	 */
+	public ISite createSite(URL url)
+		throws CoreException, InvalidSiteTypeException {
+		ISite site = null;
+		InputStream siteStream = null;
+
+		try {
+			URL resolvedURL = URLEncoder.encode(url);
+			siteStream = resolvedURL.openStream();
+
+			SiteModelFactory factory = this;
+			factory.parseSite(siteStream);
+
+			site = new SiteFTP(new URL("http://eclipse.org/" + FILE));
+			
+		} catch (MalformedURLException e) {
+			throw Utilities.newCoreException("Unable to create URL", e);
+		} catch (IOException e) {
+			throw Utilities.newCoreException("Unable to access URL",ISite.SITE_ACCESS_EXCEPTION, e);
+		} finally {
+			try {
+				if (siteStream != null)
+					siteStream.close();
+			} catch (Exception e) {
+			}
+		}
+		return site;
+	}
+
+	/*
+	 * @see SiteModelFactory#canParseSiteType(String)
+	 */
+	public boolean canParseSiteType(String type) {
+		return "org.eclipse.update.tests.core.ftp".equalsIgnoreCase(type);
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/AllMirrorTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/AllMirrorTests.java
new file mode 100644
index 0000000..c05a6a7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/AllMirrorTests.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.mirror;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class AllMirrorTests extends UpdateManagerTestCase {
+	
+	public AllMirrorTests(String name){
+		super(name);
+	}
+	
+	public static Test suite(){
+		TestSuite suite = new TestSuite();
+		suite.setName("Mirror Tests");
+		
+		// the following will take all the test methods in the class that starts with "test"
+		
+		suite.addTest(new TestSuite(TestRemoteFeatureVersionMirror.class));
+		suite.addTest(new TestSuite(TestRemoteEmbeddedFeatureMirror.class));
+		suite.addTest(new TestSuite(TestRemoteDoubleEmbeddedFeatureMirror.class));
+		
+		// or you can specify the method
+		//suite.addTest(new TestGetFeature("methodThatDoesNotStartWithtest"));
+		return suite;	
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/MirrorManagerTestCase.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/MirrorManagerTestCase.java
new file mode 100644
index 0000000..400eba2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/MirrorManagerTestCase.java
@@ -0,0 +1,490 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.mirror;
+
+import java.io.*;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import org.osgi.framework.Bundle;
+
+
+public class MirrorManagerTestCase extends UpdateManagerTestCase{
+	public static int exitValue=-1;
+	public static StringBuffer errOutput;
+	
+	public MirrorManagerTestCase(String arg0){
+		super(arg0);
+	}
+	
+	//WatchDog thread to kill mirroring process if it hangs (or takes too long)
+	public static class Timer extends Thread{
+		private Process proc;
+		
+		public Timer(Process proc){
+			super();
+			this.setDaemon(true);
+			this.proc = proc;
+		}
+		
+		public void run(){
+			try {
+				// Note: normal test on 2.2Ghz P4 is 2.9s 
+				//:. giving 100x leeway to complete process before killing it
+				sleep(300000); 
+				proc.destroy();
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	// structure to hold category definition names and descriptions
+	class CategoryDefinition {
+		private String name;
+		private String desc;
+		public void setName(String name) {
+			this.name = name;
+		}
+		public void setDesc(String desc) {
+			this.desc = desc;
+		}
+		public String getName() {
+			return name;
+		}
+		public String getDesc() {
+			return desc;
+		}
+	}
+	
+	// structure to hold feature IDs and their category names
+	public class FeatureCategory{
+		private String featureId;
+		private ArrayList category;
+		
+		public FeatureCategory(){
+			category = new ArrayList();
+		}
+		
+		public void setFeatureID(String fid){
+			featureId = fid;
+		}
+		
+		public void addCategory(String cat){
+			category.add(cat);
+		}
+		
+		public String getFeatureID(){
+			return featureId;
+		}
+		
+		public String[] getCategories(){
+			return (String[])category.toArray(new String[category.size()]);
+		}
+	}
+	
+	// StreamConsumer to display output to output files or console
+	public static class StreamConsumer extends Thread {
+		private BufferedReader bReader;
+
+		public StreamConsumer(InputStream inputStream) {
+			super();
+			setDaemon(true);
+			bReader = new BufferedReader(new InputStreamReader(inputStream));
+		}
+
+		public void run() {
+			try {
+				String line;
+				while (null != (line = bReader.readLine())) {
+					System.out.println(line);
+					errOutput.append(line);
+					errOutput.append("\n");
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	/**
+	 * Returns a string array consisting of commands and their arguments to
+	 * be run.
+	 * @param remoteLoc - path of remote site (site being mirrored)
+	 * @param toLocalSiteUrl - path of local site (new mirror site)
+	 * @param fid - feature id of featuring being mirror (optional - can be null)
+	 * @param ver - version of feature to be mirrored (optional - can be null)
+	 * @param mirUrl - directory location of policy.xml (optional - can be null)
+	 * @return
+	 */
+	public String[] getCommand(
+		String remoteLoc,
+		String toLocalSiteUrl,
+		String fid,
+		String ver,
+		String mirUrl) {
+		final String classpath = getLauncher();
+		final String launcher = "org.eclipse.equinox.launcher.Main";
+		final String command = "mirror";
+		final String application = "org.eclipse.update.core.standaloneUpdate";
+		final String FLAG_CP = "-cp";
+		final String FLAG_APP = "-application";
+		final String FLAG_CMD = "-command";
+		final String FLAG_FID = "-featureId";
+		final String FLAG_DATA = "-data";
+		final String FLAG_VERSION = "-version";
+		final String FLAG_FROM = "-from";
+		final String FLAG_TO = "-to";
+		final String FLAG_URL = "-mirrorURL";
+		final String FLAG_SPLASH = "-nosplash";
+		final String FLAG_CONSOLELOG = "-consolelog";
+		final String data =
+			UpdateCore.getPlugin().getStateLocation().toOSString();
+		String[] cmd =
+			new String[] {
+				getJavaVMPath(),
+				FLAG_CP,
+				classpath,
+				launcher,
+				FLAG_APP,
+				application,
+				FLAG_CMD,
+				command,
+				FLAG_FROM,
+				(remoteLoc !=null ? remoteLoc : ""),
+				FLAG_TO,
+				toLocalSiteUrl,
+				(fid != null ? FLAG_FID : ""),
+				(fid != null ? fid : ""),
+				(ver != null ? FLAG_VERSION : ""),
+				(ver != null ? ver : ""),
+				(mirUrl != null ? FLAG_URL : ""),
+				(mirUrl != null ? mirUrl : ""),
+				FLAG_SPLASH,
+				FLAG_DATA,
+				data,
+				FLAG_CONSOLELOG};
+		return cmd;
+	}
+	
+	private String getLauncher() {
+		Bundle launcher = Platform.getBundle("org.eclipse.equinox.launcher");
+		// todo
+		if (launcher == null)
+			return "";
+		URL rootEntry = launcher.getEntry("/");
+		try {
+			rootEntry = FileLocator.resolve(rootEntry);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+			return null;
+		}
+		if ("file".equals(rootEntry.getProtocol()))
+			return new File(rootEntry.getPath()).getAbsolutePath();
+		if ("jar".equals(rootEntry.getProtocol())) {
+			String path = rootEntry.getPath();	
+			// strip off the file: and the !/
+			path = path.substring(5, path.length() - 2);
+			return new File(path).getAbsolutePath();
+		}
+		return null;
+	}
+	
+	public boolean checkFeatureInSiteXMLExists(String url, String fid, String ver){
+		File site = new File(url + "/site.xml");
+		assertTrue(site.exists());
+		BufferedReader breader;
+		FileReader freader;
+		String text = new String();
+		String jarName = fid + "_" + ver + ".jar";
+		String feature = "<feature url=\"" +
+			"features/" + jarName + 
+			"\" id=\"" + fid + 
+			"\" version=\"" + ver+"\">";
+		try {
+			freader = new FileReader(site);
+			breader = new BufferedReader(freader);
+		} catch (FileNotFoundException e) {
+			// would have been caught by assert above
+			return false;
+		}
+		try {
+			while ((text = breader.readLine()) != null) {
+				text = text.trim();
+				if (text.equals(feature)){
+					breader.close();
+					freader.close();
+					return true;
+				}
+			}
+
+			breader.close();
+			freader.close();
+			return false;
+		} catch (IOException e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	public void checkSiteXML(String url) throws Exception {
+		File mirror = new File(url);
+		File site = new File(url + "/site.xml");
+		assertTrue(mirror.isDirectory());
+		assertTrue(mirror.exists());
+		assertTrue(site.exists());
+	}
+
+	public void checkPolicyXML(String url) throws Exception {
+		File mirror = new File(url);
+		File site = new File(url + "/policy.xml");
+		assertTrue(mirror.isDirectory());
+		assertTrue(mirror.exists());
+		assertTrue(site.exists());
+	}
+	public boolean checkPolicyURL(String url, String mirrorUrl){
+		File site = new File(url + "/policy.xml");
+		assertTrue(site.exists());
+		BufferedReader breader;
+		FileReader freader;
+		String text = new String();
+
+		try {
+			freader = new FileReader(site);
+			breader = new BufferedReader(freader);
+		} catch (FileNotFoundException e) {
+			// would have been caught by assert above
+			return false;
+		}
+
+		try {
+			while ((text = breader.readLine()) != null) {
+				if (text.indexOf(mirrorUrl)!=-1){
+					breader.close();
+					freader.close();	
+					return true;
+				}
+			}
+
+			breader.close();
+			freader.close();
+			return false;
+		} catch (IOException e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+
+	public boolean doesCategoryDefinitionExist(String url) {
+		File site = new File(url + "/site.xml");
+		assertTrue(site.exists());
+		BufferedReader breader;
+		FileReader freader;
+		String text = new String();
+
+		try {
+			freader = new FileReader(site);
+			breader = new BufferedReader(freader);
+		} catch (FileNotFoundException e) {
+			// would have been caught by assert above
+			return false;
+		}
+
+		try {
+			while ((text = breader.readLine()) != null) {
+				if (text.indexOf("category-def")!=-1)
+					return true;
+			}
+
+			breader.close();
+			freader.close();
+			return false;
+		} catch (IOException e) {
+			e.printStackTrace();
+			return false;
+		}
+
+	}
+	
+	public String getEclipseRoot() {
+		return ConfiguratorUtils.getInstallURL().toExternalForm().replaceFirst(
+			"file:",
+			"");
+	}
+	
+	public FeatureCategory[] getFeatureCategories(String url){
+		File site = new File(url + "/site.xml");
+		assertTrue(site.exists());
+		BufferedReader breader;
+		FileReader freader;
+		String text = new String();
+		ArrayList featureCategories = new ArrayList();
+		
+		try {
+			freader = new FileReader(site);
+			breader = new BufferedReader(freader);
+		} catch (FileNotFoundException e) {
+			// would have been caught by assert above
+			return new FeatureCategory[0];
+		}
+
+		try {
+			FeatureCategory currTok = new FeatureCategory();
+			boolean add = false;
+			while((text =breader.readLine())!=null){
+				StringTokenizer strTok = new StringTokenizer(text);
+				while (strTok.hasMoreTokens()){
+					String temp = strTok.nextToken();
+					if (temp.equals("</feature>")){
+						add = true;
+					} else if (temp.startsWith("id")){
+						currTok.setFeatureID(temp.split("\"")[1]);
+					} else if (temp.startsWith("name")){
+						currTok.addCategory(temp.split("\"")[1]);
+					}
+				}
+				if (add){
+					featureCategories.add(currTok);
+					currTok = new FeatureCategory();
+					add = false;
+				}
+			}
+
+			breader.close();
+			freader.close();
+			return (FeatureCategory[])featureCategories.toArray(new FeatureCategory[featureCategories.size()]);
+		} catch (IOException e) {
+			System.err.println(e);
+			return new FeatureCategory[0];
+		}
+	}
+	
+	public String getJavaVMPath() {
+		// Create command string for launching the process
+		String vm = System.getProperty("java.vm.name");
+		String executable = "J9".equals(vm) ? "j9" : "java";
+		if (org.eclipse.osgi.service.environment.Constants.OS_WIN32.equals(Platform.getOS()))
+			executable += "w.exe";
+
+		String javaInstallDir =
+			System.getProperty("java.home") + File.separator + "bin";
+		return javaInstallDir + File.separator + executable;
+	}
+	
+	public CategoryDefinition[] getCategoryDefinitions(String url) {
+		File site = new File(url + "/site.xml");
+		assertTrue(site.exists());
+		BufferedReader breader;
+		FileReader freader;
+		String text = new String();
+		ArrayList catDef = new ArrayList();
+
+		try {
+			freader = new FileReader(site);
+			breader = new BufferedReader(freader);
+		} catch (FileNotFoundException e) {
+			// would have been caught by assert above
+			return new CategoryDefinition[0];
+		}
+
+		try {
+			boolean add = false;
+			boolean isDesc = false;
+			CategoryDefinition temp = new CategoryDefinition();
+			while ((text = breader.readLine()) != null) {
+				if (text.trim().startsWith("<category-def")
+					&& text.indexOf("name") != -1) {
+					temp.setName(text.split("\"")[1]);
+					add = false;
+				} else if (text.trim().equals("<description>")) {
+					isDesc = true;
+				} else if (text.trim().equals("</description>")) {
+					isDesc = false;
+				} else if (isDesc) {
+					temp.setDesc(text.trim());
+				} else if (text.trim().equals("</category-def>")) {
+					add = true;
+				}
+				if (add) {
+					catDef.add(temp);
+					add = false;
+					temp = new CategoryDefinition();
+				}
+			}
+
+			breader.close();
+			freader.close();
+			return (CategoryDefinition[])catDef.toArray(new CategoryDefinition[catDef.size()]);
+		} catch (IOException e) {
+			System.err.println(e);
+			return new CategoryDefinition[0];
+		}
+
+	}
+	
+	public int performMirror(String[] cmd_mirror) {
+		File file = new File(getEclipseRoot());
+		try {
+			System.out.println("Launching:");
+			for(int i=0; i<cmd_mirror.length; i++){
+				System.out.print(cmd_mirror[i]+" ");
+			}
+			System.out.println();
+			Process proc =
+				Runtime.getRuntime().exec(cmd_mirror, (String[]) null, file);
+
+			StreamConsumer outputs = new StreamConsumer(proc.getInputStream());
+			outputs.start();
+			StreamConsumer errors = new StreamConsumer(proc.getErrorStream());
+			errors.start();
+			Timer timer = new Timer(proc);
+			timer.start();
+
+			return proc.waitFor();
+		} catch (IOException e) {
+			System.err.println(e);
+		} catch (InterruptedException e) {
+			System.err.println(e);
+		} catch (Exception e) {
+			System.err.println(e);
+		}
+		return -1;
+	}
+
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		assertEquals(0, exitValue);
+	}
+	
+	// ensure output string buffer ends with "Mirror command completed
+	// successfully."
+	// note: output may instead by "Command completed successfully."
+	public void testMirrorSuccess() throws Exception {
+		StringTokenizer tokenizer =
+			new StringTokenizer(
+				errOutput.toString(),
+				"\n");
+		String lastLine = new String();
+		while (tokenizer.hasMoreTokens()){
+			lastLine = tokenizer.nextToken();
+		}
+		if (lastLine.equals("Mirror command completed successfully."))
+			return;
+		assertEquals("Output was: " + errOutput.toString(), "Command completed successfully.", lastLine);
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/TestRemoteDoubleEmbeddedFeatureMirror.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/TestRemoteDoubleEmbeddedFeatureMirror.java
new file mode 100644
index 0000000..dd8cf75
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/TestRemoteDoubleEmbeddedFeatureMirror.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.mirror;
+
+import java.io.File;
+import java.util.ArrayList;
+
+import org.eclipse.update.tests.UpdateTestsPlugin;
+
+public class TestRemoteDoubleEmbeddedFeatureMirror extends MirrorManagerTestCase {
+	private static boolean isMirrored;
+
+	public TestRemoteDoubleEmbeddedFeatureMirror(String arg0) {
+		super(arg0);
+		errOutput = new StringBuffer();
+		isMirrored = false;
+	}
+
+	public void umSetUp() {
+		String featureId = "update.feature1c";
+		String version = "3.0.0";
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteDoubleEmbeddedFeatureMirror";
+		String mirrorURL = "http://update.eclipse.org/my-mirror-url";
+		// first mirror
+		String fromRemoteSiteUrl =
+			"file:"
+				+ dataPath
+				+ "mirrors/update-site1";
+		if (!isMirrored) {
+			exitValue =
+				performMirror(
+					getCommand(fromRemoteSiteUrl,toLocalSiteUrl, null, null, mirrorURL));
+		
+		// end of first mirror
+		fromRemoteSiteUrl =
+			"file:"
+			+ dataPath
+			+ "mirrors/update-site5";
+			exitValue =
+				performMirror(
+					getCommand(fromRemoteSiteUrl,toLocalSiteUrl, featureId, version, mirrorURL));
+			isMirrored = true;
+		}
+	}
+
+	// make sure each feature is under its correct category names
+	public void testFeatureCategories() throws Exception{
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteDoubleEmbeddedFeatureMirror";
+		FeatureCategory[] mirrorFeatures = getFeatureCategories(toLocalSiteUrl);
+		FeatureCategory[] required = new FeatureCategory[1];
+		required[0] = new FeatureCategory();
+		required[0].setFeatureID("update.feature1c");
+		required[0].addCategory("Site5-Category1");
+		assertTrue(checkFeatureCategoriesContained(required, mirrorFeatures));
+	}
+	
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		super.testExitValue();
+	}
+	
+	// ensure category definitions exist
+	public void testCategoryDefinitionsExist() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteDoubleEmbeddedFeatureMirror";
+		assertTrue(doesCategoryDefinitionExist(toLocalSiteUrl));
+	}
+
+	// ensure feature exists per site.xml
+	public void testFeatureInSiteXMLExists() {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteDoubleEmbeddedFeatureMirror";
+		String featureId = "update.feature1c";
+		String version = "3.0.0";
+		assertTrue(
+			checkFeatureInSiteXMLExists(toLocalSiteUrl, featureId, version));
+	}
+
+	// ensure site.xml is generated
+	public void testSiteXMLExists() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteDoubleEmbeddedFeatureMirror";
+		checkSiteXML(toLocalSiteUrl);
+	}
+
+	// ensure policy.xml is generated
+	public void testPolicyXMLExists() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteDoubleEmbeddedFeatureMirror";
+		checkPolicyXML(toLocalSiteUrl);
+	}
+
+	// ensure policy.xml references the correct mirrorURL
+	public void testPolicyURL() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteDoubleEmbeddedFeatureMirror";
+		String mirrorURL = "http://update.eclipse.org/my-mirror-url";
+		assertTrue(checkPolicyURL(toLocalSiteUrl, mirrorURL));
+	}
+
+	// ensure all jars in features directory mirrored
+	public void testAllFeatureJarsExist() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteDoubleEmbeddedFeatureMirror";
+		String[] featureJars = { "update.feature1b_2.0.0.jar" };
+		assertTrue(checkAllFeatureJars(toLocalSiteUrl, featureJars));
+	}
+
+	// ensure all jars in plugins directory mirrored
+	public void testAllPluginJarsExist() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteDoubleEmbeddedFeatureMirror";
+		String[] pluginJars =
+			{ "com.plugin1_1.0.0.jar", "com.plugin1a_1.0.1.jar" };
+		assertTrue(checkAllPluginJars(toLocalSiteUrl, pluginJars));
+	}
+
+	// ensure output string buffer ends with "Mirror command completed
+	// successfully."
+	// note: output may instead by "Command completed successfully."
+	public void testMirrorSuccess() throws Exception {
+		super.testMirrorSuccess();
+	}
+	
+	public boolean checkAllFeatureJars(String url, String[] jarNames) {
+		File featuresDir = new File(url + "/features");
+		assertTrue(featuresDir.exists());
+		assertTrue(featuresDir.isDirectory());
+		String[] list = featuresDir.list();
+
+		ArrayList ls = new ArrayList();
+		for (int i = 0; i < list.length; i++) {
+			ls.add(list[i]);
+		}
+
+		for (int j = 0; j < jarNames.length; j++) {
+			assertTrue(ls.contains(jarNames[j]));
+		}
+		return true;
+	}
+
+	public boolean checkAllPluginJars(String url, String[] jarNames) {
+		File pluginsDir = new File(url + "/plugins");
+		assertTrue(pluginsDir.exists());
+		assertTrue(pluginsDir.isDirectory());
+		String[] list = pluginsDir.list();
+
+		ArrayList ls = new ArrayList();
+		for (int i = 0; i < list.length; i++) {
+			ls.add(list[i]);
+		}
+
+		for (int j = 0; j < jarNames.length; j++) {
+			assertTrue(ls.contains(jarNames[j]));
+		}
+		return true;
+	}
+
+	public boolean checkFeatureCategoriesContained(FeatureCategory[] required,FeatureCategory[] localDefs){
+		boolean hasMatch;
+		for (int i = 0 ; i<required.length; i++){
+			hasMatch = false;
+			for (int j = 0; j<localDefs.length; j++){
+				if (localDefs[j].getFeatureID().equals(required[i].getFeatureID()) &&
+					checkCategoriesMatch(localDefs[j].getCategories(), required[i].getCategories())){
+						hasMatch = true;
+						j=localDefs.length;
+				}
+			}
+			if (!hasMatch)
+				return false;
+		}
+		return true;
+	}
+	
+	public boolean checkCategoriesMatch(String[] localCat, String[] remoteCat){
+		boolean hasMatch;
+		for (int i = 0; i<localCat.length; i++){
+			hasMatch = false;
+			for (int j = 0; j<remoteCat.length; i++){
+				if (localCat[i].equals(remoteCat[j])){
+					hasMatch = true;
+					j=remoteCat.length;
+				}
+			}
+			if(!hasMatch)
+				return false;
+		}
+		return true;
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/TestRemoteEmbeddedFeatureMirror.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/TestRemoteEmbeddedFeatureMirror.java
new file mode 100644
index 0000000..dfedd69
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/TestRemoteEmbeddedFeatureMirror.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.mirror;
+
+import java.io.File;
+import java.util.ArrayList;
+
+import org.eclipse.update.tests.UpdateTestsPlugin;
+
+public class TestRemoteEmbeddedFeatureMirror extends MirrorManagerTestCase {
+	private static boolean isMirrored;
+
+	public TestRemoteEmbeddedFeatureMirror(String arg0) {
+		super(arg0);
+		errOutput = new StringBuffer();
+		isMirrored = false;
+	}
+
+	public void umSetUp() {
+		String featureId = "update.feature1c";
+		String version = "3.0.0";
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteEmbeddedFeatureMirror";
+		String mirrorURL = "http://update.eclipse.org/my-mirror-url";
+		String fromRemoteSiteUrl =
+				"file:"
+				+ dataPath
+				+ "mirrors/update-site4";
+		if (!isMirrored) {
+			exitValue =
+				performMirror(
+					getCommand(fromRemoteSiteUrl,toLocalSiteUrl, featureId, version, mirrorURL));
+			isMirrored = true;
+		}
+	}
+
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		super.testExitValue();
+	}
+
+	// ensure all category definitions exist
+	public void testCategoryDefinitionsExist() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteEmbeddedFeatureMirror";
+		assertTrue(doesCategoryDefinitionExist(toLocalSiteUrl));
+	}
+
+	public void testFeatureInSiteXMLExists() {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteEmbeddedFeatureMirror";
+		String featureId = "update.feature1c";
+		String version = "3.0.0";
+		assertTrue(
+			checkFeatureInSiteXMLExists(toLocalSiteUrl, featureId, version));
+	}
+
+	// ensure site.xml is generated
+	public void testSiteXMLExists() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteEmbeddedFeatureMirror";
+		checkSiteXML(toLocalSiteUrl);
+	}
+
+	// ensure policy.xml is generated
+	public void testPolicyXMLExists() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteEmbeddedFeatureMirror";
+		checkPolicyXML(toLocalSiteUrl);
+	}
+
+	// ensure policy.xml uses the correct mirrorURL
+	public void testPolicyURL() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteEmbeddedFeatureMirror";
+		String mirrorURL = "http://update.eclipse.org/my-mirror-url";
+		assertTrue(checkPolicyURL(toLocalSiteUrl, mirrorURL));
+	}
+
+	// ensure all jars in features directory mirrored
+	public void testAllFeatureJarsExist() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteEmbeddedFeatureMirror";
+		String[] featureJars = { "update.feature1_1.0.0.jar", "update.feature1_1.0.1.jar", "update.feature1b_2.0.0.jar", "update.feature1c_3.0.0.jar" };
+		assertTrue(checkAllFeatureJars(toLocalSiteUrl, featureJars));
+	}
+
+	// ensure all jars in plugins directory mirrored
+	public void testAllPluginJarsExist() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteEmbeddedFeatureMirror";
+		String[] pluginJars =
+			{ "com.plugin1_1.0.0.jar", "com.plugin1a_1.0.1.jar" };
+		assertTrue(checkAllPluginJars(toLocalSiteUrl, pluginJars));
+	}
+
+	// ensure output string buffer ends with "Mirror command completed
+	// successfully."
+	// note: output may instead by "Command completed successfully."
+	public void testMirrorSuccess() throws Exception {
+		super.testMirrorSuccess();
+	}
+
+	public boolean checkAllFeatureJars(String url, String[] jarNames) {
+		File featuresDir = new File(url + "/features");
+		assertTrue(featuresDir.exists());
+		assertTrue(featuresDir.isDirectory());
+		String[] list = featuresDir.list();
+
+		ArrayList ls = new ArrayList();
+		for (int i = 0; i < list.length; i++) {
+			ls.add(list[i]);
+		}
+
+		assertEquals(list.length, jarNames.length);
+		for (int j = 0; j < jarNames.length; j++) {
+			assertTrue(ls.contains(jarNames[j]));
+		}
+		return true;
+	}
+
+	public boolean checkAllPluginJars(String url, String[] jarNames) {
+		File pluginsDir = new File(url + "/plugins");
+		assertTrue(pluginsDir.exists());
+		assertTrue(pluginsDir.isDirectory());
+		String[] list = pluginsDir.list();
+
+		ArrayList ls = new ArrayList();
+		for (int i = 0; i < list.length; i++) {
+			ls.add(list[i]);
+		}
+
+		assertEquals(list.length, jarNames.length);
+		for (int j = 0; j < jarNames.length; j++) {
+			assertTrue(ls.contains(jarNames[j]));
+		}
+		return true;
+	}
+
+	public boolean checkCategoryDefinitionsContained(CategoryDefinition[] localDefs, CategoryDefinition[] remoteDefs){
+		boolean hasMatch;
+		for (int i = 0 ; i<localDefs.length; i++){
+			hasMatch = false;
+			for (int j = 0; j<remoteDefs.length; j++){
+				if (localDefs[i].getName().equals(remoteDefs[j].getName())
+						&& localDefs[i].getDesc().equals(remoteDefs[j].getDesc()))
+					hasMatch = true;
+			}
+			if (!hasMatch)
+				return false;
+		}
+		return true;
+	}
+	
+
+
+	// start testing category definitions
+	public void testCategoryDefinitions() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteEmbeddedFeatureMirror";
+		String fromRemoteSiteUrl =
+		        dataPath
+				+ "mirrors/update-site4";
+		CategoryDefinition[] localDefs = getCategoryDefinitions(toLocalSiteUrl);
+		CategoryDefinition[] remoteDefs = getCategoryDefinitions(fromRemoteSiteUrl);
+		assertTrue(checkCategoryDefinitionsContained(localDefs, remoteDefs));
+	}
+
+
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/TestRemoteFeatureVersionMirror.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/TestRemoteFeatureVersionMirror.java
new file mode 100644
index 0000000..62ccb0a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/mirror/TestRemoteFeatureVersionMirror.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.mirror;
+
+import java.io.File;
+
+import org.eclipse.update.tests.UpdateTestsPlugin;
+
+public class TestRemoteFeatureVersionMirror extends MirrorManagerTestCase {
+	private static boolean isMirrored;
+	
+	public TestRemoteFeatureVersionMirror(String arg0) {
+		super(arg0);
+		errOutput = new StringBuffer();
+		isMirrored = false;
+	}
+
+	public void umSetUp() {
+		String featureId = "update.feature1";
+		String version = "1.0.0";
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteFeatureVersionMirror";
+		String mirrorURL = "http://update.eclipse.org/my-mirror-url";
+		String fromRemoteSiteUrl = "file:" + dataPath + "mirrors/update-site1";
+		if (!isMirrored) {
+			exitValue =
+				performMirror(
+					getCommand(fromRemoteSiteUrl,toLocalSiteUrl, featureId, version, mirrorURL));
+			isMirrored = true;
+		}
+	}
+
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		super.testExitValue();
+	}
+
+	// ensure all category definitions exist
+	public void testCategoryDefinitionsExist() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteFeatureVersionMirror";
+		assertTrue(doesCategoryDefinitionExist(toLocalSiteUrl));
+	}
+
+	// ensure feature exists per site.xml
+	public void testFeatureInSiteXMLExists(){
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteFeatureVersionMirror";
+		String featureId = "update.feature1";
+		String version = "1.0.0";
+		assertTrue(checkFeatureInSiteXMLExists(toLocalSiteUrl, featureId, version));
+	}
+	
+	// ensure site.xml is generated
+	public void testSiteXMLExists() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteFeatureVersionMirror";
+		checkSiteXML(toLocalSiteUrl);
+	}
+
+	// ensure policy.xml is generated
+	public void testPolicyXMLExists() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteFeatureVersionMirror";
+		checkPolicyXML(toLocalSiteUrl);
+	}
+	
+	// ensure policy.xml uses the correct mirrorURL
+	public void testPolicyURL() throws Exception{
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteFeatureVersionMirror";
+		String mirrorURL = "http://update.eclipse.org/my-mirror-url";
+		assertTrue(checkPolicyURL(toLocalSiteUrl, mirrorURL));
+	}
+
+	// ensure all jars for features and plugins mirrored
+	public void testAllJarsExist() throws Exception {
+		String toLocalSiteUrl =
+			UpdateTestsPlugin.getPlugin().getStateLocation()
+				+ "/temp/testRemoteFeatureVersionMirror";
+		String featureId = "update.feature1";
+		String version = "1.0.0";
+		String jarName = featureId + "_" + version + ".jar";
+		File file = new File(toLocalSiteUrl + "/features/" + jarName);
+		assertTrue(file.exists());
+	}
+
+	// ensure output string buffer ends with "Mirror command completed
+	// successfully."
+	// note: output may instead by "Command completed successfully."
+	public void testMirrorSuccess() throws Exception {
+		super.testMirrorSuccess();
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/AllModelTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/AllModelTests.java
new file mode 100644
index 0000000..c610ef7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/AllModelTests.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.model;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+/**
+ * Manages the API tests
+ */
+public class AllModelTests extends UpdateManagerTestCase {
+	/**
+	 * Constructor
+	 */
+	public AllModelTests(String name) {
+		super(name);
+	}
+	
+	/**
+	 * List of API tests
+	 */
+	public static Test suite() throws Exception {
+		TestSuite suite = new TestSuite();
+		suite.setName("Model Tests");
+
+		suite.addTest(new TestSuite(FeatureMain.class));
+		suite.addTest(new TestSuite(SiteMain.class));		
+
+		return suite;
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/SiteMain.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/SiteMain.java
new file mode 100644
index 0000000..638b376
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/SiteMain.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.model;
+
+import java.io.*;
+import java.net.URL;
+
+import org.eclipse.update.core.SiteFeatureReferenceModel;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class SiteMain extends UpdateManagerTestCase {
+	
+	public SiteMain(String name){
+		super(name);
+	}
+
+	public void testMain() throws Exception {
+		
+		StringWriter strWriter=new StringWriter();
+		PrintWriter w = new PrintWriter(strWriter);
+
+		process("site_old_format.xml",w);
+		process("site.xml",w);
+		try {
+			process("site_with_type.xml",w);
+			fail("InvalidSiteTypeException not thrown");
+		} catch (InvalidSiteTypeException e) {
+			assertEquals(e.getNewType(),"some.other.site.type");
+		} finally {
+			System.out.println(strWriter);
+			w.close();
+		}
+	}
+	
+	private static void process(String xml, PrintWriter w) throws Exception {
+		
+		SiteModelFactory factory = new SiteModelFactory();
+		InputStream is = null;
+		SiteModel site = null;
+		
+		w.println("");
+		w.println("Parsing site map ...");
+		try {
+			is = SiteMain.class.getResourceAsStream(xml);		
+			site = factory.parseSite(is);
+		}  finally {
+			if (is != null) {
+				try { is.close();} catch(IOException e) {}
+			}
+		}
+		
+		if (site == null) return;
+		
+		String base = "http://another.server/site.xml";
+		w.println("Resolving site using "+base+" ...");
+		site.resolve(new URL(base), null);
+		
+		w.println("Writing site ...");
+		writeSite(w,0,site);
+	}
+	
+	private static void writeSite(PrintWriter w, int level, SiteModel site) {
+		if (site == null) return;
+		
+		String in = getIndent(level);
+		w.println(in+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+		
+		w.println(in+"<site");
+		w.println(in+"   "+"type=\""+site.getType()+"\"");
+		w.println(in+"   "+">");
+		
+		writeDescription(w, level+1, site.getDescriptionModel());
+		writeFeatures(w, level+1, site);
+		writeArchives(w, level+1, site);
+		writeCategoryDefs(w, level+1, site);
+         
+        w.println(in+"</feature>");
+	}
+	
+	private static void writeDescription(PrintWriter w, int level, URLEntryModel ue) {
+		if (ue == null) return;
+		String in = getIndent(level);
+		w.println("");
+		w.println(in+"<description url=\""+ue.getURLString()+"\" -> "+ue.getURL()+">");
+		w.println(in+ue.getAnnotation());
+		w.println(in+"</description>");
+	}
+	
+	private static void writeFeatures(PrintWriter w, int level, SiteModel site) {
+		String in = getIndent(level);
+		getIndent(level+1);
+		w.println("");
+		
+		SiteFeatureReferenceModel[] features = site.getFeatureReferenceModels();
+		for (int i=0; i<features.length; i++) {
+			w.println(in+"<feature");
+			w.println(in+"   "+"type=\""+features[i].getType()+"\"");
+			w.println(in+"   "+"url=\""+features[i].getURLString()+"\" -> "+features[i].getURL());
+			w.println(in+"   "+">");
+			writeCategories(w, level+1, features[i]);
+			w.println(in+"</feature>");
+		}
+	}
+	
+	private static void writeArchives(PrintWriter w, int level, SiteModel site) {
+		String in = getIndent(level);
+		w.println("");
+		
+		ArchiveReferenceModel[] archive = site.getArchiveReferenceModels();
+		for (int i=0; i<archive.length; i++) {
+			w.println(in+"<archive");
+			w.println(in+"   "+"path=\""+archive[i].getPath()+"\"");
+			w.println(in+"   "+"url=\""+archive[i].getURLString()+"\" -> "+archive[i].getURL());
+			w.println(in+"   "+"/>");
+		}
+	}
+	
+	private static void writeCategoryDefs(PrintWriter w, int level, SiteModel site) {
+		String in = getIndent(level);
+		getIndent(level+1);
+		w.println("");
+		
+		CategoryModel[] cat = site.getCategoryModels();
+		for (int i=0; i<cat.length; i++) {
+			w.println(in+"<category-def");
+			w.println(in+"   "+"name=\""+cat[i].getName()+"\"");
+			w.println(in+"   "+"label=\""+cat[i].getLabel()+"\"");
+			w.println(in+"   "+">");
+			writeDescription(w, level+1, cat[i].getDescriptionModel());
+			w.println(in+"</category-def>");
+		}
+	}
+	
+	private static void writeCategories(PrintWriter w, int level, SiteFeatureReferenceModel feature) {
+		String in = getIndent(level);
+		String[] cat = feature.getCategoryNames();
+		for (int i=0; i<cat.length; i++) {
+			w.println(in+"<category name=\""+cat[i]+"\"");
+		}
+	}
+	
+	private static String getIndent(int level) {
+		String indent = "";
+		for (int i=0; i<level; i++) 
+			indent += "   ";
+		return indent;
+	}
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/site.xml b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/site.xml
new file mode 100644
index 0000000..4674845
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/site.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<site>
+
+   <description url="http://www.tools.com/updateSite">
+      Site description
+   </description>
+
+   <feature type="my.feature.type" url="feature1.jar">
+      <category name="tools"/>
+      <category name="utilities"/>
+      <category name="windows.tools"/>
+   </feature>
+   
+   <feature type="" url="file:/feature2.jar">
+      <category name="utilities"/>
+   </feature>
+   
+   
+   <archive path="first/archive" url="archive1.jar"/>
+   <archive path="second/archive" url="archive2.jar"/>
+   
+   <category-def name="tools" label="Development Tools">
+      <description url="http://www.tools.com/tools">
+         This is description for tools
+      </description>
+   </category-def>
+   
+   <category-def name="utilities" label="Utilities">
+      <description url="tools.html"/>/
+   </category-def>
+   
+   <category-def name="windows.tools" label="Windows Development Tools"/>
+
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/site_old_format.xml b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/site_old_format.xml
new file mode 100644
index 0000000..6bc9c81
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/site_old_format.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<site url="www.tools.com/updateSite">
+
+   <feature type="my.feature.type" url="feature1.jar">
+      <category name="tools"/>
+      <category name="utilities"/>
+      <category name="windows.tools"/>
+   </feature>
+   
+   <feature type="" url="feature2.jar">
+      <category name="utilities"/>
+   </feature>
+  
+   <archive path="first/archive" url="archive1.jar"/>
+   <archive path="second/archive" url="archive2.jar"/>
+   
+   <category-def name="tools" label="Development Tools">
+      <description url="http://www.tools.com/tools">
+         This is description for tools
+      </description>
+   </category-def>
+   
+   <category-def name="utilities" label="Utilities">
+      <description url="utilities.html"/>
+   </category-def>
+   
+   <category-def name="windows.tools" label="Windows Development Tools"/>
+
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/site_with_type.xml b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/site_with_type.xml
new file mode 100644
index 0000000..699b4f7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/site_with_type.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<site url="http://www.tools.com/updateSite" type="some.other.site.type">
+
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/nativeTests/TestLocalSystemInfo.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/nativeTests/TestLocalSystemInfo.java
new file mode 100644
index 0000000..950635b
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/nativeTests/TestLocalSystemInfo.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.nativeTests;
+import java.io.File;
+
+import org.eclipse.update.configuration.IVolume;
+import org.eclipse.update.configuration.LocalSystemInfo;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestLocalSystemInfo extends UpdateManagerTestCase {
+
+	/**
+	 * Test the natives
+	 */
+	public TestLocalSystemInfo(String arg0) {
+		super(arg0);
+	}
+
+	public void testNative() throws Exception {
+	
+		// mount point
+       IVolume[] a = LocalSystemInfo.getVolumes();
+        if (a==null) throw new Exception("cannot find native library");
+		System.out.println("Found "+a.length+" mount points.");
+		for (int i =0; i<a.length;i++){
+			System.out.print("#"+i+" - "+a[i]);
+			
+			File root = a[i].getFile();
+			String label = a[i].getLabel();
+			if (label==null) label="NO LABEL";
+			int type = a[i].getType();
+			long size = LocalSystemInfo.getFreeSpace(root);
+			System.out.println(" ->:"+label+":"+getType(type)+":"+getSize(size));
+		}
+	}
+	
+	private String getType(int type){
+		switch (type) {
+			case LocalSystemInfo.VOLUME_FIXED :
+				return "VOLUME FIXED";
+			case LocalSystemInfo.VOLUME_REMOTE :
+				return "VOLUME REMOTE";
+			case LocalSystemInfo.VOLUME_REMOVABLE :
+				return "VOLUME REMOVABLE";
+			case LocalSystemInfo.VOLUME_CDROM :
+				return "VOLUME CDROM";				
+			case LocalSystemInfo.VOLUME_UNKNOWN :
+				return "VOLUME UNKNOWN";
+			default :
+				return "WRONG VOLUME INFO";
+		}
+	}
+	
+	private String getSize(long size){
+		if (size==LocalSystemInfo.SIZE_UNKNOWN) return "UNKNOWN SIZE";
+		
+		long kb = size/(1024*1024);
+		return new String(size+" ("+kb+"MB)");
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/nestedfeatures/AllNestedTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/nestedfeatures/AllNestedTests.java
new file mode 100644
index 0000000..3ee6fb4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/nestedfeatures/AllNestedTests.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.nestedfeatures;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+public class AllNestedTests extends UpdateManagerTestCase {
+public AllNestedTests(String name) {
+	super(name);
+}
+public static Test suite() {
+	TestSuite suite = new TestSuite();
+	suite.setName("Nested Install Tests");
+	
+	// the following will take all teh test methods in teh class that start with 'test'
+
+	suite.addTest(new TestSuite(TestInstall.class));
+
+	// or you can specify the method
+	//suite.addTest(new TestGetFeature("methodThatDoesNotStartWithtest"));	
+	
+	return suite;
+}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/nestedfeatures/TestInstall.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/nestedfeatures/TestInstall.java
new file mode 100644
index 0000000..978fc7e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/nestedfeatures/TestInstall.java
@@ -0,0 +1,301 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.nestedfeatures;
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestInstall extends UpdateManagerTestCase {
+
+	/**
+	 * Constructor for Test1
+	 */
+	public TestInstall(String arg0) {
+		super(arg0);
+	}
+
+	public void testFileSite() throws Exception {
+		
+		//cleanup target 
+		File target = new File(TARGET_FILE_SITE.getFile());
+		UpdateManagerUtils.removeFromFileSystem(target);		
+		InstallRegistry.cleanup();
+		
+
+		ISite remoteSite =
+			SiteManager.getSite(new URL(SOURCE_FILE_SITE, "nestedFeatureSiteTest/site.xml"),null);
+		IFeature remoteFeature = remoteSite.getFeatureReferences()[0].getFeature(null);
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		localSite.install(remoteFeature, null, null);
+
+		// verify root Feature
+		String site = localSite.getURL().getFile();
+		IPluginEntry[] entries = remoteFeature.getPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+		String pluginName = entries[0].getVersionedIdentifier().toString();
+		File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		assertTrue(
+			"plugin files not installed locally:" + pluginFile,
+			pluginFile.exists());
+		File pluginXMLFile =
+			new File(
+				site,
+				Site.DEFAULT_PLUGIN_PATH + pluginName + File.separator + "plugin.xml");
+		assertTrue("plugin.xml file not installed locally", pluginXMLFile.exists());
+
+		File featureFile =
+			new File(
+				site,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier().toString());
+		assertTrue(
+			"feature info not installed locally:" + featureFile,
+			featureFile.exists());
+
+		// clean plugins & feature
+		for (int i = 0; i < entries.length; i++) {
+			pluginName = entries[i].getVersionedIdentifier().toString();
+			pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+			UpdateManagerUtils.removeFromFileSystem(pluginFile);
+			InstallRegistry.unregisterPlugin(entries[i]);
+		}
+		UpdateManagerUtils.removeFromFileSystem(featureFile);
+
+		// verify child Feature
+		IFeature childFeature =
+			remoteFeature.getIncludedFeatureReferences()[0].getFeature(null);
+		entries = childFeature.getPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+		pluginName = entries[0].getVersionedIdentifier().toString();
+		pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		assertTrue(
+			"plugin files not installed locally:" + pluginFile,
+			pluginFile.exists());
+		pluginXMLFile =
+			new File(
+				site,
+				Site.DEFAULT_PLUGIN_PATH + pluginName + File.separator + "plugin.xml");
+		assertTrue("plugin.xml file not installed locally", pluginXMLFile.exists());
+
+		featureFile =
+			new File(
+				site,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ childFeature.getVersionedIdentifier().toString());
+		assertTrue(
+			"feature info not installed locally:" + featureFile,
+			featureFile.exists());
+
+		// clean plugins
+		for (int i = 0; i < entries.length; i++) {
+			pluginName = entries[0].getVersionedIdentifier().toString();
+			pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+			UpdateManagerUtils.removeFromFileSystem(pluginFile);
+		}
+
+		// clean features
+		UpdateManagerUtils.removeFromFileSystem(featureFile);
+		UpdateManagerUtils.removeFromFileSystem(new File(localSite.getURL().getFile()));
+		InstallRegistry.cleanup();
+	}
+
+	/**
+	 * 
+	 */
+	public void testHTTPSite() throws Exception {
+
+		ISite remoteSite =
+			SiteManager.getSite(new URL(SOURCE_HTTP_SITE, "nestedFeatureSiteTest/"),null);
+		IFeatureReference[] features = remoteSite.getFeatureReferences();
+		IFeature remoteFeature = null;
+
+		if (features == null || features.length == 0)
+			fail("No features on the site");
+
+		for (int i = 0; i < features.length; i++) {
+			if (features[i].getURL().toExternalForm().endsWith("rootfeature.jar")) {
+				remoteFeature = features[i].getFeature(null);
+				break;
+			}
+		}
+
+		assertNotNull("Cannot find rootfeature.jar on site", remoteFeature);
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		localSite.install(remoteFeature, null, null);
+
+		// rootfeature.jar should not be in the local site
+		IFeatureReference[] localFeatures = localSite.getFeatureReferences();
+		if (localFeatures == null || localFeatures.length == 0)
+			fail("No features on the target site");
+
+		boolean found = false;
+		for (int i = 0; i < localFeatures.length; i++) {
+			if (localFeatures[i].getURL().toExternalForm().endsWith("rootfeature.jar")) {
+				found = true;
+				break;
+			}
+		}
+
+		assertTrue(
+			"Found rootfeature.jar on target site. Target site feature ref shouldnot contain JAR file",
+			!found);
+
+		// check root
+		String site = localSite.getURL().getFile();
+		IPluginEntry[] entries = remoteFeature.getPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+
+		String pluginName = entries[0].getVersionedIdentifier().toString();
+		File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		assertTrue(
+			"plugin files not installed locally:" + pluginFile,
+			pluginFile.exists());		
+		File pluginXMLFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName+ File.separator + "plugin.xml");
+		assertTrue(
+			"plugin info not installed locally:" + pluginXMLFile,
+			pluginXMLFile.exists());
+
+		File featureFile =
+			new File(
+				site,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier().toString());
+		assertTrue("feature info not installed locally", featureFile.exists());
+
+		// clean plugins & feature
+		for (int i = 0; i < entries.length; i++) {
+			pluginName = entries[i].getVersionedIdentifier().toString();
+			pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+			UpdateManagerUtils.removeFromFileSystem(pluginFile);
+			InstallRegistry.unregisterPlugin(entries[i]);
+		}
+		UpdateManagerUtils.removeFromFileSystem(featureFile);
+
+		// verify child Feature
+		IFeature childFeature =
+			remoteFeature.getIncludedFeatureReferences()[0].getFeature(null);
+		entries = childFeature.getPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+		pluginName = entries[0].getVersionedIdentifier().toString();
+		pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		assertTrue(
+			"plugin files not installed locally:" + pluginFile,
+			pluginFile.exists());
+		pluginXMLFile =
+			new File(
+				site,
+				Site.DEFAULT_PLUGIN_PATH + pluginName + File.separator + "plugin.xml");
+		assertTrue("plugin.xml file not installed locally", pluginXMLFile.exists());
+
+		featureFile =
+			new File(
+				site,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ childFeature.getVersionedIdentifier().toString());
+		assertTrue(
+			"feature info not installed locally:" + featureFile,
+			featureFile.exists());
+
+		// clean plugins
+		for (int i = 0; i < entries.length; i++) {
+			pluginName = entries[0].getVersionedIdentifier().toString();
+			pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+			UpdateManagerUtils.removeFromFileSystem(pluginFile);
+		}
+
+		// clean features
+		UpdateManagerUtils.removeFromFileSystem(featureFile);
+		UpdateManagerUtils.removeFromFileSystem(new File(localSite.getURL().getFile()));
+	}
+
+//	public void testInstall() throws Exception {
+//
+//		// cleanup local files...
+//		URL localURL = ((LocalSite) SiteManager.getLocalSite()).getLocationURL();
+//		File localFile = new File(localURL.getFile());
+//		UpdateManagerUtils.removeFromFileSystem(localFile);
+//		InstallRegistry.cleanup();
+//
+//		URL INSTALL_SITE = null;
+//		try {
+//			INSTALL_SITE = new URL(SOURCE_FILE_SITE, "nestedFeatureSiteTest/site.xml");
+//		} catch (Exception e) {
+//			fail(e.toString());
+//			e.printStackTrace();
+//		}
+//
+//		ISite remoteSite = SiteManager.getSite(INSTALL_SITE,null);
+//		IFeatureReference[] features = remoteSite.getFeatureReferences();
+//		IFeature remoteFeature = null;
+//
+//		if (features == null || features.length == 0)
+//			fail("No features on the site");
+//
+//		for (int i = 0; i < features.length; i++) {
+//			if (features[i].getURL().toExternalForm().endsWith("rootfeature.jar")) {
+//				remoteFeature = features[i].getFeature(null);
+//				break;
+//			}
+//		}
+//
+//		assertNotNull("Cannot find rootfeature.jar on site", remoteFeature);
+//		ILocalSite localSite = SiteManager.getLocalSite();
+//		IConfiguredSite site =
+//			localSite.getCurrentConfiguration().getConfiguredSites()[0];
+//
+//		((ConfiguredSite)site).setUpdatable(true);
+//		site.install(remoteFeature, null, null);
+//
+//		IPluginEntry[] entries = remoteFeature.getPluginEntries();
+//		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+//
+//		String sitePath = site.getSite().getURL().getFile();
+//		String pluginName = entries[0].getVersionedIdentifier().toString();
+//		File pluginFile = new File(sitePath, Site.DEFAULT_PLUGIN_PATH + pluginName);
+//		assertTrue("plugin info not installed locally"+pluginFile, pluginFile.exists());
+//
+//		File featureFile =
+//			new File(
+//				sitePath,
+//				Site.DEFAULT_INSTALLED_FEATURE_PATH
+//					+ remoteFeature.getVersionedIdentifier().toString());
+//		assertTrue("feature info not installed locally", featureFile.exists());
+//
+//		//cleanup
+//		File file =
+//			new File(
+//				site.getSite().getURL().getFile()
+//					+ File.separator
+//					+ Site.DEFAULT_INSTALLED_FEATURE_PATH
+//					+ remoteFeature.getVersionedIdentifier());
+//		// clean plugins
+//		for (int i = 0; i < entries.length; i++) {
+//			pluginName = entries[0].getVersionedIdentifier().toString();
+//			pluginFile =
+//				new File(
+//					site.getSite().getURL().getFile(),
+//					Site.DEFAULT_PLUGIN_PATH + pluginName);
+//			UpdateManagerUtils.removeFromFileSystem(pluginFile);
+//		}
+//
+//		UpdateManagerUtils.removeFromFileSystem(file);
+//		UpdateManagerUtils.removeFromFileSystem(pluginFile);
+//		UpdateManagerUtils.removeFromFileSystem(localFile);
+//		UpdateManagerUtils.removeFromFileSystem(
+//			new File(
+//				((InstallConfiguration) localSite.getCurrentConfiguration())
+//					.getURL()
+//					.getFile()));
+//	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/AllParserTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/AllParserTests.java
new file mode 100644
index 0000000..b94b27d
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/AllParserTests.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.parser;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+
+public class AllParserTests extends UpdateManagerTestCase {
+public AllParserTests(String name) {
+	super(name);
+}
+public static Test suite() {
+	TestSuite suite = new TestSuite();
+	suite.setName("Parsing Tests");
+	
+	// the following will take all teh test methods in teh class that start with 'test'
+	suite.addTest(new TestSuite(TestFeatureParse.class));
+	suite.addTest(new TestSuite(TestSiteParse.class));	
+	suite.addTest(new TestSuite(TestCategories.class));		
+	
+	// or you can specify the method
+	//suite.addTest(new TestGetFeature("methodThatDoesNotStartWithtest"));	
+	
+	return suite;
+}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/TestCategories.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/TestCategories.java
new file mode 100644
index 0000000..f4b8a10
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/TestCategories.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.parser;
+import java.net.URL;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestCategories extends UpdateManagerTestCase {
+	/**
+	 * Constructor for Test1
+	 */
+	public TestCategories(String arg0) {
+		super(arg0);
+	}
+
+	public void testCategories() throws Exception {
+
+		URL remoteUrl = new URL(SOURCE_FILE_SITE + "xmls/site1/");
+		ISite remoteSite = SiteManager.getSite(remoteUrl,null);
+
+		ISiteFeatureReference[] feature = remoteSite.getFeatureReferences();
+		//ICategory[] categories = remoteSite.getCategories();
+
+		ICategory featureCategory = feature[0].getCategories()[0];
+
+		assertEquals("UML tools", featureCategory.getLabel());
+
+	}
+
+	public void testOrderedCategories() throws Exception {
+
+		URL remoteUrl = new URL(SOURCE_FILE_SITE + "xmls/site1/");
+		ISite remoteSite = SiteManager.getSite(remoteUrl,null);
+
+		ICategory[] categories = remoteSite.getCategories();
+		for (int i = 0; i < categories.length; i++) {
+			System.out.println("Cat ordered->" + categories[i].getName());
+		}
+
+		assertEquals("Eclipse tools", categories[1].getLabel());
+
+	}
+
+	public void testTranslatedCategories() throws Exception {
+
+		ISite remoteSite = SiteManager.getSite(SOURCE_HTTP_SITE,null);
+
+		ICategory[] categories = remoteSite.getCategories();
+
+		assertEquals("Required Drivers", categories[0].getLabel());
+
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/TestFeatureParse.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/TestFeatureParse.java
new file mode 100644
index 0000000..6f537e4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/TestFeatureParse.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.parser;
+
+import java.net.URL;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.DefaultFeatureParser;
+import org.eclipse.update.core.model.FeatureModel;
+import org.eclipse.update.core.model.URLEntryModel;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import org.xml.sax.SAXParseException;
+
+public class TestFeatureParse extends UpdateManagerTestCase {
+
+	/**
+	 * Constructor for Test1
+	 */
+	public TestFeatureParse(String arg0) {
+		super(arg0);
+	}
+
+	public void testParse() throws Exception {
+
+		String xmlFile = "xmls/feature_1.0.0/";
+		ISite remoteSite = SiteManager.getSite(SOURCE_FILE_SITE, null);
+		URL url = UpdateManagerUtils.getURL(remoteSite.getURL(), xmlFile, null);
+
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(remoteSite);
+		ref.setURL(url);
+		IFeature feature = ref.getFeature(null);
+
+		String prov = feature.getProvider();
+		assertEquals("Object Technology International", prov);
+
+	}
+
+	public void testParseValid1() throws Exception {
+
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/feature1.xml");
+			DefaultFeatureParser parser = new DefaultFeatureParser();
+			parser.init(new FeatureExecutableFactory());
+			URL resolvedURL = URLEncoder.encode(remoteURL);
+			FeatureModel remoteFeature = parser.parse(resolvedURL.openStream());
+			remoteFeature.resolve(remoteURL, null);
+
+		} catch (SAXParseException e) {
+			fail("Exception should NOT be thrown");
+		}
+	}
+
+	public void testParseValid1bis() throws Exception {
+
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/feature1bis.xml");
+			DefaultFeatureParser parser = new DefaultFeatureParser();
+			parser.init(new FeatureExecutableFactory());
+			URL resolvedURL = URLEncoder.encode(remoteURL);
+			FeatureModel remoteFeature = parser.parse(resolvedURL.openStream());
+			remoteFeature.resolve(remoteURL, null);
+
+		} catch (SAXParseException e) {
+			fail("Exception should NOT be thrown");
+		}
+	}
+
+	public void testParseValid2() throws Exception {
+
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/feature2.xml");
+			DefaultFeatureParser parser = new DefaultFeatureParser();
+			parser.init(new FeatureExecutableFactory());
+			URL resolvedURL = URLEncoder.encode(remoteURL);
+			FeatureModel remoteFeature = parser.parse(resolvedURL.openStream());
+			remoteFeature.resolve(remoteURL, null);
+
+		} catch (SAXParseException e) {
+			fail("Exception should not be thrown" + e.getMessage());
+		}
+	}
+
+	public void testParseValid3() throws Exception {
+
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/feature3.xml");
+			DefaultFeatureParser parser = new DefaultFeatureParser();
+			parser.init(new FeatureExecutableFactory());
+			URL resolvedURL = URLEncoder.encode(remoteURL);
+			FeatureModel remoteFeature = parser.parse(resolvedURL.openStream());
+			remoteFeature.resolve(remoteURL, null);
+
+			String copyrightString = remoteFeature.getCopyrightModel().getURL().getFile();
+			boolean resolved = copyrightString.indexOf(SiteManager.getOS()) != -1;
+			assertTrue("Copyright URL not resolved:" + copyrightString, resolved);
+		} catch (SAXParseException e) {
+			fail("Exception should not be thrown" + e.getMessage());
+		}
+	}
+
+	// parse type
+	public void testParseValid4() throws Exception {
+
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/feature4.xml");
+			DefaultFeatureParser parser = new DefaultFeatureParser();
+			parser.init(new FeatureExecutableFactory());
+			URL resolvedURL = URLEncoder.encode(remoteURL);
+			FeatureModel remoteFeature = parser.parse(resolvedURL.openStream());
+			remoteFeature.resolve(remoteURL, null);
+
+			URLEntryModel[] models = remoteFeature.getDiscoverySiteEntryModels();
+			assertTrue("Discovery model is not a Web Model", models[0].getType()==IURLEntry.WEB_SITE);
+			URLEntryModel copyright = remoteFeature.getCopyrightModel();
+			assertTrue("Copyright model is not an Update Model", copyright.getType()==IURLEntry.UPDATE_SITE);
+			
+		} catch (SAXParseException e) {
+			fail("Exception should not be thrown" + e.getMessage());
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/TestSiteParse.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/TestSiteParse.java
new file mode 100644
index 0000000..f090a7c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/parser/TestSiteParse.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.tests.parser;
+
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.SiteFileFactory;
+import org.eclipse.update.internal.core.URLEncoder;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import org.xml.sax.SAXParseException;
+
+public class TestSiteParse extends UpdateManagerTestCase {
+
+	/**
+	 * Constructor for Test1
+	 */
+	public TestSiteParse(String arg0) {
+		super(arg0);
+	}
+
+	public void testParse() throws Exception {
+
+		URL remoteUrl = new URL(SOURCE_FILE_SITE + "xmls/site1/");
+		ISite remoteSite = SiteManager.getSite(remoteUrl,null);
+
+		//IFeatureReference[] feature = remoteSite.getFeatureReferences();
+		//ICategory[] categories = remoteSite.getCategories();
+
+		String path = remoteUrl.getFile();
+		String path2 = remoteSite.getDescription().getURL().getFile();
+		assertEquals(new File(path + "index.html"), new File(path2));
+
+	}
+
+	public void testNumberOfFeatures() throws Exception {
+
+		URL remoteURL = new URL("http", getHttpHost(), getHttpPort(), bundle.getString("HTTP_PATH_2"));
+		ISite remoteSite = SiteManager.getSite(remoteURL,null);
+
+		IFeatureReference[] feature = remoteSite.getFeatureReferences();
+		assertEquals(feature.length, 2);
+
+	}
+
+	public void testParseValid1() throws Exception {
+
+		URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/site.xml");
+		DefaultSiteParser parser = new DefaultSiteParser();
+		parser.init(new SiteFileFactory());
+		URL resolvedURL = URLEncoder.encode(remoteURL);
+		SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+		remoteSite.resolve(remoteURL, null);
+
+		FeatureReferenceModel[] feature = remoteSite.getFeatureReferenceModels();
+		CategoryModel[] categories = remoteSite.getCategoryModels();
+		ArchiveReferenceModel[] archives = remoteSite.getArchiveReferenceModels();
+
+		assertTrue("Wrong number of features", feature.length == 6);
+		assertTrue("Wrong number of categories", categories.length == 3);
+		assertTrue("Wrong number of archives", archives.length == 0);
+
+		String path = new URL(SOURCE_FILE_SITE + "parsertests/").getFile();
+		String path2 = remoteSite.getDescriptionModel().getURL().getFile();
+		assertEquals(path + "index.html", path2);
+
+	}
+
+	public void testParseValid2() throws Exception {
+
+		URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/reddot.xml");
+		DefaultSiteParser parser = new DefaultSiteParser();
+		parser.init(new SiteFileFactory());
+		URL resolvedURL = URLEncoder.encode(remoteURL);
+		SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+		remoteSite.resolve(remoteURL, null);
+
+		FeatureReferenceModel[] feature = remoteSite.getFeatureReferenceModels();
+		CategoryModel[] categories = remoteSite.getCategoryModels();
+		ArchiveReferenceModel[] archives = remoteSite.getArchiveReferenceModels();
+
+		assertTrue("Wrong number of features", feature.length == 2);
+		assertTrue("Wrong number of categories", categories.length == 1);
+		assertTrue("Wrong number of archives", archives.length == 2);
+
+		String valideString = "This category contains all of the <currently> available versions of Red Dot feature. <greeting>Hello, world!</greeting>";
+		assertEquals(valideString, remoteSite.getCategoryModels()[0].getDescriptionModel().getAnnotation());
+
+		String path = new URL(SOURCE_FILE_SITE + "parsertests/").getFile();
+		String path2 = remoteSite.getDescriptionModel().getURL().getFile();
+		assertEquals(path + "index.html", path2);
+
+	}
+
+	public void testParseValid3() throws Exception {
+
+		URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/reddot1.xml");
+		DefaultSiteParser parser = new DefaultSiteParser();
+		parser.init(new SiteFileFactory());
+		URL resolvedURL = URLEncoder.encode(remoteURL);
+		SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+		remoteSite.resolve(remoteURL, null);
+
+		FeatureReferenceModel[] feature = remoteSite.getFeatureReferenceModels();
+		CategoryModel[] categories = remoteSite.getCategoryModels();
+		ArchiveReferenceModel[] archives = remoteSite.getArchiveReferenceModels();
+
+		assertTrue("Wrong number of features", feature.length == 2);
+		assertTrue("Wrong number of categories", categories.length == 1);
+		assertTrue("Wrong number of archives", archives.length == 2);
+
+		String valideString = "This category contains all of the <currently> available versions of Red Dot feature.";
+		assertEquals(valideString, remoteSite.getCategoryModels()[0].getDescriptionModel().getAnnotation());
+
+		String path = new URL(SOURCE_FILE_SITE + "parsertests/").getFile();
+		String path2 = remoteSite.getDescriptionModel().getURL().getFile();
+		assertEquals(path + "index.html", path2);
+
+	}
+
+	public void testParseValid4() throws Exception {
+
+		URL remoteURL = new URL(SOURCE_FILE_SITE + "SiteURLTest/data/site.xml");
+		DefaultSiteParser parser = new DefaultSiteParser();
+		parser.init(new SiteFileFactory());
+		URL resolvedURL = URLEncoder.encode(remoteURL);
+		SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+		remoteSite.resolve(remoteURL, null);
+
+		FeatureReferenceModel[] feature = remoteSite.getFeatureReferenceModels();
+		//CategoryModel[] categories = remoteSite.getCategoryModels();
+		ArchiveReferenceModel[] archives = remoteSite.getArchiveReferenceModels();
+
+		assertTrue("Wrong number of features", feature.length == 2);
+		assertTrue("Wrong number of archives", archives.length == 3);
+
+		URL path1 = new URL(SOURCE_FILE_SITE + "SiteURLTest/data/artifacts/features/helpFeature.jar");
+		URL url1 = feature[0].getURL();
+		assertEquals(path1, url1);
+		URL path2 = new URL(SOURCE_FILE_SITE + "SiteURLTest/data/artifacts/plugins/help.jar");
+		assertEquals(path2, archives[0].getURL());
+
+		String path = new URL(SOURCE_FILE_SITE + "SiteURLTest/data/info/").getFile();
+		String path3 = remoteSite.getDescriptionModel().getURL().getFile();
+		assertEquals(path + "siteInfo.html", path3);
+
+	}
+
+	public void testParseValid5() throws Exception {
+
+		URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/site2.xml");
+		DefaultSiteParser parser = new DefaultSiteParser();
+		parser.init(new SiteFileFactory());
+		URL resolvedURL = URLEncoder.encode(remoteURL);
+		SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+		remoteSite.resolve(remoteURL, null);
+
+		FeatureReferenceModel[] featureRef = remoteSite.getFeatureReferenceModels();
+		//CategoryModel[] categories = remoteSite.getCategoryModels();
+		ArchiveReferenceModel[] archives = remoteSite.getArchiveReferenceModels();
+
+		assertTrue("Wrong number of features", featureRef.length == 1);
+		assertTrue("Wrong number of archives", archives.length == 0);
+
+		try {
+			((FeatureReference) featureRef[0]).getFeature(null);
+		} catch (CoreException e) {
+			Throwable e1 = e.getStatus().getException();
+			if (e1.getMessage().indexOf("not-eclipse") == -1) {
+				throw e;
+			}
+		}
+	}
+
+	public void testParseValid6() throws Exception {
+
+		URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/site4.xml");
+		DefaultSiteParser parser = new DefaultSiteParser();
+		parser.init(new SiteFileFactory());
+		URL resolvedURL = URLEncoder.encode(remoteURL);
+		SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+		remoteSite.resolve(remoteURL, null);
+
+		FeatureReferenceModel[] featureRef = remoteSite.getFeatureReferenceModels();
+		//CategoryModel[] categories = remoteSite.getCategoryModels();
+		ArchiveReferenceModel[] archives = remoteSite.getArchiveReferenceModels();
+
+		assertTrue("Wrong number of features", featureRef.length == 2);
+		assertTrue("Wrong number of archives", archives.length == 0);
+
+		try {
+			((FeatureReference) featureRef[0]).getFeature(null);
+		} catch (CoreException e) {
+			Throwable e1 = e.getStatus().getException();
+			String msg = e1.getMessage().replace(File.separatorChar, '/');
+			if (msg.indexOf("_1.0.0.jar/feature.xml") == -1) {
+				throw e;
+			}
+		}
+	}
+
+	public void testParseUnknownCategory() throws Exception {
+
+		URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/site3.xml");
+		DefaultSiteParser parser = new DefaultSiteParser();
+		parser.init(new SiteFileFactory());
+		URL resolvedURL = URLEncoder.encode(remoteURL);
+		SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+		remoteSite.resolve(remoteURL, null);
+
+		FeatureReferenceModel[] featureRef = remoteSite.getFeatureReferenceModels();
+		ICategory[] categories = ((SiteFeatureReference) featureRef[0]).getCategories();
+		assertTrue(categories.length == 1 && "Other".equals(categories[0].getName()));
+	}
+
+	public void testParseValid7() throws Exception {
+
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/site7.xml");
+			DefaultSiteParser parser = new DefaultSiteParser();
+			parser.init(new SiteFileFactory());
+			URL resolvedURL = URLEncoder.encode(remoteURL);
+			SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+			remoteSite.resolve(remoteURL, null);
+
+		} catch (SAXParseException e) {
+			fail("Exception should not be thrown" + e.getMessage());
+		}
+	}
+
+	public void testParseValid8() throws Exception {
+
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/site8.xml");
+			DefaultSiteParser parser = new DefaultSiteParser();
+			parser.init(new SiteFileFactory());
+			URL resolvedURL = URLEncoder.encode(remoteURL);
+			SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+			remoteSite.resolve(remoteURL, null);
+
+		} catch (SAXParseException e) {
+			fail("Exception should not be thrown" + e.getMessage());
+		}
+	}
+
+	public void testParseValid9() throws Exception {
+
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/site9.xml");
+			DefaultSiteParser parser = new DefaultSiteParser();
+			parser.init(new SiteFileFactory());
+			URL resolvedURL = URLEncoder.encode(remoteURL);
+			SiteModel remoteSite = parser.parse(resolvedURL.openStream());
+			remoteSite.resolve(remoteURL, null);
+		} catch (SAXParseException e) {
+			fail("Exception should not be thrown" + e.getMessage());
+		}
+	}
+
+	public void testParseValid10() throws Exception {
+
+		SiteModel remoteSite = null;
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/site10.xml");
+			DefaultSiteParser parser = new DefaultSiteParser();
+			parser.init(new SiteFileFactory());
+			URL resolvedURL = URLEncoder.encode(remoteURL);
+			remoteSite = parser.parse(resolvedURL.openStream());
+			remoteSite.resolve(remoteURL, null);
+		} catch (SAXParseException e) {
+			fail("Exception should not be thrown" + e.getMessage());
+		}
+		FeatureReferenceModel[] models = remoteSite.getFeatureReferenceModels();
+		assertEquals("Invalid versioned identifier", models[0].getFeatureIdentifier(), "org.eclipse.test.feature");
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/perfms/AllPerformanceTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/perfms/AllPerformanceTests.java
new file mode 100644
index 0000000..4969c91
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/perfms/AllPerformanceTests.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.perfms;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+
+public class AllPerformanceTests extends UpdateManagerTestCase {
+public AllPerformanceTests(String name) {
+	super(name);
+}
+public static Test suite() {
+	TestSuite suite = new TestSuite();
+	suite.setName("Update Performance Tests");
+	
+	// the following will take all teh test methods in the class that start with 'test'
+	//suite.addTest(new TestSuite(TestStartup.class));
+	return suite;
+}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/perfms/TestStartup.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/perfms/TestStartup.java
new file mode 100644
index 0000000..a274866
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/perfms/TestStartup.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.perfms;
+//import java.net.*;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.test.performance.Dimension;
+import org.eclipse.test.performance.Performance;
+import org.eclipse.test.performance.PerformanceMeter;
+import org.eclipse.update.internal.configurator.PlatformConfigurationFactory;
+import org.eclipse.update.internal.configurator.SiteEntry;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestStartup extends UpdateManagerTestCase {
+	public TestStartup(String arg0) {
+		super(arg0);
+	}
+	
+
+	public void testConfigurationCreation() {
+		Performance perf= Performance.getDefault();
+		PerformanceMeter performanceMeter= perf.createPerformanceMeter(perf.getDefaultScenarioId(this));
+		perf.tagAsGlobalSummary(performanceMeter, "Configuration creation", Dimension.ELAPSED_PROCESS);
+		
+		try {
+			for (int i= 0; i < 10; i++) {
+				performanceMeter.start();
+				try {
+					URL platformXml = new URL("file", "",dataPath + "/" + "perf/platform.xml");
+					new PlatformConfigurationFactory().getPlatformConfiguration(platformXml);
+				} catch (IOException e) {
+					System.out.println("Cannot create configuration for performance measurement");
+				}
+				performanceMeter.stop();
+	 		}
+			performanceMeter.commit();
+			perf.assertPerformance(performanceMeter);
+	 	} finally {
+			performanceMeter.dispose();
+	 	}
+	}
+	
+	public void testConfigurationDetection() {
+		Performance perf= Performance.getDefault();
+		PerformanceMeter performanceMeter= perf.createPerformanceMeter(perf.getDefaultScenarioId(this));
+		perf.tagAsGlobalSummary(performanceMeter, "Configuration detection", Dimension.ELAPSED_PROCESS);
+
+		try {
+			for (int i= 0; i < 10; i++) {
+				performanceMeter.start();
+				try {
+					URL siteURL = new URL("file", "",dataPath + "/" + "perf/eclipse");
+					SiteEntry site = new SiteEntry(siteURL);
+					site.loadFromDisk(0);
+				} catch (Exception e) {
+					System.out.println("Cannot create site entry for performance measurement");
+				}
+				performanceMeter.stop();
+	 		}
+			performanceMeter.commit();
+			perf.assertPerformance(performanceMeter);
+	 	} finally {
+			performanceMeter.dispose();
+	 	}
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/reconciliation/AllReconciliationTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/reconciliation/AllReconciliationTests.java
new file mode 100644
index 0000000..068d7c1
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/reconciliation/AllReconciliationTests.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.reconciliation;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+/**
+ * Manages the API tests
+ */
+public class AllReconciliationTests extends UpdateManagerTestCase {
+	/**
+	 * Constructor
+	 */
+	public AllReconciliationTests(String name) {
+		super(name);
+	}
+	
+	/**
+	 * List of API tests
+	 */
+	public static Test suite() throws Exception {
+		TestSuite suite = new TestSuite();
+		suite.setName("API Tests");
+
+
+		suite.addTest(new TestSuite(TestSiteReconciliation.class));
+
+		return suite;
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/reconciliation/TestSiteReconciliation.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/reconciliation/TestSiteReconciliation.java
new file mode 100644
index 0000000..1ce06d9
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/reconciliation/TestSiteReconciliation.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.reconciliation;
+import java.io.*;
+import java.net.*;
+
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.configurator.IPlatformConfiguration;
+import org.eclipse.update.configurator.IPlatformConfiguration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.*;
+
+public class TestSiteReconciliation extends UpdateManagerTestCase {
+	
+
+	
+
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestSiteReconciliation(String arg0) {
+		super(arg0);
+	}
+
+	private void addConfigSite(int policy, URL url,String[] listOfPlugins) throws Exception {
+		String xmlFile = ((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile();
+		UpdateManagerUtils.removeFromFileSystem(new File(xmlFile));		
+		InternalSiteManager.localSite=null;
+		// get new config object
+		IPlatformConfiguration cfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		ISitePolicy p1 = cfig.createSitePolicy(policy, listOfPlugins);	
+		ISiteEntry s1 = cfig.createSiteEntry(url,p1);
+		cfig.configureSite(s1);	
+	}
+	
+	private void removeConfigSite(URL url) throws Exception {
+		// get new config object
+		IPlatformConfiguration cfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		ISiteEntry s1 = cfig.findConfiguredSite(url);
+		assertNotNull("Unable to find site entry:"+url,s1);
+		cfig.unconfigureSite(s1);
+		cfig.save();
+	}	
+	/**
+	 * Site 1 contains a feature which needs a plugin taht is not on the path when we start
+	 * it will never be configured
+	 */
+	public void testNewSiteInclude1() throws Exception {
+	
+		int policy  = ISitePolicy.USER_INCLUDE;
+		URL url = new URL("file",null,dataPath+"reconciliationSites/site1/");
+		String[] plugins = new String[]{};
+		addConfigSite(policy,url, plugins);
+
+		ILocalSite local = SiteManager.getLocalSite();
+		((LocalSite)local).setStamp(0);
+		IConfiguredSite[] newSites = local.getCurrentConfiguration().getConfiguredSites();
+		IConfiguredSite newSite = null;
+		for (int i = 0; i < newSites.length; i++) {
+			if (UpdateManagerUtils.sameURL(newSites[i].getSite().getURL(),url)){
+				newSite = newSites[i];
+			}
+		}
+		
+		if (newSite==null) fail("Site not found in configuration");
+		
+		IFeatureReference[] ref = newSite.getConfiguredFeatures();
+		assertEquals("Wrong number of configured features",0,ref.length);		
+		ref = ((ConfiguredSite)newSite).getConfigurationPolicy().getUnconfiguredFeatures();
+		assertEquals("Wrong number of unconfigured features",0,ref.length);		
+		
+		removeConfigSite(url);
+	}
+
+	public void testNewSiteExclude1() throws Exception {
+		
+		int policy  = ISitePolicy.USER_EXCLUDE;
+		URL url = new URL("file",null,dataPath+"reconciliationSites/site1/");
+		String[] plugins = new String[]{};
+		addConfigSite(policy,url, plugins);
+		
+		ILocalSite local = SiteManager.getLocalSite();
+		((LocalSite)local).setStamp(0);		
+		IConfiguredSite[] newSites = local.getCurrentConfiguration().getConfiguredSites();
+		IConfiguredSite newSite = null;
+		for (int i = 0; i < newSites.length; i++) {
+			if (UpdateManagerUtils.sameURL(newSites[i].getSite().getURL(),url)){
+				newSite = newSites[i];
+			}
+		}
+		
+		if (newSite==null) fail("Site not found in configuration");
+		
+		IFeatureReference[] ref = newSite.getConfiguredFeatures();
+		assertEquals("Wrong number of configured features",0,ref.length);		
+		ref = ((ConfiguredSite)newSite).getConfigurationPolicy().getUnconfiguredFeatures();
+		assertEquals("Wrong number of unconfigured features",0,ref.length);				
+		removeConfigSite(url);
+	}
+
+	/**
+	 * Site 2 contains a feature which needs a plugin taht is on the path when we start
+	 * it will be configured
+	 */
+	public void testNewSiteInclude2() throws Exception {
+		
+		int policy  = ISitePolicy.USER_INCLUDE;
+		URL url = new URL("file",null,dataPath+"reconciliationSites/site2/");
+		String[] plugins = new String[]{};
+		addConfigSite(policy,url, plugins);
+		ILocalSite local = SiteManager.getLocalSite();
+		((LocalSite)local).setStamp(0);		
+		IConfiguredSite[] newSites = local.getCurrentConfiguration().getConfiguredSites();
+		IConfiguredSite newSite = null;
+		for (int i = 0; i < newSites.length; i++) {
+			if (UpdateManagerUtils.sameURL(newSites[i].getSite().getURL(),url)){
+				newSite = newSites[i];
+			}
+		}
+		
+		if (newSite==null) fail("Site not found in configuration");
+		
+		IFeatureReference[] ref = newSite.getConfiguredFeatures();
+		assertEquals("Wrong number of configured features",0,ref.length);
+		ref = ((ConfiguredSite)newSite).getConfigurationPolicy().getUnconfiguredFeatures();
+		assertEquals("Wrong number of unconfigured features",0,ref.length);
+		
+		removeConfigSite(url);
+	}
+
+
+
+	public void testNewSiteExclude2() throws Exception {
+		
+		int policy  = ISitePolicy.USER_EXCLUDE;
+		URL url = new URL("file",null,dataPath+"reconciliationSites/site2/");
+		String[] plugins = new String[]{};
+		addConfigSite(policy,url, plugins);
+		ILocalSite local = SiteManager.getLocalSite();
+		((LocalSite)local).setStamp(0);		
+		IConfiguredSite[] newSites = local.getCurrentConfiguration().getConfiguredSites();
+		IConfiguredSite newSite = null;
+		for (int i = 0; i < newSites.length; i++) {
+			if (UpdateManagerUtils.sameURL(newSites[i].getSite().getURL(),url)){
+				newSite = newSites[i];
+			}
+		}
+		
+		if (newSite==null) fail("Site not found in configuration");
+		
+		IFeatureReference[] ref = newSite.getConfiguredFeatures();
+		assertEquals("Wrong number of configured features",0,ref.length);
+		ref = ((ConfiguredSite)newSite).getConfigurationPolicy().getUnconfiguredFeatures();
+		assertEquals("Wrong number of unconfigured features",0,ref.length);
+
+		removeConfigSite(url);
+	}
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/AllRegularInstallTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/AllRegularInstallTests.java
new file mode 100644
index 0000000..7ebf19f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/AllRegularInstallTests.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+
+public class AllRegularInstallTests extends UpdateManagerTestCase {
+public AllRegularInstallTests(String name) {
+	super(name);
+}
+public static Test suite() {
+	TestSuite suite = new TestSuite();
+	suite.setName("Regular Install Tests");
+	
+	// the following will take all teh test methods in teh class that start with 'test'
+
+	suite.addTest(new TestSuite(TestInstall.class));
+	suite.addTest(new TestSuite(TestInstallURLSIteXML.class));	
+	suite.addTest(new TestSuite(TestSpaceInInstall.class));	
+	suite.addTest(new TestSuite(TestGetFeature.class));
+	suite.addTest(new TestSuite(TestExecutableInstall.class));	
+	suite.addTest(new TestSuite(TestExecutablePackagedInstall.class));		
+	suite.addTest(new TestSuite(TestDataEntryInstall.class));
+	suite.addTest(new TestSuite(TestLocalSite.class));		
+	
+	// or you can specify the method
+	//suite.addTest(new TestGetFeature("methodThatDoesNotStartWithtest"));	
+	
+	return suite;
+}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/MultipleTestLocalSite.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/MultipleTestLocalSite.java
new file mode 100644
index 0000000..2a6df92
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/MultipleTestLocalSite.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+
+public class MultipleTestLocalSite extends UpdateManagerTestCase {
+public MultipleTestLocalSite(String name) {
+	super(name);
+}
+public static Test suite() {
+	TestSuite suite = new TestSuite();
+	suite.setName("Multiple Test Local Site");
+	
+	// the following will take all teh test methods in teh class that start with 'test'
+	
+	for(int i=0; i<50; i++){
+		suite.addTest(new TestSuite(TestLocalSite.class));
+	}
+	
+	return suite;
+}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestDataEntryInstall.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestDataEntryInstall.java
new file mode 100644
index 0000000..c6105c1
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestDataEntryInstall.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestDataEntryInstall extends UpdateManagerTestCase {
+	/**
+	 * Constructor for Test1
+	 */
+	public TestDataEntryInstall(String arg0) {
+		super(arg0);
+	}
+
+	/**
+	 * With site.xml
+	 */
+	public void testDataEntrySite() throws Exception {
+
+		//cleanup target 
+		File target = new File(TARGET_FILE_SITE.getFile());
+		UpdateManagerUtils.removeFromFileSystem(target);
+		
+		URL newURL =new File(dataPath + "dataEntrySiteTest/site1/site.xml").toURL();
+		ISite remoteSite = SiteManager.getSite(newURL,null);
+		IFeatureReference[] featuresRef = remoteSite.getFeatureReferences();
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		IFeature remoteFeature = null;
+		
+		for (int i = 0; i < featuresRef.length; i++) {
+			remoteFeature = featuresRef[i].getFeature(null);
+			localSite.install(remoteFeature, null,null);
+
+			// verify
+			String site = localSite.getURL().getFile();
+			INonPluginEntry[] entries = remoteFeature.getNonPluginEntries();
+			assertTrue("no data entry", (entries != null && entries.length != 0));
+			String pluginName = entries[0].getIdentifier().toString();
+			File pluginFile = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString()+File.separator+ pluginName);
+			assertTrue("data files not installed locally:"+pluginFile, pluginFile.exists());
+		} 
+
+		//cleanup target 
+		UpdateManagerUtils.removeFromFileSystem(target);
+
+
+	}
+	
+	
+	/**
+	 * With site.xml
+	 */
+	public void testDataEntrySitePackaged() throws Exception {
+
+		//cleanup target 
+		File target = new File(TARGET_FILE_SITE.getFile());
+		UpdateManagerUtils.removeFromFileSystem(target);
+		
+		URL newURL =new File(dataPath + "dataEntrySiteTest/site2/site.xml").toURL();
+		ISite remoteSite = SiteManager.getSite(newURL,null);
+		IFeatureReference[] featuresRef = remoteSite.getFeatureReferences();
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		IFeature remoteFeature = null;
+		
+		for (int i = 0; i < featuresRef.length; i++) {
+			remoteFeature = featuresRef[i].getFeature(null);
+			localSite.install(remoteFeature, null,null);
+
+			// verify
+			String site = localSite.getURL().getFile();
+			INonPluginEntry[] entries = remoteFeature.getNonPluginEntries();
+			assertTrue("no data entry", (entries != null && entries.length != 0));
+			entries[0].getIdentifier().toString();
+			File pluginFile = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString()+File.separator+ "nondata"+File.separator+"file1.zip");
+			assertTrue("Data file inside the jar not installed locally:"+pluginFile, pluginFile.exists());
+			pluginFile = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString()+File.separator+ "file.zip");
+			assertTrue("Data file outside the jar not installed locally:"+pluginFile, pluginFile.exists());
+			
+		} 
+		
+
+		//cleanup target 
+		UpdateManagerUtils.removeFromFileSystem(target);
+
+
+	}	
+	
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestExecutableInstall.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestExecutableInstall.java
new file mode 100644
index 0000000..5f9dfe4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestExecutableInstall.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+
+import java.io.File;
+import java.util.Locale;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+
+public class TestExecutableInstall extends UpdateManagerTestCase {
+
+	/**
+	 * Constructor for Test1
+	 */
+	public TestExecutableInstall(String arg0) {
+		super(arg0);
+	}
+	
+
+
+	public void testFileSite() throws Exception{
+		
+		//cleanup target 
+		File target = new File(TARGET_FILE_SITE.getFile());
+		UpdateManagerUtils.removeFromFileSystem(target);		
+		InstallRegistry.cleanup();
+		
+		ISite remoteSite = SiteManager.getSite(SOURCE_FILE_SITE_INSTALLED,null);
+		IFeatureReference[] remoteFeatureReference = remoteSite.getFeatureReferences();
+		IFeature remoteFeature = remoteFeatureReference[0].getFeature(null);
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		assertNotNull(remoteFeature);
+		remove(remoteFeature,localSite);		
+		localSite.install(remoteFeature,null,null);
+		
+		// verify
+		String site = localSite.getURL().getFile();
+		IPluginEntry[] entries = remoteFeature.getRawPluginEntries();
+		assertTrue("no plugins entry",(entries!=null && entries.length!=0));
+		String pluginName= entries[0].getVersionedIdentifier().toString();
+		File pluginFile = new File(site,Site.DEFAULT_PLUGIN_PATH+pluginName);
+		if (Locale.getDefault().toString().indexOf("us") != -1)
+			assertTrue("plugin files not installed locally",pluginFile.exists());
+
+		File featureFile = new File(site,Site.DEFAULT_INSTALLED_FEATURE_PATH+remoteFeature.getVersionedIdentifier().toString());
+		assertTrue("feature info not installed locally:"+featureFile,featureFile.exists());
+		assertTrue("feature is a file, not a directory:"+featureFile,featureFile.isDirectory());
+
+		
+		File featureFileXML = new File(site,Site.DEFAULT_INSTALLED_FEATURE_PATH+remoteFeature.getVersionedIdentifier().toString()+File.separator+"feature.xml");
+		assertTrue("feature info not installed locally: no feature.xml",featureFileXML.exists());
+
+		//cleanup target 
+		UpdateManagerUtils.removeFromFileSystem(target);
+		
+	}
+
+}
+
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestExecutablePackagedInstall.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestExecutablePackagedInstall.java
new file mode 100644
index 0000000..5d22cfb
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestExecutablePackagedInstall.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+import java.util.Arrays;
+
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestExecutablePackagedInstall extends UpdateManagerTestCase {
+	/**
+	 * Constructor for Test1
+	 */
+	public TestExecutablePackagedInstall(String arg0) {
+		super(arg0);
+	}
+
+	/**
+	 * With site.xml
+	 */
+	public void testFilePackageExecutableFeatureSite() throws Exception {
+
+		//cleanup target  
+		File target = new File(TARGET_FILE_SITE.getFile());
+		UpdateManagerUtils.removeFromFileSystem(target);
+		
+		URL newURL = new File(dataPath + "ExecutableFeaturePackagedSite/data2/site.xml").toURL();
+		ISite remoteSite = SiteManager.getSite(newURL,null);
+		IFeatureReference[] featuresRef = remoteSite.getFeatureReferences();
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		IFeature remoteFeature = null;
+		
+		// at least one executable feature and on packaged
+		boolean execFeature = false;
+		boolean packFeature = false;
+
+		if (featuresRef.length==0) fail ("no feature found");
+	
+		for (int i = 0; i < featuresRef.length; i++) {
+			remoteFeature = featuresRef[i].getFeature(null);
+			remove(remoteFeature,localSite);			
+			localSite.install(remoteFeature, null,null);
+			
+			if (remoteFeature.getFeatureContentProvider() instanceof FeaturePackagedContentProvider) packFeature = true;
+			if (remoteFeature.getFeatureContentProvider() instanceof FeatureExecutableContentProvider) execFeature = true;
+
+			// verify
+			String site = localSite.getURL().getFile();
+			IPluginEntry[] entries = remoteFeature.getRawPluginEntries();
+			assertTrue("no plugins entry", (entries != null && entries.length != 0));
+			String pluginName = entries[0].getVersionedIdentifier().toString();
+			File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+			if (!pluginFile.exists()) {
+				//print out more failure details - see bug 271196
+				File[] existing = pluginFile.getParentFile().listFiles();
+				String detail = existing == null ? "no children" : String.valueOf(Arrays.asList(existing));
+				assertTrue("plugin files not installed locally:"+pluginFile + "children found: " + detail, pluginFile.exists());
+			}
+
+			File featureFile = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString());
+			assertTrue("feature info not installed locally:"+featureFile, featureFile.exists());
+
+			File featureFileXML = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString() + File.separator + "feature.xml");
+			assertTrue("feature info not installed locally: no feature.xml", featureFileXML.exists());
+		}
+
+		if (!execFeature && !packFeature){
+			fail("cannot find one executable and one package feature on teh site");
+		}
+
+		//cleanup target 
+		UpdateManagerUtils.removeFromFileSystem(target);
+
+
+	}
+	
+	
+	/**
+	 * Without site.xml
+	 */
+	public void testFileNoSiteXMLSite() throws Exception {
+
+		//cleanup target 
+		File target = new File(TARGET_FILE_SITE.getFile());
+		UpdateManagerUtils.removeFromFileSystem(target);
+		
+		URL newURL = new File(dataPath + "ExecutableFeaturePackagedSite/data/").toURL();
+		ISite remoteSite = SiteManager.getSite(newURL,null);
+		IFeatureReference[] featuresRef = remoteSite.getFeatureReferences();
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		IFeature remoteFeature = null;
+		
+		// at least one executable feature and on packaged
+		boolean execFeature = false;
+		boolean packFeature = false;
+
+		if (featuresRef.length==0) fail ("no feature found");
+	
+		for (int i = 0; i < featuresRef.length; i++) {
+			try {
+				remoteFeature = featuresRef[i].getFeature(null);
+			} catch (CoreException e){
+				Throwable e1 = e.getStatus().getException();
+				String msg = e1.getMessage().replace(File.separatorChar,'/');
+				if (msg.indexOf("CVS/feature.xml")==-1){
+					throw e;
+				}				
+			}
+			if (remoteFeature!=null){
+				remove(remoteFeature,localSite);
+				localSite.install(remoteFeature,null, null);
+				
+				if (remoteFeature.getFeatureContentProvider() instanceof FeaturePackagedContentProvider) packFeature = true;
+				if (remoteFeature.getFeatureContentProvider() instanceof FeatureExecutableContentProvider) execFeature = true;
+	
+				// verify
+				String site = localSite.getURL().getFile();
+				IPluginEntry[] entries = remoteFeature.getRawPluginEntries();
+				assertTrue("no plugins entry", (entries != null && entries.length != 0));
+				String pluginName = entries[0].getVersionedIdentifier().toString();
+				File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+				assertTrue("plugin files not installed locally:"+pluginFile, pluginFile.exists());
+	
+				File featureFile = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString());
+				assertTrue("feature info not installed locally:"+featureFile, featureFile.exists());
+	
+				File featureFileXML = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString() + File.separator + "feature.xml");
+				assertTrue("feature info not installed locally: no feature.xml", featureFileXML.exists());
+			}
+		}
+
+		if (!execFeature && !packFeature){
+			fail("cannot find one executable and one package feature on teh site");
+		}
+
+		//cleanup target 
+		UpdateManagerUtils.removeFromFileSystem(target);
+
+
+	}
+	
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestGetFeature.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestGetFeature.java
new file mode 100644
index 0000000..9f20914
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestGetFeature.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+
+public class TestGetFeature extends UpdateManagerTestCase {
+
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestGetFeature(String arg0) {
+		super(arg0);
+	}
+	
+	
+	public void testFeatureFileSite() throws Exception{
+		
+		ISite remoteSite = SiteManager.getSite(SOURCE_FILE_SITE,null);
+		IFeatureReference[] remoteFeatures = remoteSite.getFeatureReferences();
+		if (remoteFeatures==null || remoteFeatures.length==0) fail("No feature available for testing");
+		for (int i=0;i<remoteFeatures.length;i++){
+			System.out.println("feature:"+remoteFeatures[i].getURL().toExternalForm());
+		}
+	}
+
+
+	public void testFeatureHTTPSite() throws Exception{ 
+		
+		ISite remoteSite = SiteManager.getSite(SOURCE_HTTP_SITE,null);
+		IFeatureReference[] remoteFeatures = remoteSite.getFeatureReferences();
+		if (remoteFeatures==null || remoteFeatures.length==0) fail("No feature available for testing");		
+		for (int i=0;i<remoteFeatures.length;i++){
+			System.out.println("feature:"+remoteFeatures[i].getURL().toExternalForm());
+		}
+	}
+}
+
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestInstall.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestInstall.java
new file mode 100644
index 0000000..aa81f84
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestInstall.java
@@ -0,0 +1,329 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configuration.IConfiguredSiteChangedListener;
+import org.eclipse.update.configuration.ILocalSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.Site;
+import org.eclipse.update.core.SiteFeatureReference;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.internal.core.ConfiguredSite;
+import org.eclipse.update.internal.core.InstallConfiguration;
+import org.eclipse.update.internal.core.InstallRegistry;
+import org.eclipse.update.internal.core.LocalSite;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestInstall extends UpdateManagerTestCase {
+
+	/**
+	 * 
+	 */
+	public static final String PACKAGED_FEATURE_TYPE = "packaged"; //$NON-NLS-1$
+	
+	public Set filesToDelete = new HashSet();
+	
+
+	public class Listener implements IConfiguredSiteChangedListener {
+
+		public boolean notified = false;
+
+		public void featureInstalled(IFeature feature) {
+			notified = true;
+			System.out.println("Notified DefaultFeature Installed");
+		}
+
+		public void featureRemoved(IFeature feature) {
+		}
+
+		public void featureConfigured(IFeature feature) {
+		}
+		public void featureUnconfigured(IFeature feature) {
+		}
+
+		public boolean isNotified() {
+			return notified;
+		}
+	}
+
+	/**
+	 * Constructor for Test1
+	 */
+	public TestInstall(String arg0) {
+		super(arg0);
+	}
+
+	private IFeature getFeature1(ISite site)
+		throws MalformedURLException, CoreException {
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(site);
+		ref.setURLString("features/org.eclipse.update.core.tests.feature1_1.0.4.jar");
+		ref.setType(getDefaultInstallableFeatureType());
+		ref.resolve(site.getURL(), null);
+		return ref.getFeature(null);
+	}
+	
+
+
+	public void testFileSite() throws Exception {
+
+		ISite remoteSite = SiteManager.getSite(SOURCE_FILE_SITE,null);
+		IFeature remoteFeature = getFeature1(remoteSite);
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE, null);
+		filesToDelete.add(new File(localSite.getURL().getFile()));
+		localSite.install(remoteFeature, null, null);
+
+		// verify
+		String site = localSite.getURL().getFile();
+		IPluginEntry[] entries = remoteFeature.getPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+		String pluginName = entries[0].getVersionedIdentifier().toString();
+		File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		filesToDelete.add(pluginFile);
+		assertTrue("plugin files not installed locally:"+pluginFile, pluginFile.exists());
+		File pluginXMLFile =
+			new File(
+				site,
+				Site.DEFAULT_PLUGIN_PATH + pluginName + File.separator + "plugin.xml");
+		assertTrue("plugin.xml file not installed locally", pluginXMLFile.exists());
+
+		File featureFile =
+			new File(
+				site,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier().toString());
+		assertTrue(
+			"feature info not installed locally:" + featureFile,
+			featureFile.exists());
+
+	}
+
+	/**
+	 * 
+	 */
+	public void testHTTPSite() throws Exception {
+
+		ISite remoteSite = SiteManager.getSite(SOURCE_HTTP_SITE,null);
+		IFeatureReference[] features = remoteSite.getFeatureReferences();
+		IFeature remoteFeature = null;
+
+		if (features == null || features.length == 0)
+			fail("No features on the site");
+
+		for (int i = 0; i < features.length; i++) {
+			if (features[i].getURL().toExternalForm().endsWith("features2.jar")) {
+				remoteFeature = features[i].getFeature(null);
+				break;
+			}
+		}
+
+		assertNotNull("Cannot find feature2.jar on site", remoteFeature);
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE, null);
+		filesToDelete.add(new File(localSite.getURL().getFile()));
+		localSite.install(remoteFeature, null, null);
+
+		// feature2.jar should not be in the local site
+		IFeatureReference[] localFeatures = localSite.getFeatureReferences();
+		if (localFeatures == null || localFeatures.length == 0)
+			fail("No features on the target site");
+
+		boolean found = false;
+		for (int i = 0; i < localFeatures.length; i++) {
+			if (localFeatures[i].getURL().toExternalForm().endsWith("features2.jar")) {
+				found = true;
+				break;
+			}
+		}
+
+		assertTrue(
+			"Found feature2.jar on target site. Target site feature ref shouldnot contain JAR file",
+			!found);
+
+		// check
+		String site = localSite.getURL().getFile();
+		IPluginEntry[] entries = remoteFeature.getPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+
+		String pluginName = entries[0].getVersionedIdentifier().toString();
+		File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		filesToDelete.add(pluginFile);
+		assertTrue("plugin info not installed locally:"+pluginFile, pluginFile.exists());
+
+		File featureFile =
+			new File(
+				site,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier().toString());
+		assertTrue("feature info not installed locally", featureFile.exists());
+		
+	}
+
+	public void testInstall() throws Exception {
+
+		// cleanup local files...
+		File localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);
+
+		URL INSTALL_SITE = null;
+		try {
+			INSTALL_SITE =
+				new URL("http", getHttpHost(), getHttpPort(), bundle.getString("HTTP_PATH_2"));
+		} catch (Exception e) {
+			fail(e.toString());
+			e.printStackTrace();
+		}
+		
+		ISite remoteSite = SiteManager.getSite(INSTALL_SITE,null);
+		IFeatureReference[] features = remoteSite.getFeatureReferences();
+		IFeature remoteFeature = null;
+
+		if (features == null || features.length == 0)
+			fail("No features on the site");
+
+		for (int i = 0; i < features.length; i++) {
+			if (features[i].getURL().toExternalForm().endsWith("helpFeature.jar")) {
+				remoteFeature = features[i].getFeature(null);
+				break;
+			}
+		}
+
+		assertNotNull("Cannot find help.jar on site", remoteFeature);
+		ILocalSite localSite = SiteManager.getLocalSite();
+		IConfiguredSite site =
+			localSite.getCurrentConfiguration().getConfiguredSites()[0];
+		Listener listener = new Listener();
+		site.addConfiguredSiteChangedListener(listener);
+
+		((ConfiguredSite)site).setUpdatable(true);
+		
+		// list of files to be cleaned at the end
+		File file = new File( site.getSite().getURL().getFile() +
+							  File.separator + 
+							  Site.DEFAULT_INSTALLED_FEATURE_PATH + 
+							  remoteFeature.getVersionedIdentifier());
+		filesToDelete.add(file);
+		filesToDelete.add(localFile);
+		filesToDelete.add( new File(((InstallConfiguration) localSite.getCurrentConfiguration()).getURL().getFile()));
+		
+		site.install(remoteFeature, null, null);
+
+		IPluginEntry[] entries = remoteFeature.getRawPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+
+		String sitePath = site.getSite().getURL().getFile();
+		String pluginName = entries[0].getVersionedIdentifier().toString();
+		File pluginFile = new File(sitePath, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		filesToDelete.add(pluginFile);
+		if (Locale.getDefault().toString().indexOf("fr") != -1) {
+			assertTrue("plugin info not installed locally", pluginFile.exists());			
+		}
+
+		File featureFile =
+			new File(
+				sitePath,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier().toString());
+		assertTrue("feature info not installed locally", featureFile.exists());
+		
+
+		
+
+		site.removeConfiguredSiteChangedListener(listener);
+		
+		assertTrue("Listener hasn't received notification", listener.isNotified());
+	}
+
+	public void testFileSiteWithoutSiteXML() throws Exception {
+
+		ISite remoteSite = SiteManager.getSite(SOURCE_FILE_SITE,null);
+		IFeature remoteFeature = getFeature1(remoteSite);
+		
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		localSite.install(remoteFeature, null, null);
+		
+		IFeatureReference[] features = localSite.getRawFeatureReferences();
+		int numberOfInstalledFeatures = features.length;
+
+		File file =
+			new File(
+				localSite.getURL().getFile()
+					+ File.separator
+					+ Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier());
+		filesToDelete.add(file);
+		file =
+			new File(
+				localSite.getURL().getFile()
+					+ File.separator
+					+ Site.DEFAULT_PLUGIN_PATH
+					+ "org.eclipse.update.core.tests.feature1.plugin1_3.5.6");
+		filesToDelete.add(file);
+		file =
+			new File(
+				localSite.getURL().getFile()
+					+ File.separator
+					+ Site.DEFAULT_PLUGIN_PATH
+					+ "org.eclipse.update.core.tests.feature1.plugin2_5.0.0");
+		filesToDelete.add(file);
+		file = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		filesToDelete.add(file);
+
+		
+		if (numberOfInstalledFeatures == 0)
+			fail("The local site does not contain feature, should not contain an XML file but features should be found anyway by parsing");
+		if (localSite/*.getSite()*/.getArchives().length == 0)
+			fail("The local site does not contain archives, should not contain an XML file but archives should be found anyway by parsing");
+		
+		try {
+			SiteManager.getSite(new URL("http://www.eclipse.org/"),null);
+			fail("The site contains site.xml... it should be an HTTP site without an XML file");			
+		} catch (CoreException e) {
+			// expected
+		}
+
+	}
+
+	/*
+	 * @see ISite#getDefaultInstallableFeatureType()
+	 */
+	public String getDefaultInstallableFeatureType() {
+		String pluginID =
+			UpdateCore.getPlugin().getBundle().getSymbolicName() + ".";
+		return pluginID + PACKAGED_FEATURE_TYPE;
+	}
+	
+	protected void umTearDown() throws Exception {
+		Iterator files = filesToDelete.iterator();		
+		while(files.hasNext()) {
+			File file = (File)files.next();
+			UpdateManagerUtils.removeFromFileSystem(file);			
+		}
+		filesToDelete.clear();
+		
+		InstallRegistry.cleanup();
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestInstallURLSIteXML.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestInstallURLSIteXML.java
new file mode 100644
index 0000000..0eeca0e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestInstallURLSIteXML.java
@@ -0,0 +1,332 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+import java.io.*;
+import java.net.*;
+import java.util.Locale;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.*;
+
+public class TestInstallURLSIteXML extends UpdateManagerTestCase {
+
+	/**
+	 * 
+	 */
+	public static final String PACKAGED_FEATURE_TYPE = "packaged"; //$NON-NLS-1$	
+
+	public class Listener implements IConfiguredSiteChangedListener {
+
+		public boolean notified = false;
+
+		public void featureInstalled(IFeature feature) {
+			notified = true;
+			System.out.println("Notified DefaultFeature Installed");
+		}
+
+		public void featureRemoved(IFeature feature) {
+		}
+
+		public void featureConfigured(IFeature feature) {
+		}
+		public void featureUnconfigured(IFeature feature) {
+		}
+
+		public boolean isNotified() {
+			return notified;
+		}
+	}
+
+	/**
+	 * Constructor for Test1
+	 */
+	public TestInstallURLSIteXML(String arg0) {
+		super(arg0);
+	}
+
+	private IFeature getFeature1(ISite site)
+		throws MalformedURLException, CoreException {
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(site);
+		ref.setURLString("features/org.eclipse.update.core.tests.feature1_1.0.4.jar");
+		ref.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+		ref.resolve(site.getURL(), null);
+		return ref.getFeature(null);
+	}
+
+	public void testFileSite() throws Exception {
+
+		ISite remoteSite =
+			SiteManager.getSite(new URL(SOURCE_FILE_SITE, Site.SITE_XML),true,null);
+		IFeature remoteFeature = getFeature1(remoteSite);
+		URL url = TARGET_FILE_SITE;
+		File file = new File(TARGET_FILE_SITE.getFile());
+		if (!file.exists()) file.mkdirs();
+		ISite localSite = SiteManager.getSite(url,true,null);
+		remove(remoteFeature,localSite);
+		localSite.install(remoteFeature, null, null);
+
+		// verify
+		String site = TARGET_FILE_SITE.getFile();
+		IPluginEntry[] entries = remoteFeature.getPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+		String pluginName = entries[0].getVersionedIdentifier().toString();
+		File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		assertTrue("plugin files not installed locally", pluginFile.exists());
+		File pluginXMLFile =
+			new File(
+				site,
+				Site.DEFAULT_PLUGIN_PATH + pluginName + File.separator + "plugin.xml");
+		assertTrue("plugin.xml file not installed locally", pluginXMLFile.exists());
+
+		File featureFile =
+			new File(
+				site,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier().toString());
+		assertTrue(
+			"feature info not installed locally:" + featureFile,
+			featureFile.exists());
+		//cleanup
+		UpdateManagerUtils.removeFromFileSystem(pluginFile);
+		UpdateManagerUtils.removeFromFileSystem(new File(localSite.getURL().getFile()));
+		InstallRegistry.cleanup();
+	}
+
+	/**
+	 * 
+	 */
+	public void testHTTPSite() throws Exception {
+
+		// clean
+		File targetFile  = new File(TARGET_FILE_SITE.getFile());
+		UpdateManagerUtils.removeFromFileSystem(targetFile);
+		InstallRegistry.cleanup();
+
+		ISite remoteSite =
+			SiteManager.getSite(new URL(SOURCE_HTTP_SITE, Site.SITE_XML),true,null);
+		IFeatureReference[] features = remoteSite.getFeatureReferences();
+		IFeature remoteFeature = null;
+
+		if (features == null || features.length == 0)
+			fail("No features on the site");
+
+		for (int i = 0; i < features.length; i++) {
+			if (features[i].getURL().toExternalForm().endsWith("features2.jar")) {
+				remoteFeature = features[i].getFeature(null);
+				break;
+			}
+		}
+
+		assertNotNull("Cannot find feature2.jar on site", remoteFeature);
+		URL url = TARGET_FILE_SITE;
+		File file = new File(TARGET_FILE_SITE.getFile());
+		if (!file.exists()) file.mkdirs();
+		ISite localSite = SiteManager.getSite(url,true,null);
+		localSite.install(remoteFeature, null, null);
+
+		// feature2.jar should not be in the local site
+		IFeatureReference[] localFeatures = localSite.getFeatureReferences();
+		if (localFeatures == null || localFeatures.length == 0)
+			fail("No features on the target site");
+
+		boolean found = false;
+		for (int i = 0; i < localFeatures.length; i++) {
+			if (localFeatures[i].getURL().toExternalForm().endsWith("features2.jar")) {
+				found = true;
+				break;
+			}
+		}
+
+		assertTrue(
+			"Found feature2.jar on target site. Target site feature ref shouldnot contain JAR file",
+			!found);
+
+		// check
+		String site = TARGET_FILE_SITE.getFile();
+		IPluginEntry[] entries = remoteFeature.getPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+
+		String pluginName = entries[0].getVersionedIdentifier().toString();
+		File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		assertTrue("plugin info not installed locally", pluginFile.exists());
+
+		File featureFile =
+			new File(
+				site,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier().toString());
+		assertTrue("feature info not installed locally", featureFile.exists());
+
+		//localSite.save();
+
+		//cleanup
+		UpdateManagerUtils.removeFromFileSystem(pluginFile);
+		UpdateManagerUtils.removeFromFileSystem(new File(localSite.getURL().getFile()));
+		InstallRegistry.cleanup();
+	}
+
+	public void testInstall() throws Exception {
+
+		// cleanup local files...
+		LocalSite siteLocal = ((LocalSite) SiteManager.getLocalSite());
+		File localFile = new File(siteLocal.getLocationURL().getFile());
+		//if (!localFile.exists()) fail("LocalSite file doesn't exist ->"+localFile.getAbsolutePath()+"<-");
+		UpdateManagerUtils.removeFromFileSystem(localFile);		
+		/*
+		localFile = new File(localFile,LocalSite.SITE_LOCAL_FILE);
+		if (!localFile.exists()) fail("LocalSite.xml doesn't exist:"+localFile);
+		UpdateManagerUtils.removeFromFileSystem(localFile);
+		*/
+		
+		InternalSiteManager.localSite = null;
+
+		URL INSTALL_SITE = null;
+		try {
+			INSTALL_SITE =
+				new URL("http", getHttpHost(), getHttpPort(), bundle.getString("HTTP_PATH_2"));
+		} catch (Exception e) {
+			fail(e.toString());
+			e.printStackTrace();
+		}
+
+		ISite remoteSite = SiteManager.getSite(INSTALL_SITE,true,null);
+		IFeatureReference[] features = remoteSite.getFeatureReferences();
+		IFeature remoteFeature = null;
+
+		if (features == null || features.length == 0)
+			fail("No features on the site");
+
+		for (int i = 0; i < features.length; i++) {
+			if (features[i].getURL().toExternalForm().endsWith("helpFeature.jar")) {
+				remoteFeature = features[i].getFeature(null);
+				break;
+			}
+		}
+
+		assertNotNull("Cannot find help.jar on site", remoteFeature);
+		ILocalSite localSite = SiteManager.getLocalSite();
+		IConfiguredSite site = localSite.getCurrentConfiguration().getConfiguredSites()[0];
+		Listener listener = new Listener();
+		site.addConfiguredSiteChangedListener(listener);
+
+		((ConfiguredSite)site).setUpdatable(true);
+		site.install(remoteFeature, null, null);
+
+		IPluginEntry[] entries = remoteFeature.getRawPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+
+		String sitePath = site.getSite().getURL().getFile();
+		String pluginName = entries[0].getVersionedIdentifier().toString();
+		File pluginFile = new File(sitePath, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		if (Locale.getDefault().toString().indexOf("fr") != -1)
+			assertTrue("plugin info not installed locally:"+pluginFile, pluginFile.exists());
+
+		File featureFile =
+			new File(
+				sitePath,
+				Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier().toString());
+		if (Locale.getDefault().toString().indexOf("fr") != -1 ||
+				Locale.getDefault().toString().indexOf("us") != -1 ||
+				Locale.getDefault().toString().indexOf("de") != -1)
+		assertTrue("feature info not installed locally", featureFile.exists());
+
+		//cleanup
+		File file =
+			new File(
+				site.getSite().getURL().getFile()
+					+ File.separator
+					+ Site.DEFAULT_INSTALLED_FEATURE_PATH
+					+ remoteFeature.getVersionedIdentifier());
+		UpdateManagerUtils.removeFromFileSystem(file);
+		UpdateManagerUtils.removeFromFileSystem(pluginFile);
+		UpdateManagerUtils.removeFromFileSystem(localFile);
+		UpdateManagerUtils.removeFromFileSystem(
+			new File(
+				((InstallConfiguration) localSite.getCurrentConfiguration())
+					.getURL()
+					.getFile()));
+		InstallRegistry.cleanup();
+		
+		site.removeConfiguredSiteChangedListener(listener);
+		assertTrue("Listener hasn't received notification", listener.isNotified());
+	}
+
+//	public void testFileSiteWithoutSiteXML() throws Exception {
+//
+//		ISite remoteSite =
+//			SiteManager.getSite(new URL(SOURCE_FILE_SITE, Site.SITE_XML),true,null);
+//		IFeature remoteFeature = getFeature1(remoteSite);
+//		IConfiguredSite localSite =
+//			SiteManager.getLocalSite().getCurrentConfiguration().getConfiguredSites()[0];
+//		localSite.getSite().install(remoteFeature, null, null);
+//
+//		IFeatureReference[] features = localSite.getSite().getFeatureReferences();
+//		if (features.length == 0)
+//			fail("The local site does not contain feature, should not contain an XML file but features should be found anyway by parsing");
+//		if (localSite.getSite().getArchives().length == 0)
+//			fail("The local site does not contain archives, should not contain an XML file but archives should be found anyway by parsing");
+//
+//		//cleanup
+//		File file =
+//			new File(
+//				localSite.getSite().getURL().getFile()
+//					+ File.separator
+//					+ Site.DEFAULT_INSTALLED_FEATURE_PATH
+//					+ remoteFeature.getVersionedIdentifier());
+//		UpdateManagerUtils.removeFromFileSystem(file);
+//		file =
+//			new File(
+//				localSite.getSite().getURL().getFile()
+//					+ File.separator
+//					+ Site.DEFAULT_PLUGIN_PATH
+//					+ "org.eclipse.update.core.tests.feature1.plugin1_3.5.6");
+//		UpdateManagerUtils.removeFromFileSystem(file);
+//		file =
+//			new File(
+//				localSite.getSite().getURL().getFile()
+//					+ File.separator
+//					+ Site.DEFAULT_PLUGIN_PATH
+//					+ "org.eclipse.update.core.tests.feature1.plugin2_5.0.0");
+//		UpdateManagerUtils.removeFromFileSystem(file);
+//		File localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+//		UpdateManagerUtils.removeFromFileSystem(localFile);
+//
+//	}
+
+	/**
+	* 
+	*/
+//	private Feature createPackagedFeature(URL url, ISite site)
+//		throws CoreException {
+//		String packagedFeatureType = ISite.DEFAULT_PACKAGED_FEATURE_TYPE;
+//		Feature result = null;
+//		if (packagedFeatureType != null) {
+//			IFeatureFactory factory =
+//				FeatureTypeFactory.getInstance().getFactory(packagedFeatureType);
+//			result = (Feature) factory.createFeature(url, site);
+//		}
+//		return result;
+//	}
+	/*
+	 * @see ISite#getDefaultInstallableFeatureType()
+	 */
+	public String getDefaultInstallableFeatureType() {
+		String pluginID =
+			UpdateCore.getPlugin().getDescriptor().getUniqueIdentifier() + ".";
+		return pluginID + PACKAGED_FEATURE_TYPE;
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestLocalSite.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestLocalSite.java
new file mode 100644
index 0000000..47b0411
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestLocalSite.java
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+import java.io.*;
+import java.net.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.model.*;
+import org.eclipse.update.tests.*;
+
+public class TestLocalSite extends UpdateManagerTestCase {
+	
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestLocalSite(String arg0) {
+		super(arg0);
+	}
+	
+	public void testCreationConfigFile() throws Exception {
+
+		//clean up
+		File localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);	
+		InternalSiteManager.localSite=null;	
+
+
+		ILocalSite site = SiteManager.getLocalSite();
+		site.save();
+		assertTrue("config file hasn't been saved in :"+localFile.getAbsolutePath(), localFile.exists());
+		
+		// cleanup
+		UpdateManagerUtils.removeFromFileSystem(localFile);		
+		
+
+	}
+	
+	public void testDefaultConfigFile() throws Exception {
+
+		//clean up
+
+		File localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);	
+		InternalSiteManager.localSite=null;
+
+		ILocalSite site = SiteManager.getLocalSite();
+		assertTrue("The local site does not contain an history of install configuration",site.getConfigurationHistory().length!=0);
+		assertTrue("The local site does not contain an current install configuration",site.getCurrentConfiguration()!=null);
+		assertTrue("The local site does not contain a default configuration site for the current install config",site.getCurrentConfiguration().getConfiguredSites().length!=0);
+		
+		System.out.println("Default Config Site is :"+site.getCurrentConfiguration().getConfiguredSites()[0].getSite().getURL().toExternalForm());
+		
+		// cleanup	
+		UpdateManagerUtils.removeFromFileSystem(localFile);		
+		
+
+	}
+	
+/*	public void testInstallFeatureSaveConfig() throws Exception {
+
+		//clean up
+		LocalSite siteLocal = (LocalSite)SiteManager.getLocalSite();
+		URL newURL = new URL(siteLocal.getLocationURL(),LocalSite.SITE_LOCAL_FILE);
+		File localFile = new File(newURL.getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);
+		UpdateManagerUtils.removeFromFileSystem(new File(((InstallConfiguration)siteLocal.getCurrentConfiguration()).getURL().getFile()));	
+		InternalSiteManager.localSite=null;		
+
+		ILocalSite site = SiteManager.getLocalSite();
+		ISite remoteSite = SiteManager.getSite(SOURCE_FILE_SITE_INSTALLED);
+		IFeature feature = remoteSite.getFeatureReferences()[0].getFeature();
+		int oldNumber = site.getCurrentConfiguration().getConfiguredSites().length;
+		
+		// we are not checking if this is read only
+		IInstallConfiguration newConfig = site.cloneCurrentConfiguration();
+		newConfig.setLabel("new Label");		
+		//IInstallConfiguration newConfig = site.getCurrentConfiguration();
+		IConfiguredSite configSite = newConfig.getConfiguredSites()[0];
+		ConfigurationPolicyModel configPolicy = new BaseSiteLocalFactory().createConfigurationPolicyModel();
+		configPolicy.setPolicy(IPlatformConfiguration.ISitePolicy.USER_INCLUDE);
+		((ConfiguredSite)configSite).setConfigurationPolicy((ConfigurationPolicy)configPolicy);
+		int oldNumberOfhistory = site.getConfigurationHistory().length;		
+		site.addConfiguration(newConfig);	
+		assertNotNull(feature);	
+
+		((ConfiguredSite)configSite).isUpdatable(true);
+		remove(feature,configSite);				
+		configSite.install(feature,null,null);
+				
+		// teh current one points to a real fature
+		// does not throw error.
+		IConfiguredSite configSite2 = site.getCurrentConfiguration().getConfiguredSites()[0];
+		assertTrue("No Configured features found",configSite.getConfiguredFeatures().length>0);
+		IFeatureReference ref = configSite2.getConfiguredFeatures()[0];
+		IFeature feature2 = ref.getFeature();
+		//String configuredFeature = feature2.getLabel();
+
+		assertEquals(feature2.getVersionedIdentifier().toString(),"org.eclipse.update.core.tests.feature3_1.0.0");
+		assertTrue("Wrong id  version of feature",feature2.getVersionedIdentifier().toString().equalsIgnoreCase("org.eclipse.update.core.tests.feature3_1.0.0"));
+		
+		// only one feature configured
+		assertTrue("too many features configured",configSite2.getConfiguredFeatures().length==1);
+		
+		// no feature unconfigured
+		assertTrue("too many unconfigured features",((ConfiguredSite)configSite2).getConfigurationPolicy().getUnconfiguredFeatures().length==0);
+		
+		// test only 2 install config in local site
+		//assertEquals("wrong number of history in Local site:",oldNumberOfhistory+1,site.getConfigurationHistory().length);
+		
+		// test same # of sites in current config
+		assertTrue("Wrong number of config sites in current config",site.getCurrentConfiguration().getConfiguredSites().length==oldNumber);
+		
+		//test only one feature for the site
+		assertTrue("wrong number of configured features for config site",site.getCurrentConfiguration().getConfiguredSites()[0].getConfiguredFeatures().length==1);
+		
+		// test only 2 activities
+		assertTrue("Wrong number of activities for install config",site.getCurrentConfiguration().getActivities().length==2);
+
+		site.save();		
+
+		// check
+		// there are 2 configuration
+		String time = ""+site.getCurrentConfiguration().getCreationDate().getTime();
+		URL location = ((LocalSite)site).getLocationURL();
+		File file = new File(new URL(location,"Config"+time+".xml").getFile());
+		assertTrue("new configuration does not exist", file.exists());
+		
+		// cleanup
+		localFile = new File(new URL(location,LocalSite.SITE_LOCAL_FILE).getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);		
+		localFile = new File(new URL(location,LocalSite.DEFAULT_CONFIG_FILE).getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);	
+		localFile = new File(new URL(location,Site.DEFAULT_FEATURE_PATH+File.separator+feature.getVersionedIdentifier().toString()).getFile());		
+		UpdateManagerUtils.removeFromFileSystem(localFile);	
+		localFile = new File(new URL(location,Site.DEFAULT_FEATURE_PATH+File.separator+feature2.getVersionedIdentifier().toString()).getFile());		
+		UpdateManagerUtils.removeFromFileSystem(localFile);	
+		UpdateManagerUtils.removeFromFileSystem(file);		
+		localFile = new File(feature2.getURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);
+	}
+*/
+	
+	public void testRetriveConfig() throws Exception {
+
+		//clean up
+		File localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);	
+		InternalSiteManager.localSite=null;		
+
+		ILocalSite site = SiteManager.getLocalSite();
+		ISite remoteSite = SiteManager.getSite(SOURCE_FILE_SITE_INSTALLED,null);
+		IFeature feature = remoteSite.getFeatureReferences()[0].getFeature(null);
+		int oldNumber = site.getCurrentConfiguration().getConfiguredSites().length;		
+		
+		// we are not checking if this is read only
+		IInstallConfiguration newConfig = site.cloneCurrentConfiguration();
+		newConfig.setLabel("new Label");		
+		IConfiguredSite configSite = newConfig.getConfiguredSites()[0];
+		ConfigurationPolicyModel configPolicy = new BaseSiteLocalFactory().createConfigurationPolicyModel();
+		configPolicy.setPolicy(IPlatformConfiguration.ISitePolicy.USER_INCLUDE);
+		((ConfiguredSite)configSite).setConfigurationPolicyModel(configPolicy);	
+		site.addConfiguration(newConfig);
+		assertNotNull(feature);			
+		
+		((ConfiguredSite)configSite).setUpdatable(true);
+		remove(feature,configSite);			
+		configSite.install(feature,null,null);
+		site.save();
+		
+		// we created the second xml file
+
+		//do not cleanup, we want to reuse previously created local site
+		// but force re-read of xml File
+		InternalSiteManager.localSite=null;
+		site = SiteManager.getLocalSite();
+		
+		// check
+		// there are 2 configuration
+		URL location = ((LocalSite)site).getLocationURL();		
+		File file = new File(new URL(location,"platform.xml").getFile());
+		assertTrue("new configuration does not exist", file.exists());
+		
+		// teh current one points to a real fature
+		// does not throw error.
+		IConfiguredSite configSite2 = site.getCurrentConfiguration().getConfiguredSites()[0];
+		IFeatureReference[] refs = configSite2.getConfiguredFeatures();
+		IFeature feature2 = null;
+		for (int i = 0; i < refs.length; i++) {
+			IFeature feature3 = refs[i].getFeature(null);			
+			if ("org.eclipse.update.core.tests.feature3_1.0.0".equals(feature3.getVersionedIdentifier().toString())){
+				feature2 = feature3;
+				break;
+			}		
+		}
+		assertNotNull("Feature 2 is Null",feature2);
+		assertTrue("Wrong id  version of feature",feature2.getVersionedIdentifier().toString().equalsIgnoreCase("org.eclipse.update.core.tests.feature3_1.0.0"));
+		
+		// test only 2 install config in local site
+//		assertEquals("wrong number of history in Local site:",oldNumberOfhistory+1,site.getConfigurationHistory().length);
+		
+		// test # of sites in current config
+		assertTrue("Wrong number of config sites in current config",site.getCurrentConfiguration().getConfiguredSites().length==oldNumber);
+		
+		//test only one feature for the site
+//		assertTrue("wrong number of configured features for config site",site.getCurrentConfiguration().getConfiguredSites()[0].getConfiguredFeatures().length==1);
+		
+		// test only 2 activities
+//		assertTrue("Wrong number of activities for install config",site.getCurrentConfiguration().getActivities().length==2);
+		
+		
+		// cleanup
+		localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);		
+		localFile = new File(new URL(location,Site.DEFAULT_FEATURE_PATH+File.separator+feature.getVersionedIdentifier().toString()).getFile());		
+		UpdateManagerUtils.removeFromFileSystem(localFile);					
+		UpdateManagerUtils.removeFromFileSystem(file);		
+	}
+
+/*	public void testRetriveConfigHTTPInstall() throws Exception {
+
+		//clean up
+		File localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);
+		InternalSiteManager.localSite=null;		
+
+		ILocalSite site = SiteManager.getLocalSite();
+		ISite remoteSite = SiteManager.getSite(SOURCE_HTTP_SITE,null);
+		IFeature feature = remoteSite.getFeatureReferences()[0].getFeature(null);
+		
+		// we are not checking if this is read only
+		IInstallConfiguration newConfig = site.cloneCurrentConfiguration();
+		newConfig.setLabel("new Label");		
+		IConfiguredSite configSite = newConfig.getConfiguredSites()[0];
+		ConfigurationPolicyModel configPolicy = new BaseSiteLocalFactory().createConfigurationPolicyModel();
+		configPolicy.setPolicy(IPlatformConfiguration.ISitePolicy.USER_INCLUDE);
+		((ConfiguredSite)configSite).setConfigurationPolicyModel((ConfigurationPolicyModel)configPolicy);	
+		int oldNumberOfhistory = site.getConfigurationHistory().length;			
+		site.addConfiguration(newConfig);
+		
+	
+		((ConfiguredSite)configSite).setUpdatable(true);				
+		configSite.install(feature,null,null);
+		site.save();
+
+		//do not cleanup, we want to reuse previously created local site
+		// but force re-read of xml File
+		InternalSiteManager.localSite=null;
+		site = SiteManager.getLocalSite();
+		feature = remoteSite.getFeatureReferences()[0].getFeature(null);
+		int oldNumber = site.getCurrentConfiguration().getConfiguredSites().length;		
+		
+		// check
+		// there are 2 configuration
+		String time = ""+site.getCurrentConfiguration().getCreationDate().getTime();
+		URL location = ((LocalSite)site).getLocationURL();		
+		File file = new File(new URL(location,"platform.xml").getFile());
+		assertTrue("new configuration does not exist", file.exists());
+		
+		// teh current one points to a real fature
+		// does not throw error.
+		IConfiguredSite configSite2 = site.getCurrentConfiguration().getConfiguredSites()[0];
+		
+		IFeatureReference[] refs = configSite2.getConfiguredFeatures();
+		boolean found = false;
+		IFeature feature2 = null;
+		for (int i = 0; !found && i < refs.length; i++) {
+			IFeature feature3 = refs[i].getFeature(null);			
+			if ("org.test1.ident1_1.0.0".equals(feature3.getVersionedIdentifier().toString())){
+				feature2 = feature3;
+				found = true;
+			}		
+		}
+
+		//String configuredFeature = feature2.getLabel();
+		assertTrue("cannot find feature org.test1.ident1_1.0.0 in configured Site",found);
+		assertTrue("Wrong id  version of feature",feature2.getVersionedIdentifier().toString().equalsIgnoreCase("org.test1.ident1_1.0.0"));
+		
+		// test only 2 install config in local site
+//		assertEquals("wrong number of history in Local site:",oldNumberOfhistory+1,site.getConfigurationHistory().length);
+		
+		// test same number of sites in current config
+		assertTrue("Wrong number of config sites in current config",site.getCurrentConfiguration().getConfiguredSites().length==oldNumber);
+		
+		//test only one feature for the site
+//		assertTrue("wrong number of configured features for config site",site.getCurrentConfiguration().getConfiguredSites()[0].getConfiguredFeatures().length==1);
+		
+		// test only 2 activities
+//		assertTrue("Wrong number of activities for install config",site.getCurrentConfiguration().getActivities().length==2);
+		
+		
+		// cleanup
+		localFile = new File(location.getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);		
+		localFile = new File(new URL(location,Site.DEFAULT_FEATURE_PATH+File.separator+feature.getVersionedIdentifier().toString()).getFile());		
+		UpdateManagerUtils.removeFromFileSystem(localFile);							
+		UpdateManagerUtils.removeFromFileSystem(file);		
+		localFile = new File(feature2.getURL().getFile());
+		UpdateManagerUtils.removeFromFileSystem(localFile);
+	}*/
+	
+//TODO uncomment this once site disabling is supported
+public void testRetriveConfigHTTPInstallNotEnable() throws Exception {
+/*
+	//clean up
+	LocalSite siteLocal = (LocalSite)SiteManager.getLocalSite();
+	URL newURL = new URL(siteLocal.getLocationURL(),LocalSite.SITE_LOCAL_FILE);
+	File localFile = new File(newURL.getFile());
+	UpdateManagerUtils.removeFromFileSystem(localFile);
+	UpdateManagerUtils.removeFromFileSystem(new File(((InstallConfiguration)siteLocal.getCurrentConfiguration()).getURL().getFile()));	
+	InternalSiteManager.localSite=null;		
+
+	ILocalSite site = SiteManager.getLocalSite();
+	ISite remoteSite = SiteManager.getSite(SOURCE_HTTP_SITE);
+	IFeature feature = remoteSite.getFeatureReferences()[0].getFeature(null);
+		
+	// we are not checking if this is read only
+	IInstallConfiguration newConfig = site.cloneCurrentConfiguration();
+	newConfig.setLabel("new Label");		
+	IConfiguredSite configSite = newConfig.getConfiguredSites()[0];
+	ConfigurationPolicyModel configPolicy = new BaseSiteLocalFactory().createConfigurationPolicyModel();
+	configPolicy.setPolicy(IPlatformConfiguration.ISitePolicy.USER_INCLUDE);
+	((ConfiguredSite)configSite).setConfigurationPolicyModel((ConfigurationPolicyModel)configPolicy);	
+	int oldNumberOfhistory = site.getConfigurationHistory().length;			
+	site.addConfiguration(newConfig);
+		
+	
+	((ConfiguredSite)configSite).setUpdatable(true);
+	configSite.install(feature,null,null);
+	((ConfiguredSite)configSite).setEnabled(false);	
+	site.save();
+
+	//do not cleanup, we want to reuse previously created local site
+	// but force re-read of xml File
+	InternalSiteManager.localSite=null;
+	site = SiteManager.getLocalSite();
+	feature = remoteSite.getFeatureReferences()[0].getFeature(null);
+	int oldNumber = site.getCurrentConfiguration().getConfiguredSites().length;		
+		
+	// check
+	// there are 2 configuration
+	String time = ""+site.getCurrentConfiguration().getCreationDate().getTime();
+	URL location = ((LocalSite)site).getLocationURL();		
+	File file = new File(location.getFile());
+	assertTrue("new configuration does not exist", file.exists());
+		
+	// teh current one points to a real fature
+	// does not throw error.
+	IConfiguredSite configSite2 = site.getCurrentConfiguration().getConfiguredSites()[0];
+		
+	IFeatureReference[] refs = configSite2.getConfiguredFeatures();
+	boolean found = false;
+	IFeature feature2 = null;
+	for (int i = 0; !found && i < refs.length; i++) {
+		IFeature feature3 = refs[i].getFeature(null);			
+		if ("org.test1.ident1_1.0.0".equals(feature3.getVersionedIdentifier().toString())){
+			feature2 = feature3;
+			found = true;
+		}		
+	}
+
+	//String configuredFeature = feature2.getLabel();
+	assertTrue("found feature org.test1.ident1_1.0.0 in disabled configured Site",!found);
+		
+	//test no configured features
+//	assertTrue("wrong number of configured features for config site",site.getCurrentConfiguration().getConfiguredSites()[0].getConfiguredFeatures().length==0);
+	
+	
+	configSite2.setEnabled(true);
+	refs = configSite2.getConfiguredFeatures();	
+	for (int i = 0; i < refs.length; i++) {
+		IFeature feature3 = refs[i].getFeature(null);			
+		if ("org.test1.ident1_1.0.0".equals(feature3.getVersionedIdentifier().toString())){
+			feature2 = feature3;
+			found = true;
+		}		
+	}
+
+	//String configuredFeature = feature2.getLabel();
+	assertTrue("cannot find feature org.test1.ident1_1.0.0 in configured Site",found);
+	assertTrue("Wrong id  version of feature",feature2.getVersionedIdentifier().toString().equalsIgnoreCase("org.test1.ident1_1.0.0"));
+		
+	// test only 2 install config in local site
+//	assertEquals("wrong number of history in Local site:",oldNumberOfhistory+1,site.getConfigurationHistory().length);
+		
+	// test same number of sites in current config
+//	assertTrue("Wrong number of config sites in current config",site.getCurrentConfiguration().getConfiguredSites().length==oldNumber);
+		
+	//test only one feature for the site
+//	assertTrue("wrong number of configured features for config site",site.getCurrentConfiguration().getConfiguredSites()[0].getConfiguredFeatures().length==1);
+		
+	// test only 2 activities
+//	assertTrue("Wrong number of activities for install config",site.getCurrentConfiguration().getActivities().length==2);
+		
+		
+	// cleanup
+	localFile = new File(new URL(location,LocalSite.SITE_LOCAL_FILE).getFile());
+	UpdateManagerUtils.removeFromFileSystem(localFile);		
+	localFile = new File(new URL(location,LocalSite.DEFAULT_CONFIG_FILE).getFile());
+	UpdateManagerUtils.removeFromFileSystem(localFile);	
+	localFile = new File(new URL(location,Site.DEFAULT_FEATURE_PATH+File.separator+feature.getVersionedIdentifier().toString()).getFile());		
+	UpdateManagerUtils.removeFromFileSystem(localFile);	
+	UpdateManagerUtils.removeFromFileSystem(new File(((InstallConfiguration)site.getCurrentConfiguration()).getURL().getFile()));						
+	UpdateManagerUtils.removeFromFileSystem(file);		
+	localFile = new File(feature2.getURL().getFile());
+	UpdateManagerUtils.removeFromFileSystem(localFile);*/
+}
+
+
+}
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestSpaceInInstall.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestSpaceInInstall.java
new file mode 100644
index 0000000..c5b111a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularInstall/TestSpaceInInstall.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularInstall;
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestSpaceInInstall extends UpdateManagerTestCase {
+	/**
+	 * Constructor for Test1
+	 */
+	public TestSpaceInInstall(String arg0) {
+		super(arg0);
+	}
+
+	/**
+	 *
+	 */
+	public void testSpaceInURL() throws Exception {
+
+		//cleanup target 
+		URL testURL = new URL(TARGET_FILE_SITE,"test site space/"); 
+		String testPath = testURL.getFile();
+		File target = new File(testPath);
+		UpdateManagerUtils.removeFromFileSystem(target);
+		
+		URL newURL = new File(dataPath + "Site with space/site.xml").toURL();
+		ISite remoteSite = SiteManager.getSite(newURL,true,null);
+		IFeatureReference[] featuresRef = remoteSite.getFeatureReferences();
+		if (!target.exists()) target.mkdirs();
+		ISite localSite = SiteManager.getSite(testURL,true,null);
+		IFeature remoteFeature = null;
+		
+		// at least one executable feature and on packaged
+		boolean execFeature = false;
+		boolean packFeature = false;
+
+		if (featuresRef.length==0) fail ("no feature found");
+	
+		for (int i = 0; i < featuresRef.length; i++) {
+			remoteFeature = featuresRef[i].getFeature(null);
+			remove(remoteFeature,localSite); 
+			localSite.install(remoteFeature, null,null);
+			
+			if (remoteFeature.getFeatureContentProvider() instanceof FeaturePackagedContentProvider) packFeature = true;
+			if (remoteFeature.getFeatureContentProvider() instanceof FeatureExecutableContentProvider) execFeature = true;
+
+			// verify
+			String site = testPath;
+			IPluginEntry[] entries = remoteFeature.getRawPluginEntries();
+			assertTrue("no plugins entry", (entries != null && entries.length != 0));
+			String pluginName = entries[0].getVersionedIdentifier().toString();
+			File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+			assertTrue("plugin files not installed locally (pluginFile=" + pluginFile + ",target=" + target + ')', pluginFile.exists());
+
+			File featureFile = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString());
+			assertTrue("feature info not installed locally:"+featureFile, featureFile.exists());
+
+			File featureFileXML = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString() + File.separator + "feature.xml");
+			assertTrue("feature info not installed locally: no feature.xml", featureFileXML.exists());
+		}
+
+		if (!execFeature && !packFeature){
+			fail("cannot find one executable and one package feature on teh site");
+		}
+
+		//cleanup target 
+		UpdateManagerUtils.removeFromFileSystem(target);
+
+
+	}
+	
+	
+	/**
+	 *
+	 */
+	public void testSpaceInHTTPURL() throws Exception {
+
+		//cleanup target  
+		File target = new File(TARGET_FILE_SITE.getFile());
+		UpdateManagerUtils.removeFromFileSystem(target);
+		InstallRegistry.cleanup();
+		
+		String path = bundle.getString("HTTP_PATH_3");
+		ISite remoteSite = SiteManager.getSite(new URL("http",getHttpHost(),getHttpPort(),path),true,null);		
+		IFeatureReference[] featuresRef = remoteSite.getFeatureReferences();
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,true,null);
+		IFeature remoteFeature = null;
+		
+		// at least one executable feature and on packaged
+		boolean execFeature = false;
+		boolean packFeature = false;
+
+		if (featuresRef.length==0) fail ("no feature found");
+	
+		for (int i = 0; i < featuresRef.length; i++) {
+			remoteFeature = featuresRef[i].getFeature(null);
+			localSite.install(remoteFeature, null,null);
+			
+			if (remoteFeature.getFeatureContentProvider() instanceof FeaturePackagedContentProvider) packFeature = true;
+			if (remoteFeature.getFeatureContentProvider() instanceof FeatureExecutableContentProvider) execFeature = true;
+
+			// verify
+			String site = TARGET_FILE_SITE.getFile();			
+			IPluginEntry[] entries = remoteFeature.getRawPluginEntries();
+			assertTrue("no plugins entry", (entries != null && entries.length != 0));
+			String pluginName = entries[0].getVersionedIdentifier().toString();
+			File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+			assertTrue("plugin files not installed locally", pluginFile.exists());
+
+			File featureFile = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString());
+			assertTrue("feature info not installed locally:"+featureFile, featureFile.exists());
+
+			File featureFileXML = new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + remoteFeature.getVersionedIdentifier().toString() + File.separator + "feature.xml");
+			assertTrue("feature info not installed locally: no feature.xml", featureFileXML.exists());
+		}
+
+		if (!execFeature && !packFeature){
+			fail("cannot find one executable and one package feature on teh site");
+		}
+
+		//cleanup target 
+		UpdateManagerUtils.removeFromFileSystem(target);
+		InstallRegistry.cleanup();
+
+	}
+		
+		
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularRemove/AllRegularRemoveTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularRemove/AllRegularRemoveTests.java
new file mode 100644
index 0000000..3438c43
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularRemove/AllRegularRemoveTests.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularRemove;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+
+public class AllRegularRemoveTests extends UpdateManagerTestCase {
+public AllRegularRemoveTests(String name) {
+	super(name);
+}
+public static Test suite() {
+	TestSuite suite = new TestSuite();
+	suite.setName("Regular Remove Tests");
+	
+	suite.addTest(new TestSuite(TestRemove.class));
+	
+	return suite;
+}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularRemove/TestRemove.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularRemove/TestRemove.java
new file mode 100644
index 0000000..48e75e4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/regularRemove/TestRemove.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.regularRemove;
+import java.io.File;
+import java.net.MalformedURLException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.configuration.IConfiguredSiteChangedListener;
+import org.eclipse.update.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+public class TestRemove extends UpdateManagerTestCase {
+
+	public class Listener implements IConfiguredSiteChangedListener {
+
+		public boolean notified = false;
+
+		public void featureInstalled(IFeature feature) {
+			notified = true;
+			System.out.println("Notified DefaultFeature Installed");
+		}
+
+		public void featureRemoved(IFeature feature) {
+		}
+		public void featureConfigured(IFeature feature) {
+		}
+		public void featureUnconfigured(IFeature feature) {
+		}
+
+		public boolean isNotified() {
+			return notified;
+		}
+	}
+
+	/**
+	 * Constructor for Test1
+	 */
+	public TestRemove(String arg0) {
+		super(arg0);
+	}
+
+	private IFeature getFeature1(ISite site)
+		throws MalformedURLException, CoreException {
+		//URL url = UpdateManagerUtils.getURL(site.getURL(), "features/org.eclipse.update.core.tests.feature1_1.0.4.jar", null);
+		SiteFeatureReference ref = new SiteFeatureReference();
+		ref.setSite(site);
+		ref.setURLString("features/org.eclipse.update.core.tests.feature1_1.0.4.jar");
+		ref.setType(ISite.DEFAULT_PACKAGED_FEATURE_TYPE);
+		ref.resolve(site.getURL(), null);
+		return ref.getFeature(null);
+	}
+
+	public void testRemoveFeature() throws Exception {
+
+		// install feature
+		ISite remoteSite = SiteManager.getSite(SOURCE_FILE_SITE,null);
+		IFeature remoteFeature = getFeature1(remoteSite);
+		ISite localSite = SiteManager.getSite(TARGET_FILE_SITE,null);
+		IFeatureReference ref = localSite.install(remoteFeature, null, null);
+
+		// then remove it
+		assertNotNull("Feature is null",ref.getFeature(null));
+		String featureRef = ref.getFeature(null).getVersionedIdentifier().toString();
+		localSite.remove(ref.getFeature(null), null);
+
+		// verify
+		String site = TARGET_FILE_SITE.getFile();
+		IPluginEntry[] entries = remoteFeature.getPluginEntries();
+		assertTrue("no plugins entry", (entries != null && entries.length != 0));
+		String pluginName = entries[0].getVersionedIdentifier().toString();
+
+		File pluginFile = new File(site, Site.DEFAULT_PLUGIN_PATH + pluginName);
+		assertTrue("plugin files installed locally", !pluginFile.exists());
+
+		File featureFile =
+			new File(site, Site.DEFAULT_INSTALLED_FEATURE_PATH + featureRef);
+		assertTrue(
+			"feature info installed locally:" + featureFile,
+			!featureFile.exists());
+
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/sitevalidation/AllSiteValidationTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/sitevalidation/AllSiteValidationTests.java
new file mode 100644
index 0000000..f2f3637
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/sitevalidation/AllSiteValidationTests.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.tests.sitevalidation;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+public class AllSiteValidationTests extends UpdateManagerTestCase {
+	public AllSiteValidationTests(String name) {
+		super(name);
+	}
+	public static Test suite() {
+		TestSuite suite = new TestSuite();
+		suite.setName("Site Validation Tests");
+
+		// the following will take all teh test methods in teh class that start with 'test'
+
+		suite.addTest(new TestSuite(TestSiteValidation.class));
+
+		return suite;
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/sitevalidation/TestSiteValidation.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/sitevalidation/TestSiteValidation.java
new file mode 100644
index 0000000..1f9d5b0
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/sitevalidation/TestSiteValidation.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.tests.sitevalidation;
+import java.io.*;
+import java.net.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.configurator.IPlatformConfiguration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.tests.*;
+
+public class TestSiteValidation extends UpdateManagerTestCase {
+
+
+	/**
+	 * Constructor 
+	 */
+	public TestSiteValidation(String arg0) {
+		super(arg0);
+	}
+
+	private void removeConfigSite(URL url) throws Exception {
+		// get new config object
+		IPlatformConfiguration cfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		ISiteEntry s1 = cfig.findConfiguredSite(url);
+		assertNotNull("Unable to find site entry:"+url,s1);
+		cfig.unconfigureSite(s1);
+	}
+
+	public void testSite1() throws Exception {
+
+		URL remoteUrl = new URL(TARGET_FILE_SITE + "validation/site1/eclipse");
+		File file = new File(remoteUrl.getFile());
+		ILocalSite local = SiteManager.getLocalSite();
+		IInstallConfiguration currentConfig = local.getCurrentConfiguration();
+		file.mkdirs();
+		IConfiguredSite configuredSite = currentConfig.createConfiguredSite(file);
+		IStatus status = configuredSite.verifyUpdatableStatus();
+
+		String msg = "The site "+file+" should be updatable.";
+		if (!status.isOK()){
+			fail(msg+status.getMessage());
+		}
+		currentConfig.removeConfiguredSite(configuredSite);
+		removeConfigSite(configuredSite.getSite().getURL());
+	}
+	
+	public void testSite2() throws Exception {
+
+		URL remoteUrl = new URL(SOURCE_FILE_SITE + "validation/site2/eclipse/");
+		File file = new File(remoteUrl.getFile());
+		ILocalSite local = SiteManager.getLocalSite();
+		IInstallConfiguration currentConfig = local.getCurrentConfiguration();
+		IConfiguredSite configuredSite;
+		try {
+		 configuredSite = currentConfig.createConfiguredSite(file);
+		} catch (CoreException e){
+			return;
+		}
+		IStatus status = configuredSite.verifyUpdatableStatus();
+
+//		UpdateManagerUtils.removeFromFileSystem(new File(file,".eclipseUM"));
+
+		String msg = "The site "+file+" should not be updatable.";
+		if (status.isOK()){
+			fail(msg+status.getMessage());
+		}
+		if (status.getMessage().indexOf("This site is contained in another site:")==-1){
+			fail("Wrong validation:"+status.getMessage());
+		}
+	}	
+
+	public void testSite3() throws Exception {
+
+		URL remoteUrl = new URL(SOURCE_FILE_SITE + "validation/site3/eclipse/");
+		File file = new File(remoteUrl.getFile());
+		ILocalSite local = SiteManager.getLocalSite();
+		IInstallConfiguration currentConfig = local.getCurrentConfiguration();
+		IConfiguredSite configuredSite = currentConfig.createConfiguredSite(file);
+		IStatus status = configuredSite.verifyUpdatableStatus();
+
+//		UpdateManagerUtils.removeFromFileSystem(new File(file,".eclipseUM"));
+
+		String msg = "The site "+file+" should not be updatable.";
+		if (status.isOK()){
+			fail(msg+status.getMessage());
+		}
+//		if (status.getMessage().indexOf("This site is contained in another site:")==-1){
+//			fail("Wrong validation:"+status.getMessage());
+//		}
+	}	
+
+	public void testSite4() throws Exception {
+
+		URL remoteUrl = new URL(SOURCE_FILE_SITE + "validation/site4/eclipse/");
+		File file = new File(remoteUrl.getFile());
+		ILocalSite local = SiteManager.getLocalSite();
+		IInstallConfiguration currentConfig = local.getCurrentConfiguration();
+		IConfiguredSite configuredSite = currentConfig.createConfiguredSite(file);
+		IStatus status = configuredSite.verifyUpdatableStatus();
+
+		String msg = "The site "+file+" should not be updatable.";
+		if (status.isOK()){
+			fail(msg+status.getMessage());
+		}
+		if (status.getMessage().indexOf("The site cannot be modified by this product. It is already associated with product:")==-1){
+			fail("Wrong validation:"+status.getMessage());
+		}
+	}	
+
+	public void testSite5() throws Exception {
+
+		URL remoteUrl = new URL(SOURCE_FILE_SITE + "validation/site5/");
+		File file = new File(remoteUrl.getFile());
+		ILocalSite local = SiteManager.getLocalSite();
+		IInstallConfiguration currentConfig = local.getCurrentConfiguration();
+		IConfiguredSite configuredSite = currentConfig.createConfiguredSite(file);
+		IStatus status = configuredSite.verifyUpdatableStatus();
+
+		String msg = "The site "+file+" should be updatable.";
+		if (!status.isOK()){
+			fail(msg+status.getMessage());
+		}
+		
+			// get new config object
+		URL url = configuredSite.getSite().getURL();
+		IPlatformConfiguration cfig = ConfiguratorUtils.getCurrentPlatformConfiguration();
+		ISiteEntry s1 = cfig.findConfiguredSite(url);
+		assertNotNull("Site entry not found:"+url,s1);
+		cfig.unconfigureSite(s1);
+		cfig.save();
+	}
+	
+	public void testSite6() throws Exception {
+
+		URL remoteUrl = new URL(SOURCE_FILE_SITE + "validation/site6/children/children/eclipse/");
+		File file = new File(remoteUrl.getFile());
+		if (!file.exists()) file.mkdirs();
+		ILocalSite local = SiteManager.getLocalSite();
+		IInstallConfiguration currentConfig = local.getCurrentConfiguration();
+		IConfiguredSite configuredSite = currentConfig.createConfiguredSite(file);
+		IStatus status = configuredSite.verifyUpdatableStatus();
+
+//		UpdateManagerUtils.removeFromFileSystem(new File(file,".eclipseUM"));
+
+		String msg = "The site "+file+" should not be updatable.";
+		if (status.isOK()){
+			fail(msg+status.getMessage());
+		}
+//		if (status.getMessage().indexOf("This site is contained in another site:")==-1){
+//			fail("Wrong validation:"+status.getMessage());
+//		}
+	}	
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/AllStandaloneTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/AllStandaloneTests.java
new file mode 100644
index 0000000..fe7cc2f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/AllStandaloneTests.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.standalone;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+
+public class AllStandaloneTests extends UpdateManagerTestCase{
+
+	public AllStandaloneTests(String name){
+		super(name);
+	}
+	
+	public static Test suite(){
+		TestSuite suite = new TestSuite();
+		suite.setName("Standalone Tests");
+		
+		// the following will take all the test methods in 
+		// the class that start with "test"
+		suite.addTest(new TestSuite(TestFeatureInstall.class));
+		suite.addTest(new TestSuite(TestFeatureUpdate.class));
+		suite.addTest(new TestSuite(TestFeatureEnable.class));
+		suite.addTest(new TestSuite(TestFeatureDisable.class));
+		suite.addTest(new TestSuite(TestFeatureUninstall.class));
+		suite.addTest(new TestSuite(TestBundlesInstall.class));
+		//and this one's for fun :)
+//		suite.addTest(new TestSuite(TestSiteSearch.class));
+		
+		return suite;
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/StandaloneManagerTestCase.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/StandaloneManagerTestCase.java
new file mode 100644
index 0000000..c0aebfe
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/StandaloneManagerTestCase.java
@@ -0,0 +1,323 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.standalone;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.*;
+
+public class StandaloneManagerTestCase extends UpdateManagerTestCase {
+	public static StringBuffer errOutput;
+	public static Integer exitValue= new Integer(-1);
+	public static URL TARGET_FILE_SITE;
+	private boolean oldCache = false;
+	
+	static {
+		File targetDir = new File(System.getProperty("java.io.tmpdir"));
+		targetDir = new File(targetDir, "standalone");
+		targetDir = new File(targetDir, "mytarget");
+		if (targetDir.exists())
+			deleteDirectory(targetDir);
+		try {
+			TARGET_FILE_SITE = targetDir.toURL();
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public StandaloneManagerTestCase (String arg0){
+		super(arg0);
+	}
+	
+	/**
+	 * Sets up the fixture, for example, open a network connection.
+	 * This method is called before a test is executed.
+	 */
+	protected void umSetUp() {
+		// setup cache site to true
+		oldCache = InternalSiteManager.globalUseCache;
+		InternalSiteManager.globalUseCache = true;
+	}
+	
+	/**
+	 * Tears down the fixture, for example, close a network connection.
+	 * This method is called after a test is executed.
+	 */
+	protected void umTearDown() {
+		// do nothing.
+		InternalSiteManager.globalUseCache = oldCache;
+	}
+	
+	public void checkConfiguredSites(){
+		ILocalSite localSite;
+		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
+		try {
+			localSite = SiteManager.getLocalSite();
+			System.out.println("LocalSite: " + localSite.getCurrentConfiguration().getLabel());
+		
+		//Get site to install to
+		IInstallConfiguration currentConfig = localSite.getCurrentConfiguration();
+		IConfiguredSite[] sites = currentConfig.getConfiguredSites();
+//	
+//			// start of config site print
+		System.out.println("GETTING CONFIGURED SITES...");
+		for (int i = 0; i<sites.length; i++){
+			System.out.println("site #" + i + ": " + sites[i].getSite().getURL().getFile());
+		}
+		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
+		} catch (CoreException e) {
+			System.err.println(e);
+		}
+	}
+	
+	// get the first configured site found because this is the one we're most likely to 
+	// have installed into
+	public ISite getConfiguredSite(URL target){
+		try {
+			ILocalSite local = SiteManager.getLocalSite();
+			IInstallConfiguration currentConfig = local.getCurrentConfiguration();
+			IConfiguredSite[] sites = currentConfig.getConfiguredSites();
+			System.out.println("\nretrieving configured sites...");
+			String targetFile = new File(target.getFile()).getAbsolutePath();
+			for (int i = 0; i<sites.length ; i++){
+				System.out.println("site["+i+"]: " + sites[i].getSite().getURL());
+				String siteFile = new File(sites[i].getSite().getURL().getFile()).getAbsolutePath();
+				if (targetFile.equals(siteFile))
+					return sites[i].getSite();
+			}
+			if (sites.length == 0)
+				return null;
+			return sites[0].getSite();
+		} catch (CoreException e) {
+			System.err.println(e);
+			return null;
+		}
+	}
+	//WatchDog thread to kill mirroring process if it hangs (or takes too long)
+	public static class Timer extends Thread{
+		private Process proc;
+		
+		public Timer(Process proc){
+			super();
+			this.setDaemon(true);
+			this.proc = proc;
+		}
+		
+		public void run(){
+			try {
+				// sleep time 5min
+				sleep(300000); 
+				System.out.println("destroying process");
+				proc.destroy();
+			} catch (Exception e) {
+				System.err.println(e);
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	// StreamConsumer to display output to output files or console
+	public static class StreamConsumer extends Thread {
+		private BufferedReader bReader;
+
+		public StreamConsumer(InputStream inputStream) {
+			super();
+			setDaemon(true);
+			bReader = new BufferedReader(new InputStreamReader(inputStream));
+			errOutput = new StringBuffer();
+		}
+
+		public void run() {
+			try {
+				String line;
+				while (null != (line = bReader.readLine())) {
+					System.err.println(line);
+					errOutput.append(line);
+					errOutput.append("\n");
+				}
+			} catch (IOException e) {
+				System.err.println(e);
+				e.printStackTrace();
+			}
+		}
+	}
+	
+	/**
+	 * @param command : command argument to run on site/feature 
+	 * (i.e. 'install', 'enable', 'disable', 'update') *<i>required</i>*
+	 * @param fid : feature id of the feature being installed, enabled, etc.
+	 * (optional - can be null)
+	 * @param ver : version of feature being installed, enabled, etc. (optional - can be null)
+	 * @param config : location of configuration info (i.e. file:D:\temp\.config\)
+	 * @param remoteLoc : remote site url (required for installing/searching from remote site)
+	 * @param localLoc : target site directory (required unless updating/searching)
+	 * @return a string array consisting of commands and their arguments to
+	 * be run
+	 */
+	public String[] getCommand(
+		String command,
+		String fid,
+		String ver,
+		String config,
+		String remoteLoc,
+		String localLoc){
+		final String classpath = "startup.jar";
+		final String launcher = "org.eclipse.core.launcher.Main";
+		final String application = "org.eclipse.update.core.standaloneUpdate";
+		final String FLAG_CP = "-cp";
+		final String FLAG_APP = "-application";
+		final String FLAG_CMD = "-command";
+		final String FLAG_FID = "-featureId";
+		final String FLAG_DATA = "-data";
+		final String FLAG_VERSION = "-version";
+		final String FLAG_FROM = "-from";
+		final String FLAG_TO = "-to";
+		final String FLAG_CONFIG = "-configuration";
+//		final String FLAG_URL = "-mirrorURL";
+		final String FLAG_SPLASH = "-nosplash";
+		final String FLAG_CONSOLELOG = "-consolelog";
+		final String data =
+			UpdateCore.getPlugin().getStateLocation().toOSString();
+		String[] cmd =
+			new String[] {
+				getJavaVMPath(),
+				FLAG_CP,
+				classpath,
+				launcher,
+				FLAG_APP,
+				application,
+				FLAG_CMD,
+				command,
+				(remoteLoc !=null ? FLAG_FROM : ""),
+				(remoteLoc !=null ? remoteLoc : ""),
+				(localLoc !=null ? FLAG_TO : ""),
+				(localLoc !=null ?localLoc.replaceFirst("file:", "") : ""),
+				(fid != null ? FLAG_FID : ""),
+				(fid != null ? fid : ""),
+				(ver != null ? FLAG_VERSION : ""),
+				(ver != null ? ver : ""),
+				(config != null ? FLAG_CONFIG : ""),
+				(config != null ? config : ""),
+				FLAG_SPLASH,
+				FLAG_DATA,
+				data,
+				FLAG_CONSOLELOG};
+		for (int i = 0 ;i<cmd.length; i++){
+			System.out.print(cmd[i] + " ");			
+		}System.out.println();
+		return cmd;
+	}
+	
+	public String getJavaVMPath() {
+		// Create command string for launching the process
+		String vm = System.getProperty("java.vm.name");
+		String executable = "J9".equals(vm) ? "j9" : "java";
+		if (org.eclipse.osgi.service.environment.Constants.OS_WIN32.equals(Platform.getOS()))
+			executable += "w.exe";
+
+		String javaInstallDir =
+			System.getProperty("java.home") + File.separator + "bin";
+		return javaInstallDir + File.separator + executable;
+	}
+	
+	public int performAction(String[] cmd) {
+		File file = new File(getEclipseRoot());
+		try {
+
+			Process proc =
+				Runtime.getRuntime().exec(cmd, (String[]) null, file);
+
+			StreamConsumer outputs = new StreamConsumer(proc.getInputStream());
+			outputs.start();
+			StreamConsumer errors = new StreamConsumer(proc.getErrorStream());
+			errors.start();
+			Timer timer = new Timer(proc);
+			timer.start();
+
+			return proc.waitFor();
+		} catch (IOException e) {
+			System.err.println(e);
+		} catch (InterruptedException e) {
+			System.err.println(e);
+		} catch (Exception e) {
+			System.err.println(e);
+		}
+		return -1;
+	}
+	
+	public String getEclipseRoot() {
+		return ConfiguratorUtils.getInstallURL().toExternalForm().replaceFirst(
+			"file:",
+			"");
+	}
+	
+	public ArrayList getArrayList(String[] list){
+		ArrayList temp = new ArrayList();
+		for(int i = 0; i< list.length; i++){
+			temp.add(list[i]);
+		}
+		return temp;
+	}
+	
+	public File getLatestConfigurationFile(File localFile) {
+
+		try {
+			System.out.println("reading from : " + localFile.getAbsolutePath());
+				FileReader freader = new FileReader(localFile);
+				BufferedReader breader = new BufferedReader(freader);
+				while (breader.ready()) {
+					breader.readLine();
+//					System.out.println(line);
+				}
+				// read config file
+				File parent = new File(localFile.getParent());
+				System.out.println("parent: " + parent.getAbsolutePath());
+				String[] parList = parent.list();
+				int latest = 0; 
+				for (int i = parList.length-1; i>=0; i--){
+					System.out.println("parList[" + i + "]: " + parList[i]);
+					if (parList[i].startsWith("platform")){
+						latest = i;
+						break;
+					}
+				}
+				File configFile = new File(parent.getAbsolutePath() + File.separator + parList[latest]);
+				return configFile;
+				// end of config file read
+		} catch (Exception e) {
+			System.err.println(e);
+			e.printStackTrace();
+		}
+		return localFile;
+	}
+	
+	private static void deleteDirectory(File dir) {
+		File[] list = dir.listFiles();
+		if (list == null)
+			return;
+			
+		for (int i=0; i<list.length; i++) {
+			if (list[i].isDirectory()) 
+				deleteDirectory(list[i]);
+			if (!list[i].delete())
+				System.out.println("Unable to delete "+list[i].toString());
+		}
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestBundlesInstall.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestBundlesInstall.java
new file mode 100644
index 0000000..dd296cc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestBundlesInstall.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.standalone;
+
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.standalone.*;
+
+
+public class TestBundlesInstall extends StandaloneManagerTestCase {
+	private static boolean isInstalled;
+
+	public TestBundlesInstall(String arg0) {
+		super(arg0);
+		isInstalled = false;
+	}
+
+	public void umSetUp() {
+		super.umSetUp();
+		//System.out.println("looking at configured sites available....");
+		//checkConfiguredSites();
+		
+		String featureId = "com.example.bundle.feature";
+		String version = "1.0.0";
+
+		String fromRemoteSiteUrl = "http://"+getHttpHost()+":"+ getHttpPort()+ "/org.eclipse.update.tests.core.updatetests/bundleSite/";
+		if (!isInstalled) {
+			System.out.println(
+				"==============" + this.getClass() + "=============");
+			StandaloneUpdateApplication app = new StandaloneUpdateApplication();
+			try {
+				exitValue = (Integer)app.run(getCommand(
+					"install",
+					featureId,
+					version,
+					null,
+					fromRemoteSiteUrl,
+					TARGET_FILE_SITE.getFile()));
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			isInstalled = true;
+		}
+		
+	}
+
+	public void testPluginsExist() {
+		ISite localSite = getConfiguredSite(TARGET_FILE_SITE);
+		
+		System.out.println("localSite: " + localSite.getURL().getFile());
+		IPluginEntry[] pluginEntries = localSite.getPluginEntries();
+		ArrayList list = new ArrayList();
+		if (pluginEntries == null || pluginEntries.length == 0){
+			System.err.println("No plugin entries on the target site");
+			fail("No plugin entries on the target site");
+		} else{
+			for (int i = 0; i < pluginEntries.length; i++){
+				System.out.println("found plugin: " + pluginEntries[i].getVersionedIdentifier().toString());
+				list.add(pluginEntries[i].getVersionedIdentifier().toString());
+			}
+		}
+
+		String[] pluginNames =
+			{	"com.example.bundle.plugin_1.0.0",
+				"com.example.bundle.plugin.ui_2.0.0",
+				"com.example.bundle.fragment_1.0.0",
+				"com.example.budle.fragment.ui_1.0.0"};
+		assertTrue(checkFilesInList(pluginNames, list));
+	}
+
+	public void testFeaturesExist() {
+		try {
+			ISite localSite =  getConfiguredSite(TARGET_FILE_SITE);
+
+			System.out.println("localSite: " + localSite.getURL().getFile());
+			// get feature references 
+			IFeatureReference[] localFeatures =
+				localSite.getFeatureReferences();
+			System.out.println("local currentCOnfigSite: " + localSite.getCurrentConfiguredSite());
+			ArrayList list = new ArrayList();
+			if (localFeatures == null || localFeatures.length == 0){
+				System.err.println("No features on the target site");
+				fail("No features on the target site");
+			} else {
+				for (int i = 0; i < localFeatures.length; i++)
+					list.add(localFeatures[i].getVersionedIdentifier().toString());
+			}
+			String[] featureNames =
+				{
+					"com.example.bundle.feature_1.0.0"};
+			assertTrue(checkFilesInList(featureNames, list));
+		} catch (CoreException e) {
+			System.err.println(e);
+		}
+	}
+
+	// makes sure all files/directories in "names" are in the directory listing "list"
+	public boolean checkFilesInList(
+		String[] names,
+		ArrayList list) {
+		
+		for (int i = 0; i < names.length; i++) {
+			System.out.println(names[i]);
+			if (!list.contains(names[i])){
+				return false;
+			}
+		}
+		return true;
+	}
+
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		System.out.println("exitValue: " + exitValue);
+		assertEquals(exitValue, IPlatformRunnable.EXIT_OK);
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureDisable.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureDisable.java
new file mode 100644
index 0000000..9632753
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureDisable.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.standalone;
+
+import java.io.*;
+import java.util.*;
+
+import org.eclipse.core.runtime.IPlatformRunnable;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.standalone.*;
+
+public class TestFeatureDisable extends StandaloneManagerTestCase {
+	public static boolean isDisabled;
+	
+	public TestFeatureDisable(String arg0) {
+		super(arg0);
+		isDisabled = false;
+	}
+
+	public void umSetUp() {
+		super.umSetUp();
+		
+		String featureId = "my.alphabet";
+		String version = "1.0.0";
+
+		checkConfiguredSites();
+		if (!isDisabled) {
+			System.out.println(
+				"==============" + this.getClass() + "=============");
+			StandaloneUpdateApplication app = new StandaloneUpdateApplication();
+			try {
+				exitValue = (Integer)app.run(getCommand(
+					"disable",
+					featureId,
+					version,
+					null,
+					null,
+					TARGET_FILE_SITE.getFile()));
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			isDisabled = true;
+			checkConfiguredSites();
+		}
+	}
+	
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		System.out.println("exitValue: " + exitValue);
+		assertEquals(exitValue, IPlatformRunnable.EXIT_OK);
+	}
+
+	public void testFeatureStatus() throws Exception {
+		File localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		System.out.println(localFile.getAbsolutePath());
+		assertTrue(localFile.exists());
+		File configFile = getLatestConfigurationFile(localFile);
+	
+		String[] names =
+			{
+				"features/my.alphabet.round.letters_1.0.0/",
+				"features/my.alphabet.straight.letters_1.0.0/",
+				"features/my.alphabet_1.0.0/" };
+		assertTrue(configFile.exists());
+		assertTrue(checkFeaturesDisabled(getArrayList(names),configFile, TARGET_FILE_SITE.getFile()));
+	}
+
+	public boolean checkFeaturesDisabled(ArrayList featureNames, File configFile, String siteLocation){
+		try {
+			FileReader freader = new FileReader(configFile);
+			BufferedReader breader = new BufferedReader(freader);
+			String line;
+			System.out.println("now reading..." + configFile.getAbsolutePath());
+			boolean isSiteToCheck = false;
+			while (breader.ready()) {
+				line = breader.readLine();
+				if (line.trim().startsWith("<site url")){
+					isSiteToCheck = line.trim().split("\"")[1].replaceFirst("file:","").equals(siteLocation);
+				} else if (isSiteToCheck && line.trim().startsWith("<feature configured")){
+					System.err.println(line);
+					String[] configLine = line.split("\"");
+					if (featureNames.contains(configLine[3]) && configLine[1].equals("true")){
+						fail(configLine[3] + " has not been disabled.");
+					}
+				}
+			}
+		} catch (Exception e) {
+			System.err.println(e);
+		} 
+		return true;
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureEnable.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureEnable.java
new file mode 100644
index 0000000..3fc407c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureEnable.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.standalone;
+
+import java.io.*;
+import java.util.*;
+
+import org.eclipse.core.runtime.IPlatformRunnable;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.standalone.*;
+
+public class TestFeatureEnable extends StandaloneManagerTestCase {
+	public static boolean isEnabled;
+	
+	public TestFeatureEnable(String arg0) {
+		super(arg0);
+		isEnabled = false;
+	}
+
+	public void umSetUp() {
+
+		super.umSetUp();
+		
+		String featureId = "my.alphabet";
+		String version = "1.0.0";
+
+		checkConfiguredSites();
+		if (!isEnabled) {
+			System.out.println(
+				"==============" + this.getClass() + "=============");
+			StandaloneUpdateApplication app = new StandaloneUpdateApplication();
+			try {
+				exitValue = (Integer)app.run(getCommand(
+					"enable",
+					featureId,
+					version,
+					null,
+					null,
+					TARGET_FILE_SITE.getFile()));
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			isEnabled = true;
+			checkConfiguredSites();
+		}
+	}
+	
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		System.out.println("exitValue: " + exitValue);
+		assertEquals(exitValue, IPlatformRunnable.EXIT_OK);
+	}
+
+	public void testFeatureStatus() throws Exception {
+	
+		File localFile = new File(((LocalSite)SiteManager.getLocalSite()).getLocationURL().getFile());
+		System.out.println(localFile.getAbsolutePath());
+		assertTrue(localFile.exists());
+		File configFile = getLatestConfigurationFile(localFile);
+		
+		String[] names =
+			{
+				"features/my.alphabet.round.letters_1.0.0/",
+				"features/my.alphabet.straight.letters_1.0.0/",
+				"features/my.alphabet_1.0.0/" };
+		assertTrue(configFile.exists());
+		assertTrue(checkFeaturesEnabled(getArrayList(names),configFile, TARGET_FILE_SITE.getFile()));
+	}
+
+	public boolean checkFeaturesEnabled(ArrayList featureNames, File configFile, String siteLocation){
+		try {
+			FileReader freader = new FileReader(configFile);
+			BufferedReader breader = new BufferedReader(freader);
+			String line;
+			System.out.println("now reading..." + configFile.getAbsolutePath());
+			boolean isSiteToCheck = false;
+			while (breader.ready()) {
+				line = breader.readLine();
+				if (line.trim().startsWith("<site url")){
+					isSiteToCheck = line.trim().split("\"")[1].replaceFirst("file:","").equals(siteLocation);
+				} else if (isSiteToCheck && line.trim().startsWith("<feature configured")){
+					System.err.println(line);
+					String[] configLine = line.split("\"");
+					if (featureNames.contains(configLine[3]) && configLine[1].equals("false")){
+						fail(configLine[3] + " has not been enabled.");
+					}
+					// temp - delete later
+					if (featureNames.contains(configLine[3]))
+						System.err.println(line);
+					// end of temp delete
+				}
+			}
+		} catch (Exception e) {
+			System.err.println(e);
+		} 
+		return true;
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureInstall.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureInstall.java
new file mode 100644
index 0000000..b973cb4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureInstall.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.standalone;
+
+
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.standalone.*;
+
+
+public class TestFeatureInstall extends StandaloneManagerTestCase {
+	private static boolean isInstalled;
+
+	public TestFeatureInstall(String arg0) {
+		super(arg0);
+		isInstalled = false;
+	}
+
+	public void umSetUp() {
+		super.umSetUp();
+		//System.out.println("looking at configured sites available....");
+		//checkConfiguredSites();
+		
+		String featureId = "my.alphabet";
+		String version = "1.0.0";
+
+		String fromRemoteSiteUrl =
+			"http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-update-home/3.0/site/";
+		if (!isInstalled) {
+			System.out.println(
+				"==============" + this.getClass() + "=============");
+			StandaloneUpdateApplication app = new StandaloneUpdateApplication();
+			try {
+				exitValue = (Integer)app.run(getCommand(
+					"install",
+					featureId,
+					version,
+					null,
+					fromRemoteSiteUrl,
+					TARGET_FILE_SITE.getFile()));
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			isInstalled = true;
+		}
+		
+	}
+
+	public void testPluginsExist() {
+		ISite localSite = getConfiguredSite(TARGET_FILE_SITE);
+		
+		System.out.println("localSite: " + localSite.getURL().getFile());
+		IPluginEntry[] pluginEntries = localSite.getPluginEntries();
+		ArrayList list = new ArrayList();
+		if (pluginEntries == null || pluginEntries.length == 0){
+			System.err.println("No plugin entries on the target site");
+			fail("No plugin entries on the target site");
+		} else{
+			for (int i = 0; i < pluginEntries.length; i++){
+				System.out.println("found plugin: " + pluginEntries[i].getVersionedIdentifier().toString());
+				list.add(pluginEntries[i].getVersionedIdentifier().toString());
+			}
+		}
+
+		String[] pluginNames =
+			{	"my.alphabet.letter.a_1.0.0",
+				"my.alphabet.letter.b_1.0.0",
+				"my.alphabet.letter.c_1.0.0",
+				"my.alphabet.letter.e_1.0.0",
+				"my.alphabet.round.letters_1.0.0",
+				"my.alphabet.straight.letters_1.0.0",
+				"my.alphabet_1.0.0" };
+		assertTrue(checkFilesInList(pluginNames, list));
+	}
+
+	public void testFeaturesExist() {
+		try {
+			ISite localSite =  getConfiguredSite(TARGET_FILE_SITE);
+
+			System.out.println("localSite: " + localSite.getURL().getFile());
+			// get feature references 
+			IFeatureReference[] localFeatures =
+				localSite.getFeatureReferences();
+			System.out.println("local currentCOnfigSite: " + localSite.getCurrentConfiguredSite());
+			ArrayList list = new ArrayList();
+			if (localFeatures == null || localFeatures.length == 0){
+				System.err.println("No features on the target site");
+				fail("No features on the target site");
+			} else {
+				for (int i = 0; i < localFeatures.length; i++)
+					list.add(localFeatures[i].getVersionedIdentifier().toString());
+			}
+			String[] featureNames =
+				{
+					"my.alphabet.round.letters_1.0.0",
+					"my.alphabet.straight.letters_1.0.0",
+					"my.alphabet_1.0.0" };
+			assertTrue(checkFilesInList(featureNames, list));
+		} catch (CoreException e) {
+			System.err.println(e);
+		}
+	}
+
+	// makes sure all files/directories in "names" are in the directory listing "list"
+	public boolean checkFilesInList(
+		String[] names,
+		ArrayList list) {
+		
+		for (int i = 0; i < names.length; i++) {
+			System.out.println(names[i]);
+			if (!list.contains(names[i])){
+				return false;
+			}
+		}
+		return true;
+	}
+
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		System.out.println("exitValue: " + exitValue);
+		assertEquals(exitValue, IPlatformRunnable.EXIT_OK);
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureUninstall.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureUninstall.java
new file mode 100644
index 0000000..2a0d079
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureUninstall.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.standalone;
+
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.standalone.*;
+
+
+public class TestFeatureUninstall extends StandaloneManagerTestCase {
+	public static boolean isUninstalled;
+	
+	public TestFeatureUninstall(String arg0){
+		super(arg0);
+		isUninstalled = false;
+	}
+	
+	public void umSetUp() {
+		super.umSetUp();
+		System.out.println("looking at configured sites available....");
+		checkConfiguredSites();
+		
+		String featureId = "my.alphabet";
+		String version = "1.0.0";
+
+		if(!isUninstalled){
+			System.out.println(
+				"==============" + this.getClass() + "=============");
+			StandaloneUpdateApplication app = new StandaloneUpdateApplication();
+			try {
+				exitValue = (Integer)app.run(getCommand(
+					"uninstall",
+					featureId,
+					version,
+					null,
+					null,
+					TARGET_FILE_SITE.getFile()));
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			isUninstalled = true;
+		}
+	}
+	
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		System.out.println("exitValue: " + exitValue);
+		assertEquals(exitValue, IPlatformRunnable.EXIT_OK);
+	}
+	
+	public void testFeaturesUninstalled() throws Exception {
+		try {
+			ISite localSite = getConfiguredSite(TARGET_FILE_SITE);
+			
+			// get feature references 
+			IFeatureReference[] localFeatures =
+				localSite.getFeatureReferences();
+			ArrayList list = new ArrayList();
+			if (localFeatures == null || localFeatures.length == 0){
+				fail("No features on the target site");
+			} else {
+				for (int i = 0; i < localFeatures.length; i++)
+					list.add(localFeatures[i].getVersionedIdentifier().toString());
+			}
+			String[] featureNames =
+				{
+					"my.alphabet.round.letters_1.0.0",
+					"my.alphabet.straight.letters_1.0.0",
+					"my.alphabet_1.0.0" };
+			assertTrue(checkFilesNotInList(featureNames, list));
+		} catch (CoreException e) {
+			System.err.println(e);
+		}
+	}
+	
+	public void testPluginsUninstalled() throws Exception {
+			ISite localSite = getConfiguredSite(TARGET_FILE_SITE);
+			
+			IPluginEntry[] pluginEntries = localSite.getPluginEntries();
+			ArrayList list = new ArrayList();
+			if (pluginEntries == null || pluginEntries.length == 0)
+				fail("No plugin entries on the target site");
+			else
+				for (int i = 0; i < pluginEntries.length; i++){
+					list.add(pluginEntries[i].getVersionedIdentifier().toString());
+					System.out.println("plugin found: " + pluginEntries[i].getVersionedIdentifier().toString());
+				}
+
+			String[] pluginNames =
+				{	"my.alphabet.letter.a_1.0.0",
+					"my.alphabet.letter.b_1.0.0",
+					"my.alphabet.letter.c_1.0.0",
+					"my.alphabet.letter.e_1.0.0",
+					"my.alphabet.round.letters_1.0.0",
+					"my.alphabet.straight.letters_1.0.0",
+					"my.alphabet_1.0.0" };
+			assertTrue(checkFilesNotInList(pluginNames, list));	
+	}
+	
+	// makes sure all files/directories in "names" are NOT in the directory listing "list"
+	public boolean checkFilesNotInList(
+		String[] names,
+		ArrayList list) {
+		
+		for (int i = 0; i < names.length; i++) {
+			System.out.println("searching for " + names[i] + "...");
+			if (list.contains(names[i]))
+				return false;
+		}
+		return true;
+	}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureUpdate.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureUpdate.java
new file mode 100644
index 0000000..1e89b69
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/standalone/TestFeatureUpdate.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+
+package org.eclipse.update.tests.standalone;
+
+import java.util.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.standalone.*;
+
+public class TestFeatureUpdate extends StandaloneManagerTestCase {
+	public static boolean isUpdated;
+	
+	public TestFeatureUpdate(String arg0) {
+		super(arg0);
+		isUpdated = false;
+	}
+
+	public void umSetUp() {
+		super.umSetUp();
+		System.out.println("looking at configured sites available....");
+		checkConfiguredSites();
+		
+		String featureId = "my.alphabet";
+		String version = "1.0.1";
+
+		if (!isUpdated) {
+			System.out.println(
+				"==============" + this.getClass() + "=============");
+			StandaloneUpdateApplication app = new StandaloneUpdateApplication();
+			try {
+				exitValue = (Integer)app.run(getCommand(
+						"update",
+						featureId,
+						version,
+						null,
+						null,
+						TARGET_FILE_SITE.getFile()));
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			isUpdated = true;
+		}
+	}
+
+
+	// ensure exit without problems
+	public void testExitValue() throws Exception {
+		System.out.println("exitValue: " + exitValue);
+		assertEquals(exitValue, IPlatformRunnable.EXIT_OK);
+	}
+	
+	public void testPluginsExist() {
+
+			ISite localSite =  getConfiguredSite(TARGET_FILE_SITE);
+
+			IPluginEntry[] pluginEntries = localSite.getPluginEntries();
+			ArrayList list = new ArrayList();
+			if (pluginEntries == null || pluginEntries.length == 0)
+				fail("No plugin entries on the target site");
+			else
+				for (int i = 0; i < pluginEntries.length; i++) {
+					list.add(
+						pluginEntries[i].getVersionedIdentifier().toString());
+				}
+
+			String[] pluginNames =
+				{
+					"my.alphabet.letter.a_1.0.0",
+					"my.alphabet.letter.b_1.0.0",
+					"my.alphabet.letter.c_1.0.0",
+					"my.alphabet.letter.e_1.0.0",
+					"my.alphabet.round.letters_1.0.0",
+					"my.alphabet.straight.letters_1.0.0",
+					"my.alphabet_1.0.0",
+					"my.alphabet.letter.a_1.0.1",
+					"my.alphabet.letter.b_1.0.1",
+					"my.alphabet.letter.c_1.0.1",
+					"my.alphabet.letter.e_1.0.1",
+					"my.alphabet.round.letters_1.0.1",
+					"my.alphabet.straight.letters_1.0.1",
+					"my.alphabet_1.0.1" };
+			assertTrue(checkFilesInList(pluginNames, list));
+	}
+
+	public void testFeaturesExist() {
+		try {
+			ISite localSite = getConfiguredSite(TARGET_FILE_SITE);
+
+			// get feature references
+			IFeatureReference[] localFeatures =
+				localSite.getFeatureReferences();
+			ArrayList list = new ArrayList();
+			if (localFeatures == null || localFeatures.length == 0) {
+				fail("No features on the target site");
+			} else {
+				for (int i = 0; i < localFeatures.length; i++) {
+					list.add(
+						localFeatures[i].getVersionedIdentifier().toString());
+					System.out.println(
+						localFeatures[i].getVersionedIdentifier().toString());
+				}
+			}
+			String[] featureNames =
+				{
+					"my.alphabet.round.letters_1.0.0",
+					"my.alphabet.straight.letters_1.0.0",
+					"my.alphabet_1.0.0",
+					"my.alphabet.round.letters_1.0.1",
+					"my.alphabet.straight.letters_1.0.1",
+					"my.alphabet_1.0.1" };
+			assertTrue(checkFilesInList(featureNames, list));
+		} catch (CoreException e) {
+			System.err.println(e);
+		}
+	}
+
+	// makes sure all files/directories in "names" are in the directory listing
+	// "list"
+	public boolean checkFilesInList(String[] names, ArrayList list) {
+
+		for (int i = 0; i < names.length; i++) {
+			if (!list.contains(names[i]))
+				return false;
+		}
+		return true;
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/types/AllTypesTests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/types/AllTypesTests.java
new file mode 100644
index 0000000..be8c45e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/types/AllTypesTests.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.types;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+
+public class AllTypesTests extends UpdateManagerTestCase {
+public AllTypesTests(String name) {
+	super(name);
+}
+public static Test suite() {
+	TestSuite suite = new TestSuite();
+	suite.setName("Regular Install Tests");
+	
+	// the following will take all teh test methods in teh class that start with 'test'
+	suite.addTest(new TestSuite(TestFeatureType.class));
+	suite.addTest(new TestSuite(TestSiteType.class));	
+	
+	// or you can specify the method
+	//suite.addTest(new TestGetFeature("methodThatDoesNotStartWithtest"));	
+	
+	return suite;
+}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/types/TestFeatureType.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/types/TestFeatureType.java
new file mode 100644
index 0000000..442705b
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/types/TestFeatureType.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.types;
+
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+
+public class TestFeatureType extends UpdateManagerTestCase {
+
+
+	private static final String PACKAGED_FEATURE_TYPE = "packaged"; //$NON-NLS-1$
+	private static final String INSTALLED_FEATURE_TYPE = "installed"; //$NON-NLS-1$	
+	
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestFeatureType(String arg0) {
+		super(arg0);
+	}
+	
+	
+	public String getDefaultInstallableFeatureType() {
+		String pluginID = UpdateCore.getPlugin().getDescriptor().getUniqueIdentifier() + "."; //$NON-NLS-1$
+		return pluginID + PACKAGED_FEATURE_TYPE;
+	}
+	
+	public String getDefaultExecutableFeatureType() {
+		String pluginID = UpdateCore.getPlugin().getDescriptor().getUniqueIdentifier() + "."; //$NON-NLS-1$
+		return pluginID + INSTALLED_FEATURE_TYPE;
+	}		
+	
+	/**
+	 * @throws Exception
+	 */
+	public void testSimplePackagedFeatureType() throws Exception{ 
+		FeatureTypeFactory factories = FeatureTypeFactory.getInstance();
+		IFeatureFactory factory = factories.getFactory(getDefaultInstallableFeatureType());
+		
+		ISite site = SiteManager.getSite(SOURCE_FILE_SITE,null);
+		URL featureURL = new URL(SOURCE_FILE_SITE,"features/features2.jar ");
+		
+		IFeature anotherFeature = factory.createFeature(featureURL,site,null);
+		
+		assertTrue("Factory doesn't create same feature",anotherFeature.getVersionedIdentifier().equals(anotherFeature.getVersionedIdentifier()));
+	}	
+	
+		/**
+	 * @throws Exception
+	 */
+	public void testSimpleExecutableFeatureType() throws Exception{ 
+		FeatureTypeFactory factories = FeatureTypeFactory.getInstance();
+		IFeatureFactory factory = factories.getFactory(getDefaultExecutableFeatureType());
+		
+		ISite site = SiteManager.getSite(SOURCE_FILE_SITE,null);
+		URL featureURL = new URL(SOURCE_FILE_SITE,"testAPI/"+Site.DEFAULT_INSTALLED_FEATURE_PATH+"feature3/");
+		
+		IFeature anotherFeature = factory.createFeature(featureURL,site,null);
+		
+		assertTrue("Factory doesn't create same feature",anotherFeature.getVersionedIdentifier().equals(anotherFeature.getVersionedIdentifier()));
+	}	
+	
+	/**
+	 * @throws Exception
+	 */
+	public void testFeatureType() throws Exception{ 
+		FeatureTypeFactory factories = FeatureTypeFactory.getInstance();
+		IFeatureFactory factory = factories.getFactory(getDefaultInstallableFeatureType());
+		
+		ISite site = SiteManager.getSite(SOURCE_HTTP_SITE,null);
+		IFeature feature = site.getFeatureReferences()[0].getFeature(null);
+		
+		IFeature anotherFeature = factory.createFeature(feature.getURL(),site,null);
+		
+		assertTrue("Factory doesn't create same feature",feature.getVersionedIdentifier().equals(anotherFeature.getVersionedIdentifier()));
+	}
+	
+	
+	/**
+	 * @throws Exception
+	 */
+	public void testFeatureNewType() throws Exception{ 
+		FeatureTypeFactory factories = FeatureTypeFactory.getInstance();
+		IFeatureFactory factory = factories.getFactory(getDefaultExecutableFeatureType());
+		
+		String featurePath = dataPath+"FeatureTypeExamples/site1/site.xml";
+		ISite site = SiteManager.getSite(new File(featurePath).toURL(),null);
+		IFeatureReference ref = site.getFeatureReferences()[0];
+		IFeature feature = ref.getFeature(null);
+		
+		IFeature anotherFeature = factory.createFeature(feature.getURL(),site,null);
+
+		assertTrue(feature.getFeatureContentProvider() instanceof FeatureExecutableContentProvider);		
+		assertTrue(((FeatureReference)ref).getType().equals("org.eclipse.update.tests.core.feature1"));		
+		assertTrue("Factory doesn't create same feature",feature.getVersionedIdentifier().equals(anotherFeature.getVersionedIdentifier()));
+
+
+	}
+	
+	
+		/**
+	 * @throws Exception
+	 */
+	public void testFeatureAnotherType() throws Exception{ 
+		FeatureTypeFactory factories = FeatureTypeFactory.getInstance();
+		IFeatureFactory factory = factories.getFactory(getDefaultInstallableFeatureType());
+		
+		String featurePath = dataPath+"FeatureTypeExamples/site2/site.xml";
+		ISite site = SiteManager.getSite(new File(featurePath).toURL(),null);
+		IFeatureReference ref = site.getFeatureReferences()[0];		
+		IFeature feature = ref.getFeature(null);
+		
+		IFeature anotherFeature = factory.createFeature(feature.getURL(),site,null);
+		
+		assertTrue("Factory doesn't create same feature",feature.getVersionedIdentifier().equals(anotherFeature.getVersionedIdentifier()));
+		assertTrue(feature.getFeatureContentProvider() instanceof FeaturePackagedContentProvider);
+		assertTrue(((FeatureReference)ref).getType().equals("org.eclipse.update.core.packaged"));
+		
+	}
+		
+		
+	/**
+	 * @throws Exception
+	 */
+	public void testFeatureUnknownType() throws Exception{ 
+		String featurePath = dataPath+"FeatureTypeExamples/site3/site.xml";
+		ISite site = SiteManager.getSite(new File(featurePath).toURL(),null);
+		IFeatureReference ref = site.getFeatureReferences()[0];		
+		try {
+			ref.getFeature(null);
+			assertTrue("id found, should not be found",false);
+		} catch (CoreException e){
+			if (e.getMessage().indexOf("org.eclipse.update.core.unknowntype.jar")==-1){
+				throw e;
+			}
+		}
+		
+	}		
+		
+}
+
+
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/types/TestSiteType.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/types/TestSiteType.java
new file mode 100644
index 0000000..1dc7455
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/types/TestSiteType.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.types;
+
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.Site;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.internal.core.FeaturePackagedContentProvider;
+import org.eclipse.update.internal.core.SiteURLContentProvider;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import org.eclipse.update.tests.implementation.SiteFTPFactory;
+
+public class TestSiteType extends UpdateManagerTestCase {
+
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestSiteType(String arg0) {
+		super(arg0);
+	}
+
+	/**
+	 * @throws Exception
+	 */
+	public void testSiteType() throws Exception {
+
+		String featurePath = dataPath + "SiteTypeExamples/site1/site.xml";
+		ISite site = SiteManager.getSite(new File(featurePath).toURL(),null);
+		IFeatureReference ref = site.getFeatureReferences()[0];
+		IFeature feature = ref.getFeature(null);
+
+		assertTrue(site.getSiteContentProvider() instanceof SiteURLContentProvider);
+		assertTrue(((Site) site).getType().equals("org.eclipse.update.core.http"));
+		assertTrue(feature.getFeatureContentProvider() instanceof FeaturePackagedContentProvider);
+
+	}
+
+	/**
+		 * @throws Exception
+		 */
+	public void testFTPSiteType() throws Exception {
+
+		ISite site = SiteManager.getSite(new URL(SOURCE_FILE_SITE + "FTPLikeSite/"),null);
+
+		// should not find the mapping
+		// but then should attempt to read the XML file
+		// found a new type
+		// call the new type
+		assertTrue(
+			"Wrong site type",
+			site.getType().equals("org.eclipse.update.tests.ftp"));
+		assertTrue(
+			"Wrong file",
+			site.getURL().getFile().equals("/" + SiteFTPFactory.FILE));
+
+	}
+
+	public void testParseValid1() throws Exception {
+		try {
+			URL remoteURL = new URL(SOURCE_FILE_SITE + "parsertests/siteftp.xml");
+			ISite site = SiteManager.getSite(remoteURL,null);
+			site.getArchives();
+		} catch (CoreException e) {
+			if (e.getMessage().indexOf("</feature>") == -1) {
+				throw e;
+			}
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/uivalues/AllCoreUITests.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/uivalues/AllCoreUITests.java
new file mode 100644
index 0000000..a41e599
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/uivalues/AllCoreUITests.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.uivalues;
+
+import org.eclipse.update.tests.UpdateManagerTestCase;
+import junit.framework.*;
+
+
+public class AllCoreUITests extends UpdateManagerTestCase {
+public AllCoreUITests(String name) {
+	super(name);
+}
+public static Test suite() {
+	TestSuite suite = new TestSuite();
+	suite.setName("Regular Install Tests");
+	
+	// the following will take all teh test methods in teh class that start with 'test'
+	suite.addTest(new TestSuite(TestUILabel.class));
+	
+	// or you can specify the method
+	//suite.addTest(new TestGetFeature("methodThatDoesNotStartWithtest"));	
+	
+	return suite;
+}
+}
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/uivalues/TestUILabel.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/uivalues/TestUILabel.java
new file mode 100644
index 0000000..6cef7dd
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/uivalues/TestUILabel.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.tests.uivalues;
+
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.update.core.*;
+import org.eclipse.update.tests.UpdateManagerTestCase;
+
+
+public class TestUILabel extends UpdateManagerTestCase {
+
+	/**
+	 * Test the getFeatures()
+	 */
+	public TestUILabel(String arg0) {
+		super(arg0);
+	}
+	
+	
+	/**
+	 * Method testHTTPSite.
+	 * @throws Exception
+	 */
+	public void testUpdateManagerSite() throws Exception{ 
+		
+		ISite remoteSite = SiteManager.getSite(new URL("http",getHttpHost(),getHttpPort(),bundle.getString("HTTP_PATH_2")),null);
+		ICategory[] categories = remoteSite.getCategories();
+		for (int i =0; i<categories.length; i++){
+			System.out.println("Category ->"+categories[i].getLabel()+":"+categories[i].getName());
+		}
+		System.out.println(remoteSite.getDescription().getURL().toExternalForm());
+		IFeatureReference[] remoteFeatures = remoteSite.getFeatureReferences();
+		if (remoteFeatures==null || remoteFeatures.length==0) fail("No feature available for testing");		
+		for (int i=0;i<remoteFeatures.length;i++){
+			IFeature feature = remoteFeatures[i].getFeature(null);
+			System.out.println("feature:"+feature.getVersionedIdentifier()+"->"+feature.getLabel());
+			print(feature.getLicense(),"License");
+			print(feature.getCopyright(),"Copyright");			
+			print(feature.getDescription(),"Description");				
+			
+			// check that it downloads the feature.jar under the cover
+			// and unpack it
+			
+			URL url = feature.getLicense().getURL();
+			if (url!=null){
+				assertTrue((new File(url.getFile())).exists());
+			}
+
+			url = feature.getCopyright().getURL();
+			if (url!=null){
+				assertTrue((new File(url.getFile())).exists());
+			}
+			
+			url = feature.getDescription().getURL();
+			if (url!=null){
+				assertTrue((new File(url.getFile())).exists());
+			}
+			
+		}
+	}
+	
+	
+	/**
+	 * Method print.
+	 * @param info
+	 * @param text
+	 */
+	private void print(IURLEntry info, String text){
+		System.out.print("->"+text+":");
+		if (info.getURL()!=null) 
+			System.out.println("<"+info.getURL().toExternalForm()+">");
+		else 
+			System.out.println(info.getAnnotation());
+	}
+} 
+
+
diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/features space/helpFeature.jar b/update/org.eclipse.update.tests.core/webserver/Site with space/features space/helpFeature.jar
new file mode 100644
index 0000000..959e02c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/features space/helpFeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/features space/space feature.jar b/update/org.eclipse.update.tests.core/webserver/Site with space/features space/space feature.jar
new file mode 100644
index 0000000..21a6d55
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/features space/space feature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/info/img/top_titlsm.gif b/update/org.eclipse.update.tests.core/webserver/Site with space/info/img/top_titlsm.gif
new file mode 100644
index 0000000..3917bb6
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/info/img/top_titlsm.gif
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/info/img/wel_ml.jpg b/update/org.eclipse.update.tests.core/webserver/Site with space/info/img/wel_ml.jpg
new file mode 100644
index 0000000..01e33df
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/info/img/wel_ml.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/info/siteInfo.html b/update/org.eclipse.update.tests.core/webserver/Site with space/info/siteInfo.html
new file mode 100644
index 0000000..b065aa3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/info/siteInfo.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

+<html>

+<head>

+</head>

+  <body>

+<img src="img/top_titlsm.gif" alt="" width="460" height="50">

+<br>

+<br>

+     It started with Smalltalk<br>

+    OTI has been building tools for platform-independent OO development since

+  1988. Our ENVY&reg; technology first brought collaborative software development,

+  version management and shared repositories to Smalltalk. IBM is one of

+many   companies to license ENVY, which continues to be the foundation of

+VisualAge&reg;   Smalltalk.<br>

+<br>

+<br>

+<br>

+      Next came Java&#8482;<br>

+    Because of our expertise in OO technology, IBM turned to OTI for a next-generation

+  development environment for Java. The result is VisualAge for Java, which

+  continues to win awards for its innovative IDE and team support. InfoWorld

+  has chosen VisualAge for Java as development tool of the year - year after

+  year after year!<br>

+<br>

+<br>

+<br>

+      Then pervasive computing<br>

+    OTI continues its development of IBM's VisualAge Micro Edition, a state-of-the-art

+  platform for collaborative development of embedded applications and systems

+  that are very lean. As the steady stream of press releases attests, VisualAge

+  Micro Edition is already licensed to the leading microchip manufacturers,

+  microkernel developers, and producers of handheld and consumer devices.<br>

+<br>

+<br>

+<br>

+      Now it's Eclipse<br>

+    OTI has built the next generation IBM application development tools platform.

+  Eclipse is a kind of universal tool platform - an open extensible IDE for

+  anything and nothing in particular. The real value comes from tool plug-ins

+  that "teach" Eclipse how to work with things - java files, web content,

+graphics,  video - almost anything you can imagine. Eclipse allows you to

+independently  develop tools that integrate with other people's tools so

+seamlessly you won't know where one tool ends and another starts. The IBM

+supported version of this technology, WebSphere Studio Workbench, will be

+the core of the next  generation of IBM and IBM Business Partner e-business

+tools optimized for  the WebSphere software platform.<br>

+<br>

+<br>

+<br>

+      So what's next?<br>

+    OTI continues to deliver object-oriented technology that scales across

+ platforms,  across teams and across project size. From a mainframe to a

+watch  - we're  closing in on that vision.<br>

+<br>

+<img src="img/wel_ml.jpg" width="460" height="460" alt="">

+<br>

+<br>

+<br>

+<br>

+<br>

+<br>

+</body>

+</html>

diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/install/features space/feature3/feature.xml b/update/org.eclipse.update.tests.core/webserver/Site with space/install/features space/feature3/feature.xml
new file mode 100644
index 0000000..67741d9
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/install/features space/feature3/feature.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature id="org.eclipse.update.core.tests.feature3" image="feature1.gif" label="Third Feature" provider-name="Smart Company" version="1.0.0" >

+  <description>Description</description>

+  <copyright>copyright</copyright>

+  <license>license</license>

+  <url>

+    <update label="URL to update the feature" url="http://www.eclipse.org/path/feature1/"/>

+    <discovery label="Discovery 1" url="http://www.eclipse.org"/>

+    <discovery label="Discovery 2" url="http://www.eclipse.org"/>

+  </url>

+</feature>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/plugins space/Pde_core.jar b/update/org.eclipse.update.tests.core/webserver/Site with space/plugins space/Pde_core.jar
new file mode 100644
index 0000000..f107217
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/plugins space/Pde_core.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/plugins space/help.jar b/update/org.eclipse.update.tests.core/webserver/Site with space/plugins space/help.jar
new file mode 100644
index 0000000..7584f66
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/plugins space/help.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/plugins space/junit_3.7.jar b/update/org.eclipse.update.tests.core/webserver/Site with space/plugins space/junit_3.7.jar
new file mode 100644
index 0000000..67587b2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/plugins space/junit_3.7.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/Site with space/site.xml b/update/org.eclipse.update.tests.core/webserver/Site with space/site.xml
new file mode 100644
index 0000000..b5d4bbf
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/Site with space/site.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site>

+<description url="info/siteInfo.html"/>

+  <feature url="features space/helpFeature.jar">

+    <category name="eclipse/UML"/>

+  </feature>

+  <feature url="features space/space feature.jar">

+    <category name="eclipse/J2EE"/>

+  </feature>

+

+  <archive path="plugins/org.eclipse.help_1.0.0.jar" url="plugins space/help.jar"/>

+  <archive path="plugins/org.eclipse.pde.core_1.0.0.jar" url="plugins space/Pde_core.jar"/>

+  <archive path="plugins/org.junit_3.5.0.jar" url="plugins space/junit_3.7.jar"/>

+  <archive path="plugins/org.eclipse.update.plugin1_1.1.1" url="plugins space/org.eclipse.update.plugin1_1.1.1"/>  

+  <category-def label="IBM WSAD Tools" name="eclipse"/>

+  <category-def label="J2EE tools" name="eclipse/J2EE"/>

+  <category-def label="EJB Tools" name="eclipse/J2EE/EJB"/>

+  <category-def label="UML tools" name="eclipse/UML"/>

+  <category-def label="Messaging Tools" name="B2B"/>  

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager/features/helpFeature.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager/features/helpFeature.jar
new file mode 100644
index 0000000..aec67d4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager/features/helpFeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager/features/org.eclipse.pde.feature_1.0.0.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager/features/org.eclipse.pde.feature_1.0.0.jar
new file mode 100644
index 0000000..870b40a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager/features/org.eclipse.pde.feature_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager/info/img/top_titlsm.gif b/update/org.eclipse.update.tests.core/webserver/UpdateManager/info/img/top_titlsm.gif
new file mode 100644
index 0000000..3917bb6
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager/info/img/top_titlsm.gif
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager/info/img/wel_ml.jpg b/update/org.eclipse.update.tests.core/webserver/UpdateManager/info/img/wel_ml.jpg
new file mode 100644
index 0000000..01e33df
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager/info/img/wel_ml.jpg
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager/info/siteInfo.html b/update/org.eclipse.update.tests.core/webserver/UpdateManager/info/siteInfo.html
new file mode 100644
index 0000000..b065aa3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager/info/siteInfo.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

+<html>

+<head>

+</head>

+  <body>

+<img src="img/top_titlsm.gif" alt="" width="460" height="50">

+<br>

+<br>

+     It started with Smalltalk<br>

+    OTI has been building tools for platform-independent OO development since

+  1988. Our ENVY&reg; technology first brought collaborative software development,

+  version management and shared repositories to Smalltalk. IBM is one of

+many   companies to license ENVY, which continues to be the foundation of

+VisualAge&reg;   Smalltalk.<br>

+<br>

+<br>

+<br>

+      Next came Java&#8482;<br>

+    Because of our expertise in OO technology, IBM turned to OTI for a next-generation

+  development environment for Java. The result is VisualAge for Java, which

+  continues to win awards for its innovative IDE and team support. InfoWorld

+  has chosen VisualAge for Java as development tool of the year - year after

+  year after year!<br>

+<br>

+<br>

+<br>

+      Then pervasive computing<br>

+    OTI continues its development of IBM's VisualAge Micro Edition, a state-of-the-art

+  platform for collaborative development of embedded applications and systems

+  that are very lean. As the steady stream of press releases attests, VisualAge

+  Micro Edition is already licensed to the leading microchip manufacturers,

+  microkernel developers, and producers of handheld and consumer devices.<br>

+<br>

+<br>

+<br>

+      Now it's Eclipse<br>

+    OTI has built the next generation IBM application development tools platform.

+  Eclipse is a kind of universal tool platform - an open extensible IDE for

+  anything and nothing in particular. The real value comes from tool plug-ins

+  that "teach" Eclipse how to work with things - java files, web content,

+graphics,  video - almost anything you can imagine. Eclipse allows you to

+independently  develop tools that integrate with other people's tools so

+seamlessly you won't know where one tool ends and another starts. The IBM

+supported version of this technology, WebSphere Studio Workbench, will be

+the core of the next  generation of IBM and IBM Business Partner e-business

+tools optimized for  the WebSphere software platform.<br>

+<br>

+<br>

+<br>

+      So what's next?<br>

+    OTI continues to deliver object-oriented technology that scales across

+ platforms,  across teams and across project size. From a mainframe to a

+watch  - we're  closing in on that vision.<br>

+<br>

+<img src="img/wel_ml.jpg" width="460" height="460" alt="">

+<br>

+<br>

+<br>

+<br>

+<br>

+<br>

+</body>

+</html>

diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager/plugins/Pde_core.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager/plugins/Pde_core.jar
new file mode 100644
index 0000000..f107217
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager/plugins/Pde_core.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager/plugins/help.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager/plugins/help.jar
new file mode 100644
index 0000000..7584f66
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager/plugins/help.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager/plugins/junit_3.7.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager/plugins/junit_3.7.jar
new file mode 100644
index 0000000..67587b2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager/plugins/junit_3.7.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager/site.xml b/update/org.eclipse.update.tests.core/webserver/UpdateManager/site.xml
new file mode 100644
index 0000000..5e5fda7
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager/site.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site >

+<description url="info/siteInfo.html"/>

+  <feature url="features/helpFeature.jar">

+    <category name="eclipse/UML"/>

+  </feature>

+  <feature url="features/org.eclipse.pde.feature_1.0.0.jar">

+    <category name="eclipse/J2EE"/>

+  </feature>

+  <archive path="plugins/org.eclipse.help_1.0.0.jar" url="plugins/help.jar"/>

+  <archive path="plugins/org.eclipse.pde.core_1.0.0.jar" url="plugins/Pde_core.jar"/>

+  <archive path="plugins/org.junit_3.5.0.jar" url="plugins/junit_3.7.jar"/>

+  <category-def label="IBM WSAD Tools" name="eclipse"/>

+  <category-def label="J2EE tools" name="eclipse/J2EE"/>

+  <category-def label="EJB Tools" name="eclipse/J2EE/EJB"/>

+  <category-def label="UML tools" name="eclipse/UML"/>

+  <category-def label="Messaging Tools" name="B2B"/>  

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/features2.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/features2.jar
new file mode 100644
index 0000000..81df72c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/features2.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/org.eclipse.test.feature_1.0.0.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/org.eclipse.test.feature_1.0.0.jar
new file mode 100644
index 0000000..d1aee3f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/org.eclipse.test.feature_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/org.eclipse.update.core.tests.feature1_1.0.4.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/org.eclipse.update.core.tests.feature1_1.0.4.jar
new file mode 100644
index 0000000..f515ff4
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/org.eclipse.update.core.tests.feature1_1.0.4.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/org.eclipse_test_feature.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/org.eclipse_test_feature.jar
new file mode 100644
index 0000000..2be38d3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/features/org.eclipse_test_feature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/features/org.eclipse.update.core.tests.childrenfeature_2.0.0.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/features/org.eclipse.update.core.tests.childrenfeature_2.0.0.jar
new file mode 100644
index 0000000..022665c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/features/org.eclipse.update.core.tests.childrenfeature_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/features/rootfeature.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/features/rootfeature.jar
new file mode 100644
index 0000000..b519803
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/features/rootfeature.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
new file mode 100644
index 0000000..5d9f5bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
new file mode 100644
index 0000000..8b4b04a
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar
new file mode 100644
index 0000000..52208fe
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/site.xml b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/site.xml
new file mode 100644
index 0000000..7b09c86
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/nestedFeatureSiteTest/site.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+  <feature url="features/rootfeature.jar" os="*"/>
+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar
new file mode 100644
index 0000000..b00d882
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.feature1.plugin1_1.1.1.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.feature1.plugin1_1.1.1.jar
new file mode 100644
index 0000000..0c995d5
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.feature1.plugin1_1.1.1.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.feature2.plugin2_2.2.2.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.feature2.plugin2_2.2.2.jar
new file mode 100644
index 0000000..0c995d5
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.feature2.plugin2_2.2.2.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.tests.dummy_7.9.8.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.tests.dummy_7.9.8.jar
new file mode 100644
index 0000000..d6737f6
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.tests.dummy_7.9.8.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
new file mode 100644
index 0000000..eb8690f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.tests.feature1.plugin1_3.5.6.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
new file mode 100644
index 0000000..90a612f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/plugins/org.eclipse.update.core.tests.feature1.plugin2_5.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/UpdateManager2/site.xml b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/site.xml
new file mode 100644
index 0000000..657d9b2
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/UpdateManager2/site.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<site id="org.eclipse.update.core.tests" name="Tests" version="0.0.1">

+  <feature url="features/org.eclipse.test.feature_1.0.0.jar">

+    <category name="category1"/>

+  </feature>

+  <feature url="features/features2.jar">

+    <category name="category1/subcat1"/>

+    <category name="category2"/>

+  </feature>

+  <feature url="features/org.eclipse.update.core.tests.feature1_1.0.4.jar">

+    <category name="category1"/>

+    <category name="category2"/>

+  </feature>

+  <feature url="features/org.eclipse_test_feature.jar"/>

+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">

+    <category name="category1"/>

+  </feature>

+  <feature url="org.eclipse.update.core.feature2_1.0.0/org.eclipse.update.core.feature2_2.2.2.jar">

+  </feature>

+

+  <category-def name="category1/subcat1" label="Special Fix"/>

+  <category-def name="category1" label="%drivers"/>

+  <category-def name="category2" label="%security"/>

+</site>
\ No newline at end of file
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSite/features/com.example.bundle.feature_1.0.0.jar b/update/org.eclipse.update.tests.core/webserver/bundleSite/features/com.example.bundle.feature_1.0.0.jar
new file mode 100644
index 0000000..20d3589
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSite/features/com.example.bundle.feature_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.budle.fragment.ui_1.0.0.jar b/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.budle.fragment.ui_1.0.0.jar
new file mode 100644
index 0000000..d79d2cd
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.budle.fragment.ui_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.bundle.fragment_1.0.0.jar b/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.bundle.fragment_1.0.0.jar
new file mode 100644
index 0000000..edb02bb
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.bundle.fragment_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.bundle.plugin.ui_2.0.0.jar b/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.bundle.plugin.ui_2.0.0.jar
new file mode 100644
index 0000000..32ec02c
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.bundle.plugin.ui_2.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.bundle.plugin_1.0.0.jar b/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.bundle.plugin_1.0.0.jar
new file mode 100644
index 0000000..2b1b693
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSite/plugins/com.example.bundle.plugin_1.0.0.jar
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSite/site.xml b/update/org.eclipse.update.tests.core/webserver/bundleSite/site.xml
new file mode 100644
index 0000000..bab1332
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSite/site.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <feature url="features/com.example.bundle.feature_1.0.0.jar" id="com.example.bundle.feature" version="1.0.0">
+      <category name="BundleFeature"/>
+   </feature>
+   <category-def name="BundleFeature" label="Feature with Bundles"/>
+</site>
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/.classpath b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/.classpath
new file mode 100644
index 0000000..065ac06
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/.project b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/.project
new file mode 100644
index 0000000..8e20903
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/.project
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>com.example.budle.fragment.ui</name>
+	<comment></comment>
+	<projects>
+		<project>com.example.bundle.plugin</project>
+		<project>com.example.bundle.plugin.ui</project>
+		<project>org.eclipse.core.runtime</project>
+		<project>org.eclipse.ui</project>
+	</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/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/.template b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/.template
new file mode 100644
index 0000000..f3bcd41
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/.template
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<form>

+   <p/><p><b>Tips on working with this plug-in project</b></p><li>For the view of the new plug-in at a glance, go to the <img href="pageImage"/><a href="OverviewPage">Overview</a>.</li><li>You can test the contributions of this plug-in by launching another instance of the workbench. On the <b>Run</b> menu, click <b>Run As</b> and choose <img href="runTimeWorkbenchImage"/><a href="action.run">Run-time Workbench</a> from the available choices.</li><li>You can add more functionality to this plug-in by adding extensions using the <a href="action.newExtension">New Extension Wizard</a>.</li><li>The plug-in project contains Java code that you can debug. Place breakpoints in Java classes. On the <b>Run</b> menu, select <b>Debug As</b> and choose <img href="runTimeWorkbenchImage"/><a href="action.debug">Run-time Workbench</a> from the available choices.</li>

+</form>

diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2ad686f
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Generated-from: 1077062974451

+Bundle-Name: Ui Fragment

+Bundle-Version: 1.0.0

+Bundle-SymbolicName: com.example.budle.fragment.ui

+Bundle-Vendor: Eclipse.org

+Bundle-ClassPath: ui.jar

+Legacy: true

+Fragment-Host: com.example.bundle.plugin.ui; bundle-version=2.0.0

diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/fragment.xml b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/fragment.xml
new file mode 100644
index 0000000..3c484b3
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.budle.fragment.ui/fragment.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<fragment
+   id="com.example.budle.fragment.ui"
+   name="Ui Fragment"
+   version="1.0.0"
+   provider-name="Eclipse.org"
+   plugin-id="com.example.bundle.plugin.ui"
+   plugin-version="2.0.0"
+   match="greaterOrEqual">
+
+   <runtime>
+      <library name="ui.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+
+</fragment>
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.feature/.project b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.feature/.project
new file mode 100644
index 0000000..8f3e4bc
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>com.example.bundle.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/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.feature/feature.xml b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.feature/feature.xml
new file mode 100644
index 0000000..bb41043
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.feature/feature.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="com.example.bundle.feature"
+      label="com.example.bundle.feature"
+      version="1.0.0"
+      provider-name="Eclipse.org">
+
+   <license>
+      A placeholder license for the feature.
+   </license>
+
+   <install-handler/>
+
+   <requires>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.core.runtime"/>
+   </requires>
+
+   <plugin
+         id="com.example.bundle.plugin"
+         download-size="0"
+         install-size="0"
+         version="1.0.0"/>
+
+   <plugin
+         id="com.example.budle.fragment.ui"
+         download-size="0"
+         install-size="0"
+         version="1.0.0"
+         fragment="true"/>
+
+   <plugin
+         id="com.example.bundle.fragment"
+         download-size="0"
+         install-size="0"
+         version="1.0.0"
+         fragment="true"/>
+
+   <plugin
+         id="com.example.bundle.plugin.ui"
+         download-size="0"
+         install-size="0"
+         version="2.0.0"/>
+
+</feature>
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/.classpath b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/.classpath
new file mode 100644
index 0000000..065ac06
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/.project b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/.project
new file mode 100644
index 0000000..06d0c21
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/.project
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>com.example.bundle.fragment</name>
+	<comment></comment>
+	<projects>
+		<project>com.example.bundle.plugin</project>
+		<project>org.eclipse.core.runtime</project>
+		<project>org.eclipse.ui</project>
+	</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/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/.template b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/.template
new file mode 100644
index 0000000..f3bcd41
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/.template
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<form>

+   <p/><p><b>Tips on working with this plug-in project</b></p><li>For the view of the new plug-in at a glance, go to the <img href="pageImage"/><a href="OverviewPage">Overview</a>.</li><li>You can test the contributions of this plug-in by launching another instance of the workbench. On the <b>Run</b> menu, click <b>Run As</b> and choose <img href="runTimeWorkbenchImage"/><a href="action.run">Run-time Workbench</a> from the available choices.</li><li>You can add more functionality to this plug-in by adding extensions using the <a href="action.newExtension">New Extension Wizard</a>.</li><li>The plug-in project contains Java code that you can debug. Place breakpoints in Java classes. On the <b>Run</b> menu, select <b>Debug As</b> and choose <img href="runTimeWorkbenchImage"/><a href="action.debug">Run-time Workbench</a> from the available choices.</li>

+</form>

diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9d66480
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Generated-from: 1077062909487

+Bundle-Name: Fragment Fragment

+Bundle-Version: 1.0.0

+Bundle-SymbolicName: com.example.bundle.fragment

+Bundle-Vendor: Eclipse.org

+Bundle-ClassPath: fragment.jar

+Legacy: true

+Fragment-Host: com.example.bundle.plugin; bundle-version=1.0.0

diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/fragment.xml b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/fragment.xml
new file mode 100644
index 0000000..2a5cd6e
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.fragment/fragment.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<fragment
+   id="com.example.bundle.fragment"
+   name="Fragment Fragment"
+   version="1.0.0"
+   provider-name="Eclipse.org"
+   plugin-id="com.example.bundle.plugin"
+   plugin-version="1.0.0">
+
+   <runtime>
+      <library name="fragment.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+
+</fragment>
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/.classpath b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/.classpath
new file mode 100644
index 0000000..065ac06
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/.project b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/.project
new file mode 100644
index 0000000..83c3553
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/.project
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>com.example.bundle.plugin.ui</name>
+	<comment></comment>
+	<projects>
+		<project>com.example.bundle.plugin</project>
+		<project>org.eclipse.core.runtime</project>
+		<project>org.eclipse.ui</project>
+	</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/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/.template b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/.template
new file mode 100644
index 0000000..f3bcd41
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/.template
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<form>

+   <p/><p><b>Tips on working with this plug-in project</b></p><li>For the view of the new plug-in at a glance, go to the <img href="pageImage"/><a href="OverviewPage">Overview</a>.</li><li>You can test the contributions of this plug-in by launching another instance of the workbench. On the <b>Run</b> menu, click <b>Run As</b> and choose <img href="runTimeWorkbenchImage"/><a href="action.run">Run-time Workbench</a> from the available choices.</li><li>You can add more functionality to this plug-in by adding extensions using the <a href="action.newExtension">New Extension Wizard</a>.</li><li>The plug-in project contains Java code that you can debug. Place breakpoints in Java classes. On the <b>Run</b> menu, select <b>Debug As</b> and choose <img href="runTimeWorkbenchImage"/><a href="action.debug">Run-time Workbench</a> from the available choices.</li>

+</form>

diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e3507a9
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Generated-from: 1077062999827

+Bundle-Name: Ui Plug-in

+Bundle-Version: 2.0.0

+Bundle-SymbolicName: com.example.bundle.plugin.ui

+Bundle-Vendor: Eclipse.org

+Bundle-ClassPath: ui.jar

+Legacy: true

+Bundle-Activator: com.example.bundle.plugin.ui.UiPlugin

+Require-Bundle: 

+ org.eclipse.core.runtime,

+ org.eclipse.ui,

+ com.example.bundle.plugin; bundle-version=1.0.0;version-match=perfect

diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/bin/com/example/bundle/plugin/ui/UiPlugin.class b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/bin/com/example/bundle/plugin/ui/UiPlugin.class
new file mode 100644
index 0000000..5f73189
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/bin/com/example/bundle/plugin/ui/UiPlugin.class
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/plugin.xml b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/plugin.xml
new file mode 100644
index 0000000..aeffdef
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin.ui/plugin.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+   id="com.example.bundle.plugin.ui"
+   name="Ui Plug-in"
+   version="2.0.0"
+   provider-name="Eclipse.org"
+   class="com.example.bundle.plugin.ui.UiPlugin">
+
+   <runtime>
+      <library name="ui.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+   <requires>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="com.example.bundle.plugin" version="1.0.0" match="perfect"/>
+   </requires>
+
+
+</plugin>
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/.classpath b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/.classpath
new file mode 100644
index 0000000..065ac06
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/.project b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/.project
new file mode 100644
index 0000000..1719d73
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/.project
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>com.example.bundle.plugin</name>
+	<comment></comment>
+	<projects>
+		<project>org.eclipse.core.runtime</project>
+		<project>org.eclipse.ui</project>
+	</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/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/.template b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/.template
new file mode 100644
index 0000000..f3bcd41
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/.template
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<form>

+   <p/><p><b>Tips on working with this plug-in project</b></p><li>For the view of the new plug-in at a glance, go to the <img href="pageImage"/><a href="OverviewPage">Overview</a>.</li><li>You can test the contributions of this plug-in by launching another instance of the workbench. On the <b>Run</b> menu, click <b>Run As</b> and choose <img href="runTimeWorkbenchImage"/><a href="action.run">Run-time Workbench</a> from the available choices.</li><li>You can add more functionality to this plug-in by adding extensions using the <a href="action.newExtension">New Extension Wizard</a>.</li><li>The plug-in project contains Java code that you can debug. Place breakpoints in Java classes. On the <b>Run</b> menu, select <b>Debug As</b> and choose <img href="runTimeWorkbenchImage"/><a href="action.debug">Run-time Workbench</a> from the available choices.</li>

+</form>

diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/META-INF/MANIFEST.MF b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..fc1adaf
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Generated-from: 1077062603708

+Bundle-Name: Plugin Plug-in

+Bundle-Version: 1.0.0

+Bundle-SymbolicName: com.example.bundle.plugin

+Bundle-Vendor: EXAMPLE

+Bundle-ClassPath: plugin.jar

+Legacy: true

+Bundle-Activator: com.example.bundle.plugin.PluginPlugin

+Require-Bundle: 

+ org.eclipse.core.runtime,

+ org.eclipse.ui

diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/bin/com/example/bundle/plugin/PluginPlugin.class b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/bin/com/example/bundle/plugin/PluginPlugin.class
new file mode 100644
index 0000000..76caf03
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/bin/com/example/bundle/plugin/PluginPlugin.class
Binary files differ
diff --git a/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/plugin.xml b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/plugin.xml
new file mode 100644
index 0000000..297bc76
--- /dev/null
+++ b/update/org.eclipse.update.tests.core/webserver/bundleSitesrc/com.example.bundle.plugin/plugin.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+   id="com.example.bundle.plugin"
+   name="Plugin Plug-in"
+   version="1.0.0"
+   provider-name="Eclipse.org"
+   class="com.example.bundle.plugin.PluginPlugin">
+
+   <runtime>
+      <library name="plugin.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+   <requires>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.core.runtime"/>
+   </requires>
+
+
+</plugin>
diff --git a/update/org.eclipse.update.ui.forms/.project b/update/org.eclipse.update.ui.forms/.project
new file mode 100644
index 0000000..2d96b51
--- /dev/null
+++ b/update/org.eclipse.update.ui.forms/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.update.ui.forms</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+	</buildSpec>

+	<natures>

+	</natures>

+</projectDescription>

diff --git a/update/org.eclipse.update.ui.forms/README.TXT b/update/org.eclipse.update.ui.forms/README.TXT
new file mode 100644
index 0000000..3a9a8a4
--- /dev/null
+++ b/update/org.eclipse.update.ui.forms/README.TXT
@@ -0,0 +1,2 @@
+This bundle is obsolete. Functionality from this bundle was moved to org.eclipse.ui.forms
+in the Eclipse 3.0 release.
\ No newline at end of file
diff --git a/update/org.eclipse.update.ui.win32/.project b/update/org.eclipse.update.ui.win32/.project
new file mode 100644
index 0000000..4c64a08
--- /dev/null
+++ b/update/org.eclipse.update.ui.win32/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.update.ui.win32</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+	</buildSpec>

+	<natures>

+	</natures>

+</projectDescription>

diff --git a/update/org.eclipse.update.ui.win32/README.TXT b/update/org.eclipse.update.ui.win32/README.TXT
new file mode 100644
index 0000000..413cdb7
--- /dev/null
+++ b/update/org.eclipse.update.ui.win32/README.TXT
@@ -0,0 +1,2 @@
+This bundle is obsolete. It contained welcome content that is now in org.eclipse.ui.ide. This
+bundle was removed from the Eclipse SDK after the Eclipse 2.1 release.
\ No newline at end of file
diff --git a/update/org.eclipse.update.ui/.classpath b/update/org.eclipse.update.ui/.classpath
new file mode 100644
index 0000000..f1b3ad8
--- /dev/null
+++ b/update/org.eclipse.update.ui/.classpath
@@ -0,0 +1,7 @@
+<?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.4"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/update/org.eclipse.update.ui/.cvsignore b/update/org.eclipse.update.ui/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/update/org.eclipse.update.ui/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/update/org.eclipse.update.ui/.project b/update/org.eclipse.update.ui/.project
new file mode 100644
index 0000000..7085851
--- /dev/null
+++ b/update/org.eclipse.update.ui/.project
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.update.ui</name>

+	<comment></comment>

+	<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.jdt.core.javanature</nature>

+		<nature>org.eclipse.pde.PluginNature</nature>

+	</natures>

+</projectDescription>

diff --git a/update/org.eclipse.update.ui/.settings/org.eclipse.jdt.core.prefs b/update/org.eclipse.update.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ba534cd
--- /dev/null
+++ b/update/org.eclipse.update.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,69 @@
+#Tue Dec 09 11:11:23 EST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/update/org.eclipse.update.ui/Graphics_update.html b/update/org.eclipse.update.ui/Graphics_update.html
new file mode 100644
index 0000000..fdae1a3
--- /dev/null
+++ b/update/org.eclipse.update.ui/Graphics_update.html
@@ -0,0 +1,955 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!-- saved from url=(0110)http://design.torolab.ibm.com/aim/WSWB-eclipse/1020_PDE/implementation_icons/org.eclipse.pde/Graphics_pde.html -->
+<HTML><HEAD><TITLE>graphics</TITLE>
+<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<META content="Greg Adams" name=Author>
+<META content="Microsoft FrontPage 4.0" name=GENERATOR></HEAD>
+<BODY bgColor=white>
+<H2>org.eclipse.update.ui - Graphics Summary</H2><FONT size=-1><STRONG>Competency 
+lead: </STRONG>Vlad Klicnik / TOL <BR><STRONG>Technical lead: </STRONG>Dejan 
+Glozic / TOL <BR><STRONG>UCD designer: </STRONG>Julian Jones / TOL 
+<BR><STRONG>UI designer: </STRONG>Andrée Proulx / TOL <BR><STRONG>ID writer: 
+</STRONG>-</FONT> 
+<HR width="100%" SIZE=1>
+<B><FONT size=-1>History:</FONT></B> 
+<p><font size="-1">April 19, 2002 : Template Submission</font></p>
+<HR width="100%" SIZE=1>
+<!--- Start Here --->
+<TABLE cellSpacing=0 cellPadding=3 width="100%" border=0 height="3147">
+  
+  <TR bgColor=#bfbf7f>
+    <TD colSpan=7><B><FONT size=+2>View</FONT></B></TD></TR>
+  <TR bgColor=#dfdf9f>
+    <TD>&nbsp;</TD>
+    <TD><B><FONT size=-1>Item</FONT></B></TD>
+    <TD><B><FONT size=-1>File Name&nbsp; (.gif)</FONT></B></TD>
+    <TD><B><FONT size=-1>Description/Hoover Help</FONT></B></TD>
+    <TD>
+      <CENTER><B><FONT size=-1>Old</FONT></B> </CENTER></TD>
+    <TD>
+      <CENTER><B><FONT size=-1>New Full</FONT></B> </CENTER></TD>
+    <TD><B><FONT size=-1>Status</FONT></B></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>1</TD>
+    <TD>Configurations</TD>
+    <TD><FONT size=-1>configs</FONT></TD>
+    <TD><FONT size=-1> shows the configurations of the Eclipse-based application</FONT></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/view16/configs.gif" width=16 border=0></TD>
+    <TD><IMG height=16 alt="" 
+      src="icons/full/cview16/configs.gif" width=16 border=0>&nbsp;<IMG height=16 
+      alt="" src="icons/full/eview16/configs.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>2</TD>
+    <TD>Updates</TD>
+    <TD><FONT size=-1>updates</FONT></TD>
+    <TD><FONT size=-1>shows sites an Eclipse app can be updated from</FONT></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/view16/updates.gif" width=16 border=0></TD>
+    <TD><IMG height=16 alt="" 
+      src="icons/full/cview16/updates.gif" width=16 border=0>&nbsp;<IMG height=16 
+      alt="" src="icons/full/eview16/updates.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>3</TD>
+    <TD>Preview</TD>
+    <TD><font size="-1">preview</font></TD>
+    <TD><font size="-1">shows details of the selected object</font></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/view16/preview.gif" width=16 border=0></TD>
+    <TD><IMG height=16 alt="" 
+      src="icons/full/cview16/preview.gif" width=16 border=0>&nbsp;<IMG height=16 
+      alt="" src="icons/full/eview16/preview.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>4</TD>
+    <TD>Web Browser</TD>
+    <TD><font size="-1">browser</font></TD>
+    <TD><font size="-1">a fully-functioning Web browser (hosts IE5 - Windows only)</font></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/view16/browser.gif" width=16 border=0></TD>
+    <TD><IMG height=16 alt="" 
+      src="icons/full/cview16/browser.gif" width=16 border=0>&nbsp;<IMG height=16 
+      alt="" src="icons/full/eview16/browser.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+   <TR bgColor=#ffffff>
+    <TD>5</TD>
+    <TD>Update Perspective</TD>
+    <TD><font size="-1">update_pers</font></TD>
+    <TD><font size="-1">Represents Install/Update
+      perspective in the UI</font></TD>
+    <TD></TD>
+    <TD><IMG height=16 alt="" 
+      src="icons/full/cview16/update_pers.gif" width=16 border=0>&nbsp;<IMG height=16 
+      alt="" src="icons/full/eview16/update_pers.gif" width=16 
+border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD>
+  </TR>
+  
+  <TR bgColor=#bfbf7f>
+    <TD colSpan=7><B><FONT size=+2>Toolbar Wizard</FONT></B></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>1</TD>
+    <TD> </TD>
+    <TD><FONT size=-1>&nbsp;</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">    description</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;tool tip&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/ctool16/config_wiz.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/etool16/config_wiz.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dtool16/config_wiz.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+	
+  <TR bgColor=#dfdf9f>
+    <TD>2</TD>
+    <TD> </TD>
+    <TD><FONT size=-1></FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">    description</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;tool tip&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/ctool16/install_wiz.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/etool16/install_wiz.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dtool16/install_wiz.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  
+  <TR bgColor=#ffffff>
+    <TD>3</TD>
+    <TD> </TD>
+    <TD><FONT size=-1>&nbsp;</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">    description</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;tool tip&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/ctool16/new_bookmark_wiz.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/etool16/new_bookmark_wiz.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dtool16/new_bookmark_wiz.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+	
+  <TR bgColor=#dfdf9f>
+    <TD>4</TD>
+    <TD> </TD>
+    <TD><FONT size=-1>&nbsp;</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">    description</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;tool tip&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/ctool16/new_folder_wiz.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/etool16/new_folder_wiz.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dtool16/new_folder_wiz.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>5</TD>
+    <TD> </TD>
+    <TD><FONT size=-1>&nbsp;</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">    description</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;tool tip&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/ctool16/new_search_wiz.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/etool16/new_search_wiz.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dtool16/new_search_wiz.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+	
+  <TR bgColor=#dfdf9f>
+    <TD>6</TD>
+    <TD> </TD>
+    <TD><FONT size=-1>&nbsp;</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">    description</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;tool tip&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/ctool16/uninstall_wiz.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/etool16/uninstall_wiz.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dtool16/uninstall_wiz.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+	<TR bgColor=#ffffff>
+    <TD>7</TD>
+    <TD> </TD>
+    <TD><FONT size=-1>&nbsp;</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">    description</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;tool tip&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/ctool16/update_wiz.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/etool16/update_wiz.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dtool16/update_wiz.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  
+  
+  <TR bgColor=#bfbf7f>
+    <TD colSpan=7><B><FONT size=+2>Local Toolbar</FONT></B></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>1</TD>
+    <TD>Go Backward</TD>
+    <TD><FONT size=-1>&nbsp;backward_nav</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">A standard browser 'backward' button</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;Go Backward&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/clcl16/backward_nav.gif" width=16 border=0> <IMG 
+      height=16 alt="" 
+      src="../old.icons/full/elcl16/backward_nav.gif" 
+      width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/dlcl16/backward_nav.gif" 
+      width=16 border=0></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/clcl16/backward_nav.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/elcl16/backward_nav.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dlcl16/backward_nav.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+	
+  <TR bgColor=#dfdf9f>
+    <TD>2</TD>
+    <TD>Go Forward</TD>
+    <TD><FONT size=-1>&nbsp;forward_nav</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">A standard browser 'forward' button</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;Go Forward&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/clcl16/forward_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/elcl16/forward_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/dlcl16/forward_nav.gif" width=16 border=0></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/clcl16/forward_nav.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/elcl16/forward_nav.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dlcl16/forward_nav.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>3</TD>
+    <TD>Go</TD>
+    <TD><FONT size=-1>&nbsp;go_nav</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">A standard browser button for
+            navigating to a URL.</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;Go&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/clcl16/go_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/elcl16/go_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/dlcl16/go_nav.gif" width=16 border=0></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/clcl16/go_nav.gif" width=16 border=0>&nbsp;<IMG height=16 
+      alt="" src="icons/full/elcl16/go_nav.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/dlcl16/go_nav.gif" width=16 
+    border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+	
+  <TR bgColor=#dfdf9f>
+    <TD>4</TD>
+    <TD>Go Home</TD>
+    <TD><FONT size=-1>&nbsp;home_nav</FONT></TD>
+    <TD >
+      <TABLE cellSpacing=2 cellPadding=0 border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">A standard browser button
+            for going to the home location</font></TD>
+          <TD>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;Go Home&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/clcl16/home_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/elcl16/home_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/dlcl16/home_nav.gif" width=16 border=0></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/clcl16/home_nav.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/elcl16/home_nav.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" src="icons/full/dlcl16/home_nav.gif" 
+      width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>5</TD>
+    <TD>Refresh</TD>
+    <TD><FONT size=-1>&nbsp;refresh_nav</FONT></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">Refresh the contents of the view</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;Refresh&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/clcl16/refresh_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/elcl16/refresh_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/dlcl16/refresh_nav.gif" width=16 border=0></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/clcl16/refresh_nav.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/elcl16/refresh_nav.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dlcl16/refresh_nav.gif" width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#dfdf9f>
+    <TD>6</TD>
+    <TD>Stop</TD>
+    <TD><font size="-1">stop_nav</font></TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">A standard browser button for stopping
+            the navigation in progress</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;Stop&nbsp;&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/clcl16/stop_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/elcl16/stop_nav.gif" width=16 border=0> <IMG height=16 alt="" 
+      src="../old.icons/full/dlcl16/stop_nav.gif" width=16 border=0></TD>
+    <TD bgColor=#cccccc><IMG height=16 alt="" 
+      src="icons/full/clcl16/stop_nav.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/elcl16/stop_nav.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" src="icons/full/dlcl16/stop_nav.gif" 
+      width=16 border=0>&nbsp;</TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR>
+    <TD>7</TD>
+    <TD>Show Unconfigured Features</TD>
+    <TD>show_unconf</TD>
+    <TD>
+      <TABLE cellSpacing=2 cellPadding=0 width="100%" border=0>
+        
+        <TR>
+          <TD vAlign=top><font size="-1">A toggle button that allows
+            unconfigured features to show in the view</font></TD>
+          <TD vAlign=center align=right>
+            <TABLE>
+              
+              <TR>
+                <TD 
+                style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" 
+                align=middle bgColor=#ffffe1><FONT 
+                  size=-2>&nbsp;Show Unconfigured Features&nbsp;</FONT></TD></TR></TABLE></TD></TR></TABLE></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/clcl16/show_unconf.gif" width=16 border=0> </TD>
+    <TD BGCOLOR=#cccccc><IMG height=16 alt="" 
+      src="icons/full/clcl16/show_unconf.gif" width=16 border=0>&nbsp;<IMG 
+      height=16 alt="" src="icons/full/elcl16/show_unconf.gif" width=16 
+      border=0>&nbsp;<IMG height=16 alt="" 
+      src="icons/full/dlcl16/show_unconf.gif" width=16 border=0></TD>
+    <TD></TD></TR>
+	
+  <TR bgColor=#bfbf7f>
+    <TD colSpan=7><B><FONT size=+2>Model Object</FONT></B></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>1</TD>
+    <TD>&nbsp;Application Configuration</TD>
+    <TD><FONT size=-1>&nbsp;app_obj</FONT></TD>
+    <TD><font size="-1">the current configuration used to load the current
+      application</font></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/app_obj.gif" width=16 
+    align=left border=0></TD>
+    <TD><IMG height=16 alt="" src="icons/full/obj16/app_obj.gif" width=16 border=0></TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+	
+  <TR bgColor=#dfdfb>
+    <TD>2</TD>
+    <TD>My Computer</TD>
+    <TD><FONT size=-1>&nbsp;computer_obj</FONT></TD>
+    <TD><font size="-1">the file system root</font></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/computer_obj.gif" width=16 
+    align=left border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=16 alt="" 
+      src="icons/full/obj16/computer_obj.gif" width=16 border=0>
+      <P></P></TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>3</TD>
+    <TD>&nbsp;Feature</TD>
+    <TD><FONT size=-1>&nbsp;feature_obj</FONT></TD>
+    <TD><font size="-1">feature object</font></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/feature_obj.gif" width=16 
+align=left border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=16 alt="" 
+      src="icons/full/obj16/feature_obj.gif" width=16 border=0>
+      <P></P></TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>4</TD>
+    <TD>Unconfigured Feature</TD>
+    <TD><FONT size=-1>&nbsp;unconf_feature_obj</FONT></TD>
+    <TD><font size="-1">feature that is currently unconfigured (i.e. still
+      present but disabled in the current configuration)</font></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/unconf_feature_obj.gif" width=16 
+    align=left border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=16 alt="" 
+      src="icons/full/obj16/unconf_feature_obj.gif" width=16 border=0>
+      <P></P></TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>5</TD>
+    <TD>Places to Visit</TD>
+    <TD>places_obj</TD>
+    <TD>a folder that contains bookmarks to remote sites that
+      contain cool features</TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/places_obj.gif" width=16 
+align=left border=0></TD>
+    <TD bgColor=#ffffff><IMG height=16 alt="" 
+      src="icons/full/obj16/places_obj.gif" width=16 border=0>
+      &nbsp;</TD>
+    <TD></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>6</TD>
+    <TD>Site</TD>
+    <TD><font size="-1">site_obj&nbsp;</font></TD>
+    <TD><font size="-1">update site object that represent a provider
+      site (site that is set up to act as a source of features)</font></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/site_obj.gif" width=16 
+align=left border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=16 alt="" 
+      src="icons/full/obj16/site_obj.gif" width=16 border=0>
+      <P></P></TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR>
+    <TD>7</TD>
+    <TD><font size="-1">Local Site</font></TD>
+    <TD><font size="-1">lsite_obj</font></TD>
+    <TD>update site object that represents a receiver site (site
+      that is set up to act as a target of the feature installation)</TD>
+    <TD><IMG height=16 
+      alt="" 
+src="../old.icons/full/obj16/lsite_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff><IMG height=16 alt="" 
+      src="icons/full/obj16/lsite_obj.gif" width=16 border=0>
+      &nbsp;</TD>
+    <TD></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>8</TD>
+    <TD><font size="-1">Feature Category</font></TD>
+    <TD><font size="-1">category_obj</font></TD>
+    <TD>sites can classify features they host into hierarchical
+      categories</TD>
+    <TD>
+      <P align=left><IMG height=16 src="../old.icons/full/obj16/category_obj.gif" width=16 border=0></P></TD>
+    <TD bgColor=#ffffff><IMG height=16 alt="" 
+      src="icons/full/obj16/category_obj.gif" width=16 border=0>
+      &nbsp;</TD>
+    <TD></TD></TR>
+  <TR>
+    <TD>9</TD>
+    <TD><font size="-1">Bookmark Folder</font></TD>
+    <TD><font size="-1">bfolder_obj</font></TD>
+    <TD>folder object in the view that provides for
+      organizing site bookmarks and search objects</TD>
+    <TD>
+      <P align=left><IMG height=16 src="../old.icons/full/obj16/bfolder_obj.gif" width=16 border=0></P></TD>
+    <TD bgColor=#ffffff ><IMG height=16 alt="" 
+      src="icons/full/obj16/bfolder_obj.gif" width=16 border=0>
+      &nbsp;</TD>
+    <TD></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>10</TD>
+    <TD>Text Search</TD>
+    <TD><font size="-1">tsearch_obj</font></TD>
+    <TD><font size="-1">Text search object&nbsp;</font></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/tsearch_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=16 alt="" 
+      src="icons/full/obj16/tsearch_obj.gif" width=16 border=0>
+      <P></P></TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR>
+    <TD>11</TD>
+    <TD>Update Search</TD>
+    <TD>usearch_obj</TD>
+    <TD>Available Updates search object</TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/usearch_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=16 alt="" 
+      src="icons/full/obj16/usearch_obj.gif" width=16 border=0>
+      <P></P>
+    </TD>
+    <TD></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>12</TD>
+    <TD>Plug-in Search</TD>
+    <TD>psearch_obj</TD>
+    <TD>Plug-in search object</TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/psearch_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=16 alt="" 
+      src="icons/full/obj16/psearch_obj.gif" width=16 border=0>
+      <P></P>
+    </TD>
+    <TD></TD></TR>
+  <TR>
+    <TD>13</TD>
+    <TD>Fixed Volume</TD>
+    <TD>vfixed_obj</TD>
+    <TD>Local file system volume that represents a fixed drive (Windows) or
+      folder (Linux)</TD>
+    <TD><IMG height=16 
+      alt="" src="../old.icons/full/obj16/vfixed_obj.gif" width=16 align=left border=0>
+    </TD>
+    <TD bgColor=#ffffff><IMG height=16 alt="" 
+      src="icons/full/obj16/vfixed_obj.gif" width=16 border=0>
+      
+    </TD>
+    <TD></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>14</TD>
+    <TD>Remote Volume</TD>
+    <TD>vremote_obj</TD>
+    <TD>Remote file system volume that represents a shared drive (Window) or
+      mounted volume (Linux)</TD>
+    <TD height =16 
+      alt="" <IMG src="../old.icons/full/obj16/vremote_obj.gif" width=16 align=left border="1" 
+   >
+    </TD>
+    <TD bgColor=#ffffff><IMG height=16 alt="" 
+      src="icons/full/obj16/vremote_obj.gif" width=16 border=0>
+      &nbsp;
+    </TD>
+    <TD></TD></TR>
+  <TR>
+    <TD>15</TD>
+    <TD>Removable Volume</TD>
+    <TD>vremovable_obj</TD>
+    <TD>Removable file system volume that is neither CD-ROM nor Floppy Disk.
+      This image is used for all other removable volumes like DVD-ROM, various
+      PCMCIA cards etc.</TD>
+    <TD><IMG height=16 
+      alt="" src="../old.icons/full/obj16/vremovable_obj.gif" width=16 align=left border=0>
+    </TD>
+    <TD bgColor=#ffffff><IMG height=16 alt="" 
+      src="icons/full/obj16/vremovable_obj.gif" width=16 border=0>
+      &nbsp;
+    </TD>
+    <TD></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>16</TD>
+    <TD>CD-ROM</TD>
+    <TD>cd_obj</TD>
+    <TD>File system volume that represent a CD-ROM drive</TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/cd_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=16 alt="" 
+      src="icons/full/obj16/cd_obj.gif" width=16 border=0>
+      <P></P>
+    </TD>
+    <TD></TD></TR>
+  <TR>
+    <TD>17</TD>
+    <TD>Floppy Disk</TD>
+    <TD><font size="-1">floppy_obj</font></TD>
+    <TD><font size="-1">File system volume that represents a 3 1/2 inch floppy
+      disk drive</font></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/obj16/floppy_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=16 alt="" 
+      src="icons/full/obj16/floppy_obj.gif" width=16 border=0>
+      <P></P></TD>
+    <TD><FONT size=-1> </FONT></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>18</TD>
+    <TD>Saved Configurations</TD>
+    <TD>saved_obj</TD>
+    <TD><font size="2">Folder that holds past configurations that have been preserved and/or
+      renamed</font></TD>
+    <TD><IMG height=16 
+      alt="" src="../old.icons/full/obj16/saved_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff ><IMG height=16 alt="" 
+      src="icons/full/obj16/saved_obj.gif" width=16 border=0></TD>
+    <TD></TD></TR>
+  <TR>
+    <TD>19</TD>
+    <TD>Configuration History</TD>
+    <TD>history_obj</TD>
+    <TD>Folder that holds past configurations</TD>
+    <TD><IMG height=16 
+      alt="" src="../old.icons/full/obj16/history_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff ><IMG height=16 alt="" 
+      src="icons/full/obj16/history_obj.gif" width=16 border=0></TD>
+    <TD></TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>20</TD>
+    <TD>Available Updates</TD>
+    <TD>updates_obj</TD>
+    <TD>Update Search object that is pre-configured to look for
+      available updates of all the installed features. It cannot be removed from
+      the view.</TD>
+    <TD><IMG height=16 
+      alt="" src="../old.icons/full/obj16/updates_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff ><IMG height=16 alt="" 
+      src="icons/full/obj16/updates_obj.gif" width=16 border=0></TD>
+    <TD></TD></TR>
+  <TR>
+    <TD>21</TD>
+    <TD>Configuration</TD>
+    <TD>config_obj</TD>
+    <TD>A configuration history entry that represents one
+      configuration</TD>
+    <TD><IMG height=16 
+      alt="" src="../old.icons/full/obj16/config_obj.gif" width=16 align=left border=0></TD>
+    <TD bgColor=#ffffff ><IMG height=16 alt="" 
+      src="icons/full/obj16/config_obj.gif" width=16 border=0></TD>
+    <TD></TD></TR>
+	
+	
+	
+  <TR bgColor=#cccccc>
+    <TD colSpan=7><B><FONT size=+2>Object Overlay </FONT></B></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>1</TD>
+    <TD>&nbsp;current</TD>
+    <TD><font size="-1">current_co&nbsp;</font></TD>
+    <TD><FONT size=-1>&nbsp;indicates that the configuration is current i.e. in
+      effect</FONT></TD>
+    <TD><IMG height=8 alt="" 
+      src="../old.icons/full/ovr16/current_co.gif" width=7 border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=8 alt="" 
+      src="icons/full/ovr16/current_co.gif" width=7 border=0>
+      <P></P></TD>
+    <TD> </TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>2</TD>
+    <TD>&nbsp;error</TD>
+    <TD><FONT size=-1>error_co&nbsp;</FONT></TD>
+    <TD><FONT size=-1>will be overlayed over PDE editor objects that are 
+      somehow associated with XML syntax or validation errors&nbsp;</FONT></TD>
+    <TD><IMG height=8 alt="" 
+      src="../old.icons/full/ovr16/error_co.gif" width=7 border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=8 alt="" 
+      src="icons/full/ovr16/error_co.gif" width=7 border=0>
+      <P></P></TD>
+    <TD> </TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>3</TD>
+    <TD>&nbsp;installable</TD>
+    <TD><font size="-1">installable_co&nbsp;</font></TD>
+    <TD><font size="-1">indicates that site can accept features during
+      installation</font></TD>
+    <TD><IMG height=8 alt="" 
+      src="../old.icons/full/ovr16/installable_co.gif" width=7 border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=8 alt="" 
+      src="icons/full/ovr16/installable_co.gif" width=7 border=0>
+      <P></P></TD>
+    <TD> </TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>4</TD>
+    <TD>&nbsp;linked</TD>
+    <TD><font size="-1">linked_co&nbsp;</font></TD>
+    <TD><font size="-1">indicates that the site is only linked to the
+      configuration</font></TD>
+    <TD><IMG height=10 alt="" 
+      src="../old.icons/full/ovr16/linked_co.gif" width=11 border=0></TD>
+    <TD bgColor=#ffffff>
+      <IMG height=8 alt="" 
+      src="icons/full/ovr16/linked_co.gif" width=7 border=0>
+      <P></P></TD>
+    <TD> </TD></TR>
+    <TR bgColor=#ffffff>
+    <TD>5</TD>
+    <TD>unconfigured</TD>
+    <TD><font size="-1">unconfigured_co&nbsp;</font></TD>
+    <TD><font size="-1">      
+      </font></TD>
+    <TD></TD>
+    <TD bgColor=#ffffff>
+      <P></P><IMG height=8 alt="" src="icons/full/ovr16/unconfigured_co.gif" 
+      width=7 border=0></TD>
+    <TD> </TD></TR>
+	
+  
+  
+  <tr bgColor=#cccccc>
+    <TD colSpan=7><b><font size="+2">Forms Artwork</font></b></TD>
+  </tr>
+  <tr>
+    <TD>1</TD>
+    <TD>&nbsp;Topic</TD>
+    <TD><font size="-1">topic&nbsp;</font></TD>
+    <TD><FONT size=-1>&nbsp;an image to be used as a custom bullet for items in
+      a 'Welcome' page</FONT></TD>
+    <TD><IMG height=16 alt="" 
+      src="../old.icons/full/forms/topic.gif" width=16 border=0></TD>
+    <TD bgColor=#ffffff><IMG height=16 alt="" 
+      src="icons/full/forms/topic.gif" width=16 border=0></TD>
+    <TD> </TD>
+  </tr>
+  <tr bgColor=#dfdfb>
+    <TD>2</TD>
+    <TD>Default Provider</TD>
+    <TD><font size="-1">def_provider&nbsp;</font></TD>
+    <TD><font size="-1">an image to be used in a feature description page in 
+      cases where one was not supplied by feature provider (should be JPEG)<IMG 
+      height=48 alt="" src="../old.icons/full/forms/def_provider.gif" width=109 
+      border=0>          
+                 </font></TD>
+    <TD></TD>
+    <TD bgColor=#ffffff><IMG height=150 alt="" 
+      src="icons/full/forms/def_provider.gif" width=190 border=0>&nbsp;</TD>
+    <TD> </TD>
+  </tr>
+  <tr>
+    <TD>3</TD>
+    <TD>&nbsp;Form Banner</TD>
+    <TD><font size="-1">form_banner&nbsp;</font></TD>
+    <TD><font size="-1">a banner image used in all form pages behind the heading
+      (shown here in 1:10 zoom out)</font></TD>
+    <TD><IMG height=3 alt="" 
+      src="../old.icons/full/forms/form_banner.gif" width=60 border=0></TD>
+    <TD bgColor=#ffffff>&nbsp;
+      <P></P></TD>
+    <TD> </TD>
+  </tr>
+  <tr bgColor=#dfdfb>
+    <TD>4</TD>
+    <TD>&nbsp;Form Banner Underline</TD>
+    <TD><font size="-1">form_underline&nbsp;</font></TD>
+    <TD><font size="-1">a second portion of the banner used under the heading
+      text (shown here in 1:10 zoom out)</font></TD>
+    <TD><IMG height=1 alt="" 
+      src="../old.icons/full/forms/form_underline.gif" width=60 border=0></TD>
+    <TD bgColor=#ffffff>&nbsp;
+      <P></P></TD>
+    <TD> </TD>
+  </tr>
+  
+  
+  
+  
+  <TR bgColor=#cccccc>
+    <TD colSpan=7><B><FONT size=+2>Wizard Graphic</FONT></B></TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>1</TD>
+    <TD>New Bookmark wizard</TD>
+    <TD><FONT size=-1>&nbsp;new_bookmark_wiz</FONT></TD>
+    <TD><font size="-1">creates a new update site bookmark</font></TD>
+    <TD><IMG height=58 alt="" 
+      src="../old.icons/full/wizban/new_bookmark_wiz.gif" 
+      width=75 border=0></TD>
+    <TD bgColor=#ffffff><IMG height=58 alt="" 
+      src="icons/full/wizban/new_bookmark_wiz.gif" width=75 border=0>&nbsp;</TD>
+    <TD> </TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>2</TD>
+    <TD>New Folder wizard</TD>
+    <TD><FONT size=-1>&nbsp;new_folder_wiz</FONT></TD>
+    <TD><font size="-1">creates a new bookmark folder</font></TD>
+    <TD><IMG height=58 alt="" 
+      src="../old.icons/full/wizban/new_folder_wiz.gif" 
+      width=75 border=0></TD>
+    <TD bgColor=#ffffff><IMG height=58 alt="" 
+      src="icons/full/wizban/new_folder_wiz.gif" width=75 border=0>&nbsp;</TD>
+    <TD> </TD></TR>
+  <TR bgColor=#ffffff>
+    <TD>3</TD>
+    <TD>New Search wizard</TD>
+    <TD><FONT size=-1>&nbsp;new_search_wiz</FONT></TD>
+    <TD><FONT size=-1>creates a new search object</FONT></TD>
+    <TD><IMG height=58 alt="" 
+      src="../old.icons/full/wizban/new_search_wiz.gif" 
+      width=75 border=0></TD>
+    <TD bgColor=#ffffff><IMG height=58 alt="" 
+      src="icons/full/wizban/new_search_wiz.gif" width=75 border=0>&nbsp;</TD>
+    <TD> </TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>4</TD>
+    <TD>Install Feature wizard</TD>
+    <TD><FONT size=-1>&nbsp;install_wiz</FONT></TD>
+    <TD><font size="-1">installs a new feature into the platform</font></TD>
+    <TD><IMG height=58 alt="" 
+      src="../old.icons/full/wizban/install_wiz.gif" 
+      width=75 border=0></TD>
+    <TD bgColor=#ffffff><IMG height=58 alt="" 
+      src="icons/full/wizban/install_wiz.gif" width=75 border=0>&nbsp;</TD>
+    <TD> </TD></TR>
+  <TR bgColor=#ffffff>
+    <TD >5</TD>
+    <TD>Update Feature wizard</TD>
+    <TD><FONT size=-1>&nbsp;update_wiz</FONT></TD>
+    <TD><font size="-1">installs a newer version of an already installed feature</font></TD>
+    <TD><IMG height=58 alt="" 
+      src="../old.icons/full/wizban/update_wiz.gif" 
+      width=75 border=0></TD>
+    <TD bgColor=#ffffff><IMG height=58 alt="" 
+      src="icons/full/wizban/update_wiz.gif" width=75 border=0>&nbsp;</TD>
+    <TD> </TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD >6</TD>
+    <TD>Configure Feature wizard</TD>
+    <TD><FONT size=-1>&nbsp;config_wiz</FONT></TD>
+    <TD><font size="-1">configures or unconfigures an installed feature</font></TD>
+    <TD><IMG height=58 alt="" 
+      src="../old.icons/full/wizban/config_wiz.gif" 
+      width=75 border=0></TD>
+    <TD bgColor=#ffffff><IMG height=58 alt="" 
+      src="icons/full/wizban/config_wiz.gif" width=75 border=0>&nbsp;</TD>
+    <TD> </TD></TR>
+  <TR>
+    <TD>7</TD>
+    <TD>Uninstall Feature wizard</TD>
+    <TD><FONT size=-1>&nbsp;uninstall_wiz</FONT></TD>
+    <TD><font size="-1">permanently removes a feature from the platform</font></TD>
+    <TD><IMG height=58 alt="" 
+      src="../old.icons/full/wizban/uninstall_wiz.gif" 
+      width=75 border=0></TD>
+    <TD bgColor=#ffffff><IMG height=58 alt="" 
+      src="icons/full/wizban/uninstall_wiz.gif" width=75 border=0>&nbsp;</TD>
+    <TD> </TD></TR>
+  <TR bgColor=#dfdfb>
+    <TD>8</TD>
+    <TD>Default Install Wizard banner</TD>
+    <TD><FONT size=-1>&nbsp;def_wizban</FONT></TD>
+    <TD><font size="-1">a default image shown in install wizard pages when 
+      one is not supplied by feature providers<IMG height=258 alt="" 
+      src="../old.icons/full/wizban/def_wizban.jpg" width=118 
+border=0>         
+           </font></TD>
+    <TD></TD>
+    <TD bgColor=#ffffff><IMG height=258 alt="" 
+      src="icons/full/wizban/def_wizban.jpg" width=118 border=0>&nbsp;</TD>
+    <TD> </TD></TR></TABLE>
+<P></P></BODY></HTML>
diff --git a/update/org.eclipse.update.ui/about.html b/update/org.eclipse.update.ui/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/update/org.eclipse.update.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</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
+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/update/org.eclipse.update.ui/build.properties b/update/org.eclipse.update.ui/build.properties
new file mode 100644
index 0000000..9b7c373
--- /dev/null
+++ b/update/org.eclipse.update.ui/build.properties
@@ -0,0 +1,19 @@
+###############################################################################

+# Copyright (c) 2005, 2007 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

+###############################################################################

+bin.includes = plugin.properties,\

+               icons/,\

+               .,\

+               plugin.xml,\

+               about.html,\

+               META-INF/

+src.includes = about.html

+source.. = src/

+#jars.extra.classpath = ../org.eclipse.tomcat/servlet.jar

diff --git a/update/org.eclipse.update.ui/icons/dlcl16/collapseall.gif b/update/org.eclipse.update.ui/icons/dlcl16/collapseall.gif
new file mode 100644
index 0000000..7dc0de5
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/dlcl16/collapseall.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/dlcl16/hierarchicalLayout.gif b/update/org.eclipse.update.ui/icons/dlcl16/hierarchicalLayout.gif
new file mode 100644
index 0000000..52eeb6d
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/dlcl16/hierarchicalLayout.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/dlcl16/show_unconf.gif b/update/org.eclipse.update.ui/icons/dlcl16/show_unconf.gif
new file mode 100644
index 0000000..f8cf96b
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/dlcl16/show_unconf.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/dtool16/config_wiz.gif b/update/org.eclipse.update.ui/icons/dtool16/config_wiz.gif
new file mode 100644
index 0000000..2e8acec
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/dtool16/config_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/dtool16/install_wiz.gif b/update/org.eclipse.update.ui/icons/dtool16/install_wiz.gif
new file mode 100644
index 0000000..a89ff29
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/dtool16/install_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/dtool16/uninstall_wiz.gif b/update/org.eclipse.update.ui/icons/dtool16/uninstall_wiz.gif
new file mode 100644
index 0000000..075fcd2
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/dtool16/uninstall_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/dtool16/update_wiz.gif b/update/org.eclipse.update.ui/icons/dtool16/update_wiz.gif
new file mode 100644
index 0000000..f59d449
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/dtool16/update_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/elcl16/collapseall.gif b/update/org.eclipse.update.ui/icons/elcl16/collapseall.gif
new file mode 100644
index 0000000..a2d80a9
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/elcl16/collapseall.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/elcl16/hierarchicalLayout.gif b/update/org.eclipse.update.ui/icons/elcl16/hierarchicalLayout.gif
new file mode 100644
index 0000000..2344861
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/elcl16/hierarchicalLayout.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/elcl16/show_unconf.gif b/update/org.eclipse.update.ui/icons/elcl16/show_unconf.gif
new file mode 100644
index 0000000..d95b705
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/elcl16/show_unconf.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/etool16/config_wiz.gif b/update/org.eclipse.update.ui/icons/etool16/config_wiz.gif
new file mode 100644
index 0000000..95ac720
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/etool16/config_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/etool16/install_wiz.gif b/update/org.eclipse.update.ui/icons/etool16/install_wiz.gif
new file mode 100644
index 0000000..224c63f
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/etool16/install_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/etool16/uninstall_wiz.gif b/update/org.eclipse.update.ui/icons/etool16/uninstall_wiz.gif
new file mode 100644
index 0000000..d333128
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/etool16/uninstall_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/etool16/update_wiz.gif b/update/org.eclipse.update.ui/icons/etool16/update_wiz.gif
new file mode 100644
index 0000000..aa84ebe
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/etool16/update_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/eview16/configs.gif b/update/org.eclipse.update.ui/icons/eview16/configs.gif
new file mode 100644
index 0000000..c984fba
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/eview16/configs.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/eview16/preview.gif b/update/org.eclipse.update.ui/icons/eview16/preview.gif
new file mode 100644
index 0000000..e6bf9cf
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/eview16/preview.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/forms/def_provider.jpg b/update/org.eclipse.update.ui/icons/forms/def_provider.jpg
new file mode 100644
index 0000000..bbb03fd
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/forms/def_provider.jpg
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/forms/form_banner.gif b/update/org.eclipse.update.ui/icons/forms/form_banner.gif
new file mode 100644
index 0000000..aebc0b2
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/forms/form_banner.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/forms/form_banner.jpg b/update/org.eclipse.update.ui/icons/forms/form_banner.jpg
new file mode 100644
index 0000000..253e2d2
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/forms/form_banner.jpg
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/forms/form_underline.jpg b/update/org.eclipse.update.ui/icons/forms/form_underline.jpg
new file mode 100644
index 0000000..0ff3d0b
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/forms/form_underline.jpg
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/forms/topic.gif b/update/org.eclipse.update.ui/icons/forms/topic.gif
new file mode 100644
index 0000000..b5dd4ec
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/forms/topic.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/app_obj.gif b/update/org.eclipse.update.ui/icons/obj16/app_obj.gif
new file mode 100644
index 0000000..753cad7
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/app_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/bfolder_obj.gif b/update/org.eclipse.update.ui/icons/obj16/bfolder_obj.gif
new file mode 100644
index 0000000..10273e4
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/bfolder_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/category_obj.gif b/update/org.eclipse.update.ui/icons/obj16/category_obj.gif
new file mode 100644
index 0000000..b487d07
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/category_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/config_obj.gif b/update/org.eclipse.update.ui/icons/obj16/config_obj.gif
new file mode 100644
index 0000000..c984fba
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/config_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/efix2_obj.gif b/update/org.eclipse.update.ui/icons/obj16/efix2_obj.gif
new file mode 100644
index 0000000..b138957
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/efix2_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/efix_obj.gif b/update/org.eclipse.update.ui/icons/obj16/efix_obj.gif
new file mode 100644
index 0000000..57fc499
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/efix_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/error_st_obj.gif b/update/org.eclipse.update.ui/icons/obj16/error_st_obj.gif
new file mode 100644
index 0000000..0bc6068
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/error_st_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/esite_obj.gif b/update/org.eclipse.update.ui/icons/obj16/esite_obj.gif
new file mode 100644
index 0000000..25fd07b
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/esite_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/feature_obj.gif b/update/org.eclipse.update.ui/icons/obj16/feature_obj.gif
new file mode 100644
index 0000000..8706680
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/feature_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/history_obj.gif b/update/org.eclipse.update.ui/icons/obj16/history_obj.gif
new file mode 100644
index 0000000..289d43a
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/history_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/lsite_obj.gif b/update/org.eclipse.update.ui/icons/obj16/lsite_obj.gif
new file mode 100644
index 0000000..d650bdb
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/lsite_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/notinstalled_feature_obj.gif b/update/org.eclipse.update.ui/icons/obj16/notinstalled_feature_obj.gif
new file mode 100644
index 0000000..f192b84
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/notinstalled_feature_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/ok_st_obj.gif b/update/org.eclipse.update.ui/icons/obj16/ok_st_obj.gif
new file mode 100644
index 0000000..9cacb96
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/ok_st_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/psite_obj.gif b/update/org.eclipse.update.ui/icons/obj16/psite_obj.gif
new file mode 100644
index 0000000..58897f1
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/psite_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/site_obj.gif b/update/org.eclipse.update.ui/icons/obj16/site_obj.gif
new file mode 100644
index 0000000..b8568f4
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/site_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/unconf_feature_obj.gif b/update/org.eclipse.update.ui/icons/obj16/unconf_feature_obj.gif
new file mode 100644
index 0000000..86881fd
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/unconf_feature_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/updates_obj.gif b/update/org.eclipse.update.ui/icons/obj16/updates_obj.gif
new file mode 100644
index 0000000..16f4f7c
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/updates_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/usearch_obj.gif b/update/org.eclipse.update.ui/icons/obj16/usearch_obj.gif
new file mode 100644
index 0000000..5080599
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/usearch_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/obj16/web_bkmrk_obj.gif b/update/org.eclipse.update.ui/icons/obj16/web_bkmrk_obj.gif
new file mode 100644
index 0000000..cdbc528
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/obj16/web_bkmrk_obj.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/add_stat.gif b/update/org.eclipse.update.ui/icons/ovr16/add_stat.gif
new file mode 100644
index 0000000..c123a2b
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/add_stat.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/current_co.gif b/update/org.eclipse.update.ui/icons/ovr16/current_co.gif
new file mode 100644
index 0000000..13077f9
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/current_co.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/del_stat.gif b/update/org.eclipse.update.ui/icons/ovr16/del_stat.gif
new file mode 100644
index 0000000..ef0207c
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/del_stat.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/error_co.gif b/update/org.eclipse.update.ui/icons/ovr16/error_co.gif
new file mode 100644
index 0000000..119dccc
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/error_co.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/installable_co.gif b/update/org.eclipse.update.ui/icons/ovr16/installable_co.gif
new file mode 100644
index 0000000..5e999b6
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/installable_co.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/linked_co.gif b/update/org.eclipse.update.ui/icons/ovr16/linked_co.gif
new file mode 100644
index 0000000..2f40e1b
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/linked_co.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/mod_co.gif b/update/org.eclipse.update.ui/icons/ovr16/mod_co.gif
new file mode 100644
index 0000000..2b1b8d6
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/mod_co.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/unconfigured_co.gif b/update/org.eclipse.update.ui/icons/ovr16/unconfigured_co.gif
new file mode 100644
index 0000000..8a589ce
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/unconfigured_co.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/updated_co.gif b/update/org.eclipse.update.ui/icons/ovr16/updated_co.gif
new file mode 100644
index 0000000..0d686ab
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/updated_co.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/ovr16/warning_co.gif b/update/org.eclipse.update.ui/icons/ovr16/warning_co.gif
new file mode 100644
index 0000000..ee2dac4
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/ovr16/warning_co.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/wizban/config_wiz.gif b/update/org.eclipse.update.ui/icons/wizban/config_wiz.gif
new file mode 100644
index 0000000..6a19fbf
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/wizban/config_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/wizban/def_wizban.jpg b/update/org.eclipse.update.ui/icons/wizban/def_wizban.jpg
new file mode 100644
index 0000000..4d7eba6
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/wizban/def_wizban.jpg
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/wizban/install_wiz.gif b/update/org.eclipse.update.ui/icons/wizban/install_wiz.gif
new file mode 100644
index 0000000..7eee7c3
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/wizban/install_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/wizban/uninstall_wiz.gif b/update/org.eclipse.update.ui/icons/wizban/uninstall_wiz.gif
new file mode 100644
index 0000000..1223378
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/wizban/uninstall_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/icons/wizban/update_wiz.gif b/update/org.eclipse.update.ui/icons/wizban/update_wiz.gif
new file mode 100644
index 0000000..3b36487
--- /dev/null
+++ b/update/org.eclipse.update.ui/icons/wizban/update_wiz.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/ConfigurationManagerWindow.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/ConfigurationManagerWindow.java
new file mode 100644
index 0000000..892353b
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/ConfigurationManagerWindow.java
@@ -0,0 +1,297 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui;
+
+import java.util.Hashtable;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.internal.ui.views.ConfigurationView;
+import org.eclipse.update.ui.UpdateJob;
+
+/**
+ * Configuration Manager window.
+ */
+public class ConfigurationManagerWindow extends ApplicationWindow {
+	private ConfigurationView view;
+
+	private GlobalAction propertiesAction;
+
+	private IAction propertiesActionHandler;
+
+	private IJobChangeListener jobListener;
+	
+	private Hashtable jobNames;
+
+	class GlobalAction extends Action implements IPropertyChangeListener {
+		private IAction handler;
+
+		public GlobalAction() {
+		}
+
+		public void setActionHandler(IAction action) {
+			if (handler != null) {
+				handler.removePropertyChangeListener(this);
+				handler = null;
+			}
+			if (action != null) {
+				this.handler = action;
+				action.addPropertyChangeListener(this);
+			}
+			if (handler != null) {
+				setEnabled(handler.isEnabled());
+				setChecked(handler.isChecked());
+			}
+		}
+
+		public void propertyChange(PropertyChangeEvent event) {
+			if (event.getProperty().equals(Action.ENABLED)) {
+				Boolean bool = (Boolean) event.getNewValue();
+				setEnabled(bool.booleanValue());
+			} else if (event.getProperty().equals(Action.CHECKED)) {
+				Boolean bool = (Boolean) event.getNewValue();
+				setChecked(bool.booleanValue());
+			}
+		}
+
+		public void run() {
+			if (handler != null)
+				handler.run();
+		}
+	}
+
+	/**
+	 * @param parentShell
+	 */
+	public ConfigurationManagerWindow(Shell parentShell) {
+		super(parentShell);
+		setShellStyle(getShellStyle() | SWT.APPLICATION_MODAL);
+		// Setup window.
+		addMenuBar();
+		addActions();
+		addToolBar(SWT.FLAT);
+		addStatusLine();
+	}
+	
+	public boolean isProgressCanceled() {
+		return getStatusLineManager().getProgressMonitor().isCanceled();
+	}
+
+	private void addActions() {
+		IMenuManager menuBar = getMenuBarManager();
+		IMenuManager fileMenu = new MenuManager(
+				UpdateUIMessages.ConfigurationManagerWindow_fileMenu);
+		menuBar.add(fileMenu);
+
+		propertiesAction = new GlobalAction();
+		propertiesAction
+				.setText(UpdateUIMessages.ConfigurationManagerWindow_properties);
+		propertiesAction.setEnabled(false);
+
+		fileMenu.add(propertiesAction);
+		fileMenu.add(new Separator());
+
+		Action closeAction = new Action() {
+			public void run() {
+				close();
+			}
+		};
+		closeAction.setText(UpdateUIMessages.ConfigurationManagerWindow_close);
+		fileMenu.add(closeAction);
+	}
+
+	private void hookGlobalActions() {
+		if (propertiesActionHandler != null)
+			propertiesAction.setActionHandler(propertiesActionHandler);
+	}
+
+	protected Control createContents(Composite parent) {
+		view = new ConfigurationView(this);
+		Composite container = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.marginWidth = layout.marginHeight = 0;
+		layout.verticalSpacing = 0;
+		container.setLayout(layout);
+
+		addSeparator(container);
+		GridData gd;
+
+		view.createPartControl(container);
+		Control viewControl = view.getControl();
+		gd = new GridData(GridData.FILL_BOTH);
+		viewControl.setLayoutData(gd);
+
+		addSeparator(container);
+
+		hookGlobalActions();
+
+		updateActionBars();
+
+		UpdateLabelProvider provider = UpdateUI.getDefault().getLabelProvider();
+		getShell().setImage(provider.get(UpdateUIImages.DESC_CONFIGS_VIEW, 0));
+
+		return container;
+	}
+
+	public void updateStatusLine(String message, Image image) {
+		getStatusLineManager().setMessage(image, message);
+		getStatusLineManager().update(true);
+	}
+
+	public void trackUpdateJob(Job job, String name) {
+		if (jobListener == null) {
+			jobNames = new Hashtable();
+			jobListener = new IJobChangeListener() {
+				public void aboutToRun(IJobChangeEvent event) {
+				}
+
+				public void awake(IJobChangeEvent event) {
+				}
+
+				public void done(IJobChangeEvent event) {
+					Job job = event.getJob();
+					if (job.belongsTo(UpdateJob.FAMILY)) {
+						Job [] remaining = Job.getJobManager().find(UpdateJob.FAMILY);
+						updateProgress(false, remaining);
+						jobNames.remove(job);
+					}
+				}
+
+				public void running(IJobChangeEvent event) {
+					Job job = event.getJob();
+					if (job.belongsTo(UpdateJob.FAMILY)) {
+						Job [] existing = Job.getJobManager().find(UpdateJob.FAMILY);
+						updateProgress(true, existing);
+					}
+				}
+
+				public void scheduled(IJobChangeEvent event) {
+				}
+
+				public void sleeping(IJobChangeEvent event) {
+				}
+			};
+			Job.getJobManager().addJobChangeListener(jobListener);
+		}
+		jobNames.put(job, name);
+	}
+
+	private void updateProgress(final boolean begin, final Job[] jobs) {
+		getShell().getDisplay().asyncExec(new Runnable() {
+			public void run() {
+				IProgressMonitor monitor = getStatusLineManager()
+						.getProgressMonitor();
+				if (begin) {
+					if (jobs.length == 1)
+						monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
+					updateTaskName(monitor, jobs);
+					getStatusLineManager().setCancelEnabled(true);
+				} else {
+					if (jobs.length == 0) {
+						getStatusLineManager().setCancelEnabled(false);
+						monitor.done();
+					}
+					else
+						updateTaskName(monitor, jobs);
+				}
+				getStatusLineManager().update(true);
+			}
+		});
+	}
+
+	private void updateTaskName(IProgressMonitor monitor, Job [] jobs) {
+		StringBuffer buf = new StringBuffer();
+		for (int i=0; i<jobs.length; i++) {
+			String name = (String)jobNames.get(jobs[i]);
+			if (name!=null) {
+				if (buf.length()>0)
+					buf.append(", "); //$NON-NLS-1$
+				buf.append(name);
+			}
+		}
+		monitor.subTask(NLS.bind(
+				UpdateUIMessages.ConfigurationManagerWindow_searchTaskName,
+				buf.toString())); 
+	}
+
+	private void addSeparator(Composite parent) {
+		GridData gd;
+		Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.heightHint = 1;
+		separator.setLayoutData(gd);
+	}
+
+	private void updateActionBars() {
+		getMenuBarManager().updateAll(false);
+		getToolBarManager().update(false);
+		getStatusLineManager().update(false);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.window.Window#close()
+	 */
+	public boolean close() {
+		if (jobListener != null)
+			Job.getJobManager().removeJobChangeListener(jobListener);
+		if (view != null)
+			view.dispose();
+		return super.close();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.window.Window#create()
+	 */
+	public void create() {
+		super.create();
+		// set the title
+		getShell().setText(UpdateUIMessages.ConfigurationManagerAction_title);
+		getShell().setSize(800, 600);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.window.Window#open()
+	 */
+	public int open() {
+		// update action bars
+		updateActionBars();
+		return super.open();
+	}
+
+	public void setPropertiesActionHandler(IAction handler) {
+		propertiesActionHandler = handler;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/RestartDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/RestartDialog.java
new file mode 100644
index 0000000..e58091a
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/RestartDialog.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui;
+
+import org.eclipse.core.runtime.IProduct;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.operations.*;
+
+/**
+ * A dialog which prompts the user to restart after an update operation
+ * and provides Yes, No, Continue buttons. 
+ */
+public class RestartDialog extends MessageDialog {
+	private static final int CONTINUE = 2;
+	private final static String[] yesNo = new String[] {IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL};
+	private final static String[] yesNoApply = new String[] {IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, UpdateUIMessages.ApplyChanges}; 
+	
+	private int buttonId = 0;
+	
+	/**
+	 * Creates a new dialog
+	 * @see MessageDialog#MessageDialog(org.eclipse.swt.widgets.Shell, java.lang.String, org.eclipse.swt.graphics.Image, java.lang.String, int, java.lang.String[], int)
+	 */
+	public RestartDialog(Shell parent, String title, String message, boolean restartNeeded) {
+		super(parent,
+				title,
+				null,	// accept the default window icon
+				message,
+				QUESTION,
+				restartNeeded ? yesNo : yesNoApply, 
+				0);		// yes is the default
+	}
+
+	/**
+	 * Convenience method to open the Yes/No/Continue question dialog.
+	 *
+	 * @param parent the parent shell of the dialog, or <code>null</code> if none
+	 * @param restartIsReallyNeeded when false, the changes are applied to the current config
+	 * @return <code>true</code> if the user presses  YES
+	 *    <code>false</code> otherwise
+	 */
+	public static boolean openQuestion(Shell parent, boolean restartIsReallyNeeded) {
+		String title = UpdateUIMessages.RestartTitle; 
+		IProduct product = Platform.getProduct();
+		String productName = product != null && product.getName() != null ? product.getName() : UpdateUIMessages.ApplicationInRestartDialog;
+		String message = NLS.bind(restartIsReallyNeeded ? UpdateUIMessages.RestartMessage: UpdateUIMessages.OptionalRestartMessage, productName);
+		RestartDialog dialog = new RestartDialog(parent, title,	message, restartIsReallyNeeded);
+		int button= dialog.open();
+		if (button == 2)
+			OperationsManager.applyChangesNow();
+		return button == 0; // Yes
+	}
+	
+	/**
+	 * When a button is pressed, store the preference.
+	 * 
+	 * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
+	 */
+	protected void buttonPressed(int id) {
+		if (id == 2) { 
+			buttonId= CONTINUE;
+		} 
+		
+		super.buttonPressed(id);
+	}
+	
+	/**
+	 * Returns the user's selection,
+	 * <code>null</code> if the user hasn't chosen yet.
+	 * 
+	 * @return the user's selection or <code>null</code>
+	 */
+	public int getResult() {
+		return buttonId;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/URLCoder.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/URLCoder.java
new file mode 100644
index 0000000..a4b84e0
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/URLCoder.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+
+public class URLCoder {
+
+	public static String encode(String s) throws UnsupportedEncodingException {
+		return urlEncode(s.getBytes("UTF8")); //$NON-NLS-1$
+	}
+
+	public static String decode(String s) throws UnsupportedEncodingException {
+		return new String(urlDecode(s), "UTF8"); //$NON-NLS-1$
+	}
+
+	private static String urlEncode(byte[] data) {
+		StringBuffer buf = new StringBuffer(data.length);
+		for (int i = 0; i < data.length; i++) {
+			buf.append('%');
+			buf.append(Character.forDigit((data[i] & 240) >>> 4, 16));
+			buf.append(Character.forDigit(data[i] & 15, 16));
+		}
+		return buf.toString();
+	}
+
+	private static byte[] urlDecode(String encodedURL) {
+		int len = encodedURL.length();
+		ByteArrayOutputStream os = new ByteArrayOutputStream(len);
+		for (int i = 0; i < len;) {
+			switch (encodedURL.charAt(i)) {
+			case '%':
+				if (len >= i + 3) {
+					os.write(Integer.parseInt(encodedURL.substring(i + 1, i + 3), 16));
+				}
+				i += 3;
+				break;
+			case '+': // exception from standard
+				os.write(' ');
+				i++;
+				break;
+			default:
+				os.write(encodedURL.charAt(i++));
+				break;
+			}
+
+		}
+		return os.toByteArray();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateLabelProvider.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateLabelProvider.java
new file mode 100644
index 0000000..b01959b
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateLabelProvider.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui;
+
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.internal.ui.parts.*;
+
+/**
+ * 
+ */
+
+public class UpdateLabelProvider extends SharedLabelProvider {
+	/**
+	 * Constructor for UpdateLabelProvider.
+	 */
+	public UpdateLabelProvider() {
+	}
+	
+	public String getText(Object obj) {
+		return super.getText(obj);
+	}
+	
+	public Image getImage(Object obj) {
+		return super.getImage(obj);
+	}
+	
+	public ImageDescriptor getLocalSiteDescriptor(IConfiguredSite csite) {
+		if (csite.isProductSite())
+			return UpdateUIImages.DESC_PSITE_OBJ;
+		if (csite.isExtensionSite())
+			return UpdateUIImages.DESC_ESITE_OBJ;
+		return UpdateUIImages.DESC_LSITE_OBJ;
+	}
+	
+	public Image getLocalSiteImage(IConfiguredSite csite) {
+		ImageDescriptor desc = getLocalSiteDescriptor(csite);
+		return get(desc);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUI.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUI.java
new file mode 100644
index 0000000..b71c38f
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUI.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.*;
+import org.eclipse.ui.browser.IWebBrowser;
+import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.ui.model.UpdateModel;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class UpdateUI extends AbstractUIPlugin {
+	public static final String PLUGIN_ID = "org.eclipse.update.ui"; //$NON-NLS-1$
+	public static final String WEB_APP_ID = "org.eclipse.update"; //$NON-NLS-1$
+	// preference key
+	public static final String P_DISCOVERY_SITES_ENABLED = "discoverySitesEnabled"; //$NON-NLS-1$
+	//The shared instance.
+	private static UpdateUI plugin;
+	private UpdateModel model;
+	private String appServerHost;
+	private int appServerPort;
+	private UpdateLabelProvider labelProvider;
+
+	/**
+	 * The constructor.
+	 */
+	public UpdateUI() {
+
+		plugin = this;
+	}
+
+	/**
+	 * Returns the shared instance.
+	 */
+	public static UpdateUI getDefault() {
+		return plugin;
+	}
+
+	public static Shell getActiveWorkbenchShell() {
+		IWorkbenchWindow window = getActiveWorkbenchWindow();
+		return window != null ? window.getShell() : getStandardDisplay().getActiveShell();
+	}
+
+	public static IWorkbenchWindow getActiveWorkbenchWindow() {
+		return getDefault().getWorkbench().getActiveWorkbenchWindow();
+	}
+
+	public static String getPluginId() {
+		return getDefault().getBundle().getSymbolicName();
+	}
+
+	public UpdateLabelProvider getLabelProvider() {
+		if (labelProvider == null)
+			labelProvider = new UpdateLabelProvider();
+		return labelProvider;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		model = new UpdateModel();
+		int historyPref =
+			getPluginPreferences().getInt(UpdateCore.P_HISTORY_SIZE);
+		if (historyPref > 0) {
+			UpdateCore.DEFAULT_HISTORY = historyPref;
+		}
+	}
+	
+	public String getAppServerHost() {
+		return appServerHost;
+	}
+
+	public int getAppServerPort() {
+		return appServerPort;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		if (model != null)
+			model.shutdown();
+
+		if (labelProvider != null)
+			labelProvider.dispose();
+		super.stop(context);
+
+	}
+
+	public UpdateModel getUpdateModel() {
+		return model;
+	}
+
+	public static void logException(Throwable e) {
+		logException(e, true);
+	}
+
+	public static void logException(Throwable e, boolean showErrorDialog) {
+		if (e instanceof InvocationTargetException) {
+			e = ((InvocationTargetException) e).getTargetException();
+		}
+
+		IStatus status = null;
+		if (e instanceof CoreException) {
+			status = ((CoreException) e).getStatus();
+		} else {
+			String message = e.getMessage();
+			if (message == null)
+				message = e.toString();
+			status =
+				new Status(
+					IStatus.ERROR,
+					getPluginId(),
+					IStatus.OK,
+					message,
+					e);
+		}
+		log(status, showErrorDialog);
+	}
+
+	public static void log(IStatus status, boolean showErrorDialog) {
+		Bundle bundle = Platform.getBundle("org.eclipse.update.ui"); //$NON-NLS-1$
+		Platform.getLog(bundle).log(status);
+		if (Display.getCurrent() == null || !showErrorDialog)
+			return;
+		if (status.getSeverity() != IStatus.INFO) {
+			ErrorDialog.openError(getActiveWorkbenchShell(), null, null, status);
+		} else {
+			MessageDialog.openInformation(getActiveWorkbenchShell(), null, status.getMessage());
+		}
+	}
+
+	public static URL getOriginatingURL(String id) {
+		IDialogSettings section = getOriginatingURLSection();
+		String value = section.get(id);
+		if (value != null) {
+			try {
+				return new URL(value);
+			} catch (MalformedURLException e) {
+			}
+		}
+		return null;
+	}
+
+	public static void setOriginatingURL(String id, URL url) {
+		IDialogSettings section = getOriginatingURLSection();
+		section.put(id, url.toString());
+	}
+
+	private static IDialogSettings getOriginatingURLSection() {
+		IDialogSettings settings = getDefault().getDialogSettings();
+		IDialogSettings section = settings.getSection("originatingURLs"); //$NON-NLS-1$
+		if (section == null)
+			section = settings.addNewSection("originatingURLs"); //$NON-NLS-1$
+		return section;
+	}
+
+	
+	/**
+	 * Prompts the user to restart, and performs the restart if the user gives the ok.
+	 * 
+	 * @param restartIsReallyNeeded true when a restart is needed, false if the user feels lucky (tm) and wants the changes
+	 * applied to the current config
+	 * @return <code>true</code> if the system is restarting, and <code>false</code> otherwise
+	 */
+	public static boolean requestRestart(boolean restartIsReallyNeeded) {
+		boolean restart =
+			RestartDialog.openQuestion(
+				getActiveWorkbenchShell(),
+				restartIsReallyNeeded);
+		if (restart)
+			return PlatformUI.getWorkbench().restart();
+		return false;
+	}
+
+	public static void showURL(String url) {
+		showURL(url, false);
+	}
+
+	public static void showURL(String url, boolean encodeHostAndPort) {
+		if (encodeHostAndPort)
+			url = encodeHostAndPort(url);
+
+		IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
+		try {
+			IWebBrowser browser = support.getExternalBrowser();
+			browser.openURL(new URL(url));
+		}
+		catch (MalformedURLException e) {
+			UpdateUI.logException(e);
+		}
+		catch (PartInitException e) {
+			UpdateUI.logException(e);
+		}
+	}
+
+	private static String encodeHostAndPort(String urlName) {
+		String callbackURL = getCallbackURLAsString();
+		if (callbackURL == null)
+			return urlName;
+		String callbackParameter = "updateURL=" + callbackURL; //$NON-NLS-1$
+		if (urlName.indexOf('?') != -1)
+			return urlName + "&" + callbackParameter; //$NON-NLS-1$
+		else
+			return urlName + "?" + callbackParameter; //$NON-NLS-1$
+	}
+	
+	private static String getCallbackURLAsString() {
+		String host = getDefault().getAppServerHost();
+		int port = getDefault().getAppServerPort();
+		if (host == null || port == 0)
+			return null;
+		else {
+			String value =
+				"http://" //$NON-NLS-1$
+					+ host
+					+ ":" //$NON-NLS-1$
+					+ port
+					+ "/" //$NON-NLS-1$
+					+ WEB_APP_ID
+					+ "/install"; //$NON-NLS-1$
+			try {
+				value = URLCoder.encode(value);
+			} catch (UnsupportedEncodingException e) {
+			}
+			return value;
+		}
+	}
+	
+	/**
+	 * Returns the standard display to be used. The method first checks, if
+	 * the thread calling this method has an associated disaply. If so, this
+	 * display is returned. Otherwise the method returns the default display.
+	 */
+	public static Display getStandardDisplay() {
+		Display display;
+		display = Display.getCurrent();
+		if (display == null)
+			display = Display.getDefault();
+		return display;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.Plugin#initializeDefaultPluginPreferences()
+	 */
+	protected void initializeDefaultPluginPreferences() {
+		Preferences store = getPluginPreferences();
+		store.setDefault(P_DISCOVERY_SITES_ENABLED, true);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUIImages.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUIImages.java
new file mode 100644
index 0000000..1bc2a4a
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUIImages.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * Bundle of all images used by the PDE plugin.
+ */
+public class UpdateUIImages {
+
+	public final static String ICONS_PATH = "icons/"; //$NON-NLS-1$
+
+	/**
+	 * Set of predefined Image Descriptors.
+	 */
+	
+	private static final String PATH_OBJ= ICONS_PATH+"obj16/"; //$NON-NLS-1$
+	private static final String PATH_VIEW = ICONS_PATH+"eview16/"; //$NON-NLS-1$
+	private static final String PATH_LCL= ICONS_PATH+"elcl16/"; //$NON-NLS-1$
+	private static final String PATH_LCL_DISABLED= ICONS_PATH+"dlcl16/"; //$NON-NLS-1$
+	private static final String PATH_OVR = ICONS_PATH + "ovr16/"; //$NON-NLS-1$
+	private static final String PATH_WIZBAN = ICONS_PATH + "wizban/"; //$NON-NLS-1$
+	public static final String PATH_FORMS = ICONS_PATH + "forms/"; //$NON-NLS-1$
+
+
+	/**
+	 * Frequently used images
+	 */
+
+	/**
+	 * OBJ16
+	 */
+	public static final ImageDescriptor DESC_APP_OBJ = create(PATH_OBJ, "app_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_CATEGORY_OBJ = create(PATH_OBJ, "category_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_CONFIG_OBJ = create(PATH_OBJ, "config_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_FEATURE_OBJ = create(PATH_OBJ, "feature_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_EFIX_OBJ = create(PATH_OBJ, "efix2_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_HISTORY_OBJ = create(PATH_OBJ, "history_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_LSITE_OBJ = create(PATH_OBJ, "lsite_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_PSITE_OBJ = create(PATH_OBJ, "psite_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_ESITE_OBJ = create(PATH_OBJ, "esite_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_SITE_OBJ = create(PATH_OBJ, "site_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_UNCONF_FEATURE_OBJ = create(PATH_OBJ, "unconf_feature_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_NOTINST_FEATURE_OBJ = create(PATH_OBJ, "notinstalled_feature_obj.gif");	 //$NON-NLS-1$
+	public static final ImageDescriptor DESC_ERR_ST_OBJ = create(PATH_OBJ, "error_st_obj.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_OK_ST_OBJ = create(PATH_OBJ, "ok_st_obj.gif"); //$NON-NLS-1$
+
+	
+	/**
+	 * OVR16
+	 */
+	public static final ImageDescriptor DESC_LINKED_CO   = create(PATH_OVR, "linked_co.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_UPDATED_CO   = create(PATH_OVR, "updated_co.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_CURRENT_CO = create(PATH_OVR, "current_co.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_ERROR_CO = create(PATH_OVR, "error_co.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_WARNING_CO = create(PATH_OVR, "warning_co.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_MOD_CO = create(PATH_OVR, "mod_co.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_ADD_CO = create(PATH_OVR, "add_stat.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_DEL_CO = create(PATH_OVR, "del_stat.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_UNCONF_CO = create(PATH_OVR, "unconfigured_co.gif"); //$NON-NLS-1$
+
+	/**
+	 * VIEW16
+	 */
+	public static final ImageDescriptor DESC_CONFIGS_VIEW = create(PATH_VIEW, "configs.gif"); //$NON-NLS-1$
+
+	/**
+	 * LCL
+	 */
+	public static final ImageDescriptor DESC_COLLAPSE_ALL = create(PATH_LCL, "collapseall.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_SHOW_HIERARCHY = create(PATH_LCL, "hierarchicalLayout.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_SHOW_HIERARCHY_D = create(PATH_LCL_DISABLED, "hierarchicalLayout.gif"); //$NON-NLS-1$
+
+	/**
+	 * WIZ
+	 */
+	public static final ImageDescriptor DESC_UPDATE_WIZ  = create(PATH_WIZBAN, "update_wiz.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_CONFIG_WIZ  = create(PATH_WIZBAN, "config_wiz.gif"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_INSTALL_BANNER  = create(PATH_WIZBAN, "def_wizban.jpg"); //$NON-NLS-1$
+	public static final ImageDescriptor DESC_PROVIDER = create(PATH_FORMS, "def_provider.jpg"); //$NON-NLS-1$
+
+	private static ImageDescriptor create(String prefix, String name) {
+		return ImageDescriptor.createFromURL(makeImageURL(prefix, name));
+	}
+
+
+	private static URL makeImageURL(String prefix, String name) {
+		String path = "$nl$/" + prefix + name; //$NON-NLS-1$
+		return FileLocator.find(UpdateUI.getDefault().getBundle(), new Path(path), null);
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUIMessages.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUIMessages.java
new file mode 100644
index 0000000..c11bcbb
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUIMessages.java
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class UpdateUIMessages extends NLS {
+
+	private static final String BUNDLE_NAME = "org.eclipse.update.internal.ui.UpdateUIPluginResources";//$NON-NLS-1$
+
+	private UpdateUIMessages() {
+		// Do not instantiate
+	}
+
+	public static String RestartTitle;
+	public static String RestartMessage;
+	public static String OptionalRestartMessage;
+	public static String ApplicationInRestartDialog;
+	public static String ApplyChanges;
+	public static String ConfigurationManagerAction_title;
+	public static String ConfigurationManagerWindow_fileMenu;
+	public static String ConfigurationManagerWindow_properties;
+	public static String ConfigurationManagerWindow_close;
+	public static String InstallWizardAction_title;
+	public static String InstallWizard_retryTitle;
+	public static String InstallWizard_retry;
+	public static String TargetPage_Feature_Size;
+	public static String TargetPage_Feature_Version;
+	public static String TargetPage_FeatureNameColumn;
+	public static String TargetPage_InstallationDirectoryColumn;
+	public static String DiscoveryFolder_name;
+	public static String FeatureAdapter_failure;
+	public static String SiteBookmark_connecting;
+	public static String SiteBookmark_downloading;
+	public static String MainPreferencePage_checkSignature;
+	public static String MainPreferencePage_automaticallyChooseMirror;
+	public static String MainPreferencePage_historySize;
+	public static String MainPreferencePage_invalidHistorySize;
+	public static String MainPreferencePage_updateVersions;
+	public static String MainPreferencePage_updateVersions_equivalent;
+	public static String MainPreferencePage_updateVersions_compatible;
+	public static String MainPreferencePage_updatePolicy;
+	public static String MainPreferencePage_updatePolicyURL;
+	public static String MainPreferencePage_proxyGroup;
+	public static String MainPreferencePage_digitalSignature_title;
+	public static String MainPreferencePage_digitalSignature_message;
+	public static String UpdateSettingsPreferencePage_description;
+	public static String UpdateSettingsPreferencePage_label;
+	public static String UpdateSettingsPreferencePage_invalid;
+	public static String ConfiguredSitePropertyPage_path;
+	public static String ConfiguredSitePropertyPage_type;
+	public static String ConfiguredSitePropertyPage_enabled;
+	public static String ConfiguredSitePropertyPage_yes;
+	public static String ConfiguredSitePropertyPage_no;
+	public static String ConfiguredSitePropertyPage_extension;
+	public static String ConfiguredSitePropertyPage_product;
+	public static String ConfiguredSitePropertyPage_unknown;
+	public static String FeatureCopyrightPropertyPage_showInBrowser;
+	public static String FeatureCopyrightPropertyPage_noCopyright;
+	public static String FeatureGeneralPropertyPage_name;
+	public static String FeatureGeneralPropertyPage_id;
+	public static String FeatureGeneralPropertyPage_version;
+	public static String FeatureGeneralPropertyPage_provider;
+	public static String FeatureGeneralPropertyPage_size;
+	public static String FeatureGeneralPropertyPage_platforms;
+	public static String FeatureGeneralPropertyPage_ws;
+	public static String FeatureGeneralPropertyPage_arch;
+	public static String FeatureGeneralPropertyPage_nl;
+	public static String FeatureGeneralPropertyPage_all;
+	public static String FeatureGeneralPropertyPage_os;
+	public static String FeatureGeneralPropertyPage_desc;
+	public static String FeatureGeneralPropertyPage_Kilobytes;
+	public static String FeatureLicensePropertyPage_showInBrowser;
+	public static String FeatureLicensePropertyPage_noLicense;
+	public static String FeatureStatusPropertyPage_pendingChanges;
+	public static String FeatureStatusPropertyPage_reason;
+	public static String FeatureStatusPropertyPage_missingOptional;
+	public static String FeatureStatusPropertyPage_missing;
+	public static String FeatureStatusPropertyPage_goodConfiguration;
+	public static String JarVerificationDialog_wtitle;
+	public static String JarVerificationDialog_Title;
+	public static String JarVerificationDialog_Verification;
+	public static String JarVerificationDialog_ComponentNotInstalled;
+	public static String JarVerificationDialog_AboutToInstall_File;
+	public static String JarVerificationDialog_NotDigitallySigned_File;
+	public static String JarVerificationDialog_CannotVerifyProvider_File;
+	public static String JarVerificationDialog_CorruptedContent_File;
+	public static String JarVerificationDialog_SignedComponent_File;
+	public static String JarVerificationDialog_UnknownCertificate_File;
+	public static String JarVerificationDialog_UnableToVerifyProvider_File;
+	public static String JarVerificationDialog_ProviderKnown_File;
+	public static String JarVerificationDialog_KnownCertificate_File;
+	public static String JarVerificationDialog_AboutToInstall_Feature;
+	public static String JarVerificationDialog_NotDigitallySigned_Feature;
+	public static String JarVerificationDialog_CannotVerifyProvider_Feature;
+	public static String JarVerificationDialog_CorruptedContent_Feature;
+	public static String JarVerificationDialog_SignedComponent_Feature;
+	public static String JarVerificationDialog_UnknownCertificate_Feature;
+	public static String JarVerificationDialog_UnableToVerifyProvider_Feature;
+	public static String JarVerificationDialog_ProviderKnown_Feature;
+	public static String JarVerificationDialog_KnownCertificate_Feature;
+	public static String JarVerificationDialog_FileName;
+	public static String JarVerificationDialog_FeatureName;
+	public static String JarVerificationDialog_FeatureIdentifier;
+	public static String JarVerificationDialog_Provider;
+	public static String JarVerificationDialog_MayChooseToInstall;
+	public static String JarVerificationDialog_MayChooseToContinue;
+	public static String JarVerificationDialog_Install;
+	public static String JarVerificationDialog_InstallAll;
+	public static String JarVerificationDialog_Continue;
+	public static String JarVerificationDialog_Cancel;
+	public static String JarVerificationDialog_RootCA;
+	public static String JarVerificationDialog_SubjectCA;
+	public static String JarVerificationDialog_CertificateInfo;
+	public static String UserVerificationDialog_PasswordRequired;
+	public static String UserVerificationDialog_ConnectTo;
+	public static String UserVerificationDialog_Password;
+	public static String UserVerificationDialog_UserName;
+	public static String ConfigurationPreviewForm_configDescription;
+	public static String ConfigurationPreviewForm_install;
+	public static String ConfigurationPreviewForm_AvailableTasks;
+	public static String ConfigurationView_missingFeature;
+	public static String ConfigurationView_current;
+	public static String ConfigurationView_pending;
+	public static String ConfigurationView_error;
+	public static String ConfigurationView_collapseLabel;
+	public static String ConfigurationView_collapseTooltip;
+	public static String ConfigurationView_revertLabel;
+	public static String ConfigurationView_installHistory;
+	public static String ConfigurationView_extLocation;
+	public static String ConfigurationView_uninstall;
+	public static String ConfigurationView_unconfigureAndUninstall;
+	public static String ConfigurationView_install;
+	public static String ConfigurationView_anotherVersion;
+	public static String ConfigurationView_findUpdates;
+	public static String ConfigurationView_showNestedFeatures;
+	public static String ConfigurationView_showNestedTooltip;
+	public static String ConfigurationView_showInstall;
+	public static String ConfigurationView_showInstallTooltip;
+	public static String ConfigurationView_showDisabled;
+	public static String ConfigurationView_showDisabledTooltip;
+    public static String ConfigurationView_showActivitiesLabel;
+	public static String ConfigurationView_new;
+	public static String ConfigurationView_replaceWith;
+	public static String ConfigurationView_revertPreviousLabel;
+	public static String ConfigurationView_revertPreviousDesc;
+	public static String ConfigurationView_updateLabel;
+	public static String ConfigurationView_updateDesc;
+	public static String ConfigurationView_installHistLabel;
+	public static String ConfigurationView_installHistDesc;
+	public static String ConfigurationView_activitiesLabel;
+	public static String ConfigurationView_activitiesDesc;
+	public static String ConfigurationView_enableLocDesc;
+	public static String ConfigurationView_extLocLabel;
+	public static String ConfigurationView_extLocDesc;
+	public static String ConfigurationView_propertiesLabel;
+	public static String ConfigurationView_installPropDesc;
+	public static String ConfigurationView_replaceVersionLabel;
+	public static String ConfigurationView_replaceVersionDesc;
+	public static String ConfigurationView_enableFeatureDesc;
+	public static String ConfigurationView_installOptionalLabel;
+	public static String ConfigurationView_installOptionalDesc;
+	public static String ConfigurationView_uninstallLabel;
+	public static String ConfigurationView_uninstallDesc;
+	public static String ConfigurationView_uninstallDesc2;
+	public static String ConfigurationView_scanLabel;
+	public static String ConfigurationView_scanDesc;
+	public static String ConfigurationView_featurePropLabel;
+	public static String ConfigurationView_featurePropDesc;
+    public static String ConfigurationView_loading;
+	public static String Actions_brokenConfigQuestion;
+	public static String FeatureStateAction_disable;
+	public static String FeatureStateAction_enable;
+	public static String FeatureStateAction_disableQuestion;
+	public static String FeatureStateAction_EnableQuestion;
+	public static String FeatureStateAction_dialogTitle;
+	public static String FeatureUninstallAction_uninstall;
+	public static String FeatureUninstallAction_uninstallQuestion;
+	public static String FeatureUninstallAction_dialogTitle;
+	public static String FeatureUnconfigureAndUninstallAction_uninstall;
+	public static String FeatureUnconfigureAndUninstallAction_question;
+	public static String FeatureUnconfigureAndUninstallAction_dialogTitle;
+	public static String SiteStateAction_dialogTitle;
+	public static String SiteStateAction_disableLabel;
+	public static String SiteStateAction_disableMessage;
+	public static String SiteStateAction_enableLabel;
+	public static String SiteStateAction_enableMessage;
+	public static String InstallationHistoryAction_title;
+	public static String InstallationHistoryAction_desc;
+	public static String InstallationHistoryAction_dateTime;
+	public static String InstallationHistoryAction_target;
+	public static String InstallationHistoryAction_action;
+	public static String InstallationHistoryAction_status;
+	public static String InstallationHistoryAction_errors;
+	public static String NewExtensionLocationAction_selectExtLocation;
+	public static String NewExtensionLocationAction_extInfoTitle;
+	public static String NewExtensionLocationAction_extInfoMessage;
+	public static String ActivitiesTableViewer_enabled;
+	public static String ActivitiesTableViewer_featureInstalled;
+	public static String ActivitiesTableViewer_featureRemoved;
+	public static String ActivitiesTableViewer_siteInstalled;
+	public static String ActivitiesTableViewer_siteRemoved;
+	public static String ActivitiesTableViewer_disabled;
+	public static String ActivitiesTableViewer_revert;
+	public static String ActivitiesTableViewer_reconcile;
+	public static String ActivitiesTableViewer_unknown;
+	public static String ActivitiesTableViewer_date;
+	public static String ActivitiesTableViewer_target;
+	public static String ActivitiesTableViewer_action;
+	public static String DuplicateConflictsDialog_title;
+	public static String DuplicateConflictsDialog_message;
+	public static String DuplicateConflictsDialog_treeLabel;
+	public static String ModeSelectionPage_title;
+	public static String ModeSelectionPage_desc;
+	public static String ModeSelectionPage_updates;
+	public static String ModeSelectionPage_updatesText;
+	public static String ModeSelectionPage_newFeatures;
+	public static String ModeSelectionPage_newFeaturesText;
+	public static String MoreInfoGenerator_moreInfo;
+	public static String NewUpdateSiteDialog_name;
+	public static String NewUpdateSiteDialog_url;
+	public static String NewUpdateSiteDialog_error_nameOrUrlNotSpecified;
+	public static String NewUpdateSiteDialog_error_duplicateName;
+	public static String NewUpdateSiteDialog_error_duplicateUrl;
+	public static String NewUpdateSiteDialog_error_incorrectUrl;
+	public static String InstallWizard_isRunningTitle;
+	public static String InstallWizard_isRunningInfo;
+	public static String InstallWizard_jobName;
+	public static String InstallWizard_download;
+	public static String InstallWizard_downloadingFeatureJar;
+	public static String InstallWizard_anotherJob;
+	public static String InstallWizard_anotherJobTitle;
+	public static String InstallWizard_wtitle;
+	public static String InstallWizard_OptionalFeaturesPage_title;
+	public static String InstallWizard_OptionalFeaturesPage_desc;
+	public static String InstallWizard_OptionalFeaturesPage_treeLabel;
+	public static String InstallWizard_OptionalFeaturesPage_selectAll;
+	public static String InstallWizard_OptionalFeaturesPage_deselectAll;
+	public static String InstallWizard_ReviewPage_counter;
+	public static String InstallWizard_ReviewPage_title;
+	public static String InstallWizard_ReviewPage_desc;
+	public static String InstallWizard_ReviewPage_zeroUpdates;
+	public static String InstallWizard_ReviewPage_zeroFeatures;
+	public static String InstallWizard_ReviewPage_label;
+	public static String InstallWizard_ReviewPage_deselectAll;
+	public static String InstallWizard_ReviewPage_moreInfo;
+	public static String InstallWizard_ReviewPage_properties;
+	public static String InstallWizard_ReviewPage_selectRequired;
+	public static String InstallWizard_ReviewPage_showStatus;
+	public static String InstallWizard_ReviewPage_filterFeatures;
+	public static String InstallWizard_ReviewPage_filterPatches;
+	public static String InstallWizard_ReviewPage_filterOlderFeatures;
+	public static String InstallWizard_ReviewPage_invalid_long;
+	public static String InstallWizard_ReviewPage_invalid_short;
+	public static String InstallWizard_ReviewPage_cycle;
+	public static String InstallWizard_LicensePage_accept;
+	public static String InstallWizard_LicensePage_accept2;
+	public static String InstallWizard_LicensePage_decline;
+	public static String InstallWizard_LicensePage_decline2;
+	public static String InstallWizard_LicensePage_desc;
+	public static String InstallWizard_LicensePage_desc2;
+	public static String InstallWizard_LicensePage_title;
+	public static String InstallWizard_TargetPage_title;
+	public static String InstallWizard_TargetPage_desc;
+	public static String InstallWizard_TargetPage_jobsLabel;
+	public static String InstallWizard_TargetPage_siteLabel;
+	public static String InstallWizard_TargetPage_new;
+	public static String InstallWizard_TargetPage_delete;
+	public static String InstallWizard_TargetPage_requiredSpace;
+	public static String InstallWizard_TargetPage_availableSpace;
+	public static String InstallWizard_TargetPage_location;
+	public static String InstallWizard_TargetPage_location_change;
+	public static String InstallWizard_TargetPage_location_message;
+	public static String InstallWizard_TargetPage_location_empty;
+	public static String InstallWizard_TargetPage_location_error_title;
+	public static String InstallWizard_TargetPage_size_KB;
+	public static String InstallWizard_TargetPage_size_MB;
+	public static String InstallWizard_TargetPage_size_GB;
+	public static String InstallWizard_TargetPage_unknownSize;
+	public static String InstallWizard_TargetPage_patchError;
+	public static String InstallWizard_TargetPage_patchError2;
+	public static String InstallWizard2_updateOperationHasFailed;
+	public static String RevertConfigurationWizard_wtitle;
+	public static String RevertConfigurationWizardPage_title;
+	public static String RevertConfigurationWizardPage_desc;
+	public static String RevertConfigurationWizardPage_label;
+	public static String RevertConfigurationWizardPage_activities;
+	public static String RevertConfigurationWizardPage_question;
+	public static String Revert_ProblemDialog_title;
+	public static String ShowActivitiesDialog_title;
+	public static String ShowActivitiesDialog_date;
+	public static String ShowActivitiesDialog_loc;
+	public static String ShowActivitiesDialog_label;
+	public static String SitePage_title;
+	public static String SitePage_desc;
+	public static String SitePage_label;
+	public static String SitePage_addUpdateSite;
+	public static String SitePage_addLocalSite;
+	public static String SitePage_addLocalZippedSite;
+	public static String SitePage_edit;
+	public static String SitePage_remove;
+	public static String SitePage_import;
+	public static String SitePage_export;
+	public static String SitePage_ignore;
+	public static String SitePage_automaticallySelectMirrors;
+	public static String SitePage_new;
+	public static String SitePage_dialogEditLocal;
+	public static String SitePage_dialogEditUpdateSite;
+	public static String SitePage_remove_location_conf_title;
+	public static String SitePage_remove_location_conf;
+	public static String LocalSiteSelector_dialogMessage;
+	public static String LocalSiteSelector_dirInfoTitle;
+	public static String LocalSiteSelector_dirInfoMessage;
+	public static String LocalSiteSelector_dirDuplicateDefinition;
+	public static String LocalSiteSelector_dialogMessagezip;
+	public static String LocalSiteSelector_zipInfoTitle;
+	public static String LocalSiteSelector_zipInfoMessage;
+	public static String LocalSiteSelector_zipDuplicateDefinition;
+	public static String LocalSiteSelector_dialogMessageImport;
+	public static String LocalSiteSelector_importInfoTitle;
+	public static String LocalSiteSelector_importInfoMessage;
+	public static String LocalSiteSelector_dialogMessageExport;
+	public static String MissingFeature_provider;
+    public static String MissingFeature_id;
+	public static String MissingFeature_desc_unknown;
+	public static String MissingFeature_desc_optional;
+	public static String SwapFeatureWizard_title;
+	public static String SwapFeatureWizardPage_title;
+	public static String SwapFeatureWizardPage_desc;
+	public static String SwapFeatureWizardPage_label;
+	public static String MirrorsDialog_text;
+	public static String MirrorsDialog_title;
+	public static String AutomaticUpdatesJob_Updates;
+	public static String AutomaticUpdatesJob_EclipseUpdates1;
+	public static String AutomaticUpdatesJob_UpdatesAvailable;
+	public static String AutomaticUpdatesJob_EclipseUpdates2;
+	public static String AutomaticUpdatesJob_UpdatesDownloaded;
+    
+    public static String FeaturePage_optionalInstall_title;
+
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, UpdateUIMessages.class);
+	}
+
+	public static String ConfigurationManagerWindow_searchTaskName;
+	public static String FindUpdatesAction_trackedProgress;
+	public static String FindUpdatesAction_allFeaturesSearch;
+	public static String ReviewPage_validating;
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUIPluginResources.properties b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUIPluginResources.properties
new file mode 100644
index 0000000..472dd28
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/UpdateUIPluginResources.properties
@@ -0,0 +1,409 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+###############################################################################
+#
+#
+#
+RestartTitle = Install/Update
+RestartMessage = You will need to restart the {0} for the changes to take effect. \
+Would you like to restart now?
+
+OptionalRestartMessage = It is recommended you restart the {0} for the changes to take effect, \
+but it may be possible to apply the changes to the current configuration without restarting. \
+Would you like to restart now?
+
+ApplicationInRestartDialog =application
+
+ApplyChanges=Apply Changes
+
+
+ConfigurationManagerAction_title=Product Configuration
+ConfigurationManagerWindow_fileMenu=&File
+ConfigurationManagerWindow_properties=&Properties
+ConfigurationManagerWindow_searchTaskName=Searching for updates: {0}
+ConfigurationManagerWindow_close=&Close
+
+
+InstallWizardAction_title=Install/Update
+InstallWizard_retryTitle = Problem occurred
+InstallWizard_retry = Do you want to retry?
+
+
+DiscoveryFolder_name=Sites to Visit
+FeatureAdapter_failure=<failure>
+SiteBookmark_connecting = Connecting to "{0}"...
+SiteBookmark_downloading = Downloading:\
+
+MainPreferencePage_checkSignature = Check digital &signatures of downloaded archives
+MainPreferencePage_automaticallyChooseMirror = Automatically select &mirrors
+MainPreferencePage_historySize = &Maximum number of 'History' configurations:
+MainPreferencePage_invalidHistorySize = The maximum number of 'History' configurations must be 0 or more.
+MainPreferencePage_updateVersions = Valid updates
+MainPreferencePage_updateVersions_equivalent = e&quivalent (1.0.1 -> 1.0.2 - only service increments)
+MainPreferencePage_updateVersions_compatible = &compatible (1.0.9 -> 1.1.0 - service and minor increments)
+MainPreferencePage_updatePolicy = &Update Policy
+MainPreferencePage_updatePolicyURL = Po&licy URL:
+MainPreferencePage_proxyGroup = Proxy settings
+MainPreferencePage_digitalSignature_title = Digital Signature Check
+MainPreferencePage_digitalSignature_message = You have chosen to disable digital signature \
+checks for downloaded archives. Note that unsigned archives may \
+contain software that can harm your computer.
+
+UpdateSettingsPreferencePage_description=Settings for automatic feature update
+UpdateSettingsPreferencePage_label=Address &Mappings URL:
+UpdateSettingsPreferencePage_invalid=Invalid mappings URL
+
+
+ConfiguredSitePropertyPage_path=Location path:
+ConfiguredSitePropertyPage_type=Location type:
+ConfiguredSitePropertyPage_enabled=Enabled:
+ConfiguredSitePropertyPage_yes=yes
+ConfiguredSitePropertyPage_no=no
+ConfiguredSitePropertyPage_extension=product extension
+ConfiguredSitePropertyPage_product=product
+ConfiguredSitePropertyPage_unknown=unknown
+
+FeatureCopyrightPropertyPage_showInBrowser=&Show in Browser
+FeatureCopyrightPropertyPage_noCopyright=Feature does not contain a copyright statement
+
+FeatureGeneralPropertyPage_name=Name:
+FeatureGeneralPropertyPage_id=Identifier:
+FeatureGeneralPropertyPage_version=Version:
+FeatureGeneralPropertyPage_provider=Provider:
+FeatureGeneralPropertyPage_size=Size:
+FeatureGeneralPropertyPage_platforms=Supported Platforms
+FeatureGeneralPropertyPage_ws=Windowing System: {0}
+FeatureGeneralPropertyPage_arch=CPU Architecture: {0}
+FeatureGeneralPropertyPage_nl=Languages: {0}
+FeatureGeneralPropertyPage_all=all
+FeatureGeneralPropertyPage_os=Operating System: {0}
+FeatureGeneralPropertyPage_desc=Description
+FeatureGeneralPropertyPage_Kilobytes = KB
+
+FeatureLicensePropertyPage_showInBrowser=&Show in Browser
+FeatureLicensePropertyPage_noLicense=Feature does not contain a license.
+
+FeatureStatusPropertyPage_pendingChanges=The feature has pending changes.  Therefore, its status cannot be determined until you restart the workbench.
+FeatureStatusPropertyPage_reason=Reason:
+FeatureStatusPropertyPage_missingOptional=This optional feature is currently not installed.
+FeatureStatusPropertyPage_missing=Referenced feature not found.
+FeatureStatusPropertyPage_goodConfiguration=The feature is configured properly.
+
+JarVerificationDialog_wtitle = Verification
+JarVerificationDialog_Title= Feature Verification
+JarVerificationDialog_Verification=Verification
+JarVerificationDialog_ComponentNotInstalled=This feature will not be installed.
+
+JarVerificationDialog_AboutToInstall_File=Warning: You are about to install an unsigned feature file.
+JarVerificationDialog_NotDigitallySigned_File= This feature file has not been digitally signed.
+JarVerificationDialog_CannotVerifyProvider_File=The provider of this feature file cannot be verified.
+JarVerificationDialog_CorruptedContent_File=The content of this feature file has been corrupted
+JarVerificationDialog_SignedComponent_File=You are about to install a signed feature file.
+JarVerificationDialog_UnknownCertificate_File=The certificates used to authenticate this feature file are not recognized.
+JarVerificationDialog_UnableToVerifyProvider_File=The provider of this feature file cannot be verified.
+JarVerificationDialog_ProviderKnown_File=The provider of this feature file has been validated by a trusted third party.
+JarVerificationDialog_KnownCertificate_File=One of the certificates used to authenticate this feature file was recognized.
+
+JarVerificationDialog_AboutToInstall_Feature=Warning: You are about to install an unsigned feature.
+JarVerificationDialog_NotDigitallySigned_Feature= This feature has not been digitally signed.
+JarVerificationDialog_CannotVerifyProvider_Feature=The provider of this feature cannot be verified.
+JarVerificationDialog_CorruptedContent_Feature=The content of this feature has been corrupted
+JarVerificationDialog_SignedComponent_Feature=You are about to install a signed feature.
+JarVerificationDialog_UnknownCertificate_Feature=The certificates used to authenticate this feature are not recognized.
+JarVerificationDialog_UnableToVerifyProvider_Feature=The provider of this feature cannot be verified.
+JarVerificationDialog_ProviderKnown_Feature=The provider of this feature has been validated by a trusted third party.
+JarVerificationDialog_KnownCertificate_Feature=One of the certificates used to authenticate this feature was recognized.
+
+JarVerificationDialog_FileName=File Identifier:
+JarVerificationDialog_FeatureName=Feature name:
+JarVerificationDialog_FeatureIdentifier=Feature Identifier:
+JarVerificationDialog_Provider=	Provider:
+JarVerificationDialog_MayChooseToInstall=You may choose to install the feature or cancel its installation.
+JarVerificationDialog_MayChooseToContinue=You may choose to continue to install the feature or cancel its installation.
+JarVerificationDialog_Install=&Install
+JarVerificationDialog_InstallAll=Install &All
+JarVerificationDialog_Continue=C&ontinue
+JarVerificationDialog_Cancel=&Cancel
+JarVerificationDialog_RootCA= According to:
+JarVerificationDialog_SubjectCA= File signed by:
+JarVerificationDialog_CertificateInfo= Certificate:
+
+UserVerificationDialog_PasswordRequired=Password Required
+UserVerificationDialog_ConnectTo=Connect to:
+UserVerificationDialog_Password=Password:
+UserVerificationDialog_UserName=User name:
+
+ConfigurationPreviewForm_configDescription=This is the description of the current configuration.
+ConfigurationPreviewForm_install=Install Location
+ConfigurationPreviewForm_AvailableTasks=Available Tasks
+
+ConfigurationView_missingFeature = {0} (not installed)
+ConfigurationView_current=Current Configuration
+ConfigurationView_pending=\ (pending changes)
+ConfigurationView_error=Error
+ConfigurationView_collapseLabel=Collapse All
+ConfigurationView_collapseTooltip=Collapse All
+ConfigurationView_revertLabel=Revert...
+ConfigurationView_installHistory =Installation History
+ConfigurationView_extLocation=Extension Location...
+ConfigurationView_uninstall=Uninstall
+ConfigurationView_unconfigureAndUninstall=Uninstall
+ConfigurationView_install=Install
+ConfigurationView_anotherVersion=&Another Version...
+ConfigurationView_findUpdates=Find Updates...
+ConfigurationView_showNestedFeatures=Show Nested Features
+ConfigurationView_showNestedTooltip=Show Nested Features
+ConfigurationView_showInstall=Show Install Locations
+ConfigurationView_showInstallTooltip=Show Install Locations
+ConfigurationView_showDisabled=Show Disabled Features
+ConfigurationView_showDisabledTooltip=Show Disabled Features
+ConfigurationView_showActivitiesLabel = Show Activities
+
+ConfigurationView_new=Add
+ConfigurationView_replaceWith=Replace with
+ConfigurationView_revertPreviousLabel=Revert to Previous
+ConfigurationView_revertPreviousDesc=You can revert to one of the previous configurations if you are having problems with the current one.
+ConfigurationView_updateLabel=Scan for Updates
+ConfigurationView_updateDesc=Search for updates for all the installed features.
+ConfigurationView_installHistLabel=View Installation History
+ConfigurationView_installHistDesc=View all activities since the installation of the product.
+ConfigurationView_activitiesLabel=Show Activities
+ConfigurationView_activitiesDesc=View the activities that caused the creation of this configuration.
+ConfigurationView_enableLocDesc=You can enable or disable an entire install location. Disabling a location is equivalent to disabling every feature in it.
+ConfigurationView_extLocLabel=Add an Extension Location
+ConfigurationView_extLocDesc=Locate and add an extension location to the current configuration. An extension location contains features and plugins previously installed.
+ConfigurationView_propertiesLabel=Show Properties
+ConfigurationView_installPropDesc=View the properties of the install location.
+ConfigurationView_replaceVersionLabel=Replace With Another Version
+ConfigurationView_replaceVersionDesc=Disables the current version of the feature and replaces it with another version from the list of the currently disabled features.
+ConfigurationView_enableFeatureDesc=You can enable or disable the functionality of a feature. The feature is not removed by this action.
+ConfigurationView_installOptionalLabel=Install from Originating Server
+ConfigurationView_installOptionalDesc=This optional feature was not originally installed. You can install it now by connecting to the originating server of the parent.
+ConfigurationView_uninstallLabel=Uninstall
+ConfigurationView_uninstallDesc=This feature is currently not used and can be uninstalled from the product.
+ConfigurationView_uninstallDesc2=Uninstall the feature from the product. This will disable the feature from the current configuration and remove it from the disk.
+ConfigurationView_scanLabel=Scan for Updates
+ConfigurationView_scanDesc=Search for updates for this feature.
+ConfigurationView_featurePropLabel=Show Properties
+ConfigurationView_featurePropDesc=View properties of the feature such as version, provider name, license agreement etc.
+ConfigurationView_loading = Loading...
+
+Actions_brokenConfigQuestion=The current configuration contains errors and this operation can have unpredictable results. Do you want to continue ?
+
+FeatureStateAction_disable=Disable
+FeatureStateAction_enable=Enable
+FeatureStateAction_disableQuestion=Do you want to disable this feature?
+FeatureStateAction_EnableQuestion=Do you want to enable this feature?
+FeatureStateAction_dialogTitle=Current Configuration
+
+FeatureUninstallAction_uninstall=Uninstall
+FeatureUninstallAction_uninstallQuestion=Do you want to uninstall this feature?
+FeatureUninstallAction_dialogTitle=Current Configuration
+
+FeatureUnconfigureAndUninstallAction_uninstall=Uninstall
+FeatureUnconfigureAndUninstallAction_question=Do you want to disable and uninstall this feature?
+FeatureUnconfigureAndUninstallAction_dialogTitle=Uninstall
+
+SiteStateAction_dialogTitle=Current Configuration
+SiteStateAction_disableLabel=Disable
+SiteStateAction_disableMessage=Do you want to disable all the features in "{0}"?
+SiteStateAction_enableLabel=Enable
+SiteStateAction_enableMessage=Do you want to enable features in "{0}"?
+
+FindUpdatesAction_trackedProgress={0} {1}: ({2}%)
+FindUpdatesAction_allFeaturesSearch=All Features
+
+InstallationHistoryAction_title=Installation History
+InstallationHistoryAction_desc=The list below represents the history of your update activities from the product installation to date. Each operation carries a date it commenced, as well as activities performed. Operations are sorted by date in ascending order.
+InstallationHistoryAction_dateTime=Date / Time
+InstallationHistoryAction_target=Target
+InstallationHistoryAction_action=Action
+InstallationHistoryAction_status=Status
+InstallationHistoryAction_errors=Errors while creating installation history file.
+
+NewExtensionLocationAction_selectExtLocation=Select an extension location. An extension location is a directory named eclipse, which contains the .eclipseextension marker file, as well as the features and plugins folders.
+NewExtensionLocationAction_extInfoTitle=Invalid Extension
+NewExtensionLocationAction_extInfoMessage=Selected location does not contain a product extension. An extension should consist of a directory named eclipse, which contains a marker file called .eclipseextension and the features and plugins folders.  Please select another location.
+
+ActivitiesTableViewer_enabled=Enabled
+ActivitiesTableViewer_featureInstalled=Feature Installed
+ActivitiesTableViewer_featureRemoved=Feature Removed
+ActivitiesTableViewer_siteInstalled=Site Installed
+ActivitiesTableViewer_siteRemoved=Site Removed
+ActivitiesTableViewer_disabled=Disabled
+ActivitiesTableViewer_revert=Revert
+ActivitiesTableViewer_reconcile=Reconcile
+ActivitiesTableViewer_unknown=unknown
+ActivitiesTableViewer_date=Date
+ActivitiesTableViewer_target=Target
+ActivitiesTableViewer_action=Action
+
+
+DuplicateConflictsDialog_title = Duplicate Conflicts
+DuplicateConflictsDialog_message = If you continue with the update/install, \
+the resulting configuration will contain duplication conflicts \
+that may cause parts of the product to be unusable. Do you want to \
+continue?
+DuplicateConflictsDialog_treeLabel = &Detected conflicts:
+
+
+ModeSelectionPage_title=Feature Updates
+ModeSelectionPage_desc=Choose the way you want to search for features to install
+ModeSelectionPage_updates=Search for &updates of the currently installed features
+ModeSelectionPage_updatesText=Select this option if you want to search for updates of the features you already have installed.
+ModeSelectionPage_newFeatures=&Search for new features to install
+ModeSelectionPage_newFeaturesText=Select this option if you want to install new features from existing or new update sites. \
+Some sites may already be available. You can add new update site URLs to the search.
+
+MoreInfoGenerator_moreInfo=More info...
+
+NewUpdateSiteDialog_name=Name:
+NewUpdateSiteDialog_url=URL:
+NewUpdateSiteDialog_error_nameOrUrlNotSpecified=Both name and url have to be specified
+NewUpdateSiteDialog_error_duplicateName=This name is already in use
+NewUpdateSiteDialog_error_duplicateUrl=This URL is already defined under name {0}
+NewUpdateSiteDialog_error_incorrectUrl=URL is not correct
+
+InstallWizard_isRunningTitle=Install/Update in progress
+InstallWizard_isRunningInfo=Another install/update job is in progress. Please cancel it and then re-launch this action.
+InstallWizard_jobName=Update Manager
+InstallWizard_download=Download and install selected features.
+InstallWizard_downloadingFeatureJar=Downloading feature jar for {0}
+InstallWizard_anotherJob = There is another update/install task running in the background. Do you want to kill it and continue the current tasks instead?
+InstallWizard_anotherJobTitle=Installer is running
+InstallWizard_wtitle=Install
+InstallWizard_OptionalFeaturesPage_title= Optional Features
+InstallWizard_OptionalFeaturesPage_desc = Some of the features that are included in this feature are optional.
+InstallWizard_OptionalFeaturesPage_treeLabel = &Available optional features:
+InstallWizard_OptionalFeaturesPage_selectAll = &Select All
+InstallWizard_OptionalFeaturesPage_deselectAll = &Deselect All
+
+InstallWizard_ReviewPage_counter = {0} of {1} selected.
+InstallWizard_ReviewPage_title=Search Results
+InstallWizard_ReviewPage_desc=Select features to install from the search result list.
+InstallWizard_ReviewPage_zeroUpdates=No updates for the currently installed feature(s) found, try again later.
+InstallWizard_ReviewPage_zeroFeatures=No features found on the selected site(s). Choose a different site or site category.
+InstallWizard_ReviewPage_label=Select the features to &install:
+InstallWizard_ReviewPage_deselectAll=&Deselect All
+InstallWizard_ReviewPage_moreInfo=&More Info
+InstallWizard_ReviewPage_properties=&Properties
+InstallWizard_ReviewPage_selectRequired=&Select Required
+InstallWizard_ReviewPage_showStatus=&Error Details...
+InstallWizard_ReviewPage_filterFeatures=\ Fil&ter features included in other features on the list
+InstallWizard_ReviewPage_filterPatches=\ Fil&ter patches included in other patches on the list
+InstallWizard_ReviewPage_filterOlderFeatures=\ Show the latest &version of a feature only
+InstallWizard_ReviewPage_invalid_long=Invalid combination - select \"Show Status...\" for details.
+InstallWizard_ReviewPage_invalid_short=Invalid combination
+InstallWizard_ReviewPage_cycle=Cycle starting at {0}
+
+InstallWizard_LicensePage_accept = I &accept the terms in the license agreement
+InstallWizard_LicensePage_accept2 = I &accept the terms in the license agreements
+InstallWizard_LicensePage_decline = I &do not accept the terms in the license agreement
+InstallWizard_LicensePage_decline2 = I &do not accept the terms in the license agreements
+InstallWizard_LicensePage_desc = This feature has a license \
+agreement that you need to accept before proceeding with \
+the installation.
+InstallWizard_LicensePage_desc2 = Some of the features have license \
+agreements that you need to accept before proceeding with \
+the installation.
+InstallWizard_LicensePage_title = Feature License
+
+InstallWizard_TargetPage_title = Installation
+InstallWizard_TargetPage_desc = The following features will be installed. You can select a feature and change the location where the feature will be installed.
+InstallWizard_TargetPage_jobsLabel = Features to &install:
+InstallWizard_TargetPage_siteLabel = A&vailable installation locations:
+InstallWizard_TargetPage_new = &Add Location...
+InstallWizard_TargetPage_delete = &Remove Location
+InstallWizard_TargetPage_requiredSpace = Required space:
+InstallWizard_TargetPage_availableSpace = Free space:
+InstallWizard_TargetPage_location = Install Location:
+InstallWizard_TargetPage_location_change = Change Location ...
+InstallWizard_TargetPage_location_message = Select a new install location
+InstallWizard_TargetPage_location_empty = Target install location must be selected. If none is available, create a new one.
+InstallWizard_TargetPage_location_error_title = Invalid Location
+InstallWizard_TargetPage_size_KB = {0} KB
+InstallWizard_TargetPage_size_MB = {0} MB
+InstallWizard_TargetPage_size_GB = {0} GB
+InstallWizard_TargetPage_unknownSize = Unknown
+InstallWizard_TargetPage_patchError = Patch "{0}" must be installed in the same location as "{1}"
+InstallWizard_TargetPage_patchError2 = Patch "{0}" must be installed in the same location as "{1}" : {2}
+InstallWizard2_updateOperationHasFailed= Update operation has failed
+
+RevertConfigurationWizard_wtitle=Revert to a Previous Configuration
+RevertConfigurationWizardPage_title=Revert to a Previous Configuration
+RevertConfigurationWizardPage_desc=Choose a stable configuration to which you would like to revert
+RevertConfigurationWizardPage_label=&Past configurations:
+RevertConfigurationWizardPage_activities=&Activities that caused the creation of this configuration:
+RevertConfigurationWizardPage_question=This operation requires restarting the workbench.  Would you like to proceed?
+
+Revert_ProblemDialog_title = Restore Problems
+
+ShowActivitiesDialog_title = Current Configuration
+ShowActivitiesDialog_date = Date:
+ShowActivitiesDialog_loc = Location:
+ShowActivitiesDialog_label = Activities that caused the creation of the current configuration:
+
+SitePage_title=Update sites to visit
+SitePage_desc=Select update sites to visit while looking for new features.
+SitePage_label=&Sites to include in search:
+SitePage_addUpdateSite=New Remo&te Site...
+SitePage_addLocalSite=New &Local Site...
+SitePage_addLocalZippedSite=New &Archived Site...
+SitePage_edit=&Edit...
+SitePage_remove=&Remove
+SitePage_import=I&mport sites...
+SitePage_export=E&xport sites...
+SitePage_ignore=&Ignore features not applicable to this environment
+SitePage_automaticallySelectMirrors=Automatically select &mirrors
+SitePage_new=New Update Site
+SitePage_dialogEditLocal=Edit Local Site
+SitePage_dialogEditUpdateSite=Edit Remote Site
+SitePage_remove_location_conf_title=Remove Location
+SitePage_remove_location_conf=Are you sure you want to remove this location?
+
+
+LocalSiteSelector_dialogMessage=Select a local update site.
+LocalSiteSelector_dirInfoTitle=Invalid Site
+LocalSiteSelector_dirInfoMessage=Selected location does not contain an update site.  Please select another location.
+LocalSiteSelector_dirDuplicateDefinition=Selected location is already defined under another name.  Please select another location.
+LocalSiteSelector_dialogMessagezip=Select Local Site Archive
+LocalSiteSelector_zipInfoTitle=Invalid Site
+LocalSiteSelector_zipInfoMessage=Selected archive does not contain an update site.  Please select another archive.
+LocalSiteSelector_zipDuplicateDefinition=Selected archive is already defined under another name.  Please select another archive.
+LocalSiteSelector_dialogMessageImport=Import Sites Bookmarks
+LocalSiteSelector_importInfoTitle=Invalid Bookmarks File
+LocalSiteSelector_importInfoMessage=Selected file does not contain update sites bookmarks.  Please select another file.
+LocalSiteSelector_dialogMessageExport=Export Sites Bookmarks
+
+
+MissingFeature_id = unknown
+MissingFeature_provider = N/A
+MissingFeature_desc_unknown = The feature was not loaded due to errors. Open feature properties for details.
+MissingFeature_desc_optional = This optional feature has not been installed.
+SwapFeatureWizard_title=Replace With Another Version
+SwapFeatureWizardPage_title=Replace With Another Version
+SwapFeatureWizardPage_desc=Disable the current version of the feature and replace it with one of the versions from the list
+SwapFeatureWizardPage_label=&Available disabled versions:
+
+MirrorsDialog_text=The content of the update site "{0}" is also available on the mirrors listed below. You may choose to select a mirror instead of the default update site.
+MirrorsDialog_title=Update Site Mirrors
+
+AutomaticUpdatesJob_Updates=Updates
+AutomaticUpdatesJob_EclipseUpdates1=Automatic Updates
+AutomaticUpdatesJob_UpdatesAvailable=New updates are available. Do you want to review and install them now?
+AutomaticUpdatesJob_EclipseUpdates2=Automatic Updates
+AutomaticUpdatesJob_UpdatesDownloaded=New updates are available and downloaded. Do you want to review and install them now?
+
+FeaturePage_optionalInstall_title = Optional Install
+ReviewPage_validating=Validating selection...
+TargetPage_FeatureNameColumn=Feature Name
+TargetPage_Feature_Version=Feature Version
+TargetPage_Feature_Size=Feature Size
+TargetPage_InstallationDirectoryColumn=Installation Directory
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/BookmarkFolder.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/BookmarkFolder.java
new file mode 100644
index 0000000..df65f9e
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/BookmarkFolder.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.util.ArrayList;
+
+public class BookmarkFolder extends NamedModelObject {
+
+    private static final long serialVersionUID = 1L;
+    protected ArrayList children= new ArrayList();
+	public BookmarkFolder() {
+	}
+	
+	public BookmarkFolder(String name) {
+		super(name);
+	}
+	
+	public Object[] getChildren(Object parent) {
+		return children.toArray();
+	}
+	
+	public boolean hasChildren() {
+		return children.size()>0;
+	} 
+	
+	public void addChild(NamedModelObject object) {
+		internalAdd(object);
+		notifyObjectsAdded(this, new Object[] {object});
+	}
+
+	public void addChildren(NamedModelObject [] objects) {
+		for (int i=0; i<objects.length; i++) {
+			internalAdd(objects[i]);
+		}
+		notifyObjectsAdded(this, objects);
+	}
+	
+	protected void internalAdd(NamedModelObject child) {
+		children.add(child);
+		child.setModel(getModel());
+		child.setParent(this);
+	}
+	
+	public void removeChildren(NamedModelObject [] objects) {
+		for (int i=0; i<objects.length; i++) {
+			children.remove(objects[i]);
+			objects[i].setParent(null);
+		}
+		notifyObjectsRemoved(this, objects);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/BookmarkUtil.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/BookmarkUtil.java
new file mode 100644
index 0000000..a3f4605
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/BookmarkUtil.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.io.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.xml.parsers.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.ui.*;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+public class BookmarkUtil {
+	private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+
+	public static void parse(String fileName, Vector bookmarks) {
+		File file = new File(fileName);
+		if (!file.exists())
+			return;
+
+		try {
+			documentBuilderFactory.setNamespaceAware(true);
+			DocumentBuilder parser = documentBuilderFactory.newDocumentBuilder();
+			Document doc = parser.parse(file);
+			Node root = doc.getDocumentElement();
+			processRoot(root, bookmarks);
+		} catch (ParserConfigurationException e) {
+			UpdateUI.logException(e);
+		} catch (SAXException e) {
+			UpdateUI.logException(e);
+		} catch (IOException e) {
+			UpdateUI.logException(e);
+		}
+	}
+
+	public static SiteBookmark[] getBookmarks(Vector bookmarks) {
+		ArrayList result = new ArrayList();
+		for (int i = 0; i < bookmarks.size(); i++) {
+			processEntry(bookmarks.get(i), result);
+		}
+		return (SiteBookmark[]) result.toArray(new SiteBookmark[result.size()]);
+	}
+
+	public static BookmarkFolder getFolder(Vector bookmarks, IPath path) {
+		NamedModelObject object = find(bookmarks, path);
+		if (object != null && object instanceof BookmarkFolder)
+			return (BookmarkFolder) object;
+		return null;
+	}
+
+	public static NamedModelObject find(Vector bookmarks, IPath path) {
+		Object[] array = bookmarks.toArray();
+		return find(array, path);
+	}
+
+	private static NamedModelObject find(Object[] array, IPath path) {
+		String name = path.segment(0);
+		for (int i = 0; i < array.length; i++) {
+			NamedModelObject obj = (NamedModelObject) array[i];
+			if (obj.getName().equals(name)) {
+				if (obj instanceof BookmarkFolder) {
+					if (path.segmentCount() > 1) {
+						IPath childPath = path.removeFirstSegments(1);
+						BookmarkFolder folder = (BookmarkFolder) obj;
+						return find(folder.getChildren(null), childPath);
+					}
+				}
+				return obj;
+			}
+		}
+		return null;
+	}
+
+	private static void processRoot(Node root, Vector bookmarks) {
+		if (root.getNodeName().equals("bookmarks")) { //$NON-NLS-1$
+			NodeList children = root.getChildNodes();
+			processChildren(children, null, bookmarks);
+		}
+	}
+	private static void processChildren(
+		NodeList children,
+		BookmarkFolder folder,
+		Vector bookmarks) {
+		UpdateModel model = UpdateUI.getDefault().getUpdateModel();
+		for (int i = 0; i < children.getLength(); i++) {
+			Node child = children.item(i);
+			NamedModelObject object = null;
+			if (child.getNodeType() == Node.ELEMENT_NODE) {
+				if (child.getNodeName().equals("site")) { //$NON-NLS-1$
+					object = createSite(child);
+				} else if (child.getNodeName().equals("folder")) { //$NON-NLS-1$
+					object = createFolder(child);
+				} 
+			}
+			if (object != null) {
+				if (folder != null) {
+					folder.addChild(object);
+				} else {
+					bookmarks.add(object);
+				}
+				object.setModel(model);
+			}
+		}
+	}
+
+	private static SiteBookmark createSite(Node child) {
+		String name = getAttribute(child, "name"); //$NON-NLS-1$
+		URL url = null;
+		try {
+			url = new URL(getAttribute(child, "url")); //$NON-NLS-1$
+		} catch (MalformedURLException e) {
+		}
+
+		String web = getAttribute(child, "web"); //$NON-NLS-1$
+		boolean webBookmark = (web != null && web.equals("true")); //$NON-NLS-1$
+
+		String sel = getAttribute(child, "selected"); //$NON-NLS-1$
+		boolean selected = (sel != null && sel.equals("true")); //$NON-NLS-1$
+
+		SiteBookmark bookmark = new SiteBookmark(name, url, webBookmark, selected);
+
+		String local = getAttribute(child, "local"); //$NON-NLS-1$
+		bookmark.setLocal(local != null && local.equals("true")); //$NON-NLS-1$
+
+		String ign = getAttribute(child, "ignored-categories"); //$NON-NLS-1$
+		if (ign != null) {
+			StringTokenizer stok = new StringTokenizer(ign, ","); //$NON-NLS-1$
+			ArrayList array = new ArrayList();
+			while (stok.hasMoreTokens()) {
+				String tok = stok.nextToken();
+				array.add(tok);
+			}
+			bookmark.setIgnoredCategories((String[]) array.toArray(new String[array.size()]));
+		}
+		// read description
+		NodeList children = child.getChildNodes();
+		for (int i = 0; i < children.getLength(); i++) {
+			Node node = children.item(i);
+			if (node.getNodeType() == Node.ELEMENT_NODE) {
+				bookmark.setDescription(createDescription(node));
+				break;
+			}
+		}
+		return bookmark;
+	}
+
+	private static String createDescription(Node child) {
+		String description = ""; //$NON-NLS-1$
+		NodeList children = child.getChildNodes();
+		for (int i = 0; i < children.getLength(); i++) {
+			Node node = children.item(i);
+			if (node.getNodeType() == Node.TEXT_NODE) 
+				description += node.getNodeValue();
+		}
+		return description;
+	}
+
+		
+	private static BookmarkFolder createFolder(Node child) {
+		BookmarkFolder folder = new BookmarkFolder();
+		String name = getAttribute(child, "name"); //$NON-NLS-1$
+		folder.setName(name);
+		if (child.hasChildNodes())
+			processChildren(child.getChildNodes(), folder, null);
+		return folder;
+	}
+
+	public static void store(String fileName, Vector bookmarks) {
+		FileOutputStream fos = null;
+		OutputStreamWriter osw = null;
+		PrintWriter writer = null;
+		try {
+			fos = new FileOutputStream(fileName);
+			osw = new OutputStreamWriter(fos, "UTF8"); //$NON-NLS-1$
+			writer = new PrintWriter(osw);
+			writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
+			writer.println("<bookmarks>"); //$NON-NLS-1$
+			for (int i = 0; i < bookmarks.size(); i++) {
+				Object obj = bookmarks.get(i);
+				writeObject("   ", obj, writer); //$NON-NLS-1$
+			}
+		} catch (IOException e) {
+			UpdateUI.logException(e, false);
+		} finally {
+			writer.println("</bookmarks>"); //$NON-NLS-1$
+			writer.flush();
+			writer.close();
+			try {
+				if (osw != null)
+					osw.close();
+			} catch (IOException e1) {
+				UpdateUI.logException(e1, false);
+			}
+			try {
+				if (fos != null)
+					fos.close();
+			} catch (IOException e2) {
+				UpdateUI.logException(e2, false);
+			}
+		}
+	}
+	private static void writeObject(
+		String indent,
+		Object obj,
+		PrintWriter writer) {
+		if (obj instanceof SiteBookmark) {
+			SiteBookmark bookmark = (SiteBookmark) obj;
+			String name = bookmark.getName();
+			String url = bookmark.getURL().toString();
+			String web = bookmark.isWebBookmark()?"true":"false"; //$NON-NLS-1$ //$NON-NLS-2$
+			String sel = bookmark.isSelected()?"true":"false"; //$NON-NLS-1$ //$NON-NLS-2$
+			String local = bookmark.isLocal() ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
+			String [] ign = bookmark.getIgnoredCategories();
+			StringBuffer wign = new StringBuffer();
+			for (int i = 0; i < ign.length; i++) {
+				if (i > 0)
+					wign.append(',');
+				wign.append(ign[i]);
+			}
+			writer.print(indent + "<site name=\"" + UpdateManagerUtils.getWritableXMLString(name) + "\" url=\"" + url + "\" web=\"" + web + "\" selected=\"" + sel + "\" local=\"" + local + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+			if (wign.length() > 0)
+				writer.print(" ignored-categories=\""+wign.toString()+"\""); //$NON-NLS-1$ //$NON-NLS-2$
+			if (bookmark.getDescription() != null) {
+				writer.println(">"); //$NON-NLS-1$
+				writer.print(indent+"  <description>"); //$NON-NLS-1$
+				writer.print(UpdateManagerUtils.getWritableXMLString(bookmark.getDescription()));
+				writer.println("</description>"); //$NON-NLS-1$
+				writer.println(indent +"</site>"); //$NON-NLS-1$
+			} else {
+				writer.println("/>"); //$NON-NLS-1$
+			}
+		} else if (obj instanceof BookmarkFolder) {
+			BookmarkFolder folder = (BookmarkFolder) obj;
+			String name = folder.getName();
+			writer.println(indent + "<folder name=\"" + UpdateManagerUtils.getWritableXMLString(name) + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
+			Object[] children = folder.getChildren(folder);
+			String indent2 = indent + "   "; //$NON-NLS-1$
+			for (int i = 0; i < children.length; i++) {
+				writeObject(indent2, children[i], writer);
+			}
+			writer.println(indent + "</folder>"); //$NON-NLS-1$
+		}
+	}
+
+	private static String getAttribute(Node node, String name) {
+		NamedNodeMap atts = node.getAttributes();
+		Node att = atts.getNamedItem(name);
+		if (att != null) {
+			return att.getNodeValue();
+		}
+		return ""; //$NON-NLS-1$
+	}
+	private static void processFolder(BookmarkFolder folder, ArrayList result) {
+		Object[] children = folder.getChildren(folder);
+		for (int i = 0; i < children.length; i++) {
+			processEntry(children[i], result);
+		}
+	}
+	private static void processEntry(Object obj, ArrayList result) {
+		if (obj instanceof SiteBookmark)
+			result.add(obj);
+		else if (obj instanceof BookmarkFolder) {
+			processFolder((BookmarkFolder) obj, result);
+		}
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/ConfiguredFeatureAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/ConfiguredFeatureAdapter.java
new file mode 100644
index 0000000..fc36e5a
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/ConfiguredFeatureAdapter.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+
+/**
+ * @version 	1.0
+ * @author
+ */
+public class ConfiguredFeatureAdapter
+	extends SimpleFeatureAdapter
+	implements IConfiguredFeatureAdapter {
+	private IConfiguredSiteAdapter adapter;
+	private boolean configured;
+	private boolean updated;
+
+	public ConfiguredFeatureAdapter(
+		IConfiguredSiteAdapter adapter,
+		IFeature feature,
+		boolean configured,
+		boolean updated,
+		boolean optional) {
+		super(feature, optional);
+		this.adapter = adapter;
+		this.configured = configured;
+		this.updated = updated;
+	}
+
+	public boolean equals(Object object) {
+		if (object == null)
+			return false;
+		if (object == this)
+			return true;
+		if (object instanceof ConfiguredFeatureAdapter) {
+			try {
+				ConfiguredFeatureAdapter ad = (ConfiguredFeatureAdapter) object;
+				return ad.getConfiguredSite().equals(getConfiguredSite())
+					&& ad.getFeature(null).equals(getFeature(null));
+			} catch (CoreException e) {
+			}
+		}
+		return false;
+	}
+
+	public IConfiguredSite getConfiguredSite() {
+		return adapter.getConfiguredSite();
+	}
+	public IInstallConfiguration getInstallConfiguration() {
+		return adapter.getInstallConfiguration();
+	}
+	public boolean isConfigured() {
+		return configured;
+	}
+
+	public boolean isUpdated() {
+		return updated;
+	}
+	public IFeatureAdapter[] getIncludedFeatures(IProgressMonitor monitor) {
+		try {
+			IIncludedFeatureReference[] included =
+				getFeature(null).getIncludedFeatureReferences();
+			ConfiguredFeatureAdapter[] result =
+				new ConfiguredFeatureAdapter[included.length];
+			if (monitor == null)
+				monitor = new NullProgressMonitor();
+			SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
+			subMonitor.beginTask("", included.length); //$NON-NLS-1$
+
+			for (int i = 0; i < included.length; i++) {
+				IIncludedFeatureReference fref = included[i];
+				IFeature feature;
+				boolean childConfigured = configured;
+				boolean updated = false;
+				try {
+					feature = fref.getFeature(
+							new SubProgressMonitor(subMonitor, 1));
+					childConfigured =
+						adapter.getConfiguredSite().isConfigured(feature);
+					///*
+					PluginVersionIdentifier refpid =
+						fref.getVersionedIdentifier().getVersion();
+					PluginVersionIdentifier fpid =
+						feature.getVersionedIdentifier().getVersion();
+					updated = !refpid.equals(fpid);
+					//*/
+				} catch (CoreException e) {
+					feature = new MissingFeature(getFeature(null), fref);
+					childConfigured = false;
+				}
+
+				result[i] =
+					new ConfiguredFeatureAdapter(
+						adapter,
+						feature,
+						childConfigured,
+						updated,
+						fref.isOptional());
+				result[i].setIncluded(true);
+			}
+			return result;
+		} catch (CoreException e) {
+			return new IFeatureAdapter[0];
+		}
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/ConfiguredSiteAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/ConfiguredSiteAdapter.java
new file mode 100644
index 0000000..c655cb0
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/ConfiguredSiteAdapter.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import org.eclipse.update.configuration.*;
+
+/**
+ * @version 	1.0
+ * @author
+ */
+public class ConfiguredSiteAdapter
+	extends UIModelObject
+	implements IConfiguredSiteAdapter {
+	private IInstallConfiguration config;
+	private IConfiguredSite csite;
+		
+	public ConfiguredSiteAdapter(IInstallConfiguration config, IConfiguredSite csite) {
+		this.csite = csite;
+		this.config = config;
+	}
+	
+	public IConfiguredSite getConfiguredSite() {
+		return csite;
+	}
+
+	public IInstallConfiguration getInstallConfiguration() {
+		return config;
+	}
+	
+	public boolean equals(Object object) {
+		if (object==null) return false;
+		if (object == this) return true;
+		if (object instanceof ConfiguredSiteAdapter) {
+			ConfiguredSiteAdapter adapter = (ConfiguredSiteAdapter)object;
+			return csite!=null && csite.getSite().equals(adapter.getConfiguredSite().getSite());
+		}
+		return false;
+	}
+	
+	public String toString() {
+		return getConfiguredSite().getSite().getURL().toString();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/DiscoveryFolder.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/DiscoveryFolder.java
new file mode 100644
index 0000000..28e48c1
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/DiscoveryFolder.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.operations.*;
+import org.eclipse.update.internal.search.*;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.search.*;
+
+public class DiscoveryFolder extends BookmarkFolder {
+
+    private static final long serialVersionUID = 1L;
+    UpdatePolicy updatePolicy = new UpdatePolicy();
+	
+	public DiscoveryFolder() {
+		super(UpdateUIMessages.DiscoveryFolder_name); 
+		setModel(UpdateUI.getDefault().getUpdateModel());
+	}
+	public void initialize() {
+		children.clear();
+		// check if discovery sites defined by features should be exposed to the user
+		if (!UpdateUI.getDefault().getPluginPreferences().getBoolean(UpdateUI.P_DISCOVERY_SITES_ENABLED))
+			return;
+		
+		try {
+			URL updateMapURL = UpdateUtils.getUpdateMapURL();
+			if (updateMapURL!=null) {
+				updatePolicy = new UpdatePolicy();
+				// TODO may need to use a proper monitor to be able to cancel connections
+				IStatus status = UpdateUtils.loadUpdatePolicy(updatePolicy, updateMapURL, new NullProgressMonitor());
+				if (status != null) {
+					// log and continue
+					UpdateUtils.log(status);
+				}
+			}
+		} catch (CoreException e) {
+			// log and continue
+			UpdateUtils.log(e.getStatus());
+		}
+		
+		try {
+			ILocalSite site = SiteManager.getLocalSite();
+			IInstallConfiguration config = site.getCurrentConfiguration();
+			IConfiguredSite[] csites = config.getConfiguredSites();
+			for (int i = 0; i < csites.length; i++) {
+				IConfiguredSite csite = csites[i];
+				IFeatureReference[] refs = csite.getConfiguredFeatures();
+				for (int j = 0; j < refs.length; j++) {
+					IFeatureReference ref = refs[j];
+					IFeature feature = ref.getFeature(null);
+					IURLEntry[] entries = feature.getDiscoverySiteEntries();
+					if (entries.length > 0) {
+						// Only add discovery sites of root features
+						if (isIncluded(ref, refs))
+							continue;
+						addBookmarks(feature);
+					}
+				}
+			}
+		} catch (CoreException e) {
+			UpdateUI.logException(e);
+		}
+	}
+	private boolean isIncluded(
+		IFeatureReference ref,
+		IFeatureReference[] refs) {
+		try {
+			VersionedIdentifier vid = ref.getVersionedIdentifier();
+			for (int i = 0; i < refs.length; i++) {
+				IFeatureReference candidate = refs[i];
+				// Ignore self
+				if (candidate.equals(ref))
+					continue;
+				IFeature cfeature = candidate.getFeature(null);
+				IFeatureReference[] irefs =
+					cfeature.getIncludedFeatureReferences();
+				for (int j = 0; j < irefs.length; j++) {
+					IFeatureReference iref = irefs[j];
+					VersionedIdentifier ivid = iref.getVersionedIdentifier();
+					if (ivid.equals(vid)) {
+						// bingo - included in at least one feature
+						return true;
+					}
+				}
+			}
+		} catch (CoreException e) {
+		}
+		return false;
+	}
+	private void addBookmarks(IFeature feature) {
+		// See if this query site adapter is mapped in the map file
+		// to a different URL.
+		if (updatePolicy != null && updatePolicy.isLoaded()) {
+			IUpdateSiteAdapter mappedSite = updatePolicy.getMappedDiscoverySite(feature.getVersionedIdentifier().getIdentifier());
+			if (mappedSite != null) {
+				SiteBookmark bookmark =
+					new SiteBookmark(mappedSite.getLabel(),	mappedSite.getURL(), false);
+				bookmark.setReadOnly(true);
+				if (!contains(bookmark))
+					internalAdd(bookmark);
+				return;
+			} else if (!updatePolicy.isFallbackAllowed()) {
+				// no match - use original sites if fallback allowed, or nothing.
+				return;
+			}
+		}
+		IURLEntry[] entries = feature.getDiscoverySiteEntries();
+		for (int i = 0; i < entries.length; i++) {
+			IURLEntry entry = entries[i];
+			SiteBookmark bookmark =
+				new SiteBookmark(
+					entry.getAnnotation(),
+					entry.getURL(),
+					entry.getType() == IURLEntry.WEB_SITE);
+			bookmark.setReadOnly(entry.getType() != IURLEntry.WEB_SITE);
+			if (!contains(bookmark))
+				internalAdd(bookmark);
+		}
+	}
+	private boolean contains(SiteBookmark bookmark) {
+		for (int i = 0; i < children.size(); i++) {
+			Object o = children.get(i);
+			if (o instanceof SiteBookmark) {
+				// note: match on URL, not the label
+				if (bookmark.getURL().equals(((SiteBookmark) o).getURL()))
+					return true;
+			}
+		}
+		return false;
+	}
+	public Object[] getChildren(Object parent) {
+		if (hasChildren() == false)
+			initialize();
+		return super.getChildren(parent);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/FeatureAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/FeatureAdapter.java
new file mode 100644
index 0000000..7e89d27
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/FeatureAdapter.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+/**
+ * @version 	1.0
+ * @author
+ */
+public abstract class FeatureAdapter extends UIModelObject implements IFeatureAdapter {
+	private boolean included=false;
+
+	/*
+	 * @see IFeatureAdapter#getInstallConfiguration()
+	 */
+	public IInstallConfiguration getInstallConfiguration() {
+		return null;
+	}
+	
+	public boolean isIncluded() {
+		return included;
+	}
+	
+	protected void setIncluded(boolean included) {
+		this.included = included;
+	}
+	
+	public String toString() {
+		try {
+			IFeature feature = getFeature(null);
+			return feature.getLabel();
+		}
+		catch (CoreException e) {
+			return UpdateUIMessages.FeatureAdapter_failure; 
+		}
+	}
+	public boolean hasIncludedFeatures(IProgressMonitor monitor) {
+		try {
+			IFeatureReference [] included = getFeature(monitor).getIncludedFeatureReferences();
+			return included.length>0;
+		}
+		catch (CoreException e) {
+			return false;
+		}
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/FeatureReferenceAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/FeatureReferenceAdapter.java
new file mode 100644
index 0000000..9b5dc1f
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/FeatureReferenceAdapter.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+import java.lang.reflect.*;
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.operation.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.ui.*;
+
+public class FeatureReferenceAdapter extends FeatureAdapter {
+	private IFeatureReference featureRef;
+	private boolean touched;
+
+	public FeatureReferenceAdapter(IFeatureReference featureRef) {
+		this.featureRef = featureRef;
+		setIncluded(featureRef instanceof IIncludedFeatureReference);
+	}
+	
+	public IFeature getFeature(IProgressMonitor monitor) throws CoreException {
+		return featureRef.getFeature(monitor);
+	}
+	
+	public String getFastLabel() {
+		return featureRef.getURL().toString();
+	}
+	
+	public ISite getSite() {
+		return featureRef.getSite();
+	}
+	
+	public URL getURL() {
+		return featureRef.getURL();
+	}
+	
+	public boolean isOptional() {
+		return featureRef instanceof IIncludedFeatureReference ? 
+			((IIncludedFeatureReference)featureRef).isOptional():false;
+	}
+	
+	public void touchIncludedFeatures(IRunnableContext context) {
+		if (touched) return;
+		final IFeatureReference [] included;
+		
+		try {
+			included = 	getFeature(null).getIncludedFeatureReferences();
+		}
+		catch (CoreException e) {
+			return;
+		}
+		if (included.length == 0) return;
+		IRunnableWithProgress op = new IRunnableWithProgress () {
+			public void run(IProgressMonitor monitor) {
+				monitor.beginTask(UpdateUIMessages.SiteBookmark_downloading, included.length); 
+				for (int i=0; i<included.length; i++) {
+					IFeatureReference ref = included[i];
+					try {
+						monitor.subTask(ref.getURL().toString());
+						ref.getFeature(new SubProgressMonitor(monitor, 1));
+						//monitor.worked(1);
+					}
+					catch (CoreException e) {
+					}
+				}
+				monitor.done();
+			}
+		};
+		try {
+			context.run(true, false, op);
+			touched=true;
+		}
+		catch (InvocationTargetException e) {
+		}
+		catch (InterruptedException e) {
+		}
+	}
+
+	public IFeatureAdapter[] getIncludedFeatures(IProgressMonitor monitor) {
+		try {
+			IFeatureReference[] included =
+				getFeature(monitor).getIncludedFeatureReferences();
+			FeatureReferenceAdapter[] result =
+				new FeatureReferenceAdapter[included.length];
+			for (int i = 0; i < included.length; i++) {
+				result[i] = new FeatureReferenceAdapter(included[i]);
+			}
+			return result;
+		} catch (CoreException e) {
+			return new IFeatureAdapter[0];
+		}
+	}
+
+	public IFeatureReference getFeatureReference() {
+		return featureRef;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IConfiguredFeatureAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IConfiguredFeatureAdapter.java
new file mode 100644
index 0000000..35ecf1c
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IConfiguredFeatureAdapter.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+
+/**
+ * @version 	1.0
+ * @author
+ */
+public interface IConfiguredFeatureAdapter extends IFeatureAdapter, IConfiguredSiteContext {
+	public boolean isConfigured();
+	public boolean isUpdated();
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IConfiguredSiteAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IConfiguredSiteAdapter.java
new file mode 100644
index 0000000..36fc8b4
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IConfiguredSiteAdapter.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+
+/**
+ * @version 	1.0
+ * @author
+ */
+public interface IConfiguredSiteAdapter extends IConfiguredSiteContext {
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IConfiguredSiteContext.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IConfiguredSiteContext.java
new file mode 100644
index 0000000..245dd58
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IConfiguredSiteContext.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import org.eclipse.update.configuration.*;
+
+/**
+ * @version 	1.0
+ * @author
+ */
+public interface IConfiguredSiteContext {
+	public IInstallConfiguration getInstallConfiguration();
+	public IConfiguredSite getConfiguredSite();
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IFeatureAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IFeatureAdapter.java
new file mode 100644
index 0000000..cb86942
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/IFeatureAdapter.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+
+/**
+ * @version 	1.0
+ * @author
+ */
+public interface IFeatureAdapter {
+	public URL getURL();
+	public ISite getSite();
+	public IFeature getFeature(IProgressMonitor monitor) throws CoreException;
+	public IFeatureAdapter [] getIncludedFeatures(IProgressMonitor monitor);
+	public boolean hasIncludedFeatures(IProgressMonitor monitor);
+	public boolean isIncluded();
+	public boolean isOptional();
+	public String getFastLabel();
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/ISiteAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/ISiteAdapter.java
new file mode 100644
index 0000000..58208ad
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/ISiteAdapter.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+
+public interface ISiteAdapter {
+	
+	public String getLabel();
+	public URL getURL();
+	public ISite getSite(IProgressMonitor monitor);
+
+}
+
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/MissingFeature.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/MissingFeature.java
new file mode 100644
index 0000000..7606da8
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/MissingFeature.java
@@ -0,0 +1,456 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.io.*;
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.ui.*;
+
+public class MissingFeature implements IFeature {
+
+	private URL url;
+	private ISite site;
+	private IFeatureReference reference;
+	private IFeature parent;
+	private IURLEntry desc;
+	private VersionedIdentifier id = new VersionedIdentifier(UpdateUIMessages.MissingFeature_id, "0.0.0");  //$NON-NLS-1$
+	public MissingFeature(ISite site, URL url) {
+		this.site = site;
+		this.url = url;
+		desc = new IURLEntry() {
+			public URL getURL() {
+				return null;
+			}
+			public String getAnnotation() {
+				return UpdateUIMessages.MissingFeature_desc_unknown; 
+			}
+			public Object getAdapter(Class key) {
+				return null;
+			}
+			public int getType() {
+				return IURLEntry.UPDATE_SITE;
+			}
+		};
+	}
+	public MissingFeature(IFeatureReference ref) {
+		this(null, ref);
+	}
+
+	public MissingFeature(IFeature parent, IFeatureReference ref) {
+		this(ref.getSite(), ref.getURL());
+		this.reference = ref;
+		this.parent = parent;
+
+		if (isOptional()) {
+			desc = new IURLEntry() {
+				public URL getURL() {
+					return null;
+				}
+				public String getAnnotation() {
+					return UpdateUIMessages.MissingFeature_desc_optional; 
+				}
+				public Object getAdapter(Class key) {
+					return null;
+				}
+				public int getType() {
+					return IURLEntry.UPDATE_SITE;
+				}
+			};
+		}
+	}
+
+	public boolean isOptional() {
+		return reference != null
+			&& reference instanceof IIncludedFeatureReference
+			&& ((IIncludedFeatureReference) reference).isOptional();
+	}
+
+	public IFeature getParent() {
+		return parent;
+	}
+
+	public URL getOriginatingSiteURL() {
+		VersionedIdentifier vid = getVersionedIdentifier();
+		if (vid == null)
+			return null;
+		String key = vid.getIdentifier();
+		return UpdateUI.getOriginatingURL(key);
+	}
+
+	/*
+	 * @see IFeature#getIdentifier()
+	 */
+	public VersionedIdentifier getVersionedIdentifier() {
+		if (reference != null) {
+			try {
+				return reference.getVersionedIdentifier();
+			} catch (CoreException e) {
+			}
+		}
+		return id;
+	}
+
+	/*
+	 * @see IFeature#getSite()
+	 */
+	public ISite getSite() {
+		return site;
+	}
+
+	/*
+	 * @see IFeature#getLabel()
+	 */
+	public String getLabel() {
+		if (reference != null
+			&& reference instanceof IIncludedFeatureReference) {
+			String name = ((IIncludedFeatureReference) reference).getName();
+			if (name != null)
+				return name;
+		}
+		return url.toString();
+	}
+
+	/*
+	 * @see IFeature#getURL()
+	 */
+	public URL getURL() {
+		return url;
+	}
+
+	/*
+	 * @see IFeature#getUpdateInfo()
+	 */
+	public IURLEntry getUpdateSiteEntry() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getDiscoveryInfos()
+	 */
+	public IURLEntry[] getDiscoverySiteEntries() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getProvider()
+	 */
+	public String getProvider() {
+		return UpdateUIMessages.MissingFeature_provider; 
+	}
+
+	/*
+	 * @see IFeature#getDescription()
+	 */
+	public IURLEntry getDescription() {
+		return desc;
+	}
+
+	/*
+	 * @see IFeature#getCopyright()
+	 */
+	public IURLEntry getCopyright() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getLicense()
+	 */
+	public IURLEntry getLicense() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getOS()
+	 */
+	public String getOS() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getWS()
+	 */
+	public String getWS() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getNL()
+	 */
+	public String getNL() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getArch()
+	 */
+	public String getOSArch() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getImage()
+	 */
+	public URL getImage() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getImports()
+	 */
+	public IImport[] getImports() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getArchives()
+	 */
+	public String[] getArchives() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#getDataEntries()
+	 */
+	public INonPluginEntry[] getNonPluginEntries() {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#addDataEntry(IDataEntry)
+	 */
+	public void addNonPluginEntry(INonPluginEntry dataEntry) {
+	}
+
+	/*
+	 * @see IFeature#getDownloadSize()
+	 */
+	public long getDownloadSize() {
+		return 0;
+	}
+
+	/*
+	 * @see IFeature#getInstallSize(ISite)
+	 */
+	public long getInstallSize() {
+		return 0;
+	}
+
+	/*
+	 * @see IFeature#isPrimary()
+	 */
+	public boolean isPrimary() {
+		return false;
+	}
+
+	/*
+	 * @see IFeature#getApplication()
+	 */
+	public String getApplication() {
+		return null;
+	}
+
+	/*
+	 * @see IPluginContainer#getPluginEntries()
+	 */
+	public IPluginEntry[] getPluginEntries() {
+		return new IPluginEntry[0];
+	}
+
+	/*
+	 * @see IPluginContainer#getPluginEntryCount()
+	 */
+	public int getPluginEntryCount() {
+		return 0;
+	}
+
+	/*
+	 * @see IPluginContainer#getDownloadSize(IPluginEntry)
+	 */
+	public long getDownloadSize(IPluginEntry entry) {
+		return 0;
+	}
+
+	/*
+	 * @see IPluginContainer#getInstallSize(IPluginEntry)
+	 */
+	public long getInstallSize(IPluginEntry entry) {
+		return 0;
+	}
+
+	/*
+	 * @see IPluginContainer#addPluginEntry(IPluginEntry)
+	 */
+	public void addPluginEntry(IPluginEntry pluginEntry) {
+	}
+
+	/*
+	 * @see IPluginContainer#store(IPluginEntry, String, InputStream)
+	 */
+	public void store(IPluginEntry entry, String name, InputStream inStream)
+		throws CoreException {
+	}
+
+	/*
+	 * @see IAdaptable#getAdapter(Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		return null;
+	}
+
+	/*
+	 * @see IPluginContainer#remove(IPluginEntry)
+	 */
+	public void remove(IPluginEntry entry) throws CoreException {
+	}
+
+	/*
+	 * @see IFeature#setFeatureContentProvider(IFeatureContentProvider)
+	 */
+	public void setFeatureContentProvider(IFeatureContentProvider featureContentProvider) {
+	}
+
+	/*
+	 * @see IFeature#getFeatureContentConsumer()
+	 */
+	public IFeatureContentConsumer getFeatureContentConsumer()
+		throws CoreException {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#setSite(ISite)
+	 */
+	public void setSite(ISite site) throws CoreException {
+		this.site = site;
+	}
+
+	/*
+	 * @see IFeature#getFeatureContentProvider()
+	 */
+	public IFeatureContentProvider getFeatureContentProvider()
+		throws CoreException {
+		return null;
+	}
+
+	/*
+	 * @see IFeature#install(IFeature,IVerifier, IProgressMonitor)
+	 */
+	public IFeatureReference install(
+		IFeature targetFeature,
+		IVerificationListener verificationListener,
+		IProgressMonitor monitor)
+		throws CoreException {
+		return null;
+	}
+
+	/*
+	 * @see org.eclipse.update.core.IFeature#install(IFeature, IFeatureReference[], IVerificationListener, IProgressMonitor)
+	 */
+	public IFeatureReference install(
+		IFeature targetFeature,
+		IFeatureReference[] optionalFeatures,
+		IVerificationListener verificationListener,
+		IProgressMonitor monitor)
+		throws InstallAbortedException, CoreException {
+		return null;
+	}
+	/*
+	 * @see IFeature#remove(IProgressMonitor)
+	 */
+	public void remove(IProgressMonitor monitor) throws CoreException {
+	}
+
+	/*
+	 * @see IPluginContainer#remove(IPluginEntry, IProgressMonitor)
+	 */
+	public void remove(IPluginEntry entry, IProgressMonitor monitor)
+		throws CoreException {
+	}
+
+	/*
+	 * @see IFeature#getNonPluginEntryCount()
+	 */
+	public int getNonPluginEntryCount() {
+		return 0;
+	}
+
+	/*
+	 * @see IFeature#getInstallHandlerEntry()
+	 */
+	public IInstallHandlerEntry getInstallHandlerEntry() {
+		return null;
+	}
+	/*
+	 * @see IFeature#getIncludedFeatureReferences()
+	 */
+	public IIncludedFeatureReference[] getIncludedFeatureReferences()
+		throws CoreException {
+		return new IIncludedFeatureReference[0];
+	}
+
+	/**
+	 * @see IFeature#getAffinityFeature()
+	 */
+	public String getAffinityFeature() {
+		return null;
+	}
+	/**
+	 * @see org.eclipse.update.core.IFeature#getRawIncludedFeatureReferences()
+	 */
+	public IIncludedFeatureReference[] getRawIncludedFeatureReferences()
+		throws CoreException {
+		return getIncludedFeatureReferences();
+	}
+
+	/**
+	 * @see org.eclipse.update.core.IFeature#getRawNonPluginEntries()
+	 */
+	public INonPluginEntry[] getRawNonPluginEntries() {
+		return getNonPluginEntries();
+	}
+
+	/**
+	 * @see org.eclipse.update.core.IFeature#getRawPluginEntries()
+	 */
+	public IPluginEntry[] getRawPluginEntries() {
+		return getPluginEntries();
+	}
+
+	/**
+	 * @see org.eclipse.update.core.IFeature#getPrimaryPluginID()
+	 */
+	public String getPrimaryPluginID() {
+		return null;
+	}
+
+	/**
+	 * @see org.eclipse.update.core.IFeature#getRawImports()
+	 */
+	public IImport[] getRawImports() {
+		return new IImport[0];
+	}
+
+	/**
+	 * @see org.eclipse.update.core.IFeature#isPatch()
+	 */
+	public boolean isPatch() {
+		return false;
+	}
+	
+	public boolean isExclusive() {
+		return false;
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/NamedModelObject.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/NamedModelObject.java
new file mode 100644
index 0000000..73ab965
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/NamedModelObject.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.io.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.resource.*;
+import org.eclipse.ui.model.*;
+
+public class NamedModelObject extends UIModelObject 
+							implements IWorkbenchAdapter, Serializable  {
+
+    private static final long serialVersionUID = 1L;
+    private String name;
+	transient private NamedModelObject parent;
+	
+	public static final String P_NAME="p_name"; //$NON-NLS-1$
+	
+	public NamedModelObject() {
+	}
+	
+	public NamedModelObject(String name) {
+		this.name = name;
+	}
+	
+	public Object getAdapter(Class adapter) {
+		if (adapter.equals(IWorkbenchAdapter.class)) {
+			return this;
+		}
+		return super.getAdapter(adapter);
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public IPath getPath() {
+		Object parent = getParent(null);
+		if (parent!=null && parent instanceof NamedModelObject)
+			return ((NamedModelObject)parent).getPath().append(getName());
+		else
+			return new Path(getName());
+	}
+	
+	public String toString() {
+		return getName();
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+		notifyObjectChanged(P_NAME);
+	}
+	
+	/**
+	 * @see IWorkbenchAdapter#getChildren(Object)
+	 */
+	public Object[] getChildren(Object parent) {
+		return null;
+	}
+
+
+	/**
+	 * @see IWorkbenchAdapter#getImageDescriptor(Object)
+	 */
+	public ImageDescriptor getImageDescriptor(Object obj) {
+		return null;
+	}
+
+
+	/**
+	 * @see IWorkbenchAdapter#getLabel(Object)
+	 */
+	public String getLabel(Object obj) {
+		return getName();
+	}
+
+
+	/**
+	 * @see IWorkbenchAdapter#getParent(Object)
+	 */
+	public Object getParent(Object arg0) {
+		return parent;
+	}
+	public void setParent(NamedModelObject parent) {
+		this.parent = parent;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/SimpleFeatureAdapter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/SimpleFeatureAdapter.java
new file mode 100644
index 0000000..880f79d
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/SimpleFeatureAdapter.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.core.*;
+
+/**
+ * @version 	1.0
+ * @author
+ */
+public class SimpleFeatureAdapter extends FeatureAdapter {
+	protected IFeature feature;
+	private boolean optional;
+	public SimpleFeatureAdapter(IFeature feature) {
+		this(feature, false);
+	}
+	public SimpleFeatureAdapter(IFeature feature, boolean optional) {
+		this.feature = feature;
+		this.optional = optional;
+	}
+	
+	public IFeature getFeature(IProgressMonitor monitor) throws CoreException {
+		return feature;
+	}
+	
+	public String getFastLabel() {
+		return feature.getLabel();
+	}
+	
+	public URL getURL() {
+		return feature.getURL();
+	}
+	
+	public ISite getSite() {
+		return feature.getSite();
+	}
+	
+	public IFeatureAdapter[] getIncludedFeatures(IProgressMonitor monitor) {
+		try {
+			IIncludedFeatureReference[] included = getFeature(monitor).getIncludedFeatureReferences();
+			SimpleFeatureAdapter[] result =
+				new SimpleFeatureAdapter[included.length];
+			for (int i = 0; i < included.length; i++) {
+				result[i] =
+					new SimpleFeatureAdapter(included[i].getFeature(null), included[i].isOptional());
+				result[i].setIncluded(true);
+			}
+			return result;
+		} catch (CoreException e) {
+			return new IFeatureAdapter[0];
+		}
+	}
+	public boolean isOptional() {
+		return optional;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/SiteBookmark.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/SiteBookmark.java
new file mode 100644
index 0000000..492d65d
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/SiteBookmark.java
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.net.*;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.ui.*;
+
+public class SiteBookmark extends NamedModelObject 
+							implements ISiteAdapter {
+
+    private static final long serialVersionUID = 1L;
+    public static final String P_URL="p_url"; //$NON-NLS-1$
+	public static final String P_TYPE="p_type"; //$NON-NLS-1$
+	
+	private URL url;
+	transient private ISite site;
+	transient private Vector catalog = new Vector();
+	transient private SiteCategory otherCategory;
+	private boolean webBookmark;
+	private boolean selected;
+	private String [] ignoredCategories = new String[0];
+	private boolean readOnly = false;
+	private boolean local = false;
+	private boolean unavailable = false;
+	private String description;
+
+	public SiteBookmark() {
+	}
+	
+	public SiteBookmark(String name, URL url, boolean webBookmark) {
+		this(name, url, webBookmark, false);
+	}
+	
+	public SiteBookmark(String name, URL url, boolean webBookmark, boolean selected) {
+		super(name);
+		this.url = url;
+		this.webBookmark = webBookmark;
+		this.selected = selected;
+	}
+
+	public boolean equals(Object obj) {
+        if (obj == this)
+            return true;
+        if (!(obj instanceof SiteBookmark))
+            return false;
+        SiteBookmark b = (SiteBookmark)obj;
+        if (url == null)
+            return false;
+        return url.equals(b.url);
+    }
+
+    public int hashCode() {
+        if (url == null)
+            return super.hashCode();
+        else
+            return url.hashCode();
+    }
+
+    public void setSelected(boolean selected) {
+		this.selected = selected;
+	}
+	
+	public boolean isSelected() {
+		return selected;
+	}
+	
+	public String [] getIgnoredCategories() {
+		return ignoredCategories;
+	}
+	
+	public void setIgnoredCategories(String [] categories) {
+		this.ignoredCategories = categories;
+	}
+	
+	public void setWebBookmark(boolean value) {
+		if (isLocal()) return;
+		this.webBookmark = value;
+		notifyObjectChanged(P_TYPE);
+	}
+	
+	public boolean isWebBookmark() {
+		return webBookmark;
+	}
+	
+	public URL getURL() {
+		return url;
+	}
+
+
+	public void setURL(URL url) {
+		this.url = url;
+		site = null;
+		notifyObjectChanged(P_URL);
+	}
+	
+	public ISite getSite(IProgressMonitor monitor) {
+		return getSite(true, monitor);
+	}
+	
+	public ISite getSite(boolean showDialogIfFailed, IProgressMonitor monitor) {
+		if (site==null) {
+			try {
+				connect(monitor);
+			}
+			catch (CoreException e) {
+				UpdateUI.logException(e, showDialogIfFailed);
+			}
+		}
+		return site;
+	}
+	
+	public boolean isSiteConnected() {
+		return site!=null;
+	}
+	
+	public void connect(IProgressMonitor monitor) throws CoreException {
+		connect(true, monitor);
+	}
+	
+	public void connect(boolean useCache, IProgressMonitor monitor) throws CoreException {
+		try {
+			if (monitor==null) monitor = new NullProgressMonitor();
+			monitor.beginTask("", 2); //$NON-NLS-1$
+			monitor.subTask(NLS.bind(UpdateUIMessages.SiteBookmark_connecting, url.toString()));
+			site = SiteManager.getSite(url, useCache, new SubProgressMonitor(monitor, 1));
+			if (site!=null) {
+				createCatalog(new SubProgressMonitor(monitor, 1));
+				unavailable = false;
+			} else {
+				catalog = new Vector();
+				unavailable = true;
+			}
+		} catch (CoreException e) {
+			unavailable = true;
+			throw e;
+		}
+	}
+	
+	public boolean isUnavailable() {
+		return unavailable;
+	}
+	
+	public void setUnavailable(boolean value) {
+		unavailable = value;
+	}
+	
+	private void createCatalog(IProgressMonitor monitor) {
+		catalog = new Vector();
+		otherCategory = new SiteCategory(this, null, null);
+		// Add all the categories
+		ICategory [] categories = site.getCategories();
+		
+		ISiteFeatureReference [] featureRefs;
+		featureRefs = site.getRawFeatureReferences();
+		
+		monitor.beginTask("", featureRefs.length + categories.length); //$NON-NLS-1$
+
+		for (int i=0; i<categories.length; i++) {
+			ICategory category = categories[i];
+			addCategoryToCatalog(category);
+			monitor.worked(1);
+		}
+		// Add features to categories
+
+		for (int i=0; i<featureRefs.length; i++) {
+			ISiteFeatureReference featureRef = featureRefs[i];
+			addFeatureToCatalog(featureRef);
+			monitor.worked(1);
+		}
+		if (otherCategory.getChildCount()>0)
+		   catalog.add(otherCategory);
+		
+		// set the site description
+		IURLEntry descURL = site.getDescription();
+		if (descURL != null)
+			description = descURL.getAnnotation();
+	}
+
+	public Object [] getCatalog(boolean withCategories, IProgressMonitor monitor) {
+		if (withCategories)
+			return catalog.toArray();
+		else {
+			// Make a flat catalog
+			Vector flatCatalog = new Vector();
+			for (int i=0; i<catalog.size(); i++) {
+				SiteCategory category = (SiteCategory)catalog.get(i);
+				category.addFeaturesTo(flatCatalog);
+			}
+			return flatCatalog.toArray();
+		}
+	}
+	
+	private void addCategoryToCatalog(ICategory category) {
+		String name = category.getName();
+		int loc = name.indexOf('/');
+		if (loc == -1) {
+			// first level
+			catalog.add(new SiteCategory(this, name, category));
+		}
+		else {
+			IPath path = new Path(name);
+			name = path.lastSegment().toString();
+			path = path.removeLastSegments(1);
+			SiteCategory parentCategory = findCategory(path, catalog.toArray());
+			if (parentCategory!=null) {
+				parentCategory.add(new SiteCategory(this, name, category));
+			}
+		}
+	}
+	private void addFeatureToCatalog(ISiteFeatureReference feature) {
+		ICategory [] categories = feature.getCategories();
+		boolean orphan = true;
+
+		for (int i=0; i<categories.length; i++) {
+			ICategory category = categories[i];
+			String name = category.getName();
+			IPath path = new Path(name);
+			SiteCategory parentCategory = findCategory(path, catalog.toArray());
+			if (parentCategory!=null) {
+		   		parentCategory.add(new FeatureReferenceAdapter(feature));
+		   		orphan = false;
+			}
+		}
+		if (orphan)
+			otherCategory.add(new FeatureReferenceAdapter(feature));
+	}
+	
+	private SiteCategory findCategory(IPath path, Object [] children) {
+		for (int i=0; i<children.length; i++) {
+			Object child = children[i];
+			if (child instanceof SiteCategory) {
+				SiteCategory sc = (SiteCategory)child;
+				if (sc.getName().equals(path.segment(0))) {
+				   if (path.segmentCount()==1) return sc;
+					else {
+						path = path.removeFirstSegments(1);
+						return findCategory(path, sc.getChildren());
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * @see ISiteAdapter#getLabel()
+	 */
+	public String getLabel() {
+		return getName();
+	}
+	
+	public void setReadOnly(boolean readOnly) {
+		this.readOnly = readOnly;
+	}
+	
+	public boolean isReadOnly() {
+		return readOnly;
+	}
+	
+	public void setLocal(boolean local) {
+		this.local = local;
+	}
+	
+	public boolean isLocal() {
+		return local;
+	}
+
+	/**
+	 * @param description The description to set.
+	 */
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	/**
+	 * @return Returns the description.
+	 */
+	public String getDescription() {
+		if (description == null && isSiteConnected()) {
+			IURLEntry descURL = site.getDescription();
+			if (descURL != null)
+				description = descURL.getAnnotation();
+		}
+		return description;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/SiteCategory.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/SiteCategory.java
new file mode 100644
index 0000000..753b094
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/SiteCategory.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.update.core.ICategory;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IURLEntry;
+import org.eclipse.update.internal.core.Messages;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+public class SiteCategory extends UIModelObject {
+
+	Vector children;
+	private ICategory category;
+	private String name;
+	private boolean touched;
+	private int featureCount;
+	private boolean canceled;
+	private SiteBookmark bookmark;
+
+	class OtherCategory implements ICategory {
+		IURLEntry entry;
+		public OtherCategory() {
+			entry = new IURLEntry() {
+				public String getAnnotation() {
+					return Messages.SiteCategory_other_description; 
+				}
+				public URL getURL() {
+					return null;
+				}
+				public Object getAdapter(Class clazz) {
+					return null;
+				}
+				public int getType() {
+					return IURLEntry.UPDATE_SITE;
+				}
+			};
+		}
+		public String getName() {
+			return SiteCategory.this.getName();
+		}
+		public String getLabel() {
+			return SiteCategory.this.getName();
+		}
+		public IURLEntry getDescription() {
+			return entry;
+		}
+		public Object getAdapter(Class clazz) {
+			return null;
+		}
+	}
+
+	public SiteCategory(SiteBookmark bookmark, String name, ICategory category) {
+		this.bookmark = bookmark;
+		if (category == null) {
+			this.name = Messages.SiteCategory_other_label; 
+			this.category = new OtherCategory();
+		} else {
+			this.name = name;
+			this.category = category;
+		}
+		children = new Vector();
+	}
+	
+	public SiteBookmark getBookmark() {
+		return bookmark;
+	}
+
+	public boolean isOtherCategory() {
+		return category instanceof OtherCategory;
+	}
+
+	public Object[] getChildren() {
+		return canceled ? new Object[0] : children.toArray();
+	}
+
+	public int getChildCount() {
+		return canceled ? 0 : children.size();
+	}
+
+	public String getName() {
+		return name;
+	}
+	public String getFullName() {
+		return category.getName();
+	}
+
+	public String toString() {
+		return category.getLabel();
+	}
+
+	public ICategory getCategory() {
+		return category;
+	}
+
+	void add(Object child) {
+		if (child instanceof IFeatureAdapter)
+			featureCount++;
+		children.add(child);
+	}
+
+	public void touchFeatures(IRunnableContext context) {
+		if (children.size() == 0 || touched || featureCount == 0)
+			return;
+
+		IRunnableWithProgress op = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) {
+				monitor.beginTask(
+					UpdateUIMessages.SiteBookmark_downloading, 
+					featureCount);
+				for (int i = 0; i < children.size(); i++) {
+					Object child = children.get(i);
+					if (monitor.isCanceled())
+						break;
+					if (child instanceof IFeatureAdapter) {
+						IFeatureAdapter adapter = (IFeatureAdapter) child;
+						monitor.subTask(adapter.getFastLabel());
+						try {
+							adapter.getFeature(
+								new SubProgressMonitor(monitor, 1));
+						} catch (CoreException e) {
+						}
+					}
+				}
+				monitor.done();
+			}
+		};
+
+		try {
+			context.run(true, true, op);
+			touched = true;
+		} catch (InterruptedException e) {
+			canceled = true;
+		} catch (InvocationTargetException e) {
+		}
+	}
+
+	public void addFeaturesTo(Vector flatList) {
+		for (int i = 0; i < children.size(); i++) {
+			Object child = children.get(i);
+			if (child instanceof FeatureReferenceAdapter) {
+				FeatureReferenceAdapter cfeature =
+					(FeatureReferenceAdapter) child;
+				// Don't add duplicates - there may be the same
+				// feature present in several categories
+				if (findFeature(flatList, cfeature.getFeatureReference())
+					== null) {
+					flatList.add(child);
+				}
+			} else if (child instanceof SiteCategory) {
+				((SiteCategory) child).addFeaturesTo(flatList);
+			}
+		}
+	}
+
+	private FeatureReferenceAdapter findFeature(
+		Vector flatList,
+		IFeatureReference featureRef) {
+		for (int i = 0; i < flatList.size(); i++) {
+			FeatureReferenceAdapter cfeature =
+				(FeatureReferenceAdapter) flatList.get(i);
+			if (cfeature.getFeatureReference().equals(featureRef))
+				return cfeature;
+		}
+		return null;
+	}
+
+	public boolean equals(Object object) {
+
+		if ( (object == null) || !( object instanceof SiteCategory))
+			return false;
+		
+		if ( this == object)
+			return true;
+		
+		return getName().equals(((SiteCategory)object).getName()) && bookmark.equals(((SiteCategory)object).getBookmark());
+
+	}
+
+	public int hashCode() {
+
+		return getName().hashCode() * ( (bookmark == null)? 1: bookmark.hashCode());
+	}
+	
+	
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/UIModelObject.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/UIModelObject.java
new file mode 100644
index 0000000..e874978
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/UIModelObject.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.resource.*;
+import org.eclipse.ui.model.*;
+
+
+public class UIModelObject extends PlatformObject implements IWorkbenchAdapter {
+	UpdateModel model;
+	
+	public void setModel(UpdateModel model) {
+		this.model = model;
+	}
+	
+	public UpdateModel getModel() {
+		return model;
+	}
+	
+	protected void notifyObjectChanged(String property) {
+		if (model==null) return;
+		model.fireObjectChanged(this, property);
+	}
+	
+	protected void notifyObjectsAdded(Object parent, Object [] objects) {
+		if (model==null) return;
+		model.fireObjectsAdded(parent, objects);
+	}
+	
+	protected void notifyObjectsRemoved(Object parent, Object [] objects) {
+		if (model==null) return;
+		model.fireObjectsRemoved(parent, objects);
+	}
+	
+	public Object [] getChildren(Object obj) {
+		return new Object[0];
+	}
+	
+	public Object getParent(Object obj) {
+		return null;
+	}
+	public String getLabel(Object obj) {
+		return toString();
+	}
+	public ImageDescriptor getImageDescriptor(Object obj) {
+		return null;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/UpdateModel.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/UpdateModel.java
new file mode 100644
index 0000000..93591b7
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/model/UpdateModel.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.model;
+
+import java.io.*;
+import java.net.*;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.operations.*;
+
+public class UpdateModel implements IAdaptable {
+	private Vector bookmarks = new Vector();
+	private Vector listeners = new Vector();
+	private static final String BOOKMARK_FILE = "bookmarks.xml"; //$NON-NLS-1$
+	
+	public UpdateModel() {
+		reset();
+	}
+	
+	public void reset() {
+		// load bookmarks
+		bookmarks.clear();
+		BookmarkUtil.parse(getBookmarksFileName(), bookmarks);
+	}
+	
+	private String getBookmarksFileName() {
+		URL platformXML = ConfiguratorUtils.getCurrentPlatformConfiguration().getConfigurationLocation();
+		if (!"file".equals(platformXML.getProtocol())) { //$NON-NLS-1$
+			IPath path = UpdateUI.getDefault().getStateLocation();
+			path = path.append(BOOKMARK_FILE);
+			return path.toOSString();
+		} else {
+			File f = new File(platformXML.getFile());
+			f = new File(f.getParentFile(), BOOKMARK_FILE);
+			return f.getAbsolutePath();
+		}
+	}
+	
+	public void shutdown() {
+		saveBookmarks();
+	}
+	
+	public void saveBookmarks() {
+		BookmarkUtil.store(getBookmarksFileName(), bookmarks);
+	}
+	
+	
+	public void addBookmark(NamedModelObject bookmark) {
+		bookmarks.add(bookmark);
+		bookmark.setModel(this);
+		fireObjectsAdded(null, new Object []{bookmark});
+	}
+	
+	public void removeBookmark(NamedModelObject bookmark) {
+		bookmarks.remove(bookmark);
+		bookmark.setModel(null);
+		fireObjectsRemoved(null, new Object []{bookmark});
+	}
+	
+	public NamedModelObject [] getBookmarks() {
+		return (NamedModelObject[])bookmarks.toArray(new NamedModelObject[bookmarks.size()]);
+	}
+	
+	public SiteBookmark [] getBookmarkLeafs() {
+		return BookmarkUtil.getBookmarks(bookmarks);
+	}
+	
+	public BookmarkFolder getFolder(IPath path) {
+		return BookmarkUtil.getFolder(bookmarks, path);
+	}
+	
+	public void addUpdateModelChangedListener(IUpdateModelChangedListener listener) {
+		if (!listeners.contains(listener)) 
+		   listeners.add(listener);
+	}
+
+
+	public void removeUpdateModelChangedListener(IUpdateModelChangedListener listener) {
+		if (listeners.contains(listener))
+			listeners.remove(listener);
+	}
+	
+	public void fireObjectsAdded(Object parent, Object [] children) {
+		for (Iterator iter=listeners.iterator();
+				iter.hasNext();) {
+			IUpdateModelChangedListener listener = (IUpdateModelChangedListener)iter.next();
+			listener.objectsAdded(parent, children);
+		}
+	}
+
+
+	public void fireObjectsRemoved(Object parent, Object [] children) {
+		for (Iterator iter=listeners.iterator();
+				iter.hasNext();) {
+			IUpdateModelChangedListener listener = (IUpdateModelChangedListener)iter.next();
+			listener.objectsRemoved(parent, children);
+		}
+	}
+	
+	public void fireObjectChanged(Object object, String property) {
+		for (Iterator iter=listeners.iterator();
+			iter.hasNext();) {
+			IUpdateModelChangedListener listener = (IUpdateModelChangedListener)iter.next();
+			listener.objectChanged(object, property);
+		}
+	}
+	public Object getAdapter(Class key) {
+		return null;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/AbstractOverlayIcon.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/AbstractOverlayIcon.java
new file mode 100644
index 0000000..f2e50b9
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/AbstractOverlayIcon.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.parts;
+
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * An OverlayIcon consists of a main icon and several adornments.
+ */
+public abstract class AbstractOverlayIcon extends CompositeImageDescriptor {
+
+	static final int DEFAULT_WIDTH = 16;
+	static final int DEFAULT_HEIGHT = 16;
+
+	private Point fSize = null;
+
+	private ImageDescriptor fOverlays[][];
+
+	public AbstractOverlayIcon(ImageDescriptor[][] overlays) {
+		this(overlays, null);
+	}
+
+	public AbstractOverlayIcon(ImageDescriptor[][] overlays, Point size) {
+		fOverlays = overlays;
+		if (size != null)
+			fSize = size;
+		else
+			fSize = new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+	}
+	protected void drawBottomLeft(ImageDescriptor[] overlays) {
+		if (overlays == null)
+			return;
+		int length = overlays.length;
+		int x = 0;
+		for (int i = 0; i < 3; i++) {
+			if (i < length && overlays[i] != null) {
+				ImageData id = overlays[i].getImageData();
+				drawImage(id, x, getSize().y - id.height);
+				x += id.width;
+			}
+		}
+	}
+	protected void drawBottomRight(ImageDescriptor[] overlays) {
+		if (overlays == null)
+			return;
+		int length = overlays.length;
+		int x = getSize().x;
+		for (int i = 2; i >= 0; i--) {
+			if (i < length && overlays[i] != null) {
+				ImageData id = overlays[i].getImageData();
+				x -= id.width;
+				drawImage(id, x, getSize().y - id.height);
+			}
+		}
+	}
+
+	protected abstract ImageData getBaseImageData();
+
+	protected void drawCompositeImage(int width, int height) {
+		ImageData base = getBaseImageData();
+		drawImage(base, 0, 0);
+		if (fOverlays != null) {
+			if (fOverlays.length > 0)
+				drawTopRight(fOverlays[0]);
+
+			if (fOverlays.length > 1)
+				drawBottomRight(fOverlays[1]);
+
+			if (fOverlays.length > 2)
+				drawBottomLeft(fOverlays[2]);
+
+			if (fOverlays.length > 3)
+				drawTopLeft(fOverlays[3]);
+		}
+	}
+	protected void drawTopLeft(ImageDescriptor[] overlays) {
+		if (overlays == null)
+			return;
+		int length = overlays.length;
+		int x = 0;
+		for (int i = 0; i < 3; i++) {
+			if (i < length && overlays[i] != null) {
+				ImageData id = overlays[i].getImageData();
+				drawImage(id, x, 0);
+				x += id.width;
+			}
+		}
+	}
+	protected void drawTopRight(ImageDescriptor[] overlays) {
+		if (overlays == null)
+			return;
+		int length = overlays.length;
+		int x = getSize().x;
+		for (int i = 2; i >= 0; i--) {
+			if (i < length && overlays[i] != null) {
+				ImageData id = overlays[i].getImageData();
+				x -= id.width;
+				drawImage(id, x, 0);
+			}
+		}
+	}
+
+	protected Point getSize() {
+		return fSize;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/DefaultContentProvider.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/DefaultContentProvider.java
new file mode 100644
index 0000000..b11c1f3
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/DefaultContentProvider.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.parts;
+
+import org.eclipse.jface.viewers.*;
+
+public class DefaultContentProvider implements IContentProvider {
+
+public DefaultContentProvider() {
+	super();
+}
+public void dispose() {}
+public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/ImageOverlayIcon.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/ImageOverlayIcon.java
new file mode 100644
index 0000000..f87918b
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/ImageOverlayIcon.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.parts;
+
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * An OverlayIcon consists of a main icon and several adornments.
+ */
+public class ImageOverlayIcon extends AbstractOverlayIcon {
+	private Image base;
+
+	public ImageOverlayIcon(Image base, ImageDescriptor[][] overlays) {
+		this(base, overlays, null);
+	}
+	
+	public ImageOverlayIcon(Image base, ImageDescriptor[][] overlays, Point size) {
+		super(overlays, size);
+		this.base = base;
+	}
+	
+	protected ImageData getBaseImageData() {
+		return base.getImageData();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/OverlayIcon.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/OverlayIcon.java
new file mode 100644
index 0000000..3605b9c
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/OverlayIcon.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.parts;
+
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * An OverlayIcon consists of a main icon and several adornments.
+ */
+public class OverlayIcon extends CompositeImageDescriptor {
+	
+	static final int DEFAULT_WIDTH= 16;
+	static final int DEFAULT_HEIGHT= 16;
+	
+	private Point fSize= null;
+		
+	private ImageDescriptor fBase;
+	private ImageDescriptor fOverlays[][];
+
+	public OverlayIcon(ImageDescriptor base, ImageDescriptor[][] overlays) {
+		fBase= base;
+		if (fBase == null)
+			fBase= ImageDescriptor.getMissingImageDescriptor();
+		fOverlays= overlays;
+		fSize= new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+	}
+	public OverlayIcon(ImageDescriptor base, ImageDescriptor[][] overlays, Point size) {
+		fBase= base;
+		if (fBase == null)
+			fBase= ImageDescriptor.getMissingImageDescriptor();
+		fOverlays= overlays;
+		fSize= size;
+	}
+	protected void drawBottomLeft(ImageDescriptor[] overlays) {
+		if (overlays == null)
+			return;
+		int length= overlays.length;
+		int x= 0;
+		for (int i= 0; i < 3; i++) {
+			if (i < length && overlays[i] != null) {
+				ImageData id= overlays[i].getImageData();
+				drawImage(id, x, getSize().y-id.height);
+				x+= id.width;
+			}
+		}
+	}
+	protected void drawBottomRight(ImageDescriptor[] overlays) {
+		if (overlays == null)
+			return;
+		int length= overlays.length;
+		int x= getSize().x;
+		for (int i= 2; i >= 0; i--) {
+			if (i < length && overlays[i] != null) {
+				ImageData id= overlays[i].getImageData();
+				x-= id.width;
+				drawImage(id, x, getSize().y-id.height);
+			}
+		}
+	}
+	protected void drawCompositeImage(int width, int height) {
+		ImageData bg= fBase.getImageData();
+		drawImage(bg, 0, 0);
+		
+		if (fOverlays != null) {
+			if (fOverlays.length > 0)
+				drawTopRight( fOverlays[0]);
+				
+			if (fOverlays.length > 1)
+				drawBottomRight(fOverlays[1]);
+				
+			if (fOverlays.length > 2)
+				drawBottomLeft(fOverlays[2]);
+				
+			if (fOverlays.length > 3)
+				drawTopLeft(fOverlays[3]);
+		}	
+	}
+	protected void drawTopLeft(ImageDescriptor[] overlays) {
+		if (overlays == null)
+			return;
+		int length= overlays.length;
+		int x= 0;
+		for (int i= 0; i < 3; i++) {
+			if (i < length && overlays[i] != null) {
+				ImageData id= overlays[i].getImageData();
+				drawImage(id, x, 0);
+				x+= id.width;
+			}
+		}
+	}
+	protected void drawTopRight(ImageDescriptor[] overlays) {
+		if (overlays == null)
+			return;
+		int length= overlays.length;
+		int x= getSize().x;
+		for (int i= 2; i >= 0; i--) {
+			if (i < length && overlays[i] != null) {
+				ImageData id= overlays[i].getImageData();
+				x-= id.width;
+				drawImage(id, x, 0);
+			}
+		}
+	}
+
+	protected Point getSize() {
+		return fSize;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/PixelConverter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/PixelConverter.java
new file mode 100644
index 0000000..4e7b608
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/PixelConverter.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.parts;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+public class PixelConverter {
+	
+	private FontMetrics fFontMetrics;
+	
+	public PixelConverter(Control control) {
+		GC gc = new GC(control);
+		gc.setFont(control.getFont());
+		fFontMetrics= gc.getFontMetrics();
+		gc.dispose();
+	}
+	
+	public int convertHeightInCharsToPixels(int chars) {
+		return Dialog.convertHeightInCharsToPixels(fFontMetrics, chars);
+	}
+
+	public int convertHorizontalDLUsToPixels(int dlus) {
+		return Dialog.convertHorizontalDLUsToPixels(fFontMetrics, dlus);
+	}
+
+	public int convertVerticalDLUsToPixels(int dlus) {
+		return Dialog.convertVerticalDLUsToPixels(fFontMetrics, dlus);
+	}
+	
+	public int convertWidthInCharsToPixels(int chars) {
+		return Dialog.convertWidthInCharsToPixels(fFontMetrics, chars);
+	}	
+
+}
+
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/SWTUtil.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/SWTUtil.java
new file mode 100644
index 0000000..a2a4030
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/SWTUtil.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.parts;
+/**
+ * @version 	1.0
+ * @author
+ */
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Utility class to simplify access to some SWT resources. 
+ */
+public class SWTUtil {
+
+	/**
+	 * Returns the standard display to be used. The method first checks, if
+	 * the thread calling this method has an associated disaply. If so, this
+	 * display is returned. Otherwise the method returns the default display.
+	 */
+	public static Display getStandardDisplay() {
+		Display display;
+		display = Display.getCurrent();
+		if (display == null)
+			display = Display.getDefault();
+		return display;
+	}
+
+	/**
+	 * Returns the shell for the given widget. If the widget doesn't represent
+	 * a SWT object that manage a shell, <code>null</code> is returned.
+	 * 
+	 * @return the shell for the given widget
+	 */
+	public static Shell getShell(Widget widget) {
+		if (widget instanceof Control)
+			return ((Control) widget).getShell();
+		if (widget instanceof Caret)
+			return ((Caret) widget).getParent().getShell();
+		if (widget instanceof DragSource)
+			return ((DragSource) widget).getControl().getShell();
+		if (widget instanceof DropTarget)
+			return ((DropTarget) widget).getControl().getShell();
+		if (widget instanceof Menu)
+			return ((Menu) widget).getParent().getShell();
+		if (widget instanceof ScrollBar)
+			return ((ScrollBar) widget).getParent().getShell();
+
+		return null;
+	}
+
+	/**
+	 * Returns a width hint for a button control.
+	 */
+	public static int getButtonWidthHint(Button button) {
+		if (button.getFont().equals(JFaceResources.getDefaultFont()))
+			button.setFont(JFaceResources.getDialogFont());
+		PixelConverter converter= new PixelConverter(button);
+		int widthHint= converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+		return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+	}
+
+	/**
+	 * Sets width and height hint for the button control.
+	 * <b>Note:</b> This is a NOP if the button's layout data is not
+	 * an instance of <code>GridData</code>.
+	 * 
+	 * @param button	the button for which to set the dimension hint
+	 */
+	public static void setButtonDimensionHint(Button button) {
+		Dialog.applyDialogFont(button);
+		Assert.isNotNull(button);
+		Object gd = button.getLayoutData();
+		if (gd instanceof GridData) {
+			((GridData) gd).widthHint = getButtonWidthHint(button);
+		}
+	}
+
+	public static void setDialogSize(Dialog dialog, int width, int height) {
+		Point computedSize =
+			dialog.getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
+		width = Math.max(computedSize.x, width);
+		height = Math.max(computedSize.y, height);
+		dialog.getShell().setSize(width, height);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/SharedLabelProvider.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/SharedLabelProvider.java
new file mode 100644
index 0000000..ede48b3
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/parts/SharedLabelProvider.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.parts;
+
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.eclipse.jface.resource.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.update.internal.ui.*;
+
+/**
+ * @version 	1.0
+ * @author
+ */
+public class SharedLabelProvider
+	extends LabelProvider
+	implements ITableLabelProvider {
+	public static final int F_ERROR = 1;
+	public static final int F_WARNING = 2;
+	public static final int F_CURRENT = 4;
+	public static final int F_INSTALLABLE = 8;
+	public static final int F_LINKED = 16;
+	public static final int F_MOD = 32;
+	public static final int F_UPDATED = 64;
+	public static final int F_UNCONFIGURED = 128;
+	public static final int F_ADD = 256;
+	public static final int F_DEL = 512;
+
+	Hashtable images = new Hashtable();
+	ArrayList consumers = new ArrayList();
+
+	public SharedLabelProvider() {
+	}
+
+	public void connect(Object consumer) {
+		if (!consumers.contains(consumer))
+			consumers.add(consumer);
+	}
+
+	public void disconnect(Object consumer) {
+		consumers.remove(consumer);
+		if (consumers.size() == 0) {
+			reset();
+		}
+	}
+	
+	public void dispose() {
+		reset();
+		super.dispose();
+	}
+
+	private void reset() {
+		for (Enumeration iterator = images.elements(); iterator.hasMoreElements();) {
+			Image image = (Image) iterator.nextElement();
+			image.dispose();
+		}
+		images.clear();
+	}
+
+	public Image get(ImageDescriptor desc) {
+		return get(desc, 0);
+	}
+
+	public Image get(ImageDescriptor desc, int flags) {
+		Object key = desc;
+
+		if (flags != 0) {
+			key = getKey(desc.hashCode(), flags);
+		}
+		Image image = (Image) images.get(key);
+		if (image == null) {
+			image = createImage(desc, flags);
+			images.put(key, image);
+		}
+		return image;
+	}
+	
+	public Image get(Image image, int flags) {
+		if (flags==0) return image;
+		String key = getKey(image.hashCode(), flags);
+		Image resultImage = (Image)images.get(key);
+		if (resultImage == null) {
+			resultImage = createImage(image, flags);
+			images.put(key, resultImage);
+		}
+		return resultImage;
+	}
+
+	private String getKey(long hashCode, int flags) {
+		return (""+hashCode) + ":"+flags; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	private Image createImage(ImageDescriptor baseDesc, int flags) {
+		if (flags == 0) {
+			return baseDesc.createImage();
+		}
+		ImageDescriptor[] lowerLeft = getLowerLeftOverlays(flags);
+		ImageDescriptor[] upperRight = getUpperRightOverlays(flags);
+		ImageDescriptor[] lowerRight = getLowerRightOverlays(flags);
+		ImageDescriptor[] upperLeft = getUpperLeftOverlays(flags);
+		OverlayIcon compDesc =
+			new OverlayIcon(
+				baseDesc,
+				new ImageDescriptor[][] { upperRight, lowerRight, lowerLeft, upperLeft });
+		return compDesc.createImage();
+	}
+	
+	private Image createImage(Image baseImage, int flags) {
+		if (flags == 0) {
+			return baseImage;
+		}
+		ImageDescriptor[] lowerLeft = getLowerLeftOverlays(flags);
+		ImageDescriptor[] upperRight = getUpperRightOverlays(flags);
+		ImageDescriptor[] lowerRight = getLowerRightOverlays(flags);
+		ImageDescriptor[] upperLeft = getUpperLeftOverlays(flags);
+		ImageOverlayIcon compDesc =
+			new ImageOverlayIcon(
+				baseImage,
+				new ImageDescriptor[][] { upperRight, lowerRight, lowerLeft, upperLeft });
+		return compDesc.createImage();
+	}
+
+	private ImageDescriptor[] getLowerLeftOverlays(int flags) {
+		if ((flags & F_ERROR) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_ERROR_CO };
+		if ((flags & F_WARNING) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_WARNING_CO };
+		return null;
+	}
+
+	private ImageDescriptor[] getUpperRightOverlays(int flags) {
+		if ((flags & F_ADD) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_ADD_CO };
+		if ((flags & F_DEL) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_DEL_CO };
+		if ((flags & F_UNCONFIGURED) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_UNCONF_CO };
+		if ((flags & F_LINKED) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_LINKED_CO };
+		return null;
+	}
+	
+	private ImageDescriptor[] getLowerRightOverlays(int flags) {
+		if ((flags & F_CURRENT) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_CURRENT_CO };
+		if ((flags & F_MOD) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_MOD_CO };
+		/*
+		if ((flags & F_ADD) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_ADD_CO };
+		if ((flags & F_DEL) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_DEL_CO };
+		if ((flags & F_UNCONFIGURED) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_UNCONF_CO };
+		*/
+		return null;
+	}
+	
+	private ImageDescriptor[] getUpperLeftOverlays(int flags) {
+		if ((flags & F_UPDATED) != 0)
+			return new ImageDescriptor[] { UpdateUIImages.DESC_UPDATED_CO };
+		return null;
+	}
+
+	public String getColumnText(Object obj, int index) {
+		return getText(obj);
+	}
+	public Image getColumnImage(Object obj, int index) {
+		return getImage(obj);
+	}
+
+	public Image getImageFromURL(
+		URL installURL,
+		String subdirectoryAndFilename) {
+		Image image = null;
+		try {
+			URL newURL = new URL(installURL, subdirectoryAndFilename);
+			String key = newURL.toString();
+			image = (Image)images.get(key);
+			if (image == null) {
+				ImageDescriptor desc = ImageDescriptor.createFromURL(newURL);
+				image = desc.createImage();
+				images.put(key, image);
+			}
+		} catch (MalformedURLException e) {
+		} catch (SWTException e) {
+		}
+		return image;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/preferences/MainPreferencePage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/preferences/MainPreferencePage.java
new file mode 100644
index 0000000..4b59a20
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/preferences/MainPreferencePage.java
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.preferences;
+
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+/**
+ * Insert the type's description here.
+ * @see PreferencePage
+ */
+public class MainPreferencePage
+	extends PreferencePage
+	implements IWorkbenchPreferencePage {
+
+	//private Label historySizeLabel;
+	private Text historySizeText;
+	private Button checkSignatureCheckbox;
+	private Button automaticallyChooseMirrorCheckbox;
+	private Button equivalentButton;
+	private Button compatibleButton;
+	private Text updatePolicyText;
+
+	// these two values are for compatibility with old code
+	public static final String EQUIVALENT_VALUE = "equivalent"; //$NON-NLS-1$
+	public static final String COMPATIBLE_VALUE = "compatible"; //$NON-NLS-1$
+
+	/**
+	 * The constructor.
+	 */
+	public MainPreferencePage() {
+		super();
+	}
+
+	/**
+	 * Insert the method's description here.
+	 */
+	public void init(IWorkbench workbench) {
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on PreferencePage.
+	 */
+	protected Control createContents(Composite parent) {
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.update.ui.MainPreferencePage"); //$NON-NLS-1$
+
+		Composite mainComposite = new Composite(parent, SWT.NULL);
+		mainComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		layout.numColumns = 2;
+		mainComposite.setLayout(layout);
+
+		Label historySizeLabel = new Label(mainComposite, SWT.NONE);
+		historySizeLabel.setText(UpdateUIMessages.MainPreferencePage_historySize); 
+		historySizeText = new Text(mainComposite, SWT.SINGLE | SWT.BORDER);
+		historySizeText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		historySizeText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				historySizeChanged();
+			}
+		});
+
+		checkSignatureCheckbox =
+			new Button(mainComposite, SWT.CHECK | SWT.LEFT);
+		checkSignatureCheckbox.setText(UpdateUIMessages.MainPreferencePage_checkSignature); 
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 2;
+		checkSignatureCheckbox.setLayoutData(gd);
+		checkSignatureCheckbox.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				if (checkSignatureCheckbox.getSelection() == false) {
+					warnSignatureCheck(getShell());
+				}
+			}
+		});
+		
+		automaticallyChooseMirrorCheckbox =
+			new Button(mainComposite, SWT.CHECK | SWT.LEFT);
+		automaticallyChooseMirrorCheckbox.setText(UpdateUIMessages.MainPreferencePage_automaticallyChooseMirror);
+		gd = new GridData();
+		gd.horizontalSpan = 2;
+		automaticallyChooseMirrorCheckbox.setLayoutData(gd);
+
+		createSpacer(mainComposite, 2);
+
+		Group group = new Group(mainComposite, SWT.NONE);
+		group.setText(UpdateUIMessages.MainPreferencePage_updateVersions); 
+		group.setLayout(new GridLayout());
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 2;
+		group.setLayoutData(gd);
+
+		equivalentButton = new Button(group, SWT.RADIO);
+		equivalentButton.setText(UpdateUIMessages.MainPreferencePage_updateVersions_equivalent); 
+
+		compatibleButton = new Button(group, SWT.RADIO);
+		compatibleButton.setText(UpdateUIMessages.MainPreferencePage_updateVersions_compatible); 
+
+		createSpacer(mainComposite, 2);
+
+		group = new Group(mainComposite, SWT.NONE);
+		group.setText(UpdateUIMessages.MainPreferencePage_updatePolicy); 
+		layout = new GridLayout();
+		layout.numColumns = 2;
+		group.setLayout(layout);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 2;
+		group.setLayoutData(gd);
+
+		Label label = new Label(group, SWT.NULL);
+		label.setText(UpdateUIMessages.MainPreferencePage_updatePolicyURL); 
+		updatePolicyText = new Text(group, SWT.SINGLE | SWT.BORDER);
+
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		updatePolicyText.setLayoutData(gd);
+
+		//createSpacer(mainComposite, 2);
+		//createHttpProxy(mainComposite, 2);
+		initialize();
+		updatePolicyText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				textChanged();
+			}
+		});
+		return mainComposite;
+	}
+
+	public void createControl(Composite parent) {
+		super.createControl(parent);
+		Dialog.applyDialogFont(getControl());
+	}
+
+	protected void createSpacer(Composite composite, int columnSpan) {
+		Label label = new Label(composite, SWT.NONE);
+		GridData gd = new GridData();
+		gd.horizontalSpan = columnSpan;
+		label.setLayoutData(gd);
+	}
+
+	protected void createHttpProxy(Composite composite, int columnSpan) {
+		Group group = new Group(composite, SWT.NONE);
+		group.setText(UpdateUIMessages.MainPreferencePage_proxyGroup); 
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		group.setLayout(layout);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = columnSpan;
+		group.setLayoutData(gd);
+	}
+
+	private int getHistoryCount() {
+		try {
+			Integer count = new Integer(historySizeText.getText());
+			return count.intValue();
+		} catch (NumberFormatException e) {
+		}
+		return UpdateCore.getPlugin().getPluginPreferences().getDefaultInt(
+			UpdateCore.P_HISTORY_SIZE);
+	}
+	
+	private void historySizeChanged() {
+		
+		try {
+			int historySize = Integer.parseInt(historySizeText.getText());
+			if (historySize < 0) {
+				setValid(false);
+				setErrorMessage(UpdateUIMessages.MainPreferencePage_invalidHistorySize); 
+				return;
+			}
+		} catch (NumberFormatException e) {
+			setValid(false);
+			setErrorMessage(UpdateUIMessages.MainPreferencePage_invalidHistorySize); 
+			return;
+		}
+		setValid(true);
+		setErrorMessage(null);	
+	}
+
+	public boolean performOk() {
+		BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
+			public void run() {
+				try {
+					SiteManager.getLocalSite().setMaximumHistoryCount(
+						getHistoryCount());
+				} catch (CoreException e) {
+					UpdateUI.logException(e);
+				}
+			}
+		});
+
+		Preferences prefs = UpdateCore.getPlugin().getPluginPreferences();
+		prefs.setValue(
+			UpdateCore.P_CHECK_SIGNATURE,
+			checkSignatureCheckbox.getSelection());
+		prefs.setValue(UpdateCore.P_AUTOMATICALLY_CHOOSE_MIRROR, automaticallyChooseMirrorCheckbox.getSelection());
+		prefs.setValue(UpdateCore.P_HISTORY_SIZE, historySizeText.getText());
+		prefs.setValue(
+			UpdateCore.P_UPDATE_VERSIONS,
+			equivalentButton.getSelection()
+				? EQUIVALENT_VALUE
+				: COMPATIBLE_VALUE);
+		prefs.setValue(
+			UpdateUtils.P_UPDATE_POLICY_URL,
+			updatePolicyText.getText());
+
+		UpdateCore.getPlugin().savePluginPreferences();
+		return super.performOk();
+	}
+
+
+	private void initialize() {
+		Preferences prefs = UpdateCore.getPlugin().getPluginPreferences();
+
+		checkSignatureCheckbox.setSelection(
+			prefs.getBoolean(UpdateCore.P_CHECK_SIGNATURE));
+		automaticallyChooseMirrorCheckbox.setSelection(
+				prefs.getBoolean(UpdateCore.P_AUTOMATICALLY_CHOOSE_MIRROR));
+
+		historySizeText.setText(prefs.getString(UpdateCore.P_HISTORY_SIZE));
+
+		boolean isCompatible =
+			UpdateCore.COMPATIBLE_VALUE.equals(
+				prefs.getString(UpdateCore.P_UPDATE_VERSIONS));
+		equivalentButton.setSelection(!isCompatible);
+		compatibleButton.setSelection(isCompatible);
+
+		String text = prefs.getString(UpdateUtils.P_UPDATE_POLICY_URL);
+		updatePolicyText.setText(text);
+	}
+
+	private void textChanged() {
+		String text = updatePolicyText.getText();
+		if (text.length() > 0) {
+			try {
+				new URL(text);
+			} catch (MalformedURLException e) {
+				setValid(false);
+				setErrorMessage(UpdateUIMessages.UpdateSettingsPreferencePage_invalid); 
+				return;
+			}
+		}
+		setValid(true);
+		setErrorMessage(null);
+	}
+
+	public void performDefaults() {
+		super.performDefaults();
+		Preferences prefs = UpdateCore.getPlugin().getPluginPreferences();
+
+		updatePolicyText.setText(""); //$NON-NLS-1$
+
+		checkSignatureCheckbox.setSelection(true);
+		automaticallyChooseMirrorCheckbox.setSelection(false);
+		historySizeText.setText(
+			prefs.getDefaultString(UpdateCore.P_HISTORY_SIZE));
+		
+		equivalentButton.setSelection(true);
+		compatibleButton.setSelection(false);
+	}
+
+	private void warnSignatureCheck(Shell shell) {
+		MessageDialog.openWarning(shell, UpdateUIMessages.MainPreferencePage_digitalSignature_title, 
+		UpdateUIMessages.MainPreferencePage_digitalSignature_message); 
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/preferences/UpdateSettingsPreferencePage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/preferences/UpdateSettingsPreferencePage.java
new file mode 100644
index 0000000..8808488
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/preferences/UpdateSettingsPreferencePage.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.preferences;
+
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.operations.*;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+/**
+ * Insert the type's description here.
+ * @see PreferencePage
+ */
+public class UpdateSettingsPreferencePage
+	extends PreferencePage
+	implements IWorkbenchPreferencePage {
+	private Text mappingsFile;
+
+	/**
+	 * The constructor.
+	 */
+	public UpdateSettingsPreferencePage() {
+		setDescription(UpdateUIMessages.UpdateSettingsPreferencePage_description); 
+	}
+
+	/**
+	 * Insert the method's description here.
+	 */
+	public void init(IWorkbench workbench) {
+	}
+
+	public Control createContents(Composite parent) {
+		Composite container = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		container.setLayout(layout);
+		layout.marginWidth = layout.marginHeight = 0;
+		layout.numColumns = 2;
+		Label label = new Label(container, SWT.NULL);
+		label.setText(UpdateUIMessages.UpdateSettingsPreferencePage_label); 
+		mappingsFile = new Text(container, SWT.SINGLE | SWT.BORDER);
+
+		initialize();
+		mappingsFile.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				textChanged();
+			}
+		});
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		mappingsFile.setLayoutData(gd);
+		return container;
+	}
+
+	private void initialize() {
+		Preferences pref = UpdateCore.getPlugin().getPluginPreferences();
+		String text = pref.getString(UpdateUtils.P_UPDATE_POLICY_URL);
+		mappingsFile.setText(text);
+		textChanged();
+	}
+
+	private void textChanged() {
+		String text = mappingsFile.getText();
+		if (text.length() > 0) {
+			try {
+				new URL(text);
+			} catch (MalformedURLException e) {
+				setValid(false);
+				setErrorMessage(UpdateUIMessages.UpdateSettingsPreferencePage_invalid); 
+				return;
+			}
+		}
+		setValid(true);
+		setErrorMessage(null);
+	}
+
+	public boolean performOk() {
+		Preferences pref = UpdateCore.getPlugin().getPluginPreferences();
+		String text = mappingsFile.getText();
+		if (text.length() > 0)
+			pref.setValue(UpdateUtils.P_UPDATE_POLICY_URL, text);
+		else
+			pref.setToDefault(UpdateUtils.P_UPDATE_POLICY_URL);
+		UpdateCore.getPlugin().savePluginPreferences();
+		return true;
+	}
+
+	protected void performDefaults() {
+		mappingsFile.setText(""); //$NON-NLS-1$
+		super.performDefaults();
+	}
+
+	public void createControl(Composite parent) {
+		super.createControl(parent);
+		Dialog.applyDialogFont(getControl());
+		/*
+		WorkbenchHelp.setHelp(
+			parent,"org.eclipse.update.ui.AppServerPreferencePage");
+		*/
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/ConfiguredSitePropertyPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/ConfiguredSitePropertyPage.java
new file mode 100644
index 0000000..39aeb2b
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/ConfiguredSitePropertyPage.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.properties;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.dialogs.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.internal.ui.model.*;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+/**
+ * @see PropertyPage
+ */
+public class ConfiguredSitePropertyPage extends PropertyPage implements IWorkbenchPropertyPage {
+	/**
+	 *
+	 */
+	public ConfiguredSitePropertyPage() {
+		noDefaultAndApplyButton();
+	}
+
+	protected Control createContents(Composite parent)  {
+		IConfiguredSiteAdapter adapter = (IConfiguredSiteAdapter)getElement();
+		IConfiguredSite csite = adapter.getConfiguredSite();
+		Composite composite = new Composite(parent,SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		composite.setLayout(layout);
+		addProperty(composite, UpdateUIMessages.ConfiguredSitePropertyPage_path, csite.getSite().getURL().toString()); 
+		addProperty(composite, UpdateUIMessages.ConfiguredSitePropertyPage_type, getLocationType(csite)); 
+		addProperty(composite, UpdateUIMessages.ConfiguredSitePropertyPage_enabled, csite.isEnabled()?UpdateUIMessages.ConfiguredSitePropertyPage_yes:UpdateUIMessages.ConfiguredSitePropertyPage_no); 
+		return composite;
+	}
+	
+	private String getLocationType(IConfiguredSite csite) {
+		if (csite.isExtensionSite())
+			return UpdateUIMessages.ConfiguredSitePropertyPage_extension; 
+		if (csite.isProductSite())
+			return UpdateUIMessages.ConfiguredSitePropertyPage_product; 
+		return UpdateUIMessages.ConfiguredSitePropertyPage_unknown; 
+	}
+	
+	private void addProperty(Composite parent, String key, String value) {
+		Label label = new Label(parent, SWT.NULL);
+		label.setText(key);
+		
+		label = new Label(parent, SWT.NULL);
+		label.setText(value);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		label.setLayoutData(gd);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureCopyrightPropertyPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureCopyrightPropertyPage.java
new file mode 100644
index 0000000..8e5c2a6
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureCopyrightPropertyPage.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.properties;
+
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.dialogs.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.ui.model.*;
+import org.eclipse.update.internal.ui.parts.*;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+/**
+ * @see PropertyPage
+ */
+public class FeatureCopyrightPropertyPage extends PropertyPage implements IWorkbenchPropertyPage {
+	/**
+	 *
+	 */
+	public FeatureCopyrightPropertyPage() {
+		noDefaultAndApplyButton();
+	}
+
+	protected Control createContents(Composite parent) {
+		try {
+			IFeatureAdapter adapter = (IFeatureAdapter) getElement();
+			IFeature feature = adapter.getFeature(null);
+
+			Composite composite = new Composite(parent, SWT.NULL);
+			composite.setLayout(new GridLayout());
+
+			Label label = new Label(composite, SWT.WRAP);
+			GridData gd =
+				new GridData(
+					GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
+			gd.widthHint = computeWidthLimit(label, 80);
+			label.setLayoutData(gd);
+
+			IURLEntry copyright = feature.getCopyright();
+			String annotation = (copyright != null) ? copyright.getAnnotation() : null;
+
+			if (annotation != null && annotation.length() > 0) {
+				label.setText(annotation);
+				final URL url = copyright.getURL();
+				String filename = (url != null) ? url.getFile() : null;
+				if (filename != null
+					&& (filename.endsWith(".htm") || filename.endsWith(".html"))) { //$NON-NLS-1$ //$NON-NLS-2$
+					Button button = new Button(composite, SWT.PUSH);
+					button.setText(UpdateUIMessages.FeatureCopyrightPropertyPage_showInBrowser); 
+					button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+					SWTUtil.setButtonDimensionHint(button);
+					button.addSelectionListener(new SelectionAdapter() {
+						public void widgetSelected(SelectionEvent e) {
+							UpdateUI.showURL(url.toExternalForm());
+						}
+					});
+				}
+			} else {
+				label.setText(UpdateUIMessages.FeatureCopyrightPropertyPage_noCopyright); 
+			}
+			Dialog.applyDialogFont(parent);
+		} catch (CoreException e) {
+		}
+		return null;
+	}
+	
+	private int computeWidthLimit(Label label, int nchars) {
+		GC gc = new GC(label);
+		gc.setFont(label.getFont());
+		FontMetrics fontMetrics= gc.getFontMetrics();
+		gc.dispose();
+		return Dialog.convertWidthInCharsToPixels(fontMetrics, nchars);
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureGeneralPropertyPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureGeneralPropertyPage.java
new file mode 100644
index 0000000..7acba11
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureGeneralPropertyPage.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.properties;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.IWorkbenchPropertyPage;
+import org.eclipse.ui.dialogs.PropertyPage;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IURLEntry;
+import org.eclipse.update.core.model.ContentEntryModel;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.internal.ui.model.IFeatureAdapter;
+
+public class FeatureGeneralPropertyPage
+	extends PropertyPage
+	implements IWorkbenchPropertyPage {
+		
+	public FeatureGeneralPropertyPage() {
+		noDefaultAndApplyButton();
+	}
+
+	protected Control createContents(Composite parent) {
+		try {
+			IFeatureAdapter adapter = (IFeatureAdapter) getElement();
+			IFeature feature = adapter.getFeature(null);
+
+			Composite composite = new Composite(parent, SWT.NONE);
+			GridLayout layout = new GridLayout();
+			layout.marginWidth = 0;
+			layout.marginHeight = 0;
+			layout.verticalSpacing = 15;
+			composite.setLayout(layout);
+			
+			addGeneralSection(feature, composite);
+			addSupportedPlatformsSection(feature, composite);
+			addDescription(feature, composite);
+			
+			Dialog.applyDialogFont(parent);
+			
+			return composite;
+
+		} catch (CoreException e) {
+		}
+
+		return null;
+	}
+
+	private void addGeneralSection(IFeature feature, Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		composite.setLayout(layout);
+		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		Composite fieldComposite = new Composite(composite, SWT.NONE);
+		layout = new GridLayout();
+		layout.numColumns = 2;
+		fieldComposite.setLayout(layout);
+		
+		Label imageLabel = new Label(composite, SWT.RIGHT);
+		imageLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		if (feature.getImage()!=null) {
+			ImageDescriptor desc = ImageDescriptor.createFromURL(feature.getImage());
+			imageLabel.setImage(UpdateUI.getDefault().getLabelProvider().get(desc));
+		}
+		else {
+			imageLabel.setImage(UpdateUI.getDefault().getLabelProvider().get(UpdateUIImages.DESC_PROVIDER));
+		}
+		addField(fieldComposite, UpdateUIMessages.FeatureGeneralPropertyPage_name, feature.getLabel());
+
+		addField(
+				fieldComposite,
+			UpdateUIMessages.FeatureGeneralPropertyPage_id, 
+			feature.getVersionedIdentifier().getIdentifier());
+		addField(
+				fieldComposite,
+			UpdateUIMessages.FeatureGeneralPropertyPage_version, 
+			feature.getVersionedIdentifier().getVersion().toString());
+		addField(fieldComposite, UpdateUIMessages.FeatureGeneralPropertyPage_provider, feature.getProvider()); 
+		long size = feature.getInstallSize();
+		if (size != ContentEntryModel.UNKNOWN_SIZE) {
+			addField(fieldComposite, UpdateUIMessages.FeatureGeneralPropertyPage_size, new Long(size).toString() + " " + UpdateUIMessages.FeatureGeneralPropertyPage_Kilobytes);  //$NON-NLS-1$
+		}
+	}
+	
+	private void addSupportedPlatformsSection(IFeature feature, Composite parent) {
+		Group group = new Group(parent, SWT.NONE);
+		group.setText(UpdateUIMessages.FeatureGeneralPropertyPage_platforms); 
+
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.makeColumnsEqualWidth = true;
+		group.setLayout(layout);
+		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		Label label = new Label(group, SWT.NONE);
+		label.setText(NLS.bind(UpdateUIMessages.FeatureGeneralPropertyPage_os,extractValue(feature.getOS()))); 
+
+		label = new Label(group, SWT.NONE);
+		label.setText(NLS.bind(UpdateUIMessages.FeatureGeneralPropertyPage_ws, extractValue(feature.getWS()))); 
+
+		label = new Label(group, SWT.NONE);
+		label.setText(NLS.bind(UpdateUIMessages.FeatureGeneralPropertyPage_arch, extractValue(feature.getOSArch()))); 
+
+		label = new Label(group, SWT.NONE);
+		label.setText(NLS.bind(UpdateUIMessages.FeatureGeneralPropertyPage_nl, extractValue(feature.getNL()))); 
+	}
+
+	private void addField(Composite parent, String property, String value) {
+
+		if (value != null && value.length() > 0) {
+			Label label = new Label(parent, SWT.NONE);
+			label.setText(property);
+
+			label = new Label(parent, SWT.NONE);
+			label.setText(getEscapedString(value));
+		}
+	}
+	
+	private String extractValue(String value) {
+		if (value == null || value.equals("*")) //$NON-NLS-1$
+			return UpdateUIMessages.FeatureGeneralPropertyPage_all; 
+		return value;
+	}
+
+	private void addDescription(IFeature feature, Composite parent) {
+		IURLEntry description = feature.getDescription();
+		if (description != null) {
+			String annotation = description.getAnnotation();
+			if (annotation != null && annotation.length() > 0) {
+				Group group = new Group(parent, SWT.NONE);
+				group.setText(UpdateUIMessages.FeatureGeneralPropertyPage_desc); 
+				group.setLayout(new GridLayout());
+				group.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+				Text text = new Text(group, SWT.MULTI | SWT.WRAP);
+				GridData gd = new GridData(GridData.FILL_BOTH);
+				gd.heightHint = 200;
+				gd.widthHint = 350;
+				text.setEditable(false);
+				text.setText(annotation);
+				text.setLayoutData(gd);
+			}
+		}
+	}
+	
+	private String getEscapedString(String value) {
+		StringBuffer result = new StringBuffer(value.length() + 10);
+		for (int i = 0; i < value.length(); ++i) {
+			char c = value.charAt(i);
+			if ('&' == c) {
+				result.append("&&"); //$NON-NLS-1$
+			} else {
+				result.append(c);
+			}
+		}
+		return result.toString();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureLicensePropertyPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureLicensePropertyPage.java
new file mode 100644
index 0000000..ab6e83b
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureLicensePropertyPage.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.properties;
+
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.dialogs.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.ui.model.*;
+import org.eclipse.update.internal.ui.parts.*;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+
+public class FeatureLicensePropertyPage extends PropertyPage implements IWorkbenchPropertyPage {
+	public FeatureLicensePropertyPage() {
+		noDefaultAndApplyButton();
+	}
+
+	protected Control createContents(Composite parent)  {
+		try {
+			Composite composite = new Composite(parent, SWT.NULL);
+			composite.setLayout(new GridLayout());
+
+			IFeatureAdapter adapter = (IFeatureAdapter)getElement();
+			IFeature feature = adapter.getFeature(null);			
+			IURLEntry license = feature.getLicense();
+			String annotation = (license != null) ? license.getAnnotation() : null;
+			
+			if (annotation != null && annotation.length() > 0) {
+				Text text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER | SWT.WRAP);
+				GridData gd = new GridData(GridData.FILL_BOTH);
+				gd.heightHint = 200;
+				gd.widthHint = 350;
+				text.setLayoutData(gd);
+				text.setText(annotation);
+				text.setEditable(false);
+				final URL url = license.getURL();
+				String filename = (url != null) ? url.getFile() : null;
+				if (filename != null && (filename.endsWith(".htm") || url.getFile().endsWith(".html"))) { //$NON-NLS-1$ //$NON-NLS-2$
+					Button button = new Button(composite, SWT.PUSH);
+					button.setText(UpdateUIMessages.FeatureLicensePropertyPage_showInBrowser); 
+					button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+					SWTUtil.setButtonDimensionHint(button);
+					button.addSelectionListener(new SelectionAdapter() {
+						public void widgetSelected(SelectionEvent e) {
+							UpdateUI.showURL(url.toExternalForm());
+						}
+					});
+				}
+			} else {
+				Label label = new Label(composite, SWT.NULL);
+				label.setText(UpdateUIMessages.FeatureLicensePropertyPage_noLicense); 
+			}
+			
+			Dialog.applyDialogFont(parent);
+			
+			return composite;
+			
+		} catch (CoreException e) {
+		}
+		return null;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureStatusPropertyPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureStatusPropertyPage.java
new file mode 100644
index 0000000..0290887
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/FeatureStatusPropertyPage.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.properties;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.dialogs.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.operations.*;
+import org.eclipse.update.internal.ui.model.*;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.operations.*;
+
+/**
+ * @see PropertyPage
+ */
+public class FeatureStatusPropertyPage
+	extends PropertyPage
+	implements IWorkbenchPropertyPage {
+	/**
+	 *
+	 */
+	public FeatureStatusPropertyPage() {
+		noDefaultAndApplyButton();
+	}
+
+	protected Control createContents(Composite parent) {
+		try {
+
+			Composite composite = new Composite(parent, SWT.NONE);
+			GridLayout layout = new GridLayout();
+			layout.numColumns = 1;
+			layout.verticalSpacing = 20;
+			composite.setLayout(layout);
+
+			Text message = new Text(composite, SWT.MULTI | SWT.WRAP);
+			message.setEditable(false);
+			GridData gd = new GridData();
+			gd.widthHint = 350;
+			message.setLayoutData(gd);
+			
+			ConfiguredFeatureAdapter adapter = (ConfiguredFeatureAdapter) getElement();
+			IFeature feature = adapter.getFeature(null);
+			
+			if (OperationsManager.findPendingOperation(feature) != null) {
+				message.setText(UpdateUIMessages.FeatureStatusPropertyPage_pendingChanges); 
+				return composite;
+			}
+			
+			IStatus status = getStatus(feature);
+			int severity = status.getSeverity();
+			if (severity == IStatus.ERROR
+				&& getStatusCode(feature, status) == IFeature.STATUS_HAPPY) {
+				severity = IStatus.OK;
+				message.setText(UpdateUIMessages.FeatureStatusPropertyPage_goodConfiguration); 
+			} else {
+				message.setText(status.getMessage());
+			}
+			if (severity != IStatus.OK && status.isMultiStatus()) {
+				String reason = getReason(status);
+				if (reason.length() > 0) {
+					Composite comp = new Composite(composite, SWT.NONE);
+					comp.setLayout(new GridLayout());
+					gd = new GridData(GridData.FILL_BOTH);
+					comp.setLayoutData(gd);
+
+					Label label = new Label(comp, SWT.NONE);
+					label.setText(UpdateUIMessages.FeatureStatusPropertyPage_reason); 
+
+					Text text =
+						new Text(comp, SWT.MULTI | SWT.BORDER | SWT.WRAP | SWT.V_SCROLL);
+					text.setEditable(false);
+					text.setText(reason);
+					gd.widthHint = 350;
+					text.setLayoutData(gd);
+				}
+
+			}
+			
+			Dialog.applyDialogFont(parent);
+			
+			return composite;
+
+		} catch (CoreException e) {
+		}
+
+		return null;
+	}
+
+	private String getReason(IStatus status) {
+		IStatus[] children = status.getChildren();
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0; i < children.length; i++) {
+			String message = children[i].getMessage();
+			if (message != null && message.length() > 0) {
+				buffer.append(
+					message
+						+ System.getProperty("line.separator") //$NON-NLS-1$
+						+ System.getProperty("line.separator")); //$NON-NLS-1$
+			}
+		}
+		return buffer.toString();
+	}
+
+	private IStatus getStatus(IFeature feature) throws CoreException {
+		if (feature instanceof MissingFeature) {
+			int severity;
+			String message = ""; //$NON-NLS-1$
+			if (((MissingFeature) feature).isOptional()) {
+				severity = IStatus.OK;
+				message = UpdateUIMessages.FeatureStatusPropertyPage_missingOptional; 
+			} else {
+				severity = IStatus.ERROR;
+				message = UpdateUIMessages.FeatureStatusPropertyPage_missing; 
+			}
+			return new Status(severity, UpdateUI.PLUGIN_ID, IStatus.OK, message, null);
+		}
+		return SiteManager.getLocalSite().getFeatureStatus(feature);
+	}
+
+	private int getStatusCode(IFeature feature, IStatus status) {
+		int code = status.getCode();
+		if (code == IFeature.STATUS_UNHAPPY) {
+			if (status.isMultiStatus()) {
+				IStatus[] children = status.getChildren();
+				for (int i = 0; i < children.length; i++) {
+					IStatus child = children[i];
+					if (child.isMultiStatus()
+						|| child.getCode() != IFeature.STATUS_DISABLED)
+						return code;
+				}
+				// If we are here, global status is unhappy
+				// because one or more included features
+				// is disabled.
+				if (UpdateUtils.hasObsoletePatches(feature)) {
+					// The disabled included features
+					// are old patches that are now
+					// subsumed by better versions of
+					// the features they were designed to
+					// patch.
+					return IFeature.STATUS_HAPPY;
+				}
+			}
+		}
+		return code;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/InstallConfigurationPropertyPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/InstallConfigurationPropertyPage.java
new file mode 100644
index 0000000..a5f57bc
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/properties/InstallConfigurationPropertyPage.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.properties;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.dialogs.*;
+import org.eclipse.update.configurator.*;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+/**
+ * @see PropertyPage
+ */
+public class InstallConfigurationPropertyPage extends PropertyPage implements IWorkbenchPropertyPage {
+	/**
+	 *
+	 */
+	public InstallConfigurationPropertyPage() {
+		noDefaultAndApplyButton();
+	}
+
+	protected Control createContents(Composite parent)  {
+		Composite composite = new Composite(parent,SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		composite.setLayout(layout);
+		addProperty(composite, UpdateUIMessages.ConfiguredSitePropertyPage_path, ConfiguratorUtils.getInstallURL().toString()); 
+		return composite;
+	}
+	
+
+	private void addProperty(Composite parent, String key, String value) {
+		Label label = new Label(parent, SWT.NULL);
+		label.setText(key);
+		
+		label = new Label(parent, SWT.NULL);
+		label.setText(value);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		label.setLayoutData(gd);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/Authentication.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/Authentication.java
new file mode 100644
index 0000000..fdfb9a7
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/Authentication.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.security;
+
+/**
+ * Keeps user and password strings.
+ */
+public class Authentication {
+	protected String user;
+	protected String password;
+	public Authentication(String user, String password){
+		this.user = user;
+		this.password = password;
+	}
+
+	/**
+	 * @return Returns the password.
+	 */
+	public String getPassword() {
+		return password;
+	}
+	/**
+	 * @return Returns the user.
+	 */
+	public String getUser() {
+		return user;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/JarVerificationDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/JarVerificationDialog.java
new file mode 100644
index 0000000..62e928a
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/JarVerificationDialog.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.security;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.ui.*;
+
+/**
+ * 
+ */
+public class JarVerificationDialog extends TitleAreaDialog {
+	public final static int INSTALL_ALL = CANCEL + OK + 1;
+	private IVerificationResult _VerificationResult = null;
+	private IDialogPage _DialogPage;
+	private Composite pageContainer;
+	private Image defaultImage = null;
+	private ImageDescriptor defaultImageDescriptor =
+		UpdateUIImages.DESC_UPDATE_WIZ;
+	
+	/**
+	 * Constructor for JarVerificationDialog.
+	 * @param parentShell
+	 */
+	public JarVerificationDialog(Shell parentShell,IDialogPage dialogPage, IVerificationResult verificationResult) {
+		super(parentShell);
+		setShellStyle(SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.RESIZE);		
+		_VerificationResult = verificationResult;
+		_DialogPage = dialogPage;
+		if (dialogPage instanceof JarVerificationPage){
+			((JarVerificationPage)_DialogPage).setTitleAreaDialog(this);
+		}
+	}
+
+	/**
+	 * Add buttons to the dialog's button bar.
+	 */
+	protected void createButtonsForButtonBar(Composite parent) {
+		if (_VerificationResult.getVerificationCode()
+			!= IVerificationResult.TYPE_ENTRY_CORRUPTED) {
+
+			if (_VerificationResult.isFeatureVerification()) {
+				createButton(
+					parent,
+					IDialogConstants.OK_ID,
+					UpdateUIMessages.JarVerificationDialog_Install, 
+					false);
+			} else {
+				createButton(
+					parent,
+					IDialogConstants.OK_ID,
+					UpdateUIMessages.JarVerificationDialog_Continue, 
+					false);				
+			}
+			// Radio button: Install all without prompting
+			//----------------------------------
+			createButton(
+				parent,
+				IDialogConstants.YES_TO_ALL_ID,
+				UpdateUIMessages.JarVerificationDialog_InstallAll, 
+				false);		
+			
+			// Radio button: Cancel installation
+			//----------------------------------
+			createButton(
+				parent,
+				IDialogConstants.CANCEL_ID,
+				UpdateUIMessages.JarVerificationDialog_Cancel, 
+				true);							
+		} else {
+			createButton(
+				parent,
+				IDialogConstants.CANCEL_ID,
+				UpdateUIMessages.JarVerificationDialog_Cancel, 
+				true);
+		}
+		getButton(IDialogConstants.CANCEL_ID).setFocus();
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected Control createDialogArea(Composite parent) {
+		Composite compositeParent = (Composite)super.createDialogArea(parent);
+		setTitleImage(this.getImage());
+		setTitle(UpdateUIMessages.JarVerificationDialog_Title); 
+		
+		_DialogPage.createControl(compositeParent);
+		pageContainer=(Composite)_DialogPage.getControl();
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		pageContainer.setLayoutData(gd);
+		pageContainer.setFont(parent.getFont());		
+		
+		// Build the separator line
+		Label separator= new Label(compositeParent, SWT.HORIZONTAL | SWT.SEPARATOR);
+		separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		return compositeParent;
+	}
+	
+		/**
+	 * @see IDialogPage#getImage()
+	 */
+	public Image getImage() {
+		if (defaultImage == null)
+			defaultImage = defaultImageDescriptor.createImage();
+
+		return defaultImage;
+	}
+
+	public boolean close() {
+		// dispose of image
+		if (defaultImage != null) {
+			defaultImage.dispose();
+			defaultImage = null;
+		}
+		return super.close();		
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
+	 */
+	protected void buttonPressed(int buttonId) {
+		if (IDialogConstants.YES_TO_ALL_ID == buttonId)
+			installAllPressed();
+		else
+			super.buttonPressed(buttonId);
+	}
+	
+	private void installAllPressed() {
+        setReturnCode(JarVerificationDialog.INSTALL_ALL);
+        close();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/JarVerificationPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/JarVerificationPage.java
new file mode 100644
index 0000000..e953bef
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/JarVerificationPage.java
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.security;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.*;
+import org.eclipse.update.core.IVerificationResult;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.wizards.BannerPage;
+
+/**
+ * 
+ */
+public class JarVerificationPage extends BannerPage {
+
+	private IVerificationResult _VerificationResult = null;
+	private String _fileName = null;
+	private String _strFeatureName = null;
+	private String _strId = null;
+	private String _strProviderName = null;
+	private TitleAreaDialog _Dialog;
+
+	/*
+	 * Constructor for JarVerificationPage.
+	 */
+	public JarVerificationPage(IVerificationResult verificationResult) {
+		super(UpdateUIMessages.JarVerificationDialog_Verification); 
+		_fileName = verificationResult.getContentReference().getIdentifier();
+		_VerificationResult = verificationResult;
+		_strId = verificationResult.getFeature().getVersionedIdentifier().toString();
+		_strFeatureName = verificationResult.getFeature().getLabel();
+		_strProviderName = verificationResult.getFeature().getProvider();
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected Control createContents(Composite compositeParent) {
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(compositeParent, "org.eclipse.update.ui.JarVerificationPage"); //$NON-NLS-1$
+		// Composite: Client
+		//------------------
+		Composite compositeClient = new Composite(compositeParent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = layout.marginWidth = 0;
+		compositeClient.setLayout(layout);
+		compositeClient.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		// Text Information
+		//------------------		
+		createTextArea(compositeClient);
+
+		// Certificate Area
+		//------------------
+		createCertificateArea(compositeClient);
+
+		// File and Feature Information
+		//-----------------------------		
+		createInformationArea(compositeClient);
+
+		// Choice Area
+		//------------		
+		//createChoiceArea(compositeClient);
+
+		Dialog.applyDialogFont(compositeParent);
+		return compositeClient;
+
+	}
+
+	/*
+	 * Creates the Information text
+	 */
+	private void createTextArea(Composite compositeClient) {
+
+		// Label: Information
+		//------------------
+		Label labelInformation =
+			new Label(compositeClient, SWT.WRAP);
+		labelInformation.setLayoutData(
+			new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
+
+        String actionMsg = null;
+        if (_VerificationResult.isFeatureVerification()) {
+            actionMsg = UpdateUIMessages.JarVerificationDialog_MayChooseToInstall; 
+        } else {
+            actionMsg = UpdateUIMessages.JarVerificationDialog_MayChooseToContinue; 
+        }
+        
+        StringBuffer strb = new StringBuffer();
+		switch (_VerificationResult.getVerificationCode()) {
+
+			case IVerificationResult.TYPE_ENTRY_NOT_SIGNED :
+				String msg = (_VerificationResult.isFeatureVerification()?
+					UpdateUIMessages.JarVerificationDialog_AboutToInstall_Feature:
+						UpdateUIMessages.JarVerificationDialog_AboutToInstall_File)+
+                        "\r\n" + actionMsg; //$NON-NLS-1$
+				setMessage(msg, WARNING);
+				strb.append(_VerificationResult.isFeatureVerification()?
+							UpdateUIMessages.JarVerificationDialog_NotDigitallySigned_Feature:
+								UpdateUIMessages.JarVerificationDialog_NotDigitallySigned_File);
+				strb.append("\r\n"); //$NON-NLS-1$
+				strb.append(_VerificationResult.isFeatureVerification()?
+						UpdateUIMessages.JarVerificationDialog_CannotVerifyProvider_Feature:
+							UpdateUIMessages.JarVerificationDialog_CannotVerifyProvider_File);
+                
+/*				strb.append("\r\n"); //$NON-NLS-1$
+				if (_VerificationResult.isFeatureVerification()) {
+					strb.append(
+						UpdateUI.getResourceString("JarVerificationDialog.InstallMayCorrupt"));//$NON-NLS-1$
+				} else {
+					strb.append(
+						UpdateUI.getResourceString("JarVerificationDialog.ContinueMayCorrupt"));//$NON-NLS-1$ 					
+				}
+				*/
+				labelInformation.setText(strb.toString());
+				break;
+
+			case IVerificationResult.TYPE_ENTRY_CORRUPTED :
+				msg = _VerificationResult.isFeatureVerification()?
+							UpdateUIMessages.JarVerificationDialog_CorruptedContent_Feature:
+								UpdateUIMessages.JarVerificationDialog_CorruptedContent_File;
+				setMessage(msg, ERROR);
+				strb.append(
+					UpdateUIMessages.JarVerificationDialog_ComponentNotInstalled); 
+				labelInformation.setText(strb.toString());
+				break;
+
+			case IVerificationResult.TYPE_ENTRY_SIGNED_UNRECOGNIZED :
+				msg = (_VerificationResult.isFeatureVerification()?
+						UpdateUIMessages.JarVerificationDialog_SignedComponent_Feature:
+							UpdateUIMessages.JarVerificationDialog_SignedComponent_Feature) +  
+                        "\r\n" + actionMsg; //$NON-NLS-1$
+                
+				setMessage(msg, WARNING);
+				strb.append(_VerificationResult.isFeatureVerification()?
+					UpdateUIMessages.JarVerificationDialog_UnknownCertificate_Feature:
+						UpdateUIMessages.JarVerificationDialog_UnknownCertificate_File);
+				strb.append("\r\n"); //$NON-NLS-1$
+				strb.append(_VerificationResult.isFeatureVerification()?
+						UpdateUIMessages.JarVerificationDialog_UnableToVerifyProvider_Feature:
+							UpdateUIMessages.JarVerificationDialog_UnableToVerifyProvider_File);
+/*				strb.append("\r\n"); //$NON-NLS-1$
+				if (_VerificationResult.isFeatureVerification()) {
+					strb.append(
+						UpdateUI.getResourceString("JarVerificationDialog.InstallMayCorrupt")); //$NON-NLS-1$
+				} else {
+					strb.append(
+						UpdateUI.getResourceString("JarVerificationDialog.ContinueMayCorrupt"));//$NON-NLS-1$ 					
+				}
+				*/
+				labelInformation.setText(strb.toString());
+				break;
+
+			case IVerificationResult.TYPE_ENTRY_SIGNED_RECOGNIZED :
+				msg = (_VerificationResult.isFeatureVerification()?
+						UpdateUIMessages.JarVerificationDialog_SignedComponent_Feature:
+							UpdateUIMessages.JarVerificationDialog_SignedComponent_File) +
+                        "\r\n" + actionMsg; //$NON-NLS-1$
+				setMessage(msg, WARNING);
+				strb.append(_VerificationResult.isFeatureVerification()?
+					UpdateUIMessages.JarVerificationDialog_KnownCertificate_Feature:
+						UpdateUIMessages.JarVerificationDialog_KnownCertificate_File);
+				strb.append("\r\n"); //$NON-NLS-1$
+				strb.append(_VerificationResult.isFeatureVerification()?
+					UpdateUIMessages.JarVerificationDialog_ProviderKnown_Feature:
+						UpdateUIMessages.JarVerificationDialog_ProviderKnown_File);
+				strb.append("\r\n"); //$NON-NLS-1$
+
+				labelInformation.setText(strb.toString());
+
+//				createCautionArea(compositeClient);
+				break;
+		}
+	}
+	
+
+	/*
+	 * Presents File & Feature information
+	 */
+	private void createInformationArea(Composite compositeClient) {
+
+		// Composite: Information labels
+		//------------------------------
+		Composite compositeInformation = new Composite(compositeClient, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginWidth = layout.marginHeight = 0;
+		compositeInformation.setLayout(layout);
+		compositeInformation.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		// get bold face
+		FontRegistry fregistry = JFaceResources.getFontRegistry();
+		Font boldFont = fregistry.getBold(JFaceResources.DIALOG_FONT);
+		
+		// Feature name
+		//---------------
+		Label keyLabel = null;
+		CLabel valueLabel = null;
+		if (_strFeatureName != null && _strFeatureName.length() > 0) {
+			keyLabel = new Label(compositeInformation, SWT.NULL);
+			keyLabel.setText(
+				UpdateUIMessages.JarVerificationDialog_FeatureName); 
+
+			valueLabel = new CLabel(compositeInformation, SWT.NULL);
+			valueLabel.setFont(boldFont);
+			valueLabel.setText(_strFeatureName);
+			valueLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		}
+		// Feature identifier
+		//---------------------
+		if (_strId != null && _strId.length() > 0) {
+			keyLabel = new Label(compositeInformation, SWT.NULL);
+			keyLabel.setText(
+				UpdateUIMessages.JarVerificationDialog_FeatureIdentifier); 
+
+			valueLabel = new CLabel(compositeInformation, SWT.NULL);
+			valueLabel.setFont(boldFont);
+			valueLabel.setText(_strId);
+			valueLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		}
+		// Provider name
+		//--------------
+		if (_strProviderName != null && _strProviderName.length() > 0) {
+			keyLabel = new Label(compositeInformation, SWT.NULL);
+			keyLabel.setText(
+				UpdateUIMessages.JarVerificationDialog_Provider); 
+
+			valueLabel = new CLabel(compositeInformation, SWT.NULL);
+			valueLabel.setFont(boldFont);
+			valueLabel.setText(_strProviderName);
+			valueLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		}
+		// Label: File name
+		//-----------------
+		keyLabel = new Label(compositeInformation, SWT.NULL);
+		keyLabel.setText(
+			UpdateUIMessages.JarVerificationDialog_FileName); 
+
+		valueLabel = new CLabel(compositeInformation, SWT.NULL);
+		valueLabel.setFont(boldFont);
+		valueLabel.setText(_fileName);
+		valueLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+	}
+
+	/*
+	 * Show certificate information
+	 */
+	private void createCertificateArea(Composite compositeClient) {
+
+		if (_VerificationResult.getVerificationCode()
+			== IVerificationResult.TYPE_ENTRY_SIGNED_UNRECOGNIZED
+			|| _VerificationResult.getVerificationCode()
+				== IVerificationResult.TYPE_ENTRY_SIGNED_RECOGNIZED) {
+			// Group box
+			//----------
+			Group group = new Group(compositeClient, SWT.SHADOW_ETCHED_IN);
+			GridLayout layout = new GridLayout();
+			layout.numColumns = 2;
+			layout.marginWidth = layout.marginHeight = 0;
+			group.setLayout(layout);
+			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			group.setText(UpdateUIMessages.JarVerificationDialog_CertificateInfo); 
+
+			// Signer
+			//-------------------
+			Label keyLabel = null;
+			Text valueText = null;
+			//data = new GridData(GridData.FILL_HORIZONTAL);
+			//data.horizontalIndent = 0;
+			//textInformation.setLayoutData(data);			
+			if (_VerificationResult.getSignerInfo() != null) {
+				keyLabel = new Label(group, SWT.NULL);
+				keyLabel.setText(UpdateUIMessages.JarVerificationDialog_SubjectCA); 
+				keyLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+
+				valueText = new Text(group, SWT.MULTI|SWT.BORDER|SWT.WRAP|SWT.V_SCROLL);
+				valueText.setText(_VerificationResult.getSignerInfo());
+				valueText.setEditable(false);
+				valueText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			}
+			
+			// Authenticator
+			//---------------------
+			if (_VerificationResult.getVerifierInfo() != null) {
+				keyLabel = new Label(group, SWT.NULL);
+				keyLabel.setText(UpdateUIMessages.JarVerificationDialog_RootCA); 
+				keyLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));				
+
+				valueText = new Text(group, SWT.MULTI|SWT.BORDER|SWT.WRAP|SWT.V_SCROLL);
+				valueText.setText(_VerificationResult.getVerifierInfo());
+				valueText.setEditable(false);
+				valueText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			}
+		}
+	}
+
+	/*
+	 * Sets the Dialog
+	 */
+	public void setTitleAreaDialog(TitleAreaDialog dialog) {
+		_Dialog = dialog;
+	}
+
+	/*
+	 * 
+	 */
+	public void setMessage(String newMessage, int newType) {
+		super.setMessage(newMessage, newType);
+		if (_Dialog != null) {
+			_Dialog.setMessage(newMessage, newType);
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/JarVerificationService.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/JarVerificationService.java
new file mode 100644
index 0000000..e81bc33
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/JarVerificationService.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.security;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.ui.*;
+/**
+ *
+ */
+public class JarVerificationService implements IVerificationListener {
+
+	/*
+	 * The JarVerifier is a instance variable
+	 * bacause we want to reuse it upon multiple calls
+	 */
+
+	private Shell shell;
+	// keep track of the last verify code.
+	private int lastVerifyCode = -1;
+	
+	/**
+	 * Processed ContentRefernces.  They will be skipped if prompted
+	 * to verify the same reference again.
+	 */
+	private Map processed=new HashMap();
+
+	/*
+	 * If no shell, create a new shell 
+	 */
+	public JarVerificationService() {
+		this(null);
+	}
+	
+	/*
+	 * 
+	 */
+	public JarVerificationService(Shell aShell) {
+		shell = aShell;
+
+		// find the default display and get the active shell
+		if (shell == null) {
+			final Display disp = Display.getDefault();
+			if (disp == null) {
+				shell = new Shell(new Display());
+			} else {
+				disp.syncExec(new Runnable() {
+					public void run() {
+						shell = disp.getActiveShell();
+					}
+				});
+			}
+		}
+	}
+
+	/*
+	 * 
+	 */
+	private int openWizard(IVerificationResult result) {
+		int code;
+		IDialogPage page = new JarVerificationPage(result);
+		JarVerificationDialog dialog =
+				new JarVerificationDialog(shell,page,result);
+		dialog.create();
+		dialog.getShell().setSize(600, 500);
+		dialog.getShell().setText(UpdateUIMessages.JarVerificationDialog_wtitle); 
+		dialog.open();
+		if (dialog.getReturnCode() == JarVerificationDialog.OK) {
+			code = CHOICE_INSTALL_TRUST_ONCE;
+		} else if (dialog.getReturnCode() == JarVerificationDialog.INSTALL_ALL) {
+			code = CHOICE_INSTALL_TRUST_ALWAYS;
+		} else { 
+			code = CHOICE_ABORT;
+		}
+		return code;
+
+	}
+
+	/*
+	 * 
+	 */
+	public int prompt(final IVerificationResult verificationResult){
+		if (!UpdateCore.getPlugin().getPluginPreferences().getBoolean(UpdateCore.P_CHECK_SIGNATURE)) 
+			return CHOICE_INSTALL_TRUST_ALWAYS;
+
+		if (verificationResult.alreadySeen()) return CHOICE_INSTALL_TRUST_ALWAYS;
+		
+		if(see(verificationResult)) return CHOICE_INSTALL_TRUST_ALWAYS;
+		
+		if (lastVerifyCode == CHOICE_INSTALL_TRUST_ALWAYS) return CHOICE_INSTALL_TRUST_ALWAYS;
+
+		switch (verificationResult.getVerificationCode()) {
+			case IVerificationResult.UNKNOWN_ERROR :
+					return CHOICE_ERROR;
+
+			case IVerificationResult.VERIFICATION_CANCELLED:
+					return CHOICE_ABORT;
+
+			// cannot verify it: do not prompt user.
+			case IVerificationResult.TYPE_ENTRY_UNRECOGNIZED: 
+				return CHOICE_INSTALL_TRUST_ALWAYS;				
+			
+			default :
+				{				
+					shell.getDisplay().syncExec(new Runnable() {
+						public void run() {
+							lastVerifyCode = openWizard(verificationResult);
+						}
+					});
+					return lastVerifyCode;
+				}
+		}
+	}
+
+	/**
+	 * Checks whether feature archive has been seen already.
+	 * Remembers the fact that archive is being seen now.
+	 * @param verificationResult
+	 * @return true if the archive has been seen before, false if first time
+	 */
+	private boolean see(final IVerificationResult verificationResult) {
+		String key = verificationResult.getFeature().getVersionedIdentifier().toString()
+			+"/"+verificationResult.getContentReference().getIdentifier(); //$NON-NLS-1$
+		Long value = new Long(verificationResult.getContentReference().getLastModified());
+		Long cachedValue = (Long)processed.get(key);
+		if(value.equals(cachedValue)){
+			return true;
+		}else{
+			processed.put(key, value);
+			return false;
+		}
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/UserValidationDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/UserValidationDialog.java
new file mode 100644
index 0000000..0f61728
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/security/UserValidationDialog.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.security;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.update.internal.ui.*;
+
+/**
+ * User authentication dialog
+ */
+public class UserValidationDialog extends Dialog {
+	protected Text usernameField;
+	protected Text passwordField;
+
+	protected String host;
+	protected String message;
+	protected Authentication userAuthentication = null;
+	/**
+	 * Gets user and password from a user. May be called from any thread
+	 * 
+	 * @return UserAuthentication that contains the userid and the password or
+	 *         <code>null</code> if the dialog has been cancelled
+	 */
+	public static Authentication getAuthentication(final String host,
+			final String message) {
+		class UIOperation implements Runnable {
+			public Authentication authentication;
+			public void run() {
+				authentication = UserValidationDialog.askForAuthentication(
+						host, message);
+			}
+		}
+
+		UIOperation uio = new UIOperation();
+		if (Display.getCurrent() != null) {
+			uio.run();
+		} else {
+			Display.getDefault().syncExec(uio);
+		}
+		return uio.authentication;
+	}
+	/**
+	 * Gets user and password from a user Must be called from UI thread
+	 * 
+	 * @return UserAuthentication that contains the userid and the password or
+	 *         <code>null</code> if the dialog has been cancelled
+	 */
+	protected static Authentication askForAuthentication(String host,
+			String message) {
+		UserValidationDialog ui = new UserValidationDialog(null, host, message); 
+		ui.open();
+		return ui.getAuthentication();
+	}
+	/**
+	 * Creates a new UserValidationDialog.
+	 * 
+	 * @param parentShell
+	 *            parent Shell or null
+	 */
+	protected UserValidationDialog(Shell parentShell, String host,
+			String message) {
+		super(parentShell);
+		this.host = host;
+		this.message = message;
+		setBlockOnOpen(true);
+	}
+	/**
+	 */
+	protected void configureShell(Shell newShell) {
+		super.configureShell(newShell);
+		newShell.setText(UpdateUIMessages.UserVerificationDialog_PasswordRequired); 
+	}
+	/**
+	 */
+	public void create() {
+		super.create();
+		//give focus to username field
+		usernameField.selectAll();
+		usernameField.setFocus();
+	}
+	/**
+	 */
+	protected Control createDialogArea(Composite parent) {
+		Composite main = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 3;
+		main.setLayout(layout);
+		main.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		Label label = new Label(main, SWT.WRAP);
+		String text = UpdateUIMessages.UserVerificationDialog_ConnectTo + host; 
+		text += "\n\n" + message; //$NON-NLS-1$ 
+		label.setText(text);
+		GridData data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 3;
+		label.setLayoutData(data);
+
+		createUsernameFields(main);
+		createPasswordFields(main);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(main,
+				"org.eclipse.update.ui.UserValidationDialog"); //$NON-NLS-1$
+		return main;
+	}
+	/**
+	 * Creates the three widgets that represent the user name entry area.
+	 */
+	protected void createPasswordFields(Composite parent) {
+		new Label(parent, SWT.NONE).setText(UpdateUIMessages.UserVerificationDialog_Password); 
+
+		passwordField = new Text(parent, SWT.BORDER | SWT.PASSWORD);
+		GridData data = new GridData(GridData.FILL_HORIZONTAL);
+		data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.ENTRY_FIELD_WIDTH);
+		passwordField.setLayoutData(data);
+
+		new Label(parent, SWT.NONE); //spacer
+	}
+	/**
+	 * Creates the three widgets that represent the user name entry area.
+	 */
+	protected void createUsernameFields(Composite parent) {
+		new Label(parent, SWT.NONE).setText(UpdateUIMessages.UserVerificationDialog_UserName); 
+
+		usernameField = new Text(parent, SWT.BORDER);
+		GridData data = new GridData(GridData.FILL_HORIZONTAL);
+		data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.ENTRY_FIELD_WIDTH);
+		usernameField.setLayoutData(data);
+
+		new Label(parent, SWT.NONE); //spacer
+	}
+	/**
+	 * Returns the UserAuthentication entered by the user, or null if the user
+	 * canceled.
+	 */
+	public Authentication getAuthentication() {
+		return userAuthentication;
+	}
+	/**
+	 * Notifies that the ok button of this dialog has been pressed.
+	 */
+	protected void okPressed() {
+		userAuthentication = new Authentication(usernameField.getText(),
+				passwordField.getText());
+		super.okPressed();
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ConfigurationPreview.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ConfigurationPreview.java
new file mode 100644
index 0000000..084cbe8
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ConfigurationPreview.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.forms.events.*;
+import org.eclipse.ui.forms.widgets.*;
+import org.eclipse.update.configuration.ILocalSite;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.internal.ui.model.*;
+import org.eclipse.update.operations.*;
+
+public class ConfigurationPreview implements IUpdateModelChangedListener {
+	private ScrolledForm form;
+	private ConfigurationView view;
+	private FormToolkit toolkit;
+	private FormText desc;
+	private FormText taskList;
+	private IPreviewTask[] tasks;
+	
+	public ConfigurationPreview(ConfigurationView view) {
+		this.view = view;
+		UpdateModel model = UpdateUI.getDefault().getUpdateModel();
+		model.addUpdateModelChangedListener(this);
+	}
+	public void dispose() {
+		UpdateModel model = UpdateUI.getDefault().getUpdateModel();
+		model.removeUpdateModelChangedListener(this);
+		toolkit.dispose();
+	}
+
+	public void objectsAdded(Object parent, Object[] children) {
+	}
+	public void objectsRemoved(Object parent, Object[] children) {
+	}
+	public void objectChanged(Object object, String property) {
+	}
+
+	public Control getControl() {
+		return form;
+	}
+
+	public void createControl(Composite parent) {
+		toolkit = new FormToolkit(parent.getDisplay());
+		form = toolkit.createScrolledForm(parent);
+		TableWrapLayout layout = new TableWrapLayout();
+		form.getBody().setLayout(layout);
+		layout.leftMargin = 10;
+		layout.rightMargin = 5;
+		layout.topMargin = 10;
+		layout.horizontalSpacing = 0;
+		layout.verticalSpacing = 20;
+		IHyperlinkListener urlAction = new HyperlinkAdapter() {
+			public void linkActivated(HyperlinkEvent e) {
+				String url = (String) e.getHref();
+				if (url != null)
+					UpdateUI.showURL(url);
+			}
+		};
+		IHyperlinkListener taskAction = new HyperlinkAdapter() {
+			public void linkActivated(HyperlinkEvent e) {
+				String indexArg = (String) e.getHref();
+				try {
+					int index = Integer.parseInt(indexArg);
+					if (tasks != null)
+						tasks[index].run();
+				} catch (NumberFormatException ex) {
+				}
+			}
+		};
+		//taskAction.setStatusLineManager(view.getConfigurationWindow().getStatusLineManager());
+		desc = toolkit.createFormText(form.getBody(), true);
+		desc.setHyperlinkSettings(toolkit.getHyperlinkGroup());
+		desc.addHyperlinkListener(urlAction);
+		desc.setText("", false, false); //$NON-NLS-1$
+		TableWrapData td = new TableWrapData(TableWrapData.FILL_GRAB);
+		desc.setLayoutData(td);
+		taskList = toolkit.createFormText(form.getBody(), false);
+		taskList.setHyperlinkSettings(toolkit.getHyperlinkGroup());
+		taskList.addHyperlinkListener(taskAction); 
+		taskList.setText("", false, false); //$NON-NLS-1$
+		//factory.setHyperlinkUnderlineMode(HyperlinkSettings.UNDERLINE_ROLLOVER);
+		td = new TableWrapData(TableWrapData.FILL_GRAB);
+		taskList.setLayoutData(td);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "org.eclipse.update.ui.SiteForm"); //$NON-NLS-1$
+	}
+	public void setSelection(IStructuredSelection selection) {
+		Object object = selection.getFirstElement();
+		tasks = view.getPreviewTasks(object);
+		String title = getObjectLabel(selection.size()>1?selection:object);
+		form.setText(title);
+		String description = getObjectDescription(selection.size()>1?selection:object);
+		boolean tags = description.startsWith("<form>"); //$NON-NLS-1$
+		desc.setText(description, tags, !tags);
+		String taskText = getTasksText();
+		taskList.setText(taskText, true, false);
+		form.reflow(true);
+	}
+	private String getObjectLabel(Object object) {
+		if (object == null)
+			return ""; //$NON-NLS-1$
+		TreeViewer viewer = view.getTreeViewer();
+		LabelProvider provider = (LabelProvider) viewer.getLabelProvider();
+		if (object instanceof IStructuredSelection) {
+			StringWriter sw = new StringWriter();
+			PrintWriter pw = new PrintWriter(sw);
+			int counter=1;
+			for (Iterator iter = ((IStructuredSelection)object).iterator();
+				iter.hasNext();) {
+				pw.println(counter+". "+provider.getText(iter.next())); //$NON-NLS-1$
+				counter++;
+			}
+			return sw.toString();
+		}
+		return provider.getText(object);
+	}
+	private String getObjectDescription(Object object) {
+		if (object instanceof IFeatureAdapter) {
+			return getFeatureDescription((IFeatureAdapter) object);
+		}
+		if (object instanceof IConfiguredSiteAdapter) {
+			return UpdateUIMessages.ConfigurationPreviewForm_install; 
+		}
+		if (object instanceof ILocalSite) {
+			return UpdateUIMessages.ConfigurationPreviewForm_configDescription; 
+		}
+		return ""; //$NON-NLS-1$
+	}
+	private String getFeatureDescription(IFeatureAdapter adapter) {
+		try {
+			IFeature feature = adapter.getFeature(null);
+			IURLEntry entry = feature.getDescription();
+			if (entry != null) {
+				String text = entry.getAnnotation();
+				if (text != null) {
+					URL url = entry.getURL();
+					if (url == null)
+						return text;
+					else {
+						String link = " <a href=\"" + url //$NON-NLS-1$
+								+ "\">"+UpdateUIMessages.MoreInfoGenerator_moreInfo+"</a>";   //$NON-NLS-1$//$NON-NLS-2$
+						String fullText = "<form><p>" + text + link //$NON-NLS-1$
+								+ "</p></form>"; //$NON-NLS-1$ 
+						return fullText;
+					}
+				}
+			}
+		} catch (CoreException e) {
+		}
+		return ""; //$NON-NLS-1$
+	}
+	private String getTasksText() {
+		if (tasks == null || tasks.length == 0)
+			return "<form/>"; //$NON-NLS-1$
+		boolean hasEnabledTasks = false;
+		for (int i = 0; i < tasks.length; i++) {
+			if (tasks[i].isEnabled()) {
+				hasEnabledTasks = true;
+				break;
+			}
+		}
+		if (!hasEnabledTasks)
+			return "<form/>"; //$NON-NLS-1$
+		StringBuffer buf = new StringBuffer();
+		buf.append("<form><p><b>"); //$NON-NLS-1$
+		buf.append(UpdateUIMessages.ConfigurationPreviewForm_AvailableTasks); 
+		buf.append("</b></p>"); //$NON-NLS-1$
+		for (int i = 0; i < tasks.length; i++) {
+			IPreviewTask task = tasks[i];
+			if (task.isEnabled() == false)
+				continue;
+			buf.append("<li style=\"text\" indent=\"0\"><a href=\"" + i + "\">" //$NON-NLS-1$ //$NON-NLS-2$
+					+ task.getName() + "</a></li>"); //$NON-NLS-1$  
+			buf.append("<li style=\"text\" indent=\"10\" vspace=\"false\">" //$NON-NLS-1$
+					+ task.getDescription() + "</li>"); //$NON-NLS-1$ 
+		}
+		buf.append("</form>"); //$NON-NLS-1$
+		return buf.toString();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ConfigurationView.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ConfigurationView.java
new file mode 100644
index 0000000..f8e7da0
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ConfigurationView.java
@@ -0,0 +1,1387 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.operation.*;
+import org.eclipse.jface.resource.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.*;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.branding.*;
+import org.eclipse.ui.dialogs.*;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.part.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.LocalSite;
+import org.eclipse.update.internal.operations.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.internal.ui.model.*;
+import org.eclipse.update.internal.ui.parts.*;
+import org.eclipse.update.operations.*;
+import org.osgi.framework.*;
+import org.eclipse.core.runtime.Path;
+
+
+/**
+ * Insert the type's description here.
+ * @see ViewPart
+ */
+public class ConfigurationView
+	implements
+		IInstallConfigurationChangedListener,
+		IConfiguredSiteChangedListener,
+		ILocalSiteChangedListener {
+	private TreeViewer treeViewer;
+	private DrillDownAdapter drillDownAdapter;
+	private Action collapseAllAction;
+	private static final String STATE_SHOW_UNCONF = "ConfigurationView.showUnconf"; //$NON-NLS-1$
+	private static final String STATE_SHOW_SITES = "ConfigurationView.showSites"; //$NON-NLS-1$
+	private static final String STATE_SHOW_NESTED_FEATURES =
+		"ConfigurationView.showNestedFeatures"; //$NON-NLS-1$
+
+	private Action showSitesAction;
+	private Action showNestedFeaturesAction;
+	private ReplaceVersionAction swapVersionAction;
+	private FeatureStateAction featureStateAction;
+	private UninstallFeatureAction uninstallFeatureAction;
+	private UnconfigureAndUninstallFeatureAction unconfigureAndUninstallFeatureAction;
+	private FeaturesStateAction featuresStateAction;
+	private UninstallFeaturesAction uninstallFeaturesAction;
+	private UnconfigureAndUninstallFeaturesAction unconfigureAndUninstallFeaturesAction;
+	private InstallOptionalFeatureAction installOptFeatureAction;
+	private Action showUnconfFeaturesAction;
+	private RevertConfigurationAction revertAction;
+	private ShowActivitiesAction showActivitiesAction;
+	private Action propertiesAction;
+	private SiteStateAction siteStateAction;
+	private Action installationHistoryAction;
+	private Action newExtensionLocationAction;
+	private FindUpdatesAction findUpdatesAction;
+	private SashForm splitter;
+	private ConfigurationPreview preview;
+	private Hashtable previewTasks;
+	
+	private IUpdateModelChangedListener modelListener;
+	private boolean refreshLock = false;
+	private Image eclipseImage;
+	private boolean initialized;
+	private ConfigurationManagerWindow configurationWindow;
+
+	class ConfigurationSorter extends ViewerSorter {
+		public int category(Object obj) {
+			// sites
+			if (obj instanceof IConfiguredSiteAdapter) {
+				IConfiguredSite csite =
+					((IConfiguredSiteAdapter) obj).getConfiguredSite();
+				if (csite.isProductSite())
+					return 1;
+				if (csite.isExtensionSite())
+					return 2;
+				return 3;
+			}
+			return super.category(obj);
+		}
+	}
+
+	class LocalSiteProvider
+		extends DefaultContentProvider
+		implements ITreeContentProvider {
+		public void inputChanged(
+			Viewer viewer,
+			Object oldInput,
+			Object newInput) {
+			if (newInput == null)
+				return;
+		}
+
+		public Object[] getChildren(Object parent) {
+			if (parent instanceof UpdateModel) {
+				LocalSiteWorkbenchAdapter localSite = getUIReadyLocalSite(getLocalSite());
+				return (localSite != null) ? new Object[] { localSite }
+				: new Object[0];
+			}
+
+			if (parent instanceof ILocalSite) {
+				Object[] csites = openLocalSite();
+				if (showSitesAction.isChecked())
+					return csites;
+				ArrayList result = new ArrayList();
+				boolean showUnconf = showUnconfFeaturesAction.isChecked();
+				for (int i = 0; i < csites.length; i++) {
+					IConfiguredSiteAdapter adapter =
+						(IConfiguredSiteAdapter) csites[i];
+					Object[] roots = getFeatures(adapter, !showUnconf);
+					for (int j = 0; j < roots.length; j++) {
+						result.add(roots[j]);
+					}
+				}
+				return result.toArray();
+			}
+
+			if (parent instanceof IConfiguredSiteAdapter) {
+				return getFeatures(
+					(IConfiguredSiteAdapter) parent,
+					!showUnconfFeaturesAction.isChecked());
+			}
+			if (parent instanceof ConfiguredFeatureAdapter
+				&& showNestedFeaturesAction.isChecked()) {
+				IFeatureAdapter[] nested =
+					((ConfiguredFeatureAdapter) parent).getIncludedFeatures(
+						null);
+				if (showUnconfFeaturesAction.isChecked())
+					return nested;
+				ArrayList result = new ArrayList();
+				for (int i = 0; i < nested.length; i++) {
+					if (((ConfiguredFeatureAdapter) nested[i]).isConfigured())
+						result.add(nested[i]);
+				}
+				return (IFeatureAdapter[]) result.toArray(
+					new IFeatureAdapter[result.size()]);
+			}
+			return new Object[0];
+		}
+
+		public Object getParent(Object child) {
+			return null;
+		}
+		public boolean hasChildren(Object parent) {
+			if (parent instanceof ConfiguredFeatureAdapter) {
+				if (!showNestedFeaturesAction.isChecked())
+					return false;
+				IFeatureAdapter[] features =
+					((ConfiguredFeatureAdapter) parent).getIncludedFeatures(
+						null);
+
+				if (showUnconfFeaturesAction.isChecked())
+					return features.length > 0;
+
+				for (int i = 0; i < features.length; i++) {
+					if (((ConfiguredFeatureAdapter) features[i])
+						.isConfigured())
+						return true;
+				}
+				return false;
+			}
+			if (parent instanceof ConfiguredSiteAdapter) {
+				IConfiguredSite site =
+					((ConfiguredSiteAdapter) parent).getConfiguredSite();
+				if (site.isEnabled()) {
+					if (!showUnconfFeaturesAction.isChecked())
+						return site.getConfiguredFeatures().length > 0;
+					return site.getFeatureReferences().length > 0;
+				}
+				return (showUnconfFeaturesAction.isChecked());
+			}
+			return true;
+		}
+
+		public Object[] getElements(Object input) {
+			return getChildren(input);
+		}
+	}
+
+	class LocalSiteLabelProvider extends LabelProvider {
+		public String getText(Object obj) {
+			if (obj instanceof ILocalSite) {
+				IProduct product = Platform.getProduct();
+				if (product != null)
+					return product.getName();
+				return UpdateUIMessages.ConfigurationView_current; 
+			}
+
+			if (obj instanceof IConfiguredSiteAdapter) {
+				IConfiguredSite csite =
+					((IConfiguredSiteAdapter) obj).getConfiguredSite();
+				ISite site = csite.getSite();
+				return new File(site.getURL().getFile()).toString();
+			}
+			if (obj instanceof IFeatureAdapter) {
+				try {
+					IFeature feature = ((IFeatureAdapter) obj).getFeature(null);
+					if (feature instanceof MissingFeature) {
+						return NLS.bind(UpdateUIMessages.ConfigurationView_missingFeature, feature.getLabel());
+					}
+					String version = feature.getVersionedIdentifier().getVersion().toString();
+					String pending = ""; //$NON-NLS-1$
+					if (OperationsManager.findPendingOperation(feature)
+						!= null)
+						pending = UpdateUIMessages.ConfigurationView_pending; 
+					return feature.getLabel() + " " + version + pending; //$NON-NLS-1$
+				} catch (CoreException e) {
+					return UpdateUIMessages.ConfigurationView_error; 
+				}
+			}
+			return super.getText(obj);
+		}
+
+		public Image getImage(Object obj) {
+			UpdateLabelProvider provider =
+				UpdateUI.getDefault().getLabelProvider();
+			if (obj instanceof ILocalSite)
+				return eclipseImage;
+
+			if (obj instanceof ConfiguredFeatureAdapter)
+				return getFeatureImage(
+					provider,
+					(ConfiguredFeatureAdapter) obj);
+
+			if (obj instanceof IConfiguredSiteAdapter) {
+				IConfiguredSite csite =
+					((IConfiguredSiteAdapter) obj).getConfiguredSite();
+				int flags =
+					csite.isUpdatable() ? 0 : UpdateLabelProvider.F_LINKED;
+				if (!csite.isEnabled())
+					flags |= UpdateLabelProvider.F_UNCONFIGURED;
+				return provider.get(
+					provider.getLocalSiteDescriptor(csite),
+					flags);
+			}
+			return null;
+		}
+
+		private Image getFeatureImage(
+			UpdateLabelProvider provider,
+			ConfiguredFeatureAdapter adapter) {
+			try {
+				IFeature feature = adapter.getFeature(null);
+				if (feature instanceof MissingFeature) {
+					if (((MissingFeature) feature).isOptional())
+						return provider.get(
+							UpdateUIImages.DESC_NOTINST_FEATURE_OBJ);
+					return provider.get(
+						UpdateUIImages.DESC_FEATURE_OBJ,
+						UpdateLabelProvider.F_ERROR);
+				}
+
+				boolean efix = feature.isPatch();
+				ImageDescriptor baseDesc =
+					efix
+						? UpdateUIImages.DESC_EFIX_OBJ
+						: (adapter.isConfigured()
+							? UpdateUIImages.DESC_FEATURE_OBJ
+							: UpdateUIImages.DESC_UNCONF_FEATURE_OBJ);
+
+				int flags = 0;
+				if (efix && !adapter.isConfigured())
+					flags |= UpdateLabelProvider.F_UNCONFIGURED;
+				if (OperationsManager.findPendingOperation(feature) == null) {
+					ILocalSite localSite = getLocalSite();
+					if (localSite != null) {
+						int code =
+							getStatusCode(
+								feature,
+								localSite.getFeatureStatus(feature));
+						switch (code) {
+							case IFeature.STATUS_UNHAPPY :
+								flags |= UpdateLabelProvider.F_ERROR;
+								break;
+							case IFeature.STATUS_AMBIGUOUS :
+								flags |= UpdateLabelProvider.F_WARNING;
+								break;
+							default :
+								if (adapter.isConfigured()
+									&& adapter.isUpdated())
+									flags |= UpdateLabelProvider.F_UPDATED;
+								break;
+						}
+					}
+				}
+				return provider.get(baseDesc, flags);
+			} catch (CoreException e) {
+				return provider.get(
+					UpdateUIImages.DESC_FEATURE_OBJ,
+					UpdateLabelProvider.F_ERROR);
+			}
+		}
+	}
+
+	class PreviewTask implements IPreviewTask {
+		private String name;
+		private String desc;
+		private IAction action;
+		public PreviewTask(String name, String desc, IAction action) {
+			this.name = name;
+			this.desc = desc;
+			this.action = action;
+		}
+		public IAction getAction() {
+			return action;
+		}
+		public String getName() {
+			if (name != null)
+				return name;
+			return action.getText();
+		}
+		public String getDescription() {
+			return desc;
+		}
+		public void setDescription(String desc) {
+			this.desc = desc;
+		}
+		public void run() {
+			action.run();
+		}
+		public boolean isEnabled() {
+			return action.isEnabled();
+		}
+	}
+
+	public ConfigurationView(ConfigurationManagerWindow window) {
+		UpdateUI.getDefault().getLabelProvider().connect(this);
+		configurationWindow=window;
+		initializeImages();
+	}
+
+	private void initializeImages() {
+		IProduct product = Platform.getProduct();
+		if (product != null) {
+			eclipseImage = getProductImage16(product);
+		}
+		if (eclipseImage==null) {
+			ImageDescriptor edesc = UpdateUIImages.DESC_APP_OBJ;
+			eclipseImage = UpdateUI.getDefault().getLabelProvider().get(edesc);
+		}
+	}
+	
+	private Image getProductImage16(IProduct product) {
+		// Loop through the product window images and
+		// pick the first whose size is 16x16 and does not
+		// alpha transparency type.
+		String windowImagesUrls = product.getProperty(IProductConstants.WINDOW_IMAGES);
+		Image png=null, gif=null, other = null;
+		if (windowImagesUrls != null ) {
+			StringTokenizer st = new StringTokenizer(windowImagesUrls, ","); //$NON-NLS-1$
+			while (st.hasMoreTokens()) {
+				String windowImageURL = st.nextToken();
+				ImageDescriptor edesc=null;
+				try {
+					edesc = ImageDescriptor.createFromURL(new URL(windowImageURL));
+				} catch (MalformedURLException e) {
+					// must be a path relative to the product bundle
+					Bundle productBundle = product.getDefiningBundle();
+					if (productBundle != null) { 
+						URL url = FileLocator.find(productBundle, new Path(windowImageURL), null);
+						if (url != null)
+							edesc = ImageDescriptor.createFromURL(url);
+					}
+				}
+				if (edesc!=null) {
+					Image image = UpdateUI.getDefault().getLabelProvider().get(edesc);
+					Rectangle bounds = image.getBounds();
+					if (bounds.width==16 && bounds.height==16) {
+						// avoid images with TRANSPARENCY_ALPHA
+						//if (image.getImageData().getTransparencyType()!=SWT.TRANSPARENCY_ALPHA)
+						//	return image;
+						//Instead of returning, just store the image based on the
+						// extension.
+						if (windowImageURL.toLowerCase().endsWith(".gif")) //$NON-NLS-1$
+							gif = image;
+						else if (windowImageURL.toLowerCase().endsWith(".png")) //$NON-NLS-1$
+							png = image;
+						else
+							other = image;
+					}
+				}
+			}
+		}
+		Image choice = null;
+		// Pick png first because of transparency
+		if (png!=null) {
+			choice = png;
+		}
+		// Pick other format
+		else if (other!=null)
+			choice = other;
+		// Pick gif
+		else if (gif!=null)
+			choice = gif;
+		return choice;
+	}
+
+	public void initProviders() {
+		treeViewer.setContentProvider(new LocalSiteProvider());
+		treeViewer.setLabelProvider(new LocalSiteLabelProvider());
+		treeViewer.setInput(UpdateUI.getDefault().getUpdateModel());
+		treeViewer.setSorter(new ConfigurationSorter());
+		ILocalSite localSite = getLocalSite();
+		if (localSite != null)
+			localSite.addLocalSiteChangedListener(this);
+
+		modelListener = new IUpdateModelChangedListener() {
+			public void objectsAdded(Object parent, Object[] children) {
+			}
+			public void objectsRemoved(Object parent, Object[] children) {
+			}
+			public void objectChanged(final Object obj, String property) {
+				if (refreshLock)
+					return;
+				Control control = getControl();
+				if (!control.isDisposed()) {
+					control.getDisplay().asyncExec(new Runnable() {
+						public void run() {
+							treeViewer.refresh();
+							handleSelectionChanged(
+								(IStructuredSelection) treeViewer
+									.getSelection());
+						}
+					});
+				}
+			}
+		};
+		OperationsManager.addUpdateModelChangedListener(modelListener);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(
+			getControl(),
+			"org.eclipse.update.ui.ConfigurationView"); //$NON-NLS-1$
+	}
+
+	private ILocalSite getLocalSite() {
+		try {
+			return SiteManager.getLocalSite();
+		} catch (CoreException e) {
+			UpdateUI.logException(e);
+			return null;
+		}
+	}
+
+	private Object[] openLocalSite() {
+		final Object[][] bag = new Object[1][];
+		BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
+			public void run() {
+				ILocalSite localSite = getLocalSite();
+				if (localSite == null)
+					return;
+				IInstallConfiguration config =
+					getLocalSite().getCurrentConfiguration();
+				IConfiguredSite[] sites = config.getConfiguredSites();
+				Object[] result = new Object[sites.length];
+				for (int i = 0; i < sites.length; i++) {
+					result[i] = new ConfiguredSiteAdapter(config, sites[i]);
+				}
+				if (!initialized) {
+					config.addInstallConfigurationChangedListener(
+						ConfigurationView.this);
+					initialized = true;
+				}
+				bag[0] = result;
+			}
+		});
+		return bag[0];
+	}
+
+	public void dispose() {
+		UpdateUI.getDefault().getLabelProvider().disconnect(this);
+		if (initialized) {
+			ILocalSite localSite = getLocalSite();
+			if (localSite != null) {
+				localSite.removeLocalSiteChangedListener(this);
+				IInstallConfiguration config =
+					localSite.getCurrentConfiguration();
+				config.removeInstallConfigurationChangedListener(this);
+			}
+			initialized = false;
+		}
+		OperationsManager.removeUpdateModelChangedListener(modelListener);
+		if (preview != null)
+			preview.dispose();
+		//super.dispose();
+	}
+
+	protected void makeActions() {
+		collapseAllAction = new Action() {
+			public void run() {
+				treeViewer.getControl().setRedraw(false);
+				treeViewer.collapseToLevel(
+					treeViewer.getInput(),
+					TreeViewer.ALL_LEVELS);
+				treeViewer.getControl().setRedraw(true);
+			}
+		};
+		collapseAllAction.setText(UpdateUIMessages.ConfigurationView_collapseLabel); 
+		collapseAllAction.setToolTipText(UpdateUIMessages.ConfigurationView_collapseTooltip); 
+		collapseAllAction.setImageDescriptor(UpdateUIImages.DESC_COLLAPSE_ALL);
+
+		drillDownAdapter = new DrillDownAdapter(treeViewer);
+
+		featureStateAction = new FeatureStateAction(this.getConfigurationWindow().getShell(), ""); //$NON-NLS-1$
+		featuresStateAction = new FeaturesStateAction(this.getConfigurationWindow().getShell(), ""); //$NON-NLS-1$
+
+		siteStateAction = new SiteStateAction(getConfigurationWindow().getShell());
+
+		revertAction = new RevertConfigurationAction(getConfigurationWindow().getShell(),UpdateUIMessages.ConfigurationView_revertLabel); 
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(
+			revertAction,
+			"org.eclipse.update.ui.CofigurationView_revertAction"); //$NON-NLS-1$
+
+		installationHistoryAction =
+			new InstallationHistoryAction(getConfigurationWindow().getShell(),
+				UpdateUIMessages.ConfigurationView_installHistory, 
+				UpdateUIImages.DESC_HISTORY_OBJ);
+		installationHistoryAction.setToolTipText(installationHistoryAction.getText());
+		
+		newExtensionLocationAction =
+			new NewExtensionLocationAction(getConfigurationWindow().getShell(),
+				UpdateUIMessages.ConfigurationView_extLocation, 
+				UpdateUIImages.DESC_ESITE_OBJ);
+		
+		propertiesAction =
+			new PropertyDialogAction(
+				getConfigurationWindow(),
+				treeViewer);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(
+			propertiesAction,
+			"org.eclipse.update.ui.CofigurationView_propertiesAction"); //$NON-NLS-1$
+
+		uninstallFeatureAction = new UninstallFeatureAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_uninstall); 
+		unconfigureAndUninstallFeatureAction = new UnconfigureAndUninstallFeatureAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_uninstall); 
+		
+		uninstallFeaturesAction = new UninstallFeaturesAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_uninstall); 
+		unconfigureAndUninstallFeaturesAction = new UnconfigureAndUninstallFeaturesAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_unconfigureAndUninstall); 
+
+		
+		installOptFeatureAction =
+			new InstallOptionalFeatureAction(
+				getControl().getShell(),
+				UpdateUIMessages.ConfigurationView_install); 
+
+		swapVersionAction = new ReplaceVersionAction(getConfigurationWindow().getShell(), UpdateUIMessages.ConfigurationView_anotherVersion); 
+
+		findUpdatesAction =
+			new FindUpdatesAction(configurationWindow, UpdateUIMessages.ConfigurationView_findUpdates); 
+
+		showActivitiesAction = new ShowActivitiesAction(getControl().getShell(), UpdateUIMessages.ConfigurationView_showActivitiesLabel); 
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(
+			showActivitiesAction,
+			"org.eclipse.update.ui.ConfigurationView_showActivitiesAction"); //$NON-NLS-1$
+
+		makeShowUnconfiguredFeaturesAction();
+		makeShowSitesAction();
+		makeShowNestedFeaturesAction();
+		makePreviewTasks();
+		configurationWindow.setPropertiesActionHandler(propertiesAction);
+	}
+
+	private void makeShowNestedFeaturesAction() {
+		final Preferences pref = UpdateUI.getDefault().getPluginPreferences();
+		pref.setDefault(STATE_SHOW_NESTED_FEATURES, true);
+		showNestedFeaturesAction = new Action() {
+			public void run() {
+				treeViewer.refresh();
+				pref.setValue(
+					STATE_SHOW_NESTED_FEATURES,
+					showNestedFeaturesAction.isChecked());
+			}
+		};
+		showNestedFeaturesAction.setText(UpdateUIMessages.ConfigurationView_showNestedFeatures); 
+		showNestedFeaturesAction.setImageDescriptor(
+			UpdateUIImages.DESC_SHOW_HIERARCHY);
+		showNestedFeaturesAction.setDisabledImageDescriptor(
+			UpdateUIImages.DESC_SHOW_HIERARCHY_D);
+
+		showNestedFeaturesAction.setChecked(
+			pref.getBoolean(STATE_SHOW_NESTED_FEATURES));
+		showNestedFeaturesAction.setToolTipText(UpdateUIMessages.ConfigurationView_showNestedTooltip); 
+	}
+
+	private void makeShowSitesAction() {
+		final Preferences pref = UpdateUI.getDefault().getPluginPreferences();
+		pref.setDefault(STATE_SHOW_SITES, true);
+		showSitesAction = new Action() {
+			public void run() {
+				treeViewer.refresh();
+				pref.setValue(STATE_SHOW_SITES, showSitesAction.isChecked());
+				UpdateUI.getDefault().savePluginPreferences();
+			}
+		};
+		showSitesAction.setText(UpdateUIMessages.ConfigurationView_showInstall); 
+		showSitesAction.setImageDescriptor(UpdateUIImages.DESC_LSITE_OBJ);
+		showSitesAction.setChecked(pref.getBoolean(STATE_SHOW_SITES));
+		showSitesAction.setToolTipText(UpdateUIMessages.ConfigurationView_showInstallTooltip); 
+	}
+
+	private void makeShowUnconfiguredFeaturesAction() {
+		final Preferences pref = UpdateUI.getDefault().getPluginPreferences();
+		pref.setDefault(STATE_SHOW_UNCONF, false);
+		showUnconfFeaturesAction = new Action() {
+			public void run() {
+				pref.setValue(
+					STATE_SHOW_UNCONF,
+					showUnconfFeaturesAction.isChecked());
+				UpdateUI.getDefault().savePluginPreferences();
+				treeViewer.refresh();
+			}
+		};
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(
+			showUnconfFeaturesAction,
+			"org.eclipse.update.ui.CofigurationView_showUnconfFeaturesAction"); //$NON-NLS-1$
+		showUnconfFeaturesAction.setText(UpdateUIMessages.ConfigurationView_showDisabled); 
+		showUnconfFeaturesAction.setImageDescriptor(
+			UpdateUIImages.DESC_UNCONF_FEATURE_OBJ);
+		showUnconfFeaturesAction.setChecked(pref.getBoolean(STATE_SHOW_UNCONF));
+		showUnconfFeaturesAction.setToolTipText(UpdateUIMessages.ConfigurationView_showDisabledTooltip); 
+	}
+
+	protected void fillActionBars(ToolBarManager tbm) {
+		tbm.add(showSitesAction);
+		tbm.add(showNestedFeaturesAction);
+		tbm.add(showUnconfFeaturesAction);
+		tbm.add(new Separator());
+		drillDownAdapter.addNavigationActions(tbm);
+		tbm.add(new Separator());
+		tbm.add(collapseAllAction);
+		tbm.add(new Separator());
+		tbm.add(installationHistoryAction);
+	}
+
+	protected Object getSelectedObject() {
+		ISelection selection = treeViewer.getSelection();
+		if (selection instanceof IStructuredSelection
+			&& !selection.isEmpty()) {
+			IStructuredSelection ssel = (IStructuredSelection) selection;
+			
+			if (ssel.size() == 1)
+				return ssel.getFirstElement();
+			else
+				return ssel.toArray();
+		}
+		return null;
+	}
+
+	protected void fillContextMenu(IMenuManager manager) {
+		Object obj = getSelectedObject();
+		boolean areMultipleFeaturesSelected = true;
+		
+		if ( obj instanceof Object[]) {
+			Object[] array = (Object[])obj;
+			for( int i = 0; i < array.length; i++) {
+				if (!(array[i] instanceof ConfiguredFeatureAdapter)) {
+					areMultipleFeaturesSelected = false;
+				}
+			}
+		} else {
+			areMultipleFeaturesSelected = false;
+		}
+
+		if (obj instanceof ILocalSite) {
+			manager.add(findUpdatesAction);
+			manager.add(revertAction);
+		} else if (obj instanceof IConfiguredSiteAdapter) {
+			manager.add(siteStateAction);
+		}
+
+		if (obj instanceof ILocalSite
+			|| obj instanceof IConfiguredSiteAdapter) {
+			manager.add(new Separator());
+			MenuManager mgr = new MenuManager(UpdateUIMessages.ConfigurationView_new); 
+			mgr.add(newExtensionLocationAction);
+			manager.add(mgr);
+			manager.add(new Separator());
+		} else if ( (obj instanceof ConfiguredFeatureAdapter) && !areMultipleFeaturesSelected){
+			try {
+				
+				MenuManager mgr = new MenuManager(UpdateUIMessages.ConfigurationView_replaceWith); 
+				
+				manager.add(findUpdatesAction);
+				manager.add(new Separator());
+				
+				mgr.add(swapVersionAction);
+				manager.add(mgr);
+
+				manager.add(featureStateAction);
+				
+
+				IFeature feature =
+					((ConfiguredFeatureAdapter) obj).getFeature(null);
+				if (feature instanceof MissingFeature) {
+					manager.add(installOptFeatureAction);
+				} else {
+					boolean configured = ((ConfiguredFeatureAdapter)obj).isConfigured();
+					if (!configured)
+						manager.add(uninstallFeatureAction);
+					else
+						manager.add(unconfigureAndUninstallFeatureAction);
+				}
+				manager.add(new Separator());
+
+			} catch (CoreException e) {
+			}
+		} else if (areMultipleFeaturesSelected) {
+
+				manager.add(findUpdatesAction);
+				manager.add(new Separator());
+
+				manager.add(featuresStateAction);
+				
+				manager.add(uninstallFeaturesAction);
+				manager.add(unconfigureAndUninstallFeaturesAction);
+				
+				manager.add(new Separator());
+
+		}
+
+		drillDownAdapter.addNavigationActions(manager);
+
+		if (obj instanceof ILocalSite) {
+			manager.add(new Separator());
+			manager.add(installationHistoryAction);
+		}
+
+		if (obj instanceof IFeatureAdapter
+			|| obj instanceof ILocalSite
+			|| obj instanceof IConfiguredSiteAdapter) {
+			manager.add(new Separator());
+			manager.add(propertiesAction);
+		}
+	}
+
+	public void installSiteAdded(IConfiguredSite csite) {
+		asyncRefresh();
+	}
+	public void installSiteRemoved(IConfiguredSite site) {
+		asyncRefresh();
+	}
+	public void featureInstalled(IFeature feature) {
+		asyncRefresh();
+	}
+	public void featureRemoved(IFeature feature) {
+		asyncRefresh();
+	}
+	public void featureConfigured(IFeature feature) {
+	}
+
+	public void featureUnconfigured(IFeature feature) {
+	}
+
+	public void currentInstallConfigurationChanged(IInstallConfiguration configuration) {
+		asyncRefresh();
+	}
+
+	public void installConfigurationRemoved(IInstallConfiguration configuration) {
+		asyncRefresh();
+	}
+
+	private void asyncRefresh() {
+		Display display = SWTUtil.getStandardDisplay();
+		if (display == null)
+			return;
+		if (getControl().isDisposed())
+			return;
+		display.asyncExec(new Runnable() {
+			public void run() {
+				if (!getControl().isDisposed())
+					treeViewer.refresh();
+			}
+		});
+	}
+
+	private Object[] getFeatures(
+		final IConfiguredSiteAdapter siteAdapter,
+		final boolean configuredOnly) {
+		final IConfiguredSite csite = siteAdapter.getConfiguredSite();
+		final Object[][] bag = new Object[1][];
+		refreshLock = true;
+
+		IRunnableWithProgress op = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) {
+				ArrayList result = new ArrayList();
+				IFeatureReference[] refs;
+
+				if (configuredOnly)
+					refs = csite.getConfiguredFeatures();
+				else {
+					ISite site = csite.getSite();
+					refs = site.getFeatureReferences();
+				}
+				monitor.beginTask(
+					UpdateUIMessages.ConfigurationView_loading, 
+					refs.length);
+
+				for (int i = 0; i < refs.length; i++) {
+					IFeatureReference ref = refs[i];
+					IFeature feature;
+					try {
+						monitor.subTask(ref.getURL().toString());
+						feature = ref.getFeature(null);
+					} catch (CoreException e) {
+						feature =
+							new MissingFeature(ref.getSite(), ref.getURL());
+					}
+					monitor.worked(1);
+					result.add(
+						new ConfiguredFeatureAdapter(
+							siteAdapter,
+							feature,
+							csite.isConfigured(feature),
+							false,
+							false));
+				}
+				monitor.done();
+				bag[0] = getRootFeatures(result);
+			}
+		};
+
+		try {
+			if (configurationWindow.getShell().isVisible())
+				configurationWindow.run(true, false, op);
+			else
+				op.run(new NullProgressMonitor());
+		} catch (InterruptedException e) {
+		} catch (InvocationTargetException e) {
+		} finally {
+			refreshLock = false;
+		}
+		return bag[0];
+	}
+
+	private Object[] getRootFeatures(ArrayList list) {
+		ArrayList children = new ArrayList();
+		ArrayList result = new ArrayList();
+		try {
+			for (int i = 0; i < list.size(); i++) {
+				ConfiguredFeatureAdapter cf =
+					(ConfiguredFeatureAdapter) list.get(i);
+				IFeature feature = cf.getFeature(null);
+				if (feature != null)
+					addChildFeatures(
+						feature,
+						children,
+						cf.isConfigured());
+			}
+			for (int i = 0; i < list.size(); i++) {
+				ConfiguredFeatureAdapter cf =
+					(ConfiguredFeatureAdapter) list.get(i);
+				IFeature feature = cf.getFeature(null);
+				if (feature != null
+					&& isChildFeature(feature, children) == false)
+					result.add(cf);
+			}
+		} catch (CoreException e) {
+			return list.toArray();
+		}
+		return result.toArray();
+	}
+
+	private void addChildFeatures(
+		IFeature feature,
+		ArrayList children,
+		boolean configured) {
+		try {
+			IIncludedFeatureReference[] included =
+				feature.getIncludedFeatureReferences();
+			for (int i = 0; i < included.length; i++) {
+				IFeature childFeature;
+				try {
+					childFeature =
+						included[i].getFeature(null);
+				} catch (CoreException e) {
+					childFeature = new MissingFeature(included[i]);
+				}
+				children.add(childFeature);
+			}
+		} catch (CoreException e) {
+			UpdateUI.logException(e);
+		}
+	}
+
+	private boolean isChildFeature(IFeature feature, ArrayList children) {
+		for (int i = 0; i < children.size(); i++) {
+			IFeature child = (IFeature) children.get(i);
+			if (feature
+				.getVersionedIdentifier()
+				.equals(child.getVersionedIdentifier()))
+				return true;
+		}
+		return false;
+	}
+
+	protected void handleDoubleClick(DoubleClickEvent e) {
+		if (e.getSelection() instanceof IStructuredSelection) {
+			IStructuredSelection ssel = (IStructuredSelection) e.getSelection();
+			
+			Object obj = ssel.getFirstElement();
+			if (obj!=null)
+				propertiesAction.run();
+		}
+	}
+
+	public void createPartControl(Composite parent) {
+		splitter = new SashForm(parent, SWT.HORIZONTAL);
+		splitter.setLayoutData(new GridData(GridData.FILL_BOTH));
+		Composite leftContainer = createLineContainer(splitter);
+		Composite rightContainer = createLineContainer(splitter);
+		createTreeViewer(leftContainer);
+		makeActions();
+		createVerticalLine(leftContainer);
+		createVerticalLine(rightContainer);
+		preview = new ConfigurationPreview(this);
+		preview.createControl(rightContainer);
+		preview.getControl().setLayoutData(
+			new GridData(GridData.FILL_BOTH));
+		splitter.setWeights(new int[] { 2, 3 });
+		fillActionBars(getConfigurationWindow().getToolBarManager());
+
+		treeViewer.expandToLevel(2);
+
+		if (treeViewer.getTree().getItemCount() > 0) {
+			TreeItem[] items = treeViewer.getTree().getItems();
+			treeViewer.getTree().setSelection(new TreeItem[] { items[0] });
+			handleSelectionChanged(new StructuredSelection(items[0].getData()));
+		}
+	}
+
+	private void createTreeViewer(Composite parent) {
+		treeViewer =
+			new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+		treeViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
+		treeViewer.setUseHashlookup(true);
+		initProviders();
+
+		MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+		menuMgr.setRemoveAllWhenShown(true);
+		menuMgr.addMenuListener(new IMenuListener() {
+			public void menuAboutToShow(IMenuManager manager) {
+				manager.add(new GroupMarker("additions")); //$NON-NLS-1$
+				fillContextMenu(manager);
+			}
+		});
+
+		treeViewer.getControl().setMenu(
+			menuMgr.createContextMenu(treeViewer.getControl()));
+
+		treeViewer
+			.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				handleSelectionChanged(event);
+			}
+		});
+
+		treeViewer.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+				handleDoubleClick(event);
+			}
+		});
+
+	}
+
+	public TreeViewer getTreeViewer() {
+		return treeViewer;
+	}
+
+	private Composite createLineContainer(Composite parent) {
+		Composite container = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginWidth = layout.marginHeight = 0;
+		layout.horizontalSpacing = 0;
+		container.setLayout(layout);
+		return container;
+	}
+
+	private void createVerticalLine(Composite parent) {
+		Label line = new Label(parent, SWT.SEPARATOR | SWT.VERTICAL);
+		GridData gd = new GridData(GridData.VERTICAL_ALIGN_FILL);
+		gd.widthHint = 1;
+		line.setLayoutData(gd);
+	}
+
+	public Control getControl() {
+		return splitter;
+	}
+
+	private int getStatusCode(IFeature feature, IStatus status) {
+		int code = status.getCode();
+		if (code == IFeature.STATUS_UNHAPPY) {
+			if (status.isMultiStatus()) {
+				IStatus[] children = status.getChildren();
+				for (int i = 0; i < children.length; i++) {
+					IStatus child = children[i];
+					if (child.isMultiStatus()
+						|| child.getCode() != IFeature.STATUS_DISABLED)
+						return code;
+				}
+				// If we are here, global status is unhappy
+				// because one or more included features
+				// is disabled.
+				if (UpdateUtils.hasObsoletePatches(feature)) {
+					// The disabled included features
+					// are old patches that are now
+					// subsumed by better versions of
+					// the features they were designed to
+					// patch.
+					return IFeature.STATUS_HAPPY;
+				}
+			}
+		}
+		return code;
+	}
+
+	protected void handleSelectionChanged(IStructuredSelection ssel) {
+		Object obj = ssel.getFirstElement();
+		
+		boolean areMultipleFeaturesSelected = true;
+		
+		if (ssel.size() > 1) {
+			Object[] array = ssel.toArray();
+			for( int i = 0; i < array.length; i++) {
+				if (!(array[i] instanceof ConfiguredFeatureAdapter)) {
+					areMultipleFeaturesSelected = false;
+				}
+			}
+		} else {
+			areMultipleFeaturesSelected = false;
+		}
+		
+		if (ssel.size()>1)
+			obj = null;
+		
+		if (obj!=null) {
+			ILabelProvider labelProvider = (ILabelProvider)treeViewer.getLabelProvider();
+			String text = labelProvider.getText(obj);
+			//Image img = labelProvider.getImage(obj);
+			Image img = null;
+			configurationWindow.updateStatusLine(text, img);
+		}
+		else
+			configurationWindow.updateStatusLine(null, null);
+		
+		if (areMultipleFeaturesSelected && (ssel.size() > 1)) {
+			
+			uninstallFeaturesAction.setSelection(ssel);
+			uninstallFeaturesAction.setEnabled(uninstallFeatureAction.canExecuteAction());
+			unconfigureAndUninstallFeaturesAction.setSelection(ssel);
+			unconfigureAndUninstallFeaturesAction.setEnabled(unconfigureAndUninstallFeatureAction.canExecuteAction());
+			featuresStateAction.setSelection(ssel);
+			featuresStateAction.setEnabled(featuresStateAction.canExecuteAction());
+			propertiesAction.setEnabled(false);
+			preview.setSelection(ssel);
+			return;
+		}
+		
+		if (obj instanceof IFeatureAdapter) {
+			try {
+				propertiesAction.setEnabled(true);
+				ConfiguredFeatureAdapter adapter = (ConfiguredFeatureAdapter) obj;
+				IFeature feature = adapter.getFeature(null);
+
+				boolean missing = feature instanceof MissingFeature;
+				boolean enable = !missing
+						&& ((adapter.isOptional() || !adapter.isIncluded()));
+
+				uninstallFeatureAction.setSelection(ssel);
+				uninstallFeatureAction.setEnabled(enable
+						&& uninstallFeatureAction.canExecuteAction());
+				unconfigureAndUninstallFeatureAction.setSelection(ssel);
+				unconfigureAndUninstallFeatureAction.setEnabled(enable && unconfigureAndUninstallFeatureAction.canExecuteAction());
+				if (adapter.isConfigured())
+					setDescriptionOnTask(
+							uninstallFeatureAction,
+							adapter,
+							UpdateUIMessages.ConfigurationView_uninstallDesc2);
+				else
+					setDescriptionOnTask(
+							uninstallFeatureAction,
+							adapter,
+							UpdateUIMessages.ConfigurationView_uninstallDesc);
+
+				featureStateAction.setSelection(ssel);
+				featureStateAction.setEnabled(enable);
+				swapVersionAction.setEnabled(false);
+				if (enable) {
+					IFeature[] features = UpdateUtils.getInstalledFeatures(
+							feature, false);
+					if (features.length > 1) {
+						if (adapter.isConfigured()) {
+							// We only enable replace action if configured
+							// and selected. bug 74019
+							swapVersionAction.setEnabled(true);
+							swapVersionAction.setCurrentFeature(feature);
+							swapVersionAction.setFeatures(features);
+						} else {
+							// If we are not configured and another version is
+							// we want to disable StateAction. bug 74019
+							features = UpdateUtils.getInstalledFeatures(
+									feature, true);
+							if (features.length > 0) {
+								featureStateAction.setEnabled(false);
+							}
+						}
+					}
+				}
+
+				findUpdatesAction.setEnabled(false);
+				if (enable && adapter.isConfigured()) {
+					if (feature.getUpdateSiteEntry() != null) {
+						findUpdatesAction.setFeature(feature);
+						findUpdatesAction.setEnabled(true);
+					}
+				}
+				
+				if (missing) {
+					MissingFeature mf = (MissingFeature) feature;
+					installOptFeatureAction.setEnabled(mf.isOptional()
+							&& mf.getOriginatingSiteURL() != null);
+					installOptFeatureAction.setFeature(mf);
+				} else {
+					installOptFeatureAction.setEnabled(false);
+				}
+			} catch (CoreException ex) {
+				UpdateUI.logException(ex);
+			}
+		}
+		if (obj instanceof ILocalSite) {
+			propertiesAction.setEnabled(true);
+			findUpdatesAction.setEnabled(true);
+			findUpdatesAction.setFeature(null);
+			ILocalSite site = getLocalSite();
+			revertAction.setEnabled(site != null
+					&& site.getConfigurationHistory().length > 1);
+		} else if (obj instanceof IConfiguredSiteAdapter) {
+			siteStateAction.setSite(((IConfiguredSiteAdapter) obj)
+					.getConfiguredSite());
+			siteStateAction.setEnabled(true);
+		}
+		
+		if (areMultipleFeaturesSelected) {
+			uninstallFeaturesAction.setSelection(ssel);
+			uninstallFeaturesAction.setEnabled(uninstallFeatureAction.canExecuteAction());
+			unconfigureAndUninstallFeaturesAction.setSelection(ssel);
+			unconfigureAndUninstallFeaturesAction.setEnabled(unconfigureAndUninstallFeatureAction.canExecuteAction());
+			featuresStateAction.setSelection(ssel);
+			featuresStateAction.setEnabled(featuresStateAction.canExecuteAction());
+		}
+		
+		preview.setSelection(ssel);
+	}
+
+	protected void handleSelectionChanged(SelectionChangedEvent e) {
+		handleSelectionChanged(((IStructuredSelection) e.getSelection()));
+	}
+
+	private void setDescriptionOnTask(IAction action, ConfiguredFeatureAdapter adapter, String desc) {
+		IPreviewTask[] tasks = getPreviewTasks(adapter);
+		if (tasks == null)
+			return;
+		for (int i=0; i<tasks.length; i++)
+			if (tasks[i].getAction() == action)
+				tasks[i].setDescription(desc);
+	}
+	
+	private void makePreviewTasks() {
+		previewTasks = new Hashtable();
+		Class key;
+		ArrayList array = new ArrayList();
+		// local site tasks
+		key = ILocalSite.class;
+		array.add(
+			new PreviewTask(
+				UpdateUIMessages.ConfigurationView_updateLabel, 
+				UpdateUIMessages.ConfigurationView_updateDesc, 
+				findUpdatesAction));
+		array.add(
+			new PreviewTask(
+				UpdateUIMessages.ConfigurationView_installHistLabel, 
+				UpdateUIMessages.ConfigurationView_installHistDesc, 
+				installationHistoryAction));
+		array.add(
+			new PreviewTask(
+				UpdateUIMessages.ConfigurationView_activitiesLabel, 
+				UpdateUIMessages.ConfigurationView_activitiesDesc, 
+				showActivitiesAction));
+		array.add(
+				new PreviewTask(
+					UpdateUIMessages.ConfigurationView_extLocLabel, 
+					UpdateUIMessages.ConfigurationView_extLocDesc, 
+					newExtensionLocationAction));
+		array.add(
+				new PreviewTask(
+					UpdateUIMessages.ConfigurationView_revertPreviousLabel, 
+					UpdateUIMessages.ConfigurationView_revertPreviousDesc, 
+					revertAction));
+
+		previewTasks.put(key, array.toArray(new IPreviewTask[array.size()]));
+
+		// configured site tasks
+		array.clear();
+		key = IConfiguredSiteAdapter.class;
+		array.add(
+			new PreviewTask(
+				null,
+				UpdateUIMessages.ConfigurationView_enableLocDesc, 
+				siteStateAction));
+		array.add(
+			new PreviewTask(
+				UpdateUIMessages.ConfigurationView_extLocLabel, 
+				UpdateUIMessages.ConfigurationView_extLocDesc, 
+				newExtensionLocationAction));
+		array.add(
+			new PreviewTask(
+				UpdateUIMessages.ConfigurationView_propertiesLabel, 
+				UpdateUIMessages.ConfigurationView_installPropDesc, 
+				propertiesAction));
+		previewTasks.put(key, array.toArray(new IPreviewTask[array.size()]));
+
+		// feature adapter tasks
+		array.clear();
+		key = IFeatureAdapter.class;
+		array.add(
+				new PreviewTask(
+					UpdateUIMessages.ConfigurationView_scanLabel, 
+					UpdateUIMessages.ConfigurationView_scanDesc, 
+					findUpdatesAction));
+		array.add(
+			new PreviewTask(
+				UpdateUIMessages.ConfigurationView_replaceVersionLabel, 
+				UpdateUIMessages.ConfigurationView_replaceVersionDesc, 
+				swapVersionAction));
+		array.add(
+			new PreviewTask(
+				null,
+				UpdateUIMessages.ConfigurationView_enableFeatureDesc, 
+				featureStateAction));
+		array.add(
+			new PreviewTask(
+				UpdateUIMessages.ConfigurationView_installOptionalLabel, 
+				UpdateUIMessages.ConfigurationView_installOptionalDesc, 
+				installOptFeatureAction));
+		array.add(
+			new PreviewTask(
+				UpdateUIMessages.ConfigurationView_uninstallLabel, 
+				UpdateUIMessages.ConfigurationView_uninstallDesc, 
+				uninstallFeatureAction));
+		array.add(
+			new PreviewTask(
+				UpdateUIMessages.ConfigurationView_featurePropLabel, 
+				UpdateUIMessages.ConfigurationView_featurePropDesc, 
+				propertiesAction));
+		previewTasks.put(key, array.toArray(new IPreviewTask[array.size()]));
+	}
+
+	public IPreviewTask[] getPreviewTasks(Object object) {
+		IPreviewTask[] tasks = null;
+
+		if (object instanceof IFeatureAdapter)
+			tasks = (IPreviewTask[]) previewTasks.get(IFeatureAdapter.class);
+		if (object instanceof ILocalSite)
+			tasks = (IPreviewTask[]) previewTasks.get(ILocalSite.class);
+		if (object instanceof IConfiguredSiteAdapter)
+			tasks =
+				(IPreviewTask[]) previewTasks.get(IConfiguredSiteAdapter.class);
+		return (tasks != null) ? tasks : new IPreviewTask[0];
+	}
+
+	ConfigurationManagerWindow getConfigurationWindow(){
+		return configurationWindow;
+	}
+	
+	private LocalSiteWorkbenchAdapter getUIReadyLocalSite(ILocalSite localSite) {
+			
+		return new LocalSiteWorkbenchAdapter(localSite);
+			
+	}
+	
+	
+
+}
+
+class LocalSiteWorkbenchAdapter extends LocalSite implements IWorkbenchAdapter {
+	
+	private ILocalSite localSite;
+	
+	public LocalSiteWorkbenchAdapter(ILocalSite localSite) {
+		this.localSite = localSite;
+	}
+	
+	public Object[] getChildren(Object o) {
+		return null;
+	}
+
+	public ImageDescriptor getImageDescriptor(Object object) {
+		return null;
+	}
+
+	public String getLabel(Object o) {
+		return Platform.getProduct().getName();
+	}
+
+	public Object getParent(Object o) {
+		return null;
+	}
+
+	public void addConfiguration(IInstallConfiguration config) {
+		localSite.addConfiguration(config);
+	}
+
+	public void addLocalSiteChangedListener(ILocalSiteChangedListener listener) {
+		localSite.addLocalSiteChangedListener(listener);
+	}
+
+	public IInstallConfiguration addToPreservedConfigurations(IInstallConfiguration configuration) throws CoreException {
+		return localSite.addToPreservedConfigurations(configuration);
+	}
+
+	public IInstallConfiguration cloneCurrentConfiguration() throws CoreException {
+		return localSite.cloneCurrentConfiguration();
+	}
+
+	public IInstallConfiguration[] getConfigurationHistory() {
+		return localSite.getConfigurationHistory();
+	}
+
+	public IInstallConfiguration getCurrentConfiguration() {
+		return localSite.getCurrentConfiguration();
+	}
+
+	public IStatus getFeatureStatus(IFeature feature) throws CoreException {
+		return localSite.getFeatureStatus(feature);
+	}
+
+	public int getMaximumHistoryCount() {
+		return localSite.getMaximumHistoryCount();
+	}
+
+	public IInstallConfiguration[] getPreservedConfigurations() {
+		return localSite.getPreservedConfigurations();
+	}
+
+	public void removeFromPreservedConfigurations(IInstallConfiguration configuration) {
+		localSite.removeFromPreservedConfigurations(configuration);
+	}
+
+	public void removeLocalSiteChangedListener(ILocalSiteChangedListener listener) {
+		localSite.removeLocalSiteChangedListener(listener);
+	}
+
+	public void revertTo(IInstallConfiguration configuration, IProgressMonitor monitor, IProblemHandler handler) throws CoreException {
+		localSite.revertTo(configuration, monitor, handler);
+	}
+
+	public boolean save() throws CoreException {
+		return localSite.save();
+	}
+
+	public void setMaximumHistoryCount(int history) {
+		localSite.setMaximumHistoryCount(history);
+	}
+	
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FeatureAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FeatureAction.java
new file mode 100644
index 0000000..1d96a42
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FeatureAction.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+
+public abstract class FeatureAction extends Action {
+	
+	protected String windowTitle;
+	
+    protected Shell shell;
+
+	public FeatureAction(Shell shell, String text) {
+		super(text);
+        this.shell = shell;
+	}
+
+	protected boolean confirm(String message) {
+		return MessageDialog.openConfirm( shell, windowTitle, message);
+	}
+	
+	public void setWindowTitle( String windowTitle) {
+		this.windowTitle = windowTitle;
+	}
+	
+	public abstract boolean canExecuteAction();
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FeatureStateAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FeatureStateAction.java
new file mode 100644
index 0000000..3c38660
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FeatureStateAction.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.ConfiguredFeatureAdapter;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class FeatureStateAction extends FeatureAction {
+
+	private ConfiguredFeatureAdapter adapter;
+
+    public FeatureStateAction(Shell shell, String text) {
+        super(shell, text);
+        setWindowTitle(UpdateUIMessages.FeatureStateAction_dialogTitle);
+    }
+    
+	public void setSelection(IStructuredSelection selection) {
+		
+		this.adapter = (ConfiguredFeatureAdapter) selection.getFirstElement();
+		if (adapter.isConfigured()) {
+			setText(UpdateUIMessages.FeatureStateAction_disable); 
+		} else {
+			setText(UpdateUIMessages.FeatureStateAction_enable); 
+		}
+	}
+
+	public void run() {
+		try {
+			if (adapter == null)
+				return;
+			
+			IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+			if (status != null)
+				throw new CoreException(status);
+			
+			boolean isConfigured = adapter.isConfigured();
+			// Ask user to confirm the operation
+			String message =
+				isConfigured
+					? UpdateUIMessages.FeatureStateAction_disableQuestion
+					: UpdateUIMessages.FeatureStateAction_EnableQuestion; 
+
+			if (!confirm(message))
+				return;
+
+			// If current config is broken, confirm with the user to continue
+			if (OperationsManager.getValidator().validateCurrentState() != null &&
+					!confirm(UpdateUIMessages.Actions_brokenConfigQuestion)) 
+				return;
+			
+			IOperation toggleOperation =
+				isConfigured
+					? (IOperation)OperationsManager
+						.getOperationFactory()
+						.createUnconfigOperation(
+						adapter.getConfiguredSite(),
+						adapter.getFeature(null))
+					: OperationsManager
+						.getOperationFactory()
+						.createConfigOperation(
+						adapter.getConfiguredSite(),
+						adapter.getFeature(null));
+
+			boolean restartNeeded = toggleOperation.execute(null, null);
+			UpdateUI.requestRestart(restartNeeded);
+
+		} catch (CoreException e) {
+			ErrorDialog.openError(shell,
+                    null, null, e.getStatus());
+		} catch (InvocationTargetException e) {
+			// This should not happen
+			UpdateUtils.logException(e.getTargetException());
+		}
+	}
+	
+	public boolean canExecuteAction() {
+		return true;
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FeaturesStateAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FeaturesStateAction.java
new file mode 100644
index 0000000..603a25f
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FeaturesStateAction.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.internal.core.InstallRegistry;
+import org.eclipse.update.internal.operations.OperationFactory;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.ConfiguredFeatureAdapter;
+import org.eclipse.update.operations.IFeatureOperation;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class FeaturesStateAction extends FeatureAction {
+
+	
+	private ConfiguredFeatureAdapter[] adapters;
+
+    public FeaturesStateAction(Shell shell, String text) {
+        super(shell, text);
+        setWindowTitle(UpdateUIMessages.FeatureStateAction_dialogTitle);
+    }
+    
+	public void setSelection(IStructuredSelection selection) {
+
+		this.adapters = (ConfiguredFeatureAdapter[]) selection.toList().toArray(new ConfiguredFeatureAdapter[selection.size()]);
+		if (canUnconfigure()) {
+			setText(UpdateUIMessages.FeatureStateAction_disable); 
+		} else {
+			setText(UpdateUIMessages.FeatureStateAction_enable); 
+		}
+
+	}
+	
+	public void run() {
+		try {
+			if ( (adapters == null) && (adapters.length == 0))
+				return;
+			
+			IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+			if (status != null)
+				throw new CoreException(status);
+			
+			boolean isConfigured = canUnconfigure();
+			// Ask user to confirm the operation
+			String message =
+				isConfigured
+					? UpdateUIMessages.FeatureStateAction_disableQuestion
+					: UpdateUIMessages.FeatureStateAction_EnableQuestion; 
+
+			if (!confirm(message))
+				return;
+
+			// If current config is broken, confirm with the user to continue
+			if (OperationsManager.getValidator().validateCurrentState() != null &&
+					!confirm(UpdateUIMessages.Actions_brokenConfigQuestion)) 
+				return;
+			
+			IOperation toggleOperation = null;
+			
+			IFeature[] features = new IFeature[adapters.length];
+			IConfiguredSite[] configuredSites = new IConfiguredSite[adapters.length];
+			for( int i = 0; i < adapters.length; i++) {
+				features[i] = adapters[i].getFeature(null);
+				configuredSites[i] = adapters[i].getConfiguredSite();
+			}
+			
+			if (isConfigured) {
+				toggleOperation = ((OperationFactory)OperationsManager.getOperationFactory()).createUnconfigureFeaturesOperation( configuredSites, features);
+			} else if (canConfigure()){
+				toggleOperation = ((OperationFactory)OperationsManager.getOperationFactory()).createConfigureFeaturesOperation( configuredSites, features);
+			}
+			
+			if (toggleOperation != null) {
+				boolean restartNeeded = toggleOperation.execute(null, null);
+				UpdateUI.requestRestart(restartNeeded);
+			}
+
+		} catch (CoreException e) {
+			ErrorDialog.openError(shell,
+                    null, null, e.getStatus());
+		} catch (InvocationTargetException e) {
+			// This should not happen
+			UpdateUtils.logException(e.getTargetException());
+		}
+	}
+	
+	public boolean canExecuteAction() {
+		return canConfigure() || canUnconfigure();
+	}
+	
+	private boolean canConfigure() {
+		
+		if (adapters == null || adapters.length == 0)
+			return false;
+		
+		for( int i = 0; i < adapters.length; i++) {
+			
+			if (adapters[i].isConfigured())
+				return false;
+		
+			try {
+				// check for pending changes (e.g. if the feature has just been disabled)
+				IFeatureOperation pendingOperation = OperationsManager.findPendingOperation(adapters[i].getFeature(null));
+				if (pendingOperation != null)
+					return false;
+
+				if (InstallRegistry.getInstance().get("feature_"+adapters[i].getFeature(null).getVersionedIdentifier()) == null) //$NON-NLS-1$
+					return false;
+			} catch (CoreException e) {
+				return false;
+			}
+		}
+				
+		return true;	
+	}
+	
+	private boolean canUnconfigure() {
+		
+		if (adapters == null || adapters.length == 0)
+			return false;
+		
+		for( int i = 0; i < adapters.length; i++) {
+			
+			if (!adapters[i].isConfigured())
+				return false;
+		
+			try {
+				// check for pending changes (e.g. if the feature has just been disabled)
+				IFeatureOperation pendingOperation = OperationsManager.findPendingOperation(adapters[i].getFeature(null));
+				if (pendingOperation != null)
+					return false;
+
+				if (InstallRegistry.getInstance().get("feature_"+adapters[i].getFeature(null).getVersionedIdentifier()) == null) //$NON-NLS-1$
+					return false;
+			} catch (CoreException e) {
+				return false;
+			}
+		}
+				
+		return true;	
+	}
+	
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FindAndInstallHandler.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FindAndInstallHandler.java
new file mode 100644
index 0000000..ad44271
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FindAndInstallHandler.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import org.eclipse.core.commands.*;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.update.ui.UpdateManagerUI;
+
+/**
+ * This handler is hooked to a command provided by the application (such
+ * as org.eclipse.ui.ide). This allows RCP applications to control how update
+ * functionality is surfaced.
+ */
+public class FindAndInstallHandler extends AbstractHandler {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		UpdateManagerUI.openInstaller(HandlerUtil.getActiveShell(event));
+		return null;
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FindUpdatesAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FindUpdatesAction.java
new file mode 100644
index 0000000..8cc7ab7
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/FindUpdatesAction.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ProgressMonitorWrapper;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.internal.ui.ConfigurationManagerWindow;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.wizards.InstallWizard;
+import org.eclipse.update.internal.ui.wizards.InstallWizardOperation;
+import org.eclipse.update.operations.OperationsManager;
+import org.eclipse.update.ui.UpdateJob;
+
+public class FindUpdatesAction extends Action {
+
+	private IFeature feature;
+
+	private ConfigurationManagerWindow window;
+
+	private class TrackingProgressMonitor extends ProgressMonitorWrapper {
+		private String name;
+
+		private String subname;
+
+		private int totalWork;
+
+		private double workSoFar;
+
+		protected TrackingProgressMonitor(IProgressMonitor monitor) {
+			super(monitor);
+		}
+
+		public void beginTask(String name, int totalWork) {
+			this.name = name;
+			this.totalWork = totalWork;
+			super.beginTask(name, totalWork);
+			updateStatus();
+		}
+
+		public void internalWorked(double ticks) {
+			super.internalWorked(ticks);
+			workSoFar += ticks;
+			updateStatus();
+		}
+
+		public void subTask(String subTask) {
+			subname = subTask;
+			super.subTask(subTask);
+			updateStatus();
+		}
+
+		private void updateStatus() {
+			if (window.getShell()==null || window.getShell().isDisposed())
+				return;
+			if (window.isProgressCanceled())
+				setCanceled(true);
+			if (totalWork <= 0)
+				return;
+			String perc = ((int) (workSoFar * 100.0) / totalWork) + ""; //$NON-NLS-1$
+			final String message = NLS.bind(UpdateUIMessages.FindUpdatesAction_trackedProgress, new String[] {
+					name, subname, perc });
+			Shell shell = window.getShell();
+			if (shell==null || shell.isDisposed()) return;
+			window.getShell().getDisplay().asyncExec(new Runnable() {
+				public void run() {
+					window.updateStatusLine(message, null);
+				}
+			});
+		}
+	}
+
+	private class TrackedUpdateJob extends UpdateJob {
+		public TrackedUpdateJob(String name, boolean isAutomatic,
+				boolean download, IFeature[] features) {
+			super(name, isAutomatic, download, features);
+		}
+
+		public IStatus run(IProgressMonitor monitor) {
+			return super.run(new TrackingProgressMonitor(monitor));
+		}
+	}
+
+	public FindUpdatesAction(ConfigurationManagerWindow window, String text) {
+		super(text);
+		this.window = window;
+	}
+
+	public void setFeature(IFeature feature) {
+		this.feature = feature;
+	}
+
+	public void run() {
+
+		IStatus status = OperationsManager.getValidator()
+				.validatePlatformConfigValid();
+		if (status != null) {
+			ErrorDialog.openError(window.getShell(), null, null, status);
+			return;
+		}
+
+		// If current config is broken, confirm with the user to continue
+		if (OperationsManager.getValidator().validateCurrentState() != null
+				&& !confirm(UpdateUIMessages.Actions_brokenConfigQuestion))
+			return;
+
+		if (InstallWizard.isRunning()) {
+			MessageDialog.openInformation(window.getShell(),
+					UpdateUIMessages.InstallWizard_isRunningTitle,
+					UpdateUIMessages.InstallWizard_isRunningInfo);
+			return;
+		}
+
+		IFeature[] features = null;
+		if (feature != null)
+			features = new IFeature[] { feature };
+
+		UpdateJob job = new TrackedUpdateJob(
+				UpdateUIMessages.InstallWizard_jobName, false, false, features);
+
+		job.setUser(true);
+		job.setPriority(Job.INTERACTIVE);
+
+		String name = feature!=null?feature.getLabel():UpdateUIMessages.FindUpdatesAction_allFeaturesSearch;
+		window.trackUpdateJob(job, name);
+		InstallWizardOperation operation = new InstallWizardOperation();
+
+		operation.run(window.getShell(), job);
+
+	}
+
+	private boolean confirm(String message) {
+		return MessageDialog.openConfirm(window.getShell(),
+				UpdateUIMessages.FeatureStateAction_dialogTitle, message);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/IPreviewTask.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/IPreviewTask.java
new file mode 100644
index 0000000..8957140
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/IPreviewTask.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import org.eclipse.jface.action.*;
+
+public interface IPreviewTask {
+	String getName();
+	String getDescription();
+	void run();
+	boolean isEnabled();
+	void setDescription(String desc);
+	IAction getAction();
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/InstallOptionalFeatureAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/InstallOptionalFeatureAction.java
new file mode 100644
index 0000000..0944671
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/InstallOptionalFeatureAction.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.wizard.*;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.search.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.internal.ui.model.*;
+import org.eclipse.update.internal.ui.wizards.*;
+import org.eclipse.update.operations.*;
+import org.eclipse.update.search.*;
+
+
+public class InstallOptionalFeatureAction extends Action {
+	private MissingFeature missingFeature;
+	private Shell shell;
+
+	public InstallOptionalFeatureAction(Shell shell, String text) {
+		super(text);
+		this.shell = shell;
+	}
+
+	public void setFeature(MissingFeature feature) {
+		this.missingFeature = feature;
+	}
+
+	public void run() {
+		if (missingFeature == null)
+			return;
+		
+		IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+		if (status != null) {
+			ErrorDialog.openError(shell, null, null, status);
+			return;
+		}
+		
+		// If current config is broken, confirm with the user to continue
+		if (OperationsManager.getValidator().validateCurrentState() != null &&
+				!confirm(UpdateUIMessages.Actions_brokenConfigQuestion)) 
+			return;
+			
+		
+		VersionedIdentifier vid = missingFeature.getVersionedIdentifier();
+		URL originatingURL = missingFeature.getOriginatingSiteURL();
+
+		UpdateSearchScope scope = new UpdateSearchScope();
+		scope.addSearchSite(originatingURL.toString(), originatingURL, null);
+
+		OptionalFeatureSearchCategory category = new OptionalFeatureSearchCategory();
+		category.addVersionedIdentifier(vid);
+		final UpdateSearchRequest searchRequest =
+			new UpdateSearchRequest(category, scope);
+
+		BusyIndicator.showWhile(shell.getDisplay(), new Runnable() {
+			public void run() {
+				openWizard(searchRequest);
+			}
+		});
+	}
+	private void openWizard(UpdateSearchRequest searchRequest) {
+		if (InstallWizard.isRunning()) {
+			MessageDialog.openInformation(shell, UpdateUIMessages.InstallWizard_isRunningTitle, UpdateUIMessages.InstallWizard_isRunningInfo);
+			return;
+		}
+		InstallWizard wizard = new InstallWizard(searchRequest);
+		WizardDialog dialog = new ResizableInstallWizardDialog(shell, wizard, UpdateUIMessages.FeaturePage_optionalInstall_title);
+		dialog.create();
+		dialog.open();
+	}
+	
+	private boolean confirm(String message) {
+		return MessageDialog.openConfirm(
+			shell,
+			UpdateUIMessages.FeatureStateAction_dialogTitle, 
+			message);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/InstallationHistoryAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/InstallationHistoryAction.java
new file mode 100644
index 0000000..bfb714a
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/InstallationHistoryAction.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.configurator.ConfiguratorUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+public class InstallationHistoryAction extends Action {
+    //private Shell shell;
+	private BufferedReader buffRead;
+	private PrintWriter htmlLog;
+	private File tempFile;
+	private String rowType;
+	private IPath path;
+	private static final String lightBlue = "#EEEEFF"; //$NON-NLS-1$
+	private static final String white = "#FFFFFF"; //$NON-NLS-1$
+	private static final String darkBlue = "#99AADD"; //$NON-NLS-1$
+//	private static final String CONFIGURATION = "CONFIGURATION"; //$NON-NLS-1$
+	private static final String ACTIVITY = "ACTIVITY"; //$NON-NLS-1$
+
+	public InstallationHistoryAction(Shell shell, String text, ImageDescriptor desc) {
+		super(text, desc);
+        //this.shell = shell;
+		String location =
+			ConfiguratorUtils
+				.getCurrentPlatformConfiguration()
+				.getConfigurationLocation()
+				.getFile();
+		path = new Path(location).removeLastSegments(1).append("install.log"); //$NON-NLS-1$
+		rowType = "light-row"; //$NON-NLS-1$
+	}
+
+	public void run() {
+		try {
+			openLog();
+			parseLog();
+			UpdateUI.showURL("file:" + getTempFile().getPath().toString()); //$NON-NLS-1$
+		} catch (CoreException e) {
+			UpdateUI.logException(e);
+		} finally {
+			closeLog();
+		}
+	}
+
+	private void openLog() throws CoreException {
+		try {
+		    // throws FileNotFoundException, IOException
+		    InputStream is = new FileInputStream(path.toOSString());
+		    // throws UnsupportedEncodingException
+		    InputStreamReader isr = new InputStreamReader(is,"UTF-8"); //$NON-NLS-1$
+		    buffRead = new BufferedReader(isr);
+			htmlLog = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(getTempFile()), "UTF-8"))); //$NON-NLS-1$
+		} catch (Exception e) {
+			throwCoreException(e);
+		}
+	}
+
+	private File getTempFile() throws CoreException {
+		if (tempFile == null) {
+			try {
+				tempFile = File.createTempFile("install-log", ".html"); //$NON-NLS-1$ //$NON-NLS-2$
+				tempFile.deleteOnExit();
+			} catch (IOException e) {
+				throwCoreException(e);
+			}
+		}
+		return tempFile;
+	}
+
+	private void parseLog() throws CoreException {
+		//		!CONFIGURATION <configuration-date>
+		//		!ACTIVITY <date> <target> <action> <status>
+
+		try {
+			String type, date, status, target, action;
+			StringTokenizer htmlCode;
+
+			htmlLog.println("<html>"); //$NON-NLS-1$
+			htmlLog.println("<head>"); //$NON-NLS-1$
+			htmlLog.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"); //$NON-NLS-1$
+			htmlLog.println("<title>Install-Log</title>"); //$NON-NLS-1$
+			addCSS();
+			htmlLog.println("</head>"); //$NON-NLS-1$
+			htmlLog.println("<body>"); //$NON-NLS-1$
+			String title = UpdateUIMessages.InstallationHistoryAction_title; 
+			String desc = UpdateUIMessages.InstallationHistoryAction_desc; 
+			htmlLog.println("<h1 class=title>"+title+"</h1>"); //$NON-NLS-1$ //$NON-NLS-2$
+			htmlLog.println("<p class=bodyText>"+desc+"</p>"); //$NON-NLS-1$ //$NON-NLS-2$
+			
+			htmlLog.println("<center>"); //$NON-NLS-1$
+
+			htmlLog.println("<table width =100% border=0 cellspacing=1 cellpadding=2>"); //$NON-NLS-1$
+
+			while (buffRead.ready()) {
+
+				htmlCode = new StringTokenizer(buffRead.readLine());
+				while (!(htmlCode.hasMoreElements())) {
+					if (!buffRead.ready())
+						return;
+					htmlCode = new StringTokenizer(buffRead.readLine());
+				}
+
+				type = htmlCode.nextToken();
+				type = type.substring(type.indexOf("!") + 1, type.length()); //$NON-NLS-1$
+
+				if (type.equals(ACTIVITY)) {
+					target = ""; //$NON-NLS-1$
+					Date d = new Date(new Long(htmlCode.nextToken()).longValue());
+					DateFormat df = DateFormat.getDateTimeInstance();
+					date = df.format(d);
+					// ignore string date
+					htmlCode.nextToken("."); //$NON-NLS-1$
+					htmlCode.nextToken(" "); //$NON-NLS-1$
+					while (htmlCode.countTokens() > 2)
+						target = target + " " + htmlCode.nextToken(); //$NON-NLS-1$
+
+					action = htmlCode.nextToken();
+					status = htmlCode.nextToken();
+
+					addActivity(action, date, status, target);
+
+				} else {
+					htmlLog.println();
+					htmlLog.println(
+						"<tr id=separator><td colspan=4></td></tr>"); //$NON-NLS-1$
+					htmlLog.println();
+					Date d = new Date(new Long(htmlCode.nextToken()).longValue());
+					DateFormat df = DateFormat.getDateTimeInstance();
+					date = df.format(d);
+//					date = ""; //$NON-NLS-1$
+//					while (htmlCode.countTokens() > 0)
+//						date = date + " " + htmlCode.nextToken(); //$NON-NLS-1$
+					addConfigurationHeader(date);
+					addActivityHeader();
+				}
+
+			}
+			htmlLog.println("</table>"); //$NON-NLS-1$
+			htmlLog.println("</body>"); //$NON-NLS-1$
+			htmlLog.println("</html>"); //$NON-NLS-1$
+			htmlLog.flush();
+
+		} catch (Exception e) {
+			throwCoreException(e);
+		}
+
+	}
+
+	private void addActivity(
+		String type,
+		String date,
+		String status,
+		String target) {
+		htmlLog.print("<tr class=" + rowType + ">"); //$NON-NLS-1$ //$NON-NLS-2$
+		htmlLog.print("<td class=log-text width=30%>"); //$NON-NLS-1$
+		htmlLog.print(date);
+		htmlLog.println("</td>"); //$NON-NLS-1$
+		htmlLog.print("<td class=log-text width=40%>"); //$NON-NLS-1$
+		htmlLog.print(target);
+		htmlLog.println("</td>"); //$NON-NLS-1$
+		htmlLog.print("<td class=log-text width=20%>"); //$NON-NLS-1$
+		htmlLog.print(type);
+		htmlLog.println("</td>"); //$NON-NLS-1$
+		htmlLog.print("<td class=log-text width=10%>"); //$NON-NLS-1$
+		htmlLog.print(status);
+		htmlLog.println("</td></tr>"); //$NON-NLS-1$
+		toggleRowColor();
+	}
+
+	private void addCSS() {
+		htmlLog.println("<STYLE type=\"text/css\">"); //$NON-NLS-1$
+		htmlLog.println("H1.title { font-family: sans-serif; color: #99AACC }"); //$NON-NLS-1$
+		htmlLog.println("P.bodyText { font-family: sans-serif; font-size: 9pt; }"); //$NON-NLS-1$
+		htmlLog.println(
+			"TD.log-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white}"); //$NON-NLS-1$
+		htmlLog.println(
+			"TD.log-text { font-family: sans-serif; font-style: normal; font-weight: lighter; font-size: 8pt; color:black}"); //$NON-NLS-1$
+		htmlLog.println(
+		//	"TD.config-log-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white; ;text-align: right; border-top:10px solid white}");
+		"TD.config-log-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white; border-top:10px solid white}"); //$NON-NLS-1$
+		htmlLog.println("TR.light-row {background:" + white + "}"); //$NON-NLS-1$ //$NON-NLS-2$
+		htmlLog.println("TR.dark-row {background:" + lightBlue + "}"); //$NON-NLS-1$ //$NON-NLS-2$
+		htmlLog.println("TR.header {background:" + darkBlue + "}"); //$NON-NLS-1$ //$NON-NLS-2$
+		htmlLog.println("</STYLE>"); //$NON-NLS-1$
+	}
+
+	private void addActivityHeader() {
+		htmlLog.print("<tr class=header>"); //$NON-NLS-1$
+		htmlLog.print("<td class=log-header>"); //$NON-NLS-1$
+		htmlLog.print(UpdateUIMessages.InstallationHistoryAction_dateTime); 
+		htmlLog.print("</td>"); //$NON-NLS-1$
+		htmlLog.print("<td class=log-header>"); //$NON-NLS-1$
+		htmlLog.print(UpdateUIMessages.InstallationHistoryAction_target); 
+		htmlLog.print("</td>"); //$NON-NLS-1$
+		htmlLog.print("<td class=log-header>"); //$NON-NLS-1$
+		htmlLog.print(UpdateUIMessages.InstallationHistoryAction_action); 
+		htmlLog.print("</td>"); //$NON-NLS-1$
+		htmlLog.print("<td class=log-header>"); //$NON-NLS-1$
+		htmlLog.print(UpdateUIMessages.InstallationHistoryAction_status); 
+		htmlLog.println("</td></tr>"); //$NON-NLS-1$
+	}
+
+	private void addConfigurationHeader(String date) {
+		if (date == null)
+			return;
+
+		htmlLog.print("<tr class=header>"); //$NON-NLS-1$
+		htmlLog.print("<td class=config-log-header colspan=4>"); //$NON-NLS-1$
+		htmlLog.print(date);
+		htmlLog.println("</td></tr>"); //$NON-NLS-1$
+	}
+
+	private void toggleRowColor() {
+		if (rowType.equals("light-row")) //$NON-NLS-1$
+			rowType = "dark-row"; //$NON-NLS-1$
+		else
+			rowType = "light-row"; //$NON-NLS-1$
+	}
+
+	private void throwCoreException(Throwable e) throws CoreException {
+		throw new CoreException(
+			new Status(
+				IStatus.ERROR,
+				UpdateUI.getPluginId(),
+				IStatus.ERROR,
+				UpdateUIMessages.InstallationHistoryAction_errors, 
+				e));
+	}
+
+	private void closeLog() {
+		try {
+			if (buffRead != null)
+				buffRead.close();
+			if (htmlLog != null)
+				htmlLog.close();
+		} catch (IOException e) {
+		} finally {
+			buffRead = null;
+			htmlLog = null;
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ManageConfigurationHandler.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ManageConfigurationHandler.java
new file mode 100644
index 0000000..ebb2736
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ManageConfigurationHandler.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import org.eclipse.core.commands.*;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.update.ui.UpdateManagerUI;
+
+/**
+ * This handler is hooked to a command provided by the application (such
+ * as org.eclipse.ui.ide). This allows RCP applications to control how update
+ * functionality is surfaced.
+ */
+public class ManageConfigurationHandler extends AbstractHandler {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		UpdateManagerUI.openConfigurationManager(HandlerUtil.getActiveShell(event));
+		return null;
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/NewExtensionLocationAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/NewExtensionLocationAction.java
new file mode 100644
index 0000000..f421ecd
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/NewExtensionLocationAction.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.io.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.operations.*;
+
+public class NewExtensionLocationAction extends Action {
+    private Shell shell;
+    
+	public NewExtensionLocationAction(Shell shell, String text, ImageDescriptor desc) {
+		super(text, desc);
+        this.shell = shell;
+	}
+
+	public void run() {
+		
+		IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+		if (status != null) {
+			ErrorDialog.openError(shell, null, null, status);
+			return;
+		}
+		
+		DirectoryDialog dialog =
+			new DirectoryDialog(shell, SWT.APPLICATION_MODAL);
+		dialog.setMessage(UpdateUIMessages.NewExtensionLocationAction_selectExtLocation); 
+
+		String dir = dialog.open();
+		while (dir != null) {
+			File dirFile = getExtensionSite(new File(dir));
+			if (dirFile != null) {
+				if (addExtensionLocation(dirFile))
+					return;
+				else {
+					// re-open the directory dialog
+					dialog.setFilterPath(dir);
+					dir = dialog.open();
+				}	
+			} else {
+				MessageDialog.openInformation(
+					shell,
+					UpdateUIMessages.NewExtensionLocationAction_extInfoTitle, 
+					UpdateUIMessages.NewExtensionLocationAction_extInfoMessage); 
+				// re-open the directory dialog
+				dialog.setFilterPath(dir);
+				dir = dialog.open();
+			}
+		}
+	}
+
+	/**
+	 * @param directory
+	 * @return the site file (including "eclipse" path) when directory is an eclipse exstension, null otherwise
+	 */
+	static File getExtensionSite(File directory) {
+		// Check the eclipse folder
+		if (directory.getName().equals("eclipse")) { //$NON-NLS-1$
+			// if we picked up the eclipse directory, check if its parent is a site
+			File site = getExtensionSite(directory.getParentFile());
+			if (site != null)
+				return directory;
+			// otherwise, fall through
+		}
+		
+		File eclipse = new File(directory, "eclipse"); //$NON-NLS-1$
+		if (!eclipse.exists() || !eclipse.isDirectory())
+			return null;
+
+		// check the marker
+		File marker = new File(eclipse, ".eclipseextension"); //$NON-NLS-1$
+		if (!marker.exists() || marker.isDirectory())
+			return null;
+		return eclipse;
+	}
+
+	private boolean addExtensionLocation(File dir) {
+		try {
+			IInstallConfiguration config = SiteManager.getLocalSite().getCurrentConfiguration();
+			IConfiguredSite csite = config.createLinkedConfiguredSite(dir);
+			csite.verifyUpdatableStatus();
+			config.addConfiguredSite(csite);
+			boolean restartNeeded = SiteManager.getLocalSite().save();
+			UpdateUI.requestRestart(restartNeeded);
+			return true;
+		} catch (CoreException e) {
+			String title = UpdateUIMessages.InstallWizard_TargetPage_location_error_title; 
+			ErrorDialog.openError(shell, title, null, e.getStatus());
+			UpdateUI.logException(e,false);
+			return false;
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ReplaceVersionAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ReplaceVersionAction.java
new file mode 100644
index 0000000..47b0c8e
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ReplaceVersionAction.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.internal.ui.wizards.ReplaceFeatureVersionWizard;
+import org.eclipse.update.operations.*;
+
+public class ReplaceVersionAction extends Action {
+	
+	private IFeature currentFeature;
+	private IFeature[] features;
+	private Shell shell;
+    
+	public ReplaceVersionAction(Shell shell, String text) {
+		super(text);
+        this.shell = shell;
+	}
+	
+	public void setCurrentFeature(IFeature feature) {
+		currentFeature = feature;
+	}
+	
+	public void setFeatures(IFeature[] features) {
+		this.features = features;
+	}
+		
+	public void run() {
+		if (currentFeature == null || features == null || features.length < 2)
+			return;
+			
+		IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+		if (status != null) {
+			ErrorDialog.openError(shell, null, null, status);
+			return;
+		}
+		
+		ReplaceFeatureVersionWizard wizard = new ReplaceFeatureVersionWizard(currentFeature, features);
+		WizardDialog dialog = new WizardDialog(shell, wizard);
+		dialog.create();
+		dialog.getShell().setText(shell.getText());
+		dialog.getShell().setSize(400,400);
+		dialog.open();
+	}
+
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/RevertConfigurationAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/RevertConfigurationAction.java
new file mode 100644
index 0000000..a0d4080
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/RevertConfigurationAction.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.wizard.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.internal.ui.wizards.*;
+import org.eclipse.update.operations.*;
+
+public class RevertConfigurationAction extends Action {
+    private Shell shell;
+    
+	public RevertConfigurationAction(Shell shell, String text) {
+		super(text);
+        this.shell = shell;
+	}
+	
+	public void run() {
+		IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+		if (status != null) {
+			ErrorDialog.openError(shell, null, null, status);
+			return;
+		}
+		
+		RevertConfigurationWizard wizard = new RevertConfigurationWizard();
+		WizardDialog dialog = new WizardDialog(shell, wizard);
+		dialog.create();
+		dialog.getShell().setText(shell.getText());
+		dialog.getShell().setSize(600,500);
+		dialog.open();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ShowActivitiesAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ShowActivitiesAction.java
new file mode 100644
index 0000000..b0f47bc
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/ShowActivitiesAction.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.wizards.ShowActivitiesDialog;
+
+public class ShowActivitiesAction extends Action {
+	Shell shell;
+	
+	public ShowActivitiesAction(Shell parentShell, String text) {
+		super(text);
+		this.shell = parentShell;
+	}
+	
+	public void run() {
+		ShowActivitiesDialog dialog = new ShowActivitiesDialog(shell);
+		dialog.create();
+		dialog.getShell().setText(UpdateUIMessages.ShowActivitiesDialog_title); 
+		dialog.open();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/SiteStateAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/SiteStateAction.java
new file mode 100644
index 0000000..bf5f006
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/SiteStateAction.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.lang.reflect.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.operations.*;
+
+/**
+ * Toggles a site's enabled state
+ */
+
+public class SiteStateAction extends Action {
+	private IConfiguredSite site;
+    private Shell shell;
+
+	public SiteStateAction(Shell shell) {
+        this.shell = shell;
+	}
+
+	public void setSite(IConfiguredSite site) {
+		this.site = site;
+		boolean state = site.isEnabled();
+		setText(state ? UpdateUIMessages.SiteStateAction_disableLabel : UpdateUIMessages.SiteStateAction_enableLabel); 
+	}
+
+	public void run() {
+		try {
+			if (site == null)
+				return;
+			
+			IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+			if (status != null) {
+				ErrorDialog.openError(shell, null, null, status);
+				return;
+			}
+			
+			boolean oldValue = site.isEnabled();
+			if (!confirm(!oldValue))
+				return;
+			
+			IOperation toggleSiteOperation = OperationsManager.getOperationFactory().createToggleSiteOperation(site);
+			boolean restartNeeded = toggleSiteOperation.execute(null, null);
+					
+			UpdateUI.requestRestart(restartNeeded);
+
+		} catch (CoreException e) {
+            ErrorDialog.openError(shell, null, null, e.getStatus());
+		} catch (InvocationTargetException e) {
+			UpdateUI.logException(e);
+		}
+	}
+
+	private boolean confirm(boolean newState) {
+		String name = site.getSite().getURL().toString();
+		String enableMessage = NLS.bind(UpdateUIMessages.SiteStateAction_enableMessage, name);
+		String disableMessage = NLS.bind(UpdateUIMessages.SiteStateAction_disableMessage, name);
+
+		String message = newState ? enableMessage : disableMessage;
+		return MessageDialog.openConfirm(shell, UpdateUIMessages.SiteStateAction_dialogTitle, message); 
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UnconfigureAndUninstallFeatureAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UnconfigureAndUninstallFeatureAction.java
new file mode 100644
index 0000000..08553d5
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UnconfigureAndUninstallFeatureAction.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.internal.core.InstallRegistry;
+import org.eclipse.update.internal.operations.OperationFactory;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.ConfiguredFeatureAdapter;
+import org.eclipse.update.operations.IFeatureOperation;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class UnconfigureAndUninstallFeatureAction extends FeatureAction {
+
+	private ConfiguredFeatureAdapter adapter;
+
+	public UnconfigureAndUninstallFeatureAction(Shell shell, String text) {
+		super(shell, text);
+		setWindowTitle(UpdateUIMessages.FeatureUnconfigureAndUninstallAction_dialogTitle);
+	}
+
+	public void run() {
+		try {
+			IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+			if (status != null)
+				throw new CoreException(status);
+			
+			if (adapter == null || !confirm(UpdateUIMessages.FeatureUnconfigureAndUninstallAction_question)) 
+				return;
+
+			// If current config is broken, confirm with the user to continue
+			if (OperationsManager.getValidator().validateCurrentState() != null &&
+					!confirm(UpdateUIMessages.Actions_brokenConfigQuestion)) 
+				return;
+
+			IOperation operation =
+				((OperationFactory)OperationsManager.getOperationFactory()).createUnconfigureAndUninstallFeatureOperation( adapter.getConfiguredSite(), adapter.getFeature(null));
+
+			boolean restartNeeded = operation.execute(null, null);
+			UpdateUI.requestRestart(restartNeeded);
+
+		} catch (CoreException e) {
+			ErrorDialog.openError(shell, null, null, e.getStatus());
+		} catch (InvocationTargetException e) {
+			// This should not happen
+			UpdateUtils.logException(e.getTargetException());
+		}
+	}
+
+
+
+	public void setSelection(IStructuredSelection selection) {
+		
+		this.adapter = (ConfiguredFeatureAdapter) selection.getFirstElement();
+		setText(UpdateUIMessages.FeatureUnconfigureAndUninstallAction_uninstall); 
+	}
+	
+	
+	public boolean canExecuteAction() {
+		if (adapter == null)
+			return false;
+		
+		if (!adapter.isConfigured())
+			return false;
+		
+		try {
+			// check for pending changes (e.g. if the feature has just been disabled)
+			IFeatureOperation pendingOperation = OperationsManager.findPendingOperation(adapter.getFeature(null));
+			if (pendingOperation != null)
+				return false;
+
+			if (InstallRegistry.getInstance().get("feature_"+adapter.getFeature(null).getVersionedIdentifier()) == null) //$NON-NLS-1$
+				return false;
+		} catch (CoreException e) {
+			return false;
+		}
+				
+		return true;	
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UnconfigureAndUninstallFeaturesAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UnconfigureAndUninstallFeaturesAction.java
new file mode 100644
index 0000000..cd5a758
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UnconfigureAndUninstallFeaturesAction.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.internal.core.InstallRegistry;
+import org.eclipse.update.internal.operations.OperationFactory;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.ConfiguredFeatureAdapter;
+import org.eclipse.update.operations.IFeatureOperation;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class UnconfigureAndUninstallFeaturesAction extends FeatureAction {
+
+	private ConfiguredFeatureAdapter[] adapters;
+
+	public UnconfigureAndUninstallFeaturesAction( Shell shell, String text) {
+		super(shell, text);
+		setWindowTitle(UpdateUIMessages.FeatureUnconfigureAndUninstallAction_dialogTitle);
+	}
+
+	
+	public void run() {
+		try {
+			IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+			if (status != null)
+				throw new CoreException(status);
+			
+			if (adapters == null || !confirm(UpdateUIMessages.FeatureUnconfigureAndUninstallAction_question)) 
+				return;
+
+			// If current config is broken, confirm with the user to continue
+			if (OperationsManager.getValidator().validateCurrentState() != null &&
+					!confirm(UpdateUIMessages.Actions_brokenConfigQuestion)) 
+				return;
+			
+			IFeature[] features = new IFeature[adapters.length];
+			IConfiguredSite[] configuredSites = new IConfiguredSite[adapters.length];
+			for( int i = 0; i < adapters.length; i++) {
+				features[i] = adapters[i].getFeature(null);
+				configuredSites[i] = adapters[i].getConfiguredSite();
+			}
+
+			IOperation uninstallFeaturesOperation =
+				((OperationFactory)OperationsManager.getOperationFactory()).createUnconfigureAndUninstallFeaturesOperation( configuredSites, features);
+
+			boolean restartNeeded = uninstallFeaturesOperation.execute(null, null);
+			UpdateUI.requestRestart(restartNeeded);
+
+		} catch (CoreException e) {
+			ErrorDialog.openError(shell, null, null, e.getStatus());
+		} catch (InvocationTargetException e) {
+			// This should not happen
+			UpdateUtils.logException(e.getTargetException());
+		}
+	}
+	
+	public void setSelection(IStructuredSelection selection) {
+		
+		this.adapters = (ConfiguredFeatureAdapter[]) selection.toList().toArray(new ConfiguredFeatureAdapter[selection.size()]);
+		setText(UpdateUIMessages.FeatureUnconfigureAndUninstallAction_uninstall); 
+	}
+	
+	public boolean canExecuteAction() {
+		
+		if (adapters == null || adapters.length == 0)
+			return false;
+		
+		for( int i = 0; i < adapters.length; i++) {
+			
+			if (!adapters[i].isConfigured())
+				return false;
+		
+			try {
+				// check for pending changes (e.g. if the feature has just been disabled)
+				IFeatureOperation pendingOperation = OperationsManager.findPendingOperation(adapters[i].getFeature(null));
+				if (pendingOperation != null)
+					return false;
+
+				if (InstallRegistry.getInstance().get("feature_"+adapters[i].getFeature(null).getVersionedIdentifier()) == null) //$NON-NLS-1$
+					return false;
+			} catch (CoreException e) {
+				return false;
+			}
+		}
+				
+		return true;	
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UninstallFeatureAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UninstallFeatureAction.java
new file mode 100644
index 0000000..c07b5c1
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UninstallFeatureAction.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.internal.core.InstallRegistry;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.ConfiguredFeatureAdapter;
+import org.eclipse.update.operations.IFeatureOperation;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class UninstallFeatureAction extends FeatureAction {
+	
+	private ConfiguredFeatureAdapter adapter;
+
+	public UninstallFeatureAction(Shell shell, String text) {
+		super(shell, text);
+		setWindowTitle(UpdateUIMessages.FeatureUninstallAction_dialogTitle);
+	}
+
+	public void run() {
+		try {
+			IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+			if (status != null)
+				throw new CoreException(status);
+			
+			if (adapter == null || !confirm(UpdateUIMessages.FeatureUninstallAction_uninstallQuestion)) 
+				return;
+
+			// If current config is broken, confirm with the user to continue
+			if (OperationsManager.getValidator().validateCurrentState() != null &&
+					!confirm(UpdateUIMessages.Actions_brokenConfigQuestion)) 
+				return;
+
+			IOperation uninstallOperation =
+				OperationsManager
+					.getOperationFactory()
+					.createUninstallOperation(
+					adapter.getConfiguredSite(),
+					adapter.getFeature(null));
+
+			boolean restartNeeded = uninstallOperation.execute(null, null);
+			UpdateUI.requestRestart(restartNeeded);
+
+		} catch (CoreException e) {
+			ErrorDialog.openError(shell, null, null, e.getStatus());
+		} catch (InvocationTargetException e) {
+			// This should not happen
+			UpdateUtils.logException(e.getTargetException());
+		}
+	}
+
+
+
+	public void setSelection(IStructuredSelection selection) {
+		
+		this.adapter = (ConfiguredFeatureAdapter) selection.getFirstElement();
+		setText(UpdateUIMessages.FeatureUninstallAction_uninstall); 
+	}
+
+	public boolean canExecuteAction() {
+		if (adapter == null)
+			return false;
+		
+		if (adapter.isConfigured())
+			return false;
+		
+		try {
+			// check for pending changes (e.g. if the feature has just been disabled)
+			IFeatureOperation pendingOperation = OperationsManager.findPendingOperation(adapter.getFeature(null));
+			if (pendingOperation != null)
+				return false;
+
+			if (InstallRegistry.getInstance().get("feature_"+adapter.getFeature(null).getVersionedIdentifier()) == null) //$NON-NLS-1$
+				return false;
+		} catch (CoreException e) {
+			return false;
+		}
+				
+		return true;	
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UninstallFeaturesAction.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UninstallFeaturesAction.java
new file mode 100644
index 0000000..0a0f9a9
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/views/UninstallFeaturesAction.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.views;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.internal.core.InstallRegistry;
+import org.eclipse.update.internal.operations.OperationFactory;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.ConfiguredFeatureAdapter;
+import org.eclipse.update.operations.IFeatureOperation;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.OperationsManager;
+
+public class UninstallFeaturesAction extends FeatureAction {
+
+	private ConfiguredFeatureAdapter[] adapters;
+
+	public UninstallFeaturesAction( Shell shell, String text) {
+		super(shell, text);
+		setWindowTitle(UpdateUIMessages.FeatureUninstallAction_dialogTitle);
+	}
+
+	
+	public void run() {
+		try {
+			IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+			if (status != null)
+				throw new CoreException(status);
+			
+			if (adapters == null || !confirm(UpdateUIMessages.FeatureUninstallAction_uninstallQuestion)) 
+				return;
+
+			// If current config is broken, confirm with the user to continue
+			if (OperationsManager.getValidator().validateCurrentState() != null &&
+					!confirm(UpdateUIMessages.Actions_brokenConfigQuestion)) 
+				return;
+			
+			IFeature[] features = new IFeature[adapters.length];
+			IConfiguredSite[] configuredSites = new IConfiguredSite[adapters.length];
+			for( int i = 0; i < adapters.length; i++) {
+				features[i] = adapters[i].getFeature(null);
+				configuredSites[i] = adapters[i].getConfiguredSite();
+			}
+
+			IOperation uninstallFeaturesOperation =
+				((OperationFactory)OperationsManager.getOperationFactory()).createUninstallFeaturesOperation( configuredSites, features);
+
+			boolean restartNeeded = uninstallFeaturesOperation.execute(null, null);
+			UpdateUI.requestRestart(restartNeeded);
+
+		} catch (CoreException e) {
+			ErrorDialog.openError(shell, null, null, e.getStatus());
+		} catch (InvocationTargetException e) {
+			// This should not happen
+			UpdateUtils.logException(e.getTargetException());
+		}
+	}
+
+
+	public void setSelection(IStructuredSelection selection) {
+		
+		this.adapters = (ConfiguredFeatureAdapter[]) selection.toList().toArray(new ConfiguredFeatureAdapter[selection.size()]);
+		setText(UpdateUIMessages.FeatureUninstallAction_uninstall); 
+	}
+	
+	public boolean canExecuteAction() {
+		
+		if (adapters == null || adapters.length == 0)
+			return false;
+		
+		for( int i = 0; i < adapters.length; i++) {
+			if (adapters[i].isConfigured())
+				return false;
+		
+			try {
+				// check for pending changes (e.g. if the feature has just been disabled)
+				IFeatureOperation pendingOperation = OperationsManager.findPendingOperation(adapters[i].getFeature(null));
+				if (pendingOperation != null)
+					return false;
+
+				if (InstallRegistry.getInstance().get("feature_"+adapters[i].getFeature(null).getVersionedIdentifier()) == null) //$NON-NLS-1$
+					return false;
+			} catch (CoreException e) {
+				return false;
+			}
+		}
+				
+		return true;	
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ActivitiesTableViewer.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ActivitiesTableViewer.java
new file mode 100644
index 0000000..4a7894f
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ActivitiesTableViewer.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.internal.ui.parts.*;
+
+
+/**
+ * Viewer for configuration activities
+ */
+public class ActivitiesTableViewer{
+
+	private static InstallLogParser parser; 
+	
+	static class ActivitiesContentProvider
+		extends DefaultContentProvider
+		implements IStructuredContentProvider {
+		
+		private boolean showCurrentOnly;
+		
+		public ActivitiesContentProvider(boolean showCurrentOnly){
+			this.showCurrentOnly = showCurrentOnly;
+		}
+		
+		public Object[] getElements(Object element) {
+			InstallConfiguration currentConfig = (InstallConfiguration)element;
+			InstallConfiguration[] configs = parser.getConfigurations();
+			boolean hitCurrentConfig = false;
+			ArrayList activitiesList = new ArrayList();
+			for (int i = 0; i<configs.length; i++){
+				if (configs[i].equals(currentConfig) && !hitCurrentConfig)
+					hitCurrentConfig = true;
+				if (hitCurrentConfig && showCurrentOnly)
+					return configs[i].getActivities();
+				else if (hitCurrentConfig){
+					IActivity[] activities = configs[i].getActivities();
+					for (int j = 0; j<activities.length; j++)
+						activitiesList.add(activities[j]);	
+				}
+				
+			}
+			return (IActivity[])activitiesList.toArray(new IActivity[activitiesList.size()]);
+		}
+		
+	}
+
+	static class ActivitiesLabelProvider
+		extends LabelProvider
+		implements ITableLabelProvider {
+		public Image getColumnImage(Object element, int columnIndex) {
+			if (columnIndex == 0) {
+				UpdateLabelProvider provider =
+					UpdateUI.getDefault().getLabelProvider();
+				switch (((IActivity) element).getStatus()) {
+					case IActivity.STATUS_OK :
+						return provider.get(UpdateUIImages.DESC_OK_ST_OBJ, 0);
+					case IActivity.STATUS_NOK :
+						return provider.get(UpdateUIImages.DESC_ERR_ST_OBJ, 0);
+				}
+			}
+			return null;
+		}
+
+		public String getColumnText(Object element, int columnIndex) {
+			IActivity activity = (IActivity) element;
+			switch (columnIndex) {
+				case 1 :
+					return Utilities.format(activity.getDate());
+				case 2 :
+					return activity.getLabel();
+				case 3 :
+					return getActionLabel(activity);
+			}
+			return ""; //$NON-NLS-1$
+		}
+
+		private String getActionLabel(IActivity activity) {
+			int action = activity.getAction();
+			switch (action) {
+				case IActivity.ACTION_CONFIGURE :
+					return UpdateUIMessages.ActivitiesTableViewer_enabled; 
+				case IActivity.ACTION_FEATURE_INSTALL :
+					return UpdateUIMessages.ActivitiesTableViewer_featureInstalled; 
+				case IActivity.ACTION_FEATURE_REMOVE :
+					return UpdateUIMessages.ActivitiesTableViewer_featureRemoved; 
+				case IActivity.ACTION_SITE_INSTALL :
+					return UpdateUIMessages.ActivitiesTableViewer_siteInstalled; 
+				case IActivity.ACTION_SITE_REMOVE :
+					return UpdateUIMessages.ActivitiesTableViewer_siteRemoved; 
+				case IActivity.ACTION_UNCONFIGURE :
+					return UpdateUIMessages.ActivitiesTableViewer_disabled; 
+				case IActivity.ACTION_REVERT :
+					return UpdateUIMessages.ActivitiesTableViewer_revert; 
+				case IActivity.ACTION_RECONCILIATION :
+					return UpdateUIMessages.ActivitiesTableViewer_reconcile; 
+				default :
+					return UpdateUIMessages.ActivitiesTableViewer_unknown; 
+			}
+		}
+	}
+
+	public static TableViewer createViewer(Composite parent, boolean showCurrentOnly) {
+		parser = new InstallLogParser();
+		parser.parseInstallationLog();
+		Table table = new Table(parent, SWT.BORDER);
+		table.setLayoutData(new GridData(GridData.FILL_BOTH));
+		table.setHeaderVisible(true);
+
+		TableColumn column = new TableColumn(table, SWT.NONE);
+
+		column = new TableColumn(table, SWT.NONE);
+		column.setText(UpdateUIMessages.ActivitiesTableViewer_date); 
+
+		column = new TableColumn(table, SWT.NONE);
+		column.setText(UpdateUIMessages.ActivitiesTableViewer_target); 
+
+		column = new TableColumn(table, SWT.NONE);
+		column.setText(UpdateUIMessages.ActivitiesTableViewer_action); 
+
+		TableViewer activitiesViewer = new TableViewer(table);
+		activitiesViewer.setLabelProvider(new ActivitiesLabelProvider());
+		activitiesViewer.setContentProvider(new ActivitiesContentProvider(showCurrentOnly));
+		return activitiesViewer;
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/BannerPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/BannerPage.java
new file mode 100644
index 0000000..741dd04
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/BannerPage.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+import java.net.*;
+
+import org.eclipse.jface.wizard.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.internal.ui.*;
+
+public abstract class BannerPage extends WizardPage {
+	private Image bannerImage;
+	private boolean bannerVisible = false;
+	public BannerPage(String name) {
+		super(name);
+	}
+
+	public void createControl(Composite parent) {
+		Composite client = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.horizontalSpacing = 10;
+		client.setLayout(layout);
+
+		if (bannerVisible) {
+			Label label = new Label(client, SWT.NULL);
+			label.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+			label.setImage(getBannerImage());
+		}
+
+		Control contents = createContents(client);
+		contents.setLayoutData(new GridData(GridData.FILL_BOTH));
+		setControl(client);
+	}
+
+	public void setBannerVisible(boolean visible) {
+		this.bannerVisible = visible;
+	}
+	public boolean isBannedVisible() {
+		return bannerVisible;
+	}
+
+	protected URL getBannerImageURL() {
+		return null;
+	}
+	private Image getBannerImage() {
+		URL imageURL = getBannerImageURL();
+		Image image = null;
+		if (imageURL == null) {
+			// use default
+			bannerImage =
+				UpdateUIImages.DESC_INSTALL_BANNER.createImage();
+			image = bannerImage;
+		}
+		return image;
+	}
+
+	public void dispose() {
+		if (bannerImage != null) {
+			bannerImage.dispose();
+		}
+		super.dispose();
+	}
+
+	protected abstract Control createContents(Composite parent);
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ContainerCheckedTreeViewer.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ContainerCheckedTreeViewer.java
new file mode 100644
index 0000000..c0f0656
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ContainerCheckedTreeViewer.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Copied from ui internal package.
+ * 
+ * CheckboxTreeViewer with special behaviour of the checked / gray state on 
+ * container (non-leaf) nodes:
+ * The grayed state is used to visualize the checked state of its children.
+ * Containers are checked and non-gary if all contained leafs are checked. The
+ * container is grayed if some but not all leafs are checked.
+ * 
+ */
+public class ContainerCheckedTreeViewer extends CheckboxTreeViewer {
+
+    /**
+     * Constructor for ContainerCheckedTreeViewer.
+     * @see CheckboxTreeViewer#CheckboxTreeViewer(Composite,int)
+     */
+    public ContainerCheckedTreeViewer(Composite parent, int style) {
+        super(parent, style);
+        initViewer();
+    }
+
+    private void initViewer() {
+        setUseHashlookup(true);
+        addCheckStateListener(new ICheckStateListener() {
+            public void checkStateChanged(CheckStateChangedEvent event) {
+                doCheckStateChanged(event.getElement());
+            }
+        });
+        addTreeListener(new ITreeViewerListener() {
+            public void treeCollapsed(TreeExpansionEvent event) {
+            }
+
+            public void treeExpanded(TreeExpansionEvent event) {
+                Widget item = findItem(event.getElement());
+                if (item instanceof TreeItem) {
+                    initializeItem((TreeItem) item);
+                }
+            }
+        });
+    }
+
+    protected void doCheckStateChanged(Object element) {
+        Widget item = findItem(element);
+        if (item instanceof TreeItem) {
+            TreeItem treeItem = (TreeItem) item;
+            treeItem.setGrayed(false);
+            updateChildrenItems(treeItem);
+            updateParentItems(treeItem.getParentItem());
+        }
+    }
+
+    /**
+     * The item has expanded. Updates the checked state of its children. 
+     */
+    private void initializeItem(TreeItem item) {
+        if (item.getChecked() && !item.getGrayed()) {
+            updateChildrenItems(item);
+        }
+    }
+
+    /**
+     * Updates the check state of all created children
+     */
+    protected void updateChildrenItems(TreeItem parent) {
+        Item[] children = getChildren(parent);
+        boolean state = parent.getChecked();
+        for (int i = 0; i < children.length; i++) {
+            TreeItem curr = (TreeItem) children[i];
+            if (curr.getData() != null
+                    && ((curr.getChecked() != state) || curr.getGrayed())) {
+                curr.setChecked(state);
+                curr.setGrayed(false);
+                updateChildrenItems(curr);
+            }
+        }
+    }
+
+    /**
+     * Updates the check / gray state of all parent items
+     */
+    private void updateParentItems(TreeItem item) {
+        if (item != null) {
+            Item[] children = getChildren(item);
+            boolean containsChecked = false;
+            boolean containsUnchecked = false;
+            for (int i = 0; i < children.length; i++) {
+                TreeItem curr = (TreeItem) children[i];
+                containsChecked |= curr.getChecked();
+                containsUnchecked |= (!curr.getChecked() || curr.getGrayed());
+            }
+            item.setChecked(containsChecked);
+            item.setGrayed(containsChecked && containsUnchecked);
+            updateParentItems(item.getParentItem());
+        }
+    }
+
+    /*
+     * @see ICheckable#setChecked(Object, boolean)
+     */
+    public boolean setChecked(Object element, boolean state) {
+        if (super.setChecked(element, state)) {
+            doCheckStateChanged(element);
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * @see CheckboxTreeViewer#setCheckedElements(Object[])
+     */
+    public void setCheckedElements(Object[] elements) {
+        super.setCheckedElements(elements);
+        for (int i = 0; i < elements.length; i++) {
+            doCheckStateChanged(elements[i]);
+        }
+    }
+
+    /*
+     * @see AbstractTreeViewer#setExpanded(Item, boolean)
+     */
+    protected void setExpanded(Item item, boolean expand) {
+        super.setExpanded(item, expand);
+        if (expand && item instanceof TreeItem) {
+            initializeItem((TreeItem) item);
+        }
+    }
+
+    /*
+     * @see CheckboxTreeViewer#getCheckedElements()
+     */
+    public Object[] getCheckedElements() {
+        Object[] checked = super.getCheckedElements();
+        // add all items that are children of a checked node but not created yet
+        ArrayList result = new ArrayList();
+        for (int i = 0; i < checked.length; i++) {
+            Object curr = checked[i];
+            result.add(curr);
+            Widget item = findItem(curr);
+            if (item != null) {
+                Item[] children = getChildren(item);
+                // check if contains the dummy node
+                if (children.length == 1 && children[0].getData() == null) {
+                    // not yet created
+                    collectChildren(curr, result);
+                }
+            }
+        }
+        return result.toArray();
+    }
+
+    private void collectChildren(Object element, ArrayList result) {
+        Object[] filteredChildren = getFilteredChildren(element);
+        for (int i = 0; i < filteredChildren.length; i++) {
+            Object curr = filteredChildren[i];
+            result.add(curr);
+            collectChildren(curr, result);
+        }
+    }
+
+    protected void createChildren(final Widget widget) {
+    	super.createChildren(widget);
+    }
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/DuplicateConflictsDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/DuplicateConflictsDialog.java
new file mode 100644
index 0000000..123858a
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/DuplicateConflictsDialog.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.internal.operations.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.internal.ui.parts.*;
+
+/**
+ * 
+ */
+public class DuplicateConflictsDialog extends MessageDialog {
+
+	private TreeViewer treeViewer;
+	private ArrayList conflicts;
+
+	class ConflictContentProvider
+		extends DefaultContentProvider
+		implements ITreeContentProvider, IStructuredContentProvider {
+		public Object[] getElements(Object input) {
+			return getChildren(input);
+		}
+		public Object getParent(Object child) {
+			return null;
+		}
+		public boolean hasChildren(Object parent) {
+			if (parent instanceof ArrayList)
+				return true;
+			return false;
+		}
+		public Object[] getChildren(Object parent) {
+			if (parent instanceof ArrayList)
+				return ((ArrayList) parent).toArray();
+			return new Object[0];
+		}
+	}
+
+	class ConflictLabelProvider extends LabelProvider {
+		public String getText(Object obj) {
+			if (obj instanceof ArrayList) {
+				ArrayList list = (ArrayList) obj;
+				for (int i = 0; i < list.size(); i++) {
+					DuplicateConflictsValidator.IdEntry entry =
+						(DuplicateConflictsValidator.IdEntry) (list).get(i);
+					if (entry.isInstallCandidate())
+						return entry.getFeature().getLabel();
+				}
+			}
+			return super.getText(obj);
+		}
+		public Image getImage(Object obj) {
+			int flags = 0;
+			if (obj instanceof ArrayList)
+				flags = UpdateLabelProvider.F_WARNING;
+			if (obj instanceof DuplicateConflictsValidator.IdEntry
+				|| obj instanceof ArrayList)
+				return UpdateUI.getDefault().getLabelProvider().get(
+					UpdateUIImages.DESC_FEATURE_OBJ,
+					flags);
+			return null;
+		}
+	}
+
+	public DuplicateConflictsDialog(Shell shell, ArrayList conflicts) {
+		super(
+			shell,
+			UpdateUIMessages.DuplicateConflictsDialog_title, 
+			null,
+			UpdateUIMessages.DuplicateConflictsDialog_message, 
+			WARNING,
+			new String[] {
+				IDialogConstants.YES_LABEL,
+				IDialogConstants.NO_LABEL },
+			0);
+		this.conflicts = conflicts;
+		UpdateUI.getDefault().getLabelProvider().connect(this);
+	}
+
+	public boolean close() {
+		UpdateUI.getDefault().getLabelProvider().disconnect(this);
+		return super.close();
+	}
+
+	protected Control createCustomArea(Composite parent) {
+		Composite client = new Composite(parent, SWT.NULL);
+		client.setLayoutData(new GridData(GridData.FILL_BOTH));
+		GridLayout layout = new GridLayout();
+		client.setLayout(layout);
+
+		Label label = new Label(client, SWT.NULL);
+		label.setText(UpdateUIMessages.DuplicateConflictsDialog_treeLabel); 
+
+		treeViewer = new TreeViewer(client, SWT.SINGLE | SWT.BORDER);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.heightHint = 200;
+		gd.widthHint = 300;
+		treeViewer.getTree().setLayoutData(gd);
+		treeViewer.setContentProvider(new ConflictContentProvider());
+		treeViewer.setLabelProvider(new ConflictLabelProvider());
+		treeViewer.setAutoExpandLevel(10);
+		treeViewer.setSorter(new ViewerSorter() {
+		});
+		treeViewer.setInput(conflicts);
+		return client;
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/EditSiteDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/EditSiteDialog.java
new file mode 100644
index 0000000..f77a69b
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/EditSiteDialog.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.model.SiteBookmark;
+
+
+public class EditSiteDialog extends NewUpdateSiteDialog {
+	SiteBookmark bookmark;
+	private int ignoreBookmark = -1;
+
+	public EditSiteDialog(Shell parentShell, SiteBookmark bookmark, SiteBookmark[] siteBookmarks) {
+		super(parentShell, siteBookmarks);
+		this.bookmark = bookmark;
+		ignoreBookmark(siteBookmarks);
+	}
+
+	public EditSiteDialog(Shell parentShell, SiteBookmark bookmark, SiteBookmark[] siteBookmarks, boolean enableOK) {
+		super(parentShell, enableOK, siteBookmarks);
+		this.bookmark = bookmark;
+		ignoreBookmark(siteBookmarks);
+	}
+
+	protected void initializeFields() {
+		name.setText(bookmark.getName());
+		url.setText(bookmark.getURL().toString());
+		url.setEditable(!bookmark.isLocal());
+	}
+
+	protected void update() {
+		try {
+			bookmark.setName(name.getText());
+			bookmark.setURL(new URL(url.getText()));
+			UpdateUI.getDefault().getUpdateModel().fireObjectChanged(bookmark, null);
+		} catch (MalformedURLException e) {
+		}
+	}
+	
+	private void ignoreBookmark( SiteBookmark[] siteBookmarks) {
+		
+		for( int i = 0; i < siteBookmarks.length; i++) {
+
+			if (siteBookmarks[i].getLabel().equals(bookmark.getLabel().trim()) &&
+				siteBookmarks[i].getURL().equals(bookmark.getURL())) {	
+				ignoreBookmark = i;	
+				return;
+			}
+			
+		}
+	}
+	
+	protected boolean isCurrentlyEditedSiteBookmark( int index) {
+		
+		return index == ignoreBookmark;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/FeatureSorter.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/FeatureSorter.java
new file mode 100644
index 0000000..9eab2eb
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/FeatureSorter.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.operations.*;
+
+public class FeatureSorter extends ViewerSorter {
+	
+	public static final int FEATURE_VERSION = 1;
+	public static final int FEATURE_LABEL = 2;
+	public static final int FEATURE_PROVIDER = 3;
+	
+	public static final int ASCENDING = 1;
+	public static final int DESCENDING = -1;
+	
+	private int key = FEATURE_LABEL;
+	private int labelOrder;
+	private int versionOrder;
+	private int providerOrder;
+	
+	public FeatureSorter(int key, int labelOrder, int versionOrder, int providerOrder) {
+		this.key = key;
+		this.labelOrder = labelOrder;
+		this.versionOrder = versionOrder;
+		this.providerOrder = providerOrder;
+	}
+
+	public int compare(Viewer viewer, Object e1, Object e2) {
+		if (!(e1 instanceof IInstallFeatureOperation)
+			|| !(e2 instanceof IInstallFeatureOperation))
+			return super.compare(viewer, e1, e2);
+			
+		IFeature f1 = ((IInstallFeatureOperation)e1).getFeature();
+		IFeature f2 = ((IInstallFeatureOperation)e2).getFeature();
+		
+		PluginVersionIdentifier v1 = f1.getVersionedIdentifier().getVersion();
+		PluginVersionIdentifier v2 = f2.getVersionedIdentifier().getVersion();
+		
+		String label1 = f1.getLabel() == null ? "" : f1.getLabel(); //$NON-NLS-1$
+		String label2 = f2.getLabel() == null ? "" : f2.getLabel(); //$NON-NLS-1$
+		
+		String provider1 = f1.getProvider() == null ? "" : f1.getProvider(); //$NON-NLS-1$
+		String provider2 = f2.getProvider() == null ? "" : f2.getProvider(); //$NON-NLS-1$
+		
+		int result = 0;
+		if (key == FEATURE_VERSION) {
+			result = compareVersions(v1, v2) * versionOrder;
+			if (result == 0) {
+				result = collator.compare(label1, label2) * labelOrder;
+				if (result == 0)
+					result = collator.compare(provider1, provider2) * providerOrder;
+			}
+		} else if (key == FEATURE_LABEL) {
+			result = collator.compare(label1, label2) * labelOrder;
+			if (result == 0) {
+				result = compareVersions(v1, v2) * versionOrder;
+				if (result == 0)
+					result = collator.compare(provider1, provider2) * providerOrder;
+			}
+		} else if (key == FEATURE_PROVIDER) {
+			result = collator.compare(provider1, provider2) * providerOrder;
+			if (result == 0) {
+				result = collator.compare(label1, label2) * labelOrder;
+				if (result == 0)
+					result = compareVersions(v1, v2) * versionOrder;
+			}
+		}
+		return result;
+	}
+	
+	private int compareVersions(PluginVersionIdentifier v1, PluginVersionIdentifier v2) {
+		if (v1.equals(v2))
+			return 0;
+		return v2.isGreaterThan(v1) ? -1 : 1;
+	}
+	
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/IDynamicPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/IDynamicPage.java
new file mode 100644
index 0000000..ca8bad4
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/IDynamicPage.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+
+import org.eclipse.update.operations.*;
+
+/**
+ *  A dynamic page in the install wizard
+ */
+public interface IDynamicPage {
+	public void setJobs(IInstallFeatureOperation [] jobs);
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ISearchProvider.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ISearchProvider.java
new file mode 100644
index 0000000..56f32cd
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ISearchProvider.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.update.search.UpdateSearchRequest;
+
+/**
+ * A search request provider
+ */
+public interface ISearchProvider {
+	UpdateSearchRequest getSearchRequest();
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallWizard.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallWizard.java
new file mode 100644
index 0000000..7ae0993
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallWizard.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.search.SiteSearchCategory;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIImages;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.search.BackLevelFilter;
+import org.eclipse.update.search.UpdateSearchRequest;
+import org.eclipse.update.search.UpdateSearchScope;
+import org.eclipse.update.ui.UpdateJob;
+
+public class InstallWizard
+	extends Wizard
+	implements ISearchProvider {
+	private ModeSelectionPage modePage;
+	private SitePage sitePage;
+	private int installCount = 0;
+	private UpdateSearchRequest searchRequest;
+	private boolean needsRestart;
+	private static boolean isRunning;
+	private UpdateJob job;
+	private InstallWizardOperation operation;
+
+
+	public InstallWizard(UpdateSearchRequest searchRequest) {
+		isRunning = true;
+        if (searchRequest == null) {
+            searchRequest =
+                new UpdateSearchRequest(
+                    new SiteSearchCategory(true),
+                    new UpdateSearchScope());
+            searchRequest.addFilter(new BackLevelFilter());
+        }
+        this.searchRequest = searchRequest;
+		setDialogSettings(UpdateUI.getDefault().getDialogSettings());
+		setDefaultPageImageDescriptor(UpdateUIImages.DESC_UPDATE_WIZ);
+		setForcePreviousAndNextButtons(true);
+		setNeedsProgressMonitor(true);
+		setWindowTitle(UpdateUIMessages.InstallWizard_wtitle); 
+	}
+
+	public boolean isRestartNeeded() {
+		return installCount > 0 && needsRestart; // or == selectedJobs.length
+	}
+
+	public boolean performCancel() {
+		isRunning = false;
+		return super.performCancel();
+	}
+
+	public void addPages() {
+		modePage = new ModeSelectionPage(searchRequest);
+		addPage(modePage);
+		sitePage = new SitePage(searchRequest);
+		addPage(sitePage);
+	}
+
+	private void saveSettings() {
+		if (modePage != null)
+			modePage.saveSettings();
+	}
+
+	public IWizardPage getNextPage(IWizardPage page) {
+
+		if (modePage != null && page.equals(modePage)) {
+			boolean update = modePage.isUpdateMode();
+			if (!update)
+				return sitePage;
+		}
+        return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.internal.ui.wizards.ISearchProvider2#getSearchRequest()
+	 */
+	public UpdateSearchRequest getSearchRequest() {
+		return searchRequest;
+	}
+
+	public static synchronized boolean isRunning() {
+		return isRunning || Job.getJobManager().find(UpdateJob.FAMILY).length > 0;
+	}
+
+    /**
+     * @see Wizard#performFinish()
+     */
+    public boolean performFinish() {
+
+        saveSettings();
+        
+        if (Job.getJobManager().find(UpdateJob.FAMILY).length > 0) {
+            // another update/install job is running, need to wait to finish or cancel old job
+            boolean proceed = MessageDialog.openQuestion(
+                    UpdateUI.getActiveWorkbenchShell(),
+                    UpdateUIMessages.InstallWizard_anotherJobTitle,
+                    UpdateUIMessages.InstallWizard_anotherJob); 
+            if (!proceed)
+                return false; // cancel this job, and let the old one go on
+        }
+        UpdateCore.getPlugin().getUpdateSession().reset();
+        launchInBackground();
+        isRunning = false;
+        return true;
+    }
+    
+	private void launchInBackground() {
+		// Downloads the feature content in the background.
+		// The job listener will then install the feature when download is finished.
+
+        if (isUpdate())
+            job = new UpdateJob(UpdateUIMessages.InstallWizard_jobName, false, false);  
+        else
+            job = new UpdateJob(UpdateUIMessages.InstallWizard_jobName, searchRequest);  
+		job.setUser(true);
+		job.setPriority(Job.INTERACTIVE);
+//		if (wait) {
+//			progressService.showInDialog(workbench.getActiveWorkbenchWindow().getShell(), job); 
+//		}
+		getOperation().run(UpdateUI.getActiveWorkbenchShell(), job);
+	}
+    
+    private InstallWizardOperation getOperation() {
+		if (operation == null)
+			operation = new InstallWizardOperation();
+		return operation;
+	}
+
+    public boolean canFinish() {
+    	      
+    	if ( modePage.isCurrentPage()) {
+            return isUpdate();
+    	} else {
+            return sitePage.isPageComplete();
+    	}   	
+    }
+    
+    private boolean isUpdate() {
+        return (modePage != null && modePage.isUpdateMode());
+    }
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallWizard2.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallWizard2.java
new file mode 100644
index 0000000..02d246f
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallWizard2.java
@@ -0,0 +1,552 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IIncludedFeatureReference;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.core.IVerificationListener;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.core.model.InstallAbortedException;
+import org.eclipse.update.internal.core.FeatureDownloadException;
+import org.eclipse.update.internal.core.LiteFeature;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.operations.DuplicateConflictsValidator;
+import org.eclipse.update.internal.operations.InstallOperation;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIImages;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.security.JarVerificationService;
+import org.eclipse.update.operations.IBatchOperation;
+import org.eclipse.update.operations.IFeatureOperation;
+import org.eclipse.update.operations.IInstallFeatureOperation;
+import org.eclipse.update.operations.IOperation;
+import org.eclipse.update.operations.IOperationListener;
+import org.eclipse.update.operations.OperationsManager;
+import org.eclipse.update.search.UpdateSearchRequest;
+
+
+public class InstallWizard2
+	extends Wizard
+	implements IOperationListener, ISearchProvider {
+	private ReviewPage reviewPage;
+	private LicensePage licensePage;
+	private OptionalFeaturesPage optionalFeaturesPage;
+	private TargetPage targetPage;
+	private IInstallConfiguration config;
+	private int installCount = 0;
+	private UpdateSearchRequest searchRequest;
+	private ArrayList jobs;
+	private boolean needsRestart;
+	private static boolean isRunning;
+	private IBatchOperation installOperation;
+	private Job job;
+	public static final Object jobFamily = new Object();
+	private IJobChangeListener jobListener;
+    private boolean isUpdate;
+
+	public InstallWizard2(UpdateSearchRequest searchRequest, IInstallFeatureOperation[] jobs, boolean isUpdate) {
+		this (searchRequest, new ArrayList(Arrays.asList(jobs)), isUpdate);
+	}
+
+	public InstallWizard2(UpdateSearchRequest searchRequest, ArrayList jobs, boolean isUpdate) {
+		this.isUpdate = isUpdate;
+        this.searchRequest = searchRequest;
+        this.jobs = jobs;
+        isRunning = true;
+        setDialogSettings(UpdateUI.getDefault().getDialogSettings());
+        setDefaultPageImageDescriptor(UpdateUIImages.DESC_UPDATE_WIZ);
+        setForcePreviousAndNextButtons(true);
+        setNeedsProgressMonitor(true);
+        setWindowTitle(UpdateUIMessages.InstallWizard_wtitle); 
+	}
+    
+	public int getInstallCount() {
+		return installCount;
+	}
+	public boolean isRestartNeeded() {
+		return installCount > 0 && needsRestart; // or == selectedJobs.length
+	}
+
+	public boolean performCancel() {
+		isRunning = false;
+		if (targetPage != null)
+			targetPage.removeAddedSites();
+		return super.performCancel();
+	}
+	/**
+	 * @see Wizard#performFinish()
+	 */
+	public boolean performFinish() {
+		IInstallFeatureOperation[] selectedJobs = reviewPage.getSelectedJobs();
+		
+		// Check for duplication conflicts
+		ArrayList conflicts = DuplicateConflictsValidator.computeDuplicateConflicts(selectedJobs, config);
+		if (conflicts != null) {
+			DuplicateConflictsDialog dialog = new DuplicateConflictsDialog(getShell(), conflicts);
+			if (dialog.open() != 0)
+				return false;
+		}
+		
+		if (Job.getJobManager().find(jobFamily).length > 0) {
+			// another update/install job is running, need to wait to finish or cancel old job
+			boolean proceed = MessageDialog.openQuestion(
+					UpdateUI.getActiveWorkbenchShell(),
+					UpdateUIMessages.InstallWizard_anotherJobTitle,
+					UpdateUIMessages.InstallWizard_anotherJob); 
+			if (!proceed)
+				return false; // cancel this job, and let the old one go on
+		}
+		
+		// set the install operation
+		installOperation = getBatchInstallOperation(selectedJobs);
+		if (installOperation != null)
+			launchInBackground();
+		return true;
+	}
+
+	public void addPages() {
+		reviewPage = new ReviewPage(isUpdate, searchRequest, jobs);
+		addPage(reviewPage);
+
+		try {
+//			config = UpdateUtils.createInstallConfiguration();
+			config = SiteManager.getLocalSite().getCurrentConfiguration();
+		} catch (CoreException e) {
+			UpdateUI.logException(e);
+		}
+
+		licensePage = new LicensePage(true);
+		addPage(licensePage);
+		optionalFeaturesPage = new OptionalFeaturesPage(config);
+		addPage(optionalFeaturesPage);
+		targetPage = new TargetPage(config, isUpdate);
+		addPage(targetPage);
+	}
+
+
+	private boolean isPageRequired(IWizardPage page) {
+		if (page == null)
+			return false;
+			
+		if (page.equals(licensePage)) {
+			return OperationsManager.hasSelectedJobsWithLicenses(
+				reviewPage.getSelectedJobs());
+		}
+		if (page.equals(optionalFeaturesPage)) {
+			return OperationsManager.hasSelectedJobsWithOptionalFeatures(
+				reviewPage.getSelectedJobs());
+		}
+		if (page.equals(targetPage)) {
+			return reviewPage.getSelectedJobs().length > 0;
+		}
+		return true;
+	}
+
+	public IWizardPage getNextPage(IWizardPage page) {
+		IWizardPage[] pages = getPages();
+		boolean start = false;
+		IWizardPage nextPage = null;
+
+		if (page.equals(reviewPage)) {
+			updateDynamicPages();
+		}
+
+		for (int i = 0; i < pages.length; i++) {
+			if (pages[i].equals(page)) {
+				start = true;
+			} else if (start) {
+				if (isPageRequired(pages[i])) {
+					nextPage = pages[i];
+					break;
+				}
+			}
+		}
+		return nextPage;
+	}
+
+	private void updateDynamicPages() {
+		if (licensePage != null) {
+			IInstallFeatureOperation[] licenseJobs =
+				OperationsManager.getSelectedJobsWithLicenses(
+					reviewPage.getSelectedJobs());
+			licensePage.setJobs(licenseJobs);
+		}
+		if (optionalFeaturesPage != null) {
+			IInstallFeatureOperation[] optionalJobs =
+				OperationsManager.getSelectedJobsWithOptionalFeatures(
+					reviewPage.getSelectedJobs());
+			optionalFeaturesPage.setJobs(optionalJobs);
+		}
+		if (targetPage != null) {
+			IInstallFeatureOperation[] installJobs =
+				reviewPage.getSelectedJobs();
+			targetPage.setJobs(installJobs);
+		}
+	}
+
+	public boolean canFinish() {
+		IWizardPage page = getContainer().getCurrentPage();
+		return page.equals(targetPage) && page.isPageComplete();
+	}
+
+	private void preserveOriginatingURLs(
+		IFeature feature,
+		IFeatureReference[] optionalFeatures) {
+		// walk the hierarchy and preserve the originating URL
+		// for all the optional features that are not chosen to
+		// be installed.
+		URL url = feature.getSite().getURL();
+		try {
+			IIncludedFeatureReference[] irefs =
+				feature.getIncludedFeatureReferences();
+			for (int i = 0; i < irefs.length; i++) {
+				IIncludedFeatureReference iref = irefs[i];
+				boolean preserve = false;
+				if (iref.isOptional()) {
+					boolean onTheList = false;
+					for (int j = 0; j < optionalFeatures.length; j++) {
+						if (optionalFeatures[j].equals(iref)) {
+							//was on the list
+							onTheList = true;
+							break;
+						}
+					}
+					if (!onTheList)
+						preserve = true;
+				}
+				if (preserve) {
+					try {
+						String id =
+							iref.getVersionedIdentifier().getIdentifier();
+						UpdateUI.setOriginatingURL(id, url);
+					} catch (CoreException e) {
+						// Silently ignore
+					}
+				} else {
+					try {
+						IFeature ifeature = iref.getFeature(null);
+						preserveOriginatingURLs(ifeature, optionalFeatures);
+					} catch (CoreException e) {
+						// Silently ignore
+					}
+				}
+			}
+		} catch (CoreException e) {
+			// Silently ignore
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.operations.IOperationListener#afterExecute(org.eclipse.update.operations.IOperation)
+	 */
+	public boolean afterExecute(IOperation operation, Object data) {
+		if (!(operation instanceof IInstallFeatureOperation))
+			return true;
+		IInstallFeatureOperation job = (IInstallFeatureOperation) operation;
+		IFeature oldFeature = job.getOldFeature();
+		if (oldFeature == null && job.getOptionalFeatures() != null)
+			preserveOriginatingURLs(
+				job.getFeature(),
+				job.getOptionalFeatures());
+
+		installCount++;
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.operations.IOperationListener#beforeExecute(org.eclipse.update.operations.IOperation)
+	 */
+	public boolean beforeExecute(IOperation operation, Object data) {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.internal.ui.wizards.ISearchProvider2#getSearchRequest()
+	 */
+	public UpdateSearchRequest getSearchRequest() {
+		return searchRequest;
+	}
+
+	public static synchronized boolean isRunning() {
+		return isRunning || Job.getJobManager().find(jobFamily).length > 0;
+	}
+	
+	private IBatchOperation getBatchInstallOperation(final IInstallFeatureOperation[] selectedJobs) {
+		final IVerificationListener verificationListener =new JarVerificationService(
+				//InstallWizard.this.getShell());
+				UpdateUI.getActiveWorkbenchShell());
+		
+		// setup jobs with the correct environment
+		IInstallFeatureOperation[] operations =	new IInstallFeatureOperation[selectedJobs.length];
+		for (int i = 0; i < selectedJobs.length; i++) {
+			IInstallFeatureOperation job = selectedJobs[i];
+			IFeature[] unconfiguredOptionalFeatures = null;
+			IFeatureReference[] optionalFeatures = null;
+			if (UpdateUtils.hasOptionalFeatures(job.getFeature())) {
+				optionalFeatures = optionalFeaturesPage.getCheckedOptionalFeatures(job);
+				unconfiguredOptionalFeatures = optionalFeaturesPage.getUnconfiguredOptionalFeatures(job, job.getTargetSite());
+			}
+			IInstallFeatureOperation op =
+				OperationsManager
+					.getOperationFactory()
+					.createInstallOperation(
+					job.getTargetSite(),
+					job.getFeature(),
+					optionalFeatures,
+					unconfiguredOptionalFeatures,
+					verificationListener);
+			operations[i] = op;
+		}
+		return OperationsManager.getOperationFactory().createBatchInstallOperation(operations);
+	}
+
+
+
+	private void launchInBackground() {
+		// Downloads the feature content in the background.
+		// The job listener will then install the feature when download is finished.
+		
+		// TODO: should we cancel existing jobs?
+		if (jobListener != null)
+			Job.getJobManager().removeJobChangeListener(jobListener);
+		if (job != null)
+			Job.getJobManager().cancel(job);
+		jobListener = new UpdateJobChangeListener();
+		Job.getJobManager().addJobChangeListener(jobListener);
+		
+		job = new Job(UpdateUIMessages.InstallWizard_jobName) { 
+			public IStatus run(IProgressMonitor monitor) {
+				if (download(monitor))
+					return Status.OK_STATUS;
+				else {
+					isRunning = false;
+					return Status.CANCEL_STATUS;
+				}
+			}
+			public boolean belongsTo(Object family) {
+				return InstallWizard2.jobFamily == family;
+			}
+		};
+
+		job.setUser(true);
+		job.setPriority(Job.INTERACTIVE);
+//		if (wait) {
+//			progressService.showInDialog(workbench.getActiveWorkbenchWindow().getShell(), job); 
+//		}
+		job.schedule();
+	}
+	
+	private boolean install(IProgressMonitor monitor) {
+		// Installs the (already downloaded) features and prompts for restart
+		try {
+			needsRestart = installOperation.execute(monitor, InstallWizard2.this);
+			UpdateUI.getStandardDisplay().asyncExec(new Runnable() {
+				public void run() {
+					UpdateUI.requestRestart(InstallWizard2.this.isRestartNeeded());
+				}
+			});
+		} catch (final InvocationTargetException e) {
+			final Throwable targetException = e.getTargetException();
+			if (!(targetException instanceof InstallAbortedException)){
+				UpdateUI.getStandardDisplay().syncExec(new Runnable() {
+					public void run() {
+						UpdateUI.logException(targetException);
+					}
+				});
+			}
+			return false;
+		} catch (CoreException e) {
+			return false;
+		} finally {
+			isRunning = false;
+		}
+		return true;
+	}
+	
+	private boolean download(final IProgressMonitor monitor) {
+		// Downloads the feature content.
+		// This method is called from a background job.
+		// If download fails, the user is prompted to retry.
+		try {
+			IFeatureOperation[] ops = installOperation.getOperations();
+			monitor.beginTask(UpdateUIMessages.InstallWizard_download, 5 * ops.length);
+			for (int i = 0; i < ops.length; i++) {
+				IInstallFeatureOperation op = (IInstallFeatureOperation)ops[i];
+				
+				try {
+					String featureName = op.getFeature().getLabel();
+					if ((featureName == null ) || (featureName.trim() == "") ) { //$NON-NLS-1$
+						featureName = op.getFeature().getVersionedIdentifier().getIdentifier();
+					}
+					SubProgressMonitor featureDownloadMonitor = new SubProgressMonitor(monitor, 2);
+					
+					featureDownloadMonitor.beginTask(featureName, 2);
+					featureDownloadMonitor.subTask(NLS.bind(UpdateUIMessages.InstallWizard_downloadingFeatureJar, featureName));
+					
+					if (op.getFeature() instanceof LiteFeature) {
+						ISiteFeatureReference featureReference = getFeatureReference(op.getFeature());
+						IFeature feature = featureReference.getFeature(featureDownloadMonitor);
+						if (op instanceof InstallOperation) {
+							((InstallOperation)op).setFeature(feature);
+						}
+					}
+					//featureDownloadMonitor.worked(1);
+					SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 3);
+					UpdateUtils.downloadFeatureContent(op.getTargetSite(), op.getFeature(), op.getOptionalFeatures(), subMonitor);
+				} catch (final CoreException e) {
+					if(e instanceof FeatureDownloadException){
+						boolean retry = retryDownload((FeatureDownloadException)e);
+						if (retry) {
+							// redownload current feature
+							i--;
+							continue;
+						}
+					} else {
+						UpdateCore.log(e);
+						if ( !monitor.isCanceled()) {
+							Display.getDefault().syncExec( new Runnable () {
+								public void run() {
+									IStatus status = new Status( IStatus.ERROR, UpdateUI.getPluginId(), IStatus.OK, UpdateUIMessages.InstallWizard2_updateOperationHasFailed, e);
+									ErrorDialog.openError(null, null, null, status);
+								
+								}							
+							});
+						}
+					}
+					return false;
+				}
+			}
+			return true;
+		} finally {
+			monitor.done();
+		}
+	}
+	
+	private boolean retryDownload(final FeatureDownloadException e) {
+
+		final boolean retry[] = new boolean[1];
+		UpdateUI.getStandardDisplay().syncExec(new Runnable() {
+			public void run() {
+				retry[0] =	MessageDialog.openQuestion(
+					UpdateUI.getActiveWorkbenchShell(),
+					UpdateUIMessages.InstallWizard_retryTitle, 
+					e.getMessage()+"\n" //$NON-NLS-1$
+						+ UpdateUIMessages.InstallWizard_retry); 
+			}
+		});
+		return retry[0];
+	}
+    
+
+    private class UpdateJobChangeListener extends JobChangeAdapter {
+        public void done(final IJobChangeEvent event) {
+            // the job listener is triggered when the download job is done, and it proceeds
+            // with the actual install
+            if (event.getJob() == InstallWizard2.this.job && event.getResult() == Status.OK_STATUS) {
+                Job.getJobManager().removeJobChangeListener(this);
+                Job.getJobManager().cancel(job);
+                
+                Job installJob = new Job(UpdateUIMessages.InstallWizard_jobName) { 
+        			public IStatus run(IProgressMonitor monitor) {
+        				//install(monitor);
+        				if (install(monitor)) {
+        					return Status.OK_STATUS;
+        				} else {
+        					isRunning = false;
+        					return Status.CANCEL_STATUS;
+        				}
+        			}
+        			public boolean belongsTo(Object family) {
+        				return InstallWizard2.jobFamily == family;
+        			}
+        		};
+
+        		installJob.setUser(true);
+        		installJob.setPriority(Job.INTERACTIVE);
+//        		if (wait) {
+//        			progressService.showInDialog(workbench.getActiveWorkbenchWindow().getShell(), job); 
+//        		}
+        		installJob.schedule();
+                
+                /*final IProgressService progressService= PlatformUI.getWorkbench().getProgressService();
+                UpdateUI.getStandardDisplay().asyncExec(new Runnable() {
+                    public void run() {
+                        try {
+                            progressService.busyCursorWhile( new IRunnableWithProgress() {
+                                public void run(final IProgressMonitor monitor){
+                                    install(monitor);
+                                }
+                            });
+                        } catch (InvocationTargetException e) {
+                            UpdateUI.logException(e);
+                        } catch (InterruptedException e) {
+                            UpdateUI.logException(e, false);
+                        }
+                    }
+                }); */
+            } else if (event.getJob() == InstallWizard2.this.job && event.getResult() != Status.OK_STATUS) {
+                isRunning = false;
+                Job.getJobManager().removeJobChangeListener(this);
+                Job.getJobManager().cancel(job);
+                UpdateUI.getStandardDisplay().syncExec(new Runnable() {
+                    public void run() {
+                        UpdateUI.log(event.getResult(), true);
+                    }
+                });
+            }
+        }
+    }
+    
+	
+	public ISiteFeatureReference getFeatureReference(IFeature feature) {
+
+		ISite site = feature.getSite();
+		ISiteFeatureReference[] references = site.getFeatureReferences();
+		ISiteFeatureReference currentReference = null;
+		for (int i = 0; i < references.length; i++) {
+			currentReference = references[i];
+			try {
+				if (feature.getVersionedIdentifier().equals(currentReference.getVersionedIdentifier()))
+					return currentReference;
+			} catch (CoreException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+
+		UpdateCore.warn("Feature " + feature + " not found on site" + site.getURL()); //$NON-NLS-1$ //$NON-NLS-2$
+		return null;
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallWizardOperation.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallWizardOperation.java
new file mode 100644
index 0000000..9cf4be2
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/InstallWizardOperation.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.ui.UpdateJob;
+
+public class InstallWizardOperation {
+	private UpdateJob job;
+	private IJobChangeListener jobListener;
+	private Shell shell;
+	private Shell parentShell;
+
+	public InstallWizardOperation() {
+	}
+
+	public void run(Shell parent, UpdateJob task) {
+		shell = parent;
+		if (shell.getParent()!=null && shell.getParent() instanceof Shell)
+			parentShell = (Shell)shell.getParent();
+		// cancel any existing jobs and remove listeners
+		if (jobListener != null)
+			Job.getJobManager().removeJobChangeListener(jobListener);
+		if (job != null)
+			Job.getJobManager().cancel(job);
+		
+		// then setup the new job and listener and schedule the job
+		job = task;
+		jobListener = new UpdateJobChangeListener();
+		Job.getJobManager().addJobChangeListener(jobListener);
+		job.schedule();
+	}
+	
+	private Shell getValidShell() {
+		if (shell.isDisposed())
+			return parentShell;
+		return shell;
+	}
+
+	private class UpdateJobChangeListener extends JobChangeAdapter {
+		public void done(final IJobChangeEvent event) {
+			final Shell validShell = getValidShell();
+			// the job listener is triggered when the search job is done, and proceeds to next wizard
+			if (event.getJob() == job) {
+				Job.getJobManager().removeJobChangeListener(this);
+				Job.getJobManager().cancel(job);
+				if (job.getStatus() == Status.CANCEL_STATUS)
+					return;
+				if (job.getStatus() != Status.OK_STATUS)
+					getValidShell().getDisplay().syncExec(new Runnable() {
+						public void run() {
+							UpdateUI.log(job.getStatus(), true);
+						}
+					});
+
+				validShell.getDisplay().asyncExec(new Runnable() {
+					public void run() {
+						validShell.getDisplay().beep();
+						BusyIndicator.showWhile(validShell.getDisplay(), new Runnable() {
+							public void run() {
+								openInstallWizard2();
+							}
+						});
+					}
+				});
+			}
+		}
+
+		private void openInstallWizard2() {
+			if (InstallWizard2.isRunning()) {
+				MessageDialog.openInformation(getValidShell(), UpdateUIMessages.InstallWizard_isRunningTitle, UpdateUIMessages.InstallWizard_isRunningInfo);
+				return;
+			}
+            if (job.getUpdates() == null || job.getUpdates().length == 0) {
+                if (job.isUpdate())
+                    MessageDialog.openInformation(getValidShell(), UpdateUIMessages.InstallWizard_ReviewPage_zeroUpdates, UpdateUIMessages.InstallWizard_ReviewPage_zeroUpdates); 
+                else
+                    MessageDialog.openInformation(getValidShell(), UpdateUIMessages.InstallWizard_ReviewPage_zeroFeatures, UpdateUIMessages.InstallWizard_ReviewPage_zeroFeatures); 
+                return;
+            }
+			InstallWizard2 wizard = new InstallWizard2(job.getSearchRequest(), job.getUpdates(), job.isUpdate());
+			WizardDialog dialog = new ResizableInstallWizardDialog(getValidShell(), wizard, UpdateUIMessages.AutomaticUpdatesJob_Updates); 
+			dialog.create();
+			dialog.open();
+		}
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/LicensePage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/LicensePage.java
new file mode 100644
index 0000000..77d0bdd
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/LicensePage.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.*;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIImages;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.operations.IInstallFeatureOperation;
+
+public class LicensePage extends WizardPage implements IDynamicPage {
+	private boolean multiLicenseMode = false;
+	private IInstallFeatureOperation[] jobs;
+	private IInstallFeatureOperation[] oldjJobs;
+	private Text text;
+	private Table table;
+	private Button acceptButton;
+	private Button declineButton;
+
+	/**
+	 * Constructor for LicensePage2
+	 */
+	public LicensePage(boolean multiLicenseMode) {
+		super("License"); //$NON-NLS-1$
+		setTitle(UpdateUIMessages.InstallWizard_LicensePage_title);
+		setPageComplete(false);
+		this.multiLicenseMode = multiLicenseMode;
+		UpdateUI.getDefault().getLabelProvider().connect(this);
+		setDescription(multiLicenseMode ?UpdateUIMessages.InstallWizard_LicensePage_desc2 : 
+            UpdateUIMessages.InstallWizard_LicensePage_desc);
+	}
+	public void dispose() {
+		UpdateUI.getDefault().getLabelProvider().disconnect(this);
+		super.dispose();
+	}
+
+	public void setJobs(IInstallFeatureOperation[] jobs) {		
+		this.jobs = jobs;		
+	}
+
+	public void createControl(Composite parent) {
+		Composite client = new Composite(parent, SWT.NULL);
+		client.setLayoutData(new GridData(GridData.FILL_BOTH));
+		GridLayout layout = new GridLayout();
+		client.setLayout(layout);
+		
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(client, "org.eclipse.update.ui.LicensePage2"); //$NON-NLS-1$
+
+		if (multiLicenseMode) {
+			layout.numColumns = 3;
+			layout.makeColumnsEqualWidth = true;
+
+			table = new Table(client, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+
+			table.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					if (e.item != null) {
+						Object data = e.item.getData();
+						text.setText((data == null) ? "" : (String) data); //$NON-NLS-1$
+					}
+				}
+			});
+			GridData gd = new GridData(GridData.FILL_BOTH);
+			gd.heightHint = 200;
+			table.setLayoutData(gd);
+		}
+		text =
+			new Text(
+				client,
+				SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.WRAP | SWT.READ_ONLY);
+
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.heightHint = 200;
+		if (multiLicenseMode)
+			gd.horizontalSpan = 2;
+		text.setLayoutData(gd);
+		text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+
+		Composite buttonContainer = new Composite(client, SWT.NULL);
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		if (multiLicenseMode)
+			gd.horizontalSpan = 3;
+		buttonContainer.setLayout(new GridLayout());
+		buttonContainer.setLayoutData(gd);
+
+		acceptButton = new Button(buttonContainer, SWT.RADIO);
+		acceptButton.setText(multiLicenseMode?UpdateUIMessages.InstallWizard_LicensePage_accept2
+                : UpdateUIMessages.InstallWizard_LicensePage_accept);
+		acceptButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				setPageComplete(acceptButton.getSelection());
+			}
+		});
+		declineButton = new Button(buttonContainer, SWT.RADIO);
+		declineButton.setText(multiLicenseMode?UpdateUIMessages.InstallWizard_LicensePage_decline2
+                : UpdateUIMessages.InstallWizard_LicensePage_decline);
+		declineButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				setPageComplete(acceptButton.getSelection());
+			}
+		});
+		setControl(client);
+
+		Dialog.applyDialogFont(parent);
+	}
+
+	public void setVisible(boolean visible) { // TO DO: Optimize out the case where a feature does not have a license?
+
+		boolean jobsChanged = didJobsChange(jobs);
+		declineButton.setSelection(!jobsChanged && declineButton.getSelection());
+		acceptButton.setSelection(!jobsChanged && acceptButton.getSelection());
+		
+		if (jobs.length == 1) {
+			acceptButton.setText(UpdateUIMessages.InstallWizard_LicensePage_accept);
+			declineButton.setText(UpdateUIMessages.InstallWizard_LicensePage_decline);
+		} else if (jobs.length > 1) {
+			acceptButton.setText(UpdateUIMessages.InstallWizard_LicensePage_accept2);
+			declineButton.setText(UpdateUIMessages.InstallWizard_LicensePage_decline2);
+		}
+		
+		if (visible) {
+			if (multiLicenseMode) {
+				TableItem item;
+				for (int i = 0; i < jobs.length; i++) {
+					IFeature feature = jobs[i].getFeature();
+					item = new TableItem(table, SWT.NONE);
+					String label =
+						feature.getLabel()
+							+ " " //$NON-NLS-1$
+							+ feature.getVersionedIdentifier().getVersion().toString();
+					item.setText(label);
+					item.setImage(
+						UpdateUI.getDefault().getLabelProvider().get(
+							feature.isPatch()
+								? UpdateUIImages.DESC_EFIX_OBJ
+								: UpdateUIImages.DESC_FEATURE_OBJ));
+					String license = feature.getLicense().getAnnotation();
+					// Question: Can this ever be null? What is the runtime cost?
+					item.setData(license);
+				}
+
+				table.setSelection(0);
+			}
+			showLicenseText();
+		} else {
+			if (multiLicenseMode) {
+				TableItem items[] = table.getItems();
+				for (int i = items.length - 1; i >= 0; i--) {
+					table.getItem(i).dispose();
+				}
+			}
+		}
+		super.setVisible(visible);
+		oldjJobs = jobs;
+		
+	}
+
+	private void showLicenseText() {
+		if (!multiLicenseMode) {
+			text.setText(jobs[0].getFeature().getLicense().getAnnotation());
+			return;
+		}
+		TableItem[] selectedItems = table.getSelection();
+		if (selectedItems.length == 0) {
+			text.setText(""); //$NON-NLS-1$
+		} else {
+			Object data = selectedItems[0].getData();
+			text.setText((data == null) ? "" : (String) data); //$NON-NLS-1$
+		}
+	}
+	
+	private boolean didJobsChange(IInstallFeatureOperation[] jobs){
+		
+		if ( (jobs == null) || (oldjJobs == null) || (jobs.length == 0) || (oldjJobs.length == 0) )
+			return true;
+				
+		boolean foundIt = false;
+		
+		for ( int i = 0; i < jobs.length; i++) {
+			foundIt = false;
+			for ( int j = 0; j < oldjJobs.length; j++) {
+				if (jobs[i].getFeature().getVersionedIdentifier().equals(oldjJobs[j].getFeature().getVersionedIdentifier()) ) {
+					foundIt = true;
+					break;
+				}
+			}
+			if (!foundIt) {
+				return true;
+			}
+		}
+		return false;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/LocalSiteSelector.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/LocalSiteSelector.java
new file mode 100644
index 0000000..e398298
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/LocalSiteSelector.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.SiteBookmark;
+
+/**
+ */
+public class LocalSiteSelector {
+
+	/**
+	 * 
+	 */
+	static String lastLocation = null;
+	public LocalSiteSelector() {
+		super();
+	}
+	public static SiteBookmark getLocaLSite(Shell parent, SiteBookmark[] siteBookmarks) {
+		DirectoryDialog dialog = new DirectoryDialog(parent);
+		dialog.setMessage(
+			UpdateUIMessages.LocalSiteSelector_dialogMessage); 
+		dialog.setFilterPath(lastLocation);
+		String dir = dialog.open();
+
+		SiteBookmark siteBookmark = null;
+		while (dir != null && siteBookmark == null) {
+			File dirFile = new File(dir);
+			if (isDirSite(dirFile)) {
+				if (!isDuplicate( dirFile, siteBookmarks)) {
+					siteBookmark = createDirSite(dirFile);
+					lastLocation = dir;
+				} else {
+					MessageDialog.openInformation(parent,
+												  UpdateUIMessages.LocalSiteSelector_dirInfoTitle, 
+												  UpdateUIMessages.LocalSiteSelector_dirDuplicateDefinition); 
+					dialog.setFilterPath(dir);
+					dir = dialog.open();
+				}
+			} else {
+				MessageDialog.openInformation(
+					parent,
+					UpdateUIMessages.LocalSiteSelector_dirInfoTitle, 
+					UpdateUIMessages.LocalSiteSelector_dirInfoMessage); 
+				dialog.setFilterPath(dir);
+				dir = dialog.open();
+			}
+		}
+		return siteBookmark;
+	}
+	public static SiteBookmark getLocaLZippedSite(Shell parent, SiteBookmark[] siteBookmarks) {
+		FileDialog dialog = new FileDialog(parent);
+		dialog.setText(
+			UpdateUIMessages.LocalSiteSelector_dialogMessagezip); 
+		//dialog.setFilterExtensions(new String[] { "*.zip", "*.jar" });
+		// //$NON-NLS-1$
+		dialog.setFilterExtensions(new String[] { "*.jar;*.zip" }); //$NON-NLS-1$
+
+		SiteBookmark siteBookmark = null;
+
+		String zip = dialog.open();
+		while (zip != null && siteBookmark == null) {
+			File zipF = new File(zip);
+			if (isZipSite(zipF)) {
+				siteBookmark = createZipSite(zipF);
+				if (isDuplicate( siteBookmark.getURL(), siteBookmarks)) {
+					MessageDialog.openInformation(parent,
+							  UpdateUIMessages.LocalSiteSelector_zipInfoTitle, 
+							  UpdateUIMessages.LocalSiteSelector_zipDuplicateDefinition);
+					siteBookmark = null;
+					zip = dialog.open();
+				}
+			} else {
+				MessageDialog.openInformation(
+					parent,
+					UpdateUIMessages.LocalSiteSelector_zipInfoTitle, 
+					UpdateUIMessages.LocalSiteSelector_zipInfoMessage); 
+				zip = dialog.open();
+			}
+		}
+		return siteBookmark;
+	}
+	/**
+	 * Returns true the zip file contains an update site
+	 * 
+	 * @param file
+	 * @return
+	 */
+	static boolean isZipSite(File file) {
+		if (!file.getName().toLowerCase().endsWith(".zip") //$NON-NLS-1$
+			&& !file.getName().toLowerCase().endsWith(".jar")) { //$NON-NLS-1$
+			return false;
+		}
+
+		ZippedSiteValidator validator = new ZippedSiteValidator(file);
+		BusyIndicator.showWhile(
+			UpdateUI.getActiveWorkbenchShell().getDisplay(),
+			validator);
+		return validator.isValid();
+	}
+
+	/**
+	 * Returns true if the specified dir contains an update site
+	 * 
+	 * @param dir
+	 * @return
+	 */
+	static boolean isDirSite(File dir) {
+		File siteXML = new File(dir, "site.xml"); //$NON-NLS-1$
+		File featuresDir = new File(dir, "features"); //$NON-NLS-1$
+		File pluginsDir = new File(dir, "plugins"); //$NON-NLS-1$
+		return siteXML.exists()
+			|| featuresDir.exists()
+			&& featuresDir.isDirectory()
+			&& pluginsDir.exists()
+			&& pluginsDir.isDirectory();
+	}
+
+	/**
+	 * Creates a bookmark to a zipped site
+	 * 
+	 * @param file
+	 * @return
+	 */
+	static SiteBookmark createZipSite(File file) {
+		try {
+			URL fileURL = new URL("file", null, file.getAbsolutePath()); //$NON-NLS-1$
+			URL url =
+				new URL(
+					"jar:" //$NON-NLS-1$
+						+ fileURL.toExternalForm().replace('\\', '/')
+						+ "!/"); //$NON-NLS-1$
+			SiteBookmark site = new SiteBookmark(file.getName(), url, false);
+			site.setLocal(true);
+			return site;
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	/**
+	 * Creates a bookmark to a site on the file system
+	 * 
+	 * @param file
+	 * @return
+	 */
+	static SiteBookmark createDirSite(File file) {
+		try {
+			URL url = file.toURL();
+			String parent = file.getParent();
+			if(parent == null)
+				parent = ""; //$NON-NLS-1$
+			else
+				parent = new File(parent).getName();
+			String siteName = parent + "/" + file.getName(); //$NON-NLS-1$
+			SiteBookmark site = new SiteBookmark(siteName, url, false);
+			site.setLocal(true);
+			return site;
+		} catch (Exception e) {
+			return null;
+		}
+	}
+	static class ZippedSiteValidator implements Runnable {
+		File file;
+		boolean valid = false;
+		public ZippedSiteValidator(File file) {
+			this.file = file;
+		}
+		public void run() {
+			ZipFile siteZip = null;
+			try {
+				// check if the zip file contains site.xml
+				siteZip = new ZipFile(file);
+				if (siteZip.getEntry("site.xml") != null) { //$NON-NLS-1$
+					valid = true;
+					return;
+				}
+
+				boolean hasFeatures = false;
+				boolean hasPlugins = false;
+				for (Enumeration iterator = siteZip.entries();
+					iterator.hasMoreElements();
+					) {
+					ZipEntry zEntry = (ZipEntry) iterator.nextElement();
+					if (!hasFeatures
+						&& zEntry.getName().startsWith("features")) { //$NON-NLS-1$
+						hasFeatures = true;
+					}
+					if (!hasPlugins
+						&& zEntry.getName().startsWith("plugins")) { //$NON-NLS-1$
+						hasPlugins = true;
+					}
+					if (hasFeatures && hasPlugins) {
+						valid = true;
+						return;
+					}
+				}
+			} catch (Exception e) {
+			} finally {
+				try {
+					if (siteZip != null) {
+						siteZip.close();
+					}
+				} catch (IOException ioe) {
+				}
+			}
+
+		}
+		/**
+		 * @return Returns the valid. */
+		public boolean isValid() {
+			return valid;
+		}
+	}
+	
+	private static boolean isDuplicate( File file, SiteBookmark[] siteBookmarks) {
+		
+		try {
+			return isDuplicate(file.toURL(), siteBookmarks);
+		} catch (MalformedURLException mue) {
+			// this should not ever happen
+			UpdateUI.logException(mue);
+		}
+		
+		return false;
+	}
+	
+	private static boolean isDuplicate( URL url, SiteBookmark[] siteBookmarks) {
+		
+		if ( siteBookmarks == null)
+			return false;
+
+		for( int i = 0; i < siteBookmarks.length; i++) {
+			if (siteBookmarks[i].getURL().equals(url))
+				return true;
+
+		}
+		return false;
+		
+	}	
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/MirrorsDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/MirrorsDialog.java
new file mode 100644
index 0000000..eae5756
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/MirrorsDialog.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.update.core.ISiteWithMirrors;
+import org.eclipse.update.core.IURLEntry;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+
+public class MirrorsDialog extends Dialog {
+	//private ISiteWithMirrors site;
+	private String siteName;
+	private IURLEntry[] mirrors;
+	private List mirrorsList;
+	private IURLEntry mirrorSelected;
+	private Button automaticallyChooseMirrorCheckbox;
+	//private Button okButton;
+	/**
+	 * @param parentShell
+	 */
+	public MirrorsDialog(Shell parentShell, ISiteWithMirrors site, String siteName) {
+		super(parentShell);
+		setShellStyle(getShellStyle()|SWT.RESIZE);
+		//this.site = site;
+		this.siteName = siteName;
+		try {
+			this.mirrors = site.getMirrorSiteEntries();
+		} catch (CoreException e) {
+			// ignore, as the mirrors have already been queried earlier, so we don't expect error here
+		}
+	}
+	
+	protected void createButtonsForButtonBar(Composite parent) {
+		createButton(
+				parent,
+				IDialogConstants.OK_ID,
+				IDialogConstants.OK_LABEL,
+				true);
+		createButton(
+			parent,
+			IDialogConstants.CANCEL_ID,
+			IDialogConstants.CANCEL_LABEL,
+			false);
+	}
+	
+	protected Control createDialogArea(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 10;
+		layout.marginWidth = 10;
+		layout.verticalSpacing = 10;
+		composite.setLayout(layout);
+		GridData data = new GridData(GridData.FILL_BOTH);
+		data.widthHint = 450;
+		data.heightHint = 300;
+		composite.setLayoutData(data);
+		
+		Text text = new Text(composite, SWT.WRAP );
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 2;
+		text.setLayoutData(data);
+		text.setText(NLS.bind(UpdateUIMessages.MirrorsDialog_text, siteName));
+		text.setBackground(parent.getBackground());
+		text.setEditable(false);
+		// the text should not receive focus
+		text.addFocusListener(new FocusAdapter() {
+			public void focusGained(FocusEvent e) {
+				mirrorsList.setFocus();
+			}
+		});
+		
+		mirrorsList = new List(composite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
+		data = new GridData(GridData.FILL_BOTH);
+		data.horizontalSpan = 2;
+		mirrorsList.setLayoutData(data);
+		
+		for (int i=0; i<mirrors.length; i++)
+			mirrorsList.add(mirrors[i].getAnnotation());
+		mirrorsList.add(siteName);
+
+		mirrorsList.select(0);
+		
+		automaticallyChooseMirrorCheckbox =
+			new Button(composite, SWT.CHECK | SWT.LEFT);
+		automaticallyChooseMirrorCheckbox.setText(UpdateUIMessages.MainPreferencePage_automaticallyChooseMirror);
+		data = new GridData();
+		data.horizontalSpan = 2;
+		automaticallyChooseMirrorCheckbox.setLayoutData(data);		
+		
+		Dialog.applyDialogFont(composite);
+		
+		mirrorsList.addMouseListener( new MouseListener() {
+				public void mouseDoubleClick(MouseEvent e) {
+					okPressed();			
+				}	
+				public void mouseDown(MouseEvent e) {
+					// do nothing			
+				}
+				public void mouseUp(MouseEvent e) {
+					//	do nothing				
+				}			
+			}
+		);
+		return composite;
+	}
+		
+	protected void okPressed() {
+		int i = mirrorsList.getSelectionIndex();
+		// first entry is the site itself
+		if (i <mirrors.length)
+			mirrorSelected = mirrors[i];
+		if (automaticallyChooseMirrorCheckbox.getSelection()) {
+			Preferences prefs = UpdateCore.getPlugin().getPluginPreferences();
+			prefs.setValue(UpdateCore.P_AUTOMATICALLY_CHOOSE_MIRROR, true);
+			UpdateCore.getPlugin().savePluginPreferences();
+		}
+		super.okPressed();
+	}
+	
+	public IURLEntry getMirror() {
+		return mirrorSelected;
+	}
+
+   protected void configureShell(Shell shell) {
+       super.configureShell(shell);
+       shell.setText(UpdateUIMessages.MirrorsDialog_title);
+    }
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ModeSelectionPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ModeSelectionPage.java
new file mode 100644
index 0000000..8563d59
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ModeSelectionPage.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.search.UpdateSearchRequest;
+
+/**
+ */
+public class ModeSelectionPage extends BannerPage implements ISearchProvider {
+	private boolean updateMode=true;
+	private Button updatesButton;
+	private Button newFeaturesButton;
+	private UpdateSearchRequest searchRequest;
+	private static final String SECTION_ID = "ModeSelectionPage"; //$NON-NLS-1$
+	private static final String P_NEW_FEATURES_MODE = "new-features-mode"; //$NON-NLS-1$
+	
+	public ModeSelectionPage(UpdateSearchRequest searchRequest) {
+		super("modeSelection"); //$NON-NLS-1$
+		setTitle(UpdateUIMessages.ModeSelectionPage_title); 
+		setDescription(UpdateUIMessages.ModeSelectionPage_desc); 
+		this.searchRequest = searchRequest;
+	}
+	
+	public UpdateSearchRequest getSearchRequest() {
+		initializeSearch();
+		return searchRequest;
+	}
+	
+	private IDialogSettings getSettings() {
+		IDialogSettings master = UpdateUI.getDefault().getDialogSettings();
+		IDialogSettings section = master.getSection(SECTION_ID);
+		if (section==null)
+			section = master.addNewSection(SECTION_ID);
+		return section;
+	}
+
+	private void initializeSearch() {
+		if (searchRequest!=null) return;
+		searchRequest = UpdateUtils.createNewUpdatesRequest(null, false);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.update.internal.ui.wizards.BannerPage#createContents(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createContents(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		composite.setLayout(layout);
+		updatesButton = new Button(composite, SWT.RADIO);
+		updatesButton.setText(UpdateUIMessages.ModeSelectionPage_updates); 
+		updateMode = !getSettings().getBoolean(P_NEW_FEATURES_MODE);
+		updatesButton.setSelection(updateMode);
+		
+		final Label updatesText = new Label(composite, SWT.WRAP);
+		updatesText.setText(UpdateUIMessages.ModeSelectionPage_updatesText);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.widthHint = 100;
+		updatesText.setLayoutData(gd);
+		
+		updatesButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				updateMode = true;
+                getWizard().getContainer().updateButtons();
+			}
+		});
+		// spacer
+		new Label(composite, SWT.NULL);
+		newFeaturesButton = new Button(composite, SWT.RADIO);
+		newFeaturesButton.setSelection(!updateMode);
+		newFeaturesButton.setText(UpdateUIMessages.ModeSelectionPage_newFeatures); 
+		newFeaturesButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				updateMode = false;
+                getWizard().getContainer().updateButtons();
+			}
+		});		
+
+		final Label newFeaturesText = new Label(composite, SWT.WRAP);
+		newFeaturesText.setText(UpdateUIMessages.ModeSelectionPage_newFeaturesText);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.widthHint = 100;
+		newFeaturesText.setLayoutData(gd);
+
+		/*
+		composite.addControlListener(new ControlAdapter() {
+			public void controlResized(ControlEvent e) {
+				Composite parent = (Composite)e.widget;
+				Rectangle carea = parent.getClientArea();
+				GridData gd = (GridData)updatesText.getLayoutData();
+				gd.widthHint = carea.width; 
+				gd = (GridData)newFeaturesText.getLayoutData();
+				gd.widthHint = carea.width; 
+			}
+		});
+		*/
+		
+		Dialog.applyDialogFont(parent);
+		
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, "org.eclipse.update.ui.ModeSelectionPage"); //$NON-NLS-1$
+
+		return composite;
+	}
+	
+	public void saveSettings() {
+		boolean updateMode = updatesButton.getSelection();
+		getSettings().put(P_NEW_FEATURES_MODE, !updateMode);
+	}
+	
+	public boolean isUpdateMode() {
+		return updateMode;
+	}
+
+	public boolean isPageComplete() {
+		return updateMode && super.isPageComplete();
+	}
+
+	protected boolean isCurrentPage() {
+		return super.isCurrentPage();
+	}
+
+	public boolean canFlipToNextPage() {
+		return !updateMode;
+	}
+	
+	
+    
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/NewUpdateSiteDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/NewUpdateSiteDialog.java
new file mode 100644
index 0000000..4a58077
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/NewUpdateSiteDialog.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.StatusDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.update.internal.ui.URLCoder;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.SiteBookmark;
+import org.eclipse.update.internal.ui.model.UpdateModel;
+
+
+public class NewUpdateSiteDialog extends StatusDialog {
+	
+	protected Text name;
+	protected Text url;
+	private Button okButton;
+	private boolean enableOK = false;
+	private SiteBookmark[] siteBookmarks;
+	/**
+	 * @param parentShell
+	 */
+	public NewUpdateSiteDialog(Shell parentShell) {
+		super(parentShell);
+		enableOK = false;
+	}
+	
+	public NewUpdateSiteDialog(Shell parentShell, SiteBookmark[] siteBookmarks) {
+		
+		this(parentShell);		
+		this.siteBookmarks = siteBookmarks;
+	}
+	
+	public NewUpdateSiteDialog(Shell parentShell, boolean enableOkButtons) {
+		super(parentShell);
+		enableOK = enableOkButtons;
+	}
+	
+	public NewUpdateSiteDialog(Shell parentShell, boolean enableOkButtons, SiteBookmark[] siteBookmarks) {
+		this(parentShell, enableOkButtons);
+		this.siteBookmarks = siteBookmarks;
+	}
+	
+	protected void createButtonsForButtonBar(Composite parent) {
+		
+		//super.createButtonBar(parent);
+		okButton = createButton(
+				parent,
+				IDialogConstants.OK_ID,
+				IDialogConstants.OK_LABEL,
+				true);
+		createButton(
+			parent,
+			IDialogConstants.CANCEL_ID,
+			IDialogConstants.CANCEL_LABEL,
+			false);
+		
+		okButton.setEnabled(enableOK);
+		
+	}
+	
+	protected Control createDialogArea(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		composite.setLayout(layout);
+		GridData data = new GridData();
+		data.widthHint = 350;
+		composite.setLayoutData(data);
+		
+		Label label = new Label(composite, SWT.NONE);
+		label.setText(UpdateUIMessages.NewUpdateSiteDialog_name); 
+		
+		name = new Text(composite, SWT.BORDER);
+		name.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		name.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				verifyComplete();
+			}
+		});
+		
+		label = new Label(composite, SWT.NONE);
+		label.setText(UpdateUIMessages.NewUpdateSiteDialog_url); 
+		
+		url = new Text(composite, SWT.BORDER);
+		url.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		url.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				verifyComplete();
+			}
+		});
+		
+		initializeFields();
+		Dialog.applyDialogFont(composite);
+		return composite;
+	}
+	
+	protected void initializeFields() {
+		url.setText("http://"); //$NON-NLS-1$
+	}
+	
+	protected void okPressed() {
+		update();
+		super.okPressed();
+	}
+
+	protected void update() {
+		try {
+			UpdateModel model = UpdateUI.getDefault().getUpdateModel();
+			SiteBookmark bookmark = new SiteBookmark(name.getText(), new URL(url.getText()), false);
+            bookmark.setSelected(true);
+			model.addBookmark(bookmark);
+			model.saveBookmarks();
+		} catch (MalformedURLException e) {
+		}
+	}
+	
+	private void verifyComplete() {
+			
+		if (okButton == null) {
+			return;		
+		}
+		
+		if (name.getText().trim().length() == 0 || url.getText().trim().length() == 0) {
+			okButton.setEnabled(false);
+			this.updateStatus( new Status(IStatus.ERROR, UpdateUI.getPluginId(), IStatus.OK, UpdateUIMessages.NewUpdateSiteDialog_error_nameOrUrlNotSpecified, null)); 
+			return;
+		}
+	
+		try {
+			URL newURL = new URL(URLCoder.decode(url.getText().trim()));
+			if (url.getEditable()) {
+				okButton.setEnabled(!newURL.getProtocol().equals("file")); //$NON-NLS-1$
+				if (newURL.getProtocol().equals("file")) { //$NON-NLS-1$
+					okButton.setEnabled(false);
+					this.updateStatus( new Status(IStatus.ERROR, UpdateUI.getPluginId(), IStatus.OK, UpdateUIMessages.NewUpdateSiteDialog_error_incorrectUrl, null)); 
+					return;
+				}
+			}
+		} catch (Exception e) {
+			okButton.setEnabled(false);
+			this.updateStatus( new Status(IStatus.ERROR, UpdateUI.getPluginId(), IStatus.OK, UpdateUIMessages.NewUpdateSiteDialog_error_incorrectUrl, null)); 
+			return;
+		}
+		
+		if (isDuplicate()) {
+			return;
+		} else {
+			okButton.setEnabled(true);
+			this.updateStatus( new Status(IStatus.OK, UpdateUI.getPluginId(), IStatus.OK, "", null));  //$NON-NLS-1$
+		}
+		
+		
+	}
+	
+	private boolean isDuplicate() {
+		
+		if ( siteBookmarks == null)
+			return false;
+		
+		for( int i = 0; i < this.siteBookmarks.length; i++) {
+			if ( !isCurrentlyEditedSiteBookmark(i)) {
+				if (siteBookmarks[i].getLabel().equals(name.getText().trim())) {
+					okButton.setEnabled(false);
+					this.updateStatus( new Status(IStatus.ERROR, UpdateUI.getPluginId(), IStatus.OK, UpdateUIMessages.NewUpdateSiteDialog_error_duplicateName, null)); 
+					return true;
+				} else if (siteBookmarks[i].getURL().toString().trim().equals(url.getText().trim())) {
+					okButton.setEnabled(false);
+					this.updateStatus( new Status(IStatus.ERROR, UpdateUI.getPluginId(), IStatus.OK, NLS.bind(UpdateUIMessages.NewUpdateSiteDialog_error_duplicateUrl, siteBookmarks[i].getLabel()), null)); 
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+	
+	protected boolean isCurrentlyEditedSiteBookmark( int index) {
+		return false;
+	}
+	
+	
+	protected void updateButtonsEnableState(IStatus status) {
+		if (okButton != null && !okButton.isDisposed())
+			okButton.setEnabled(!status.matches(IStatus.ERROR));
+	}
+	
+
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/OptionalFeaturesPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/OptionalFeaturesPage.java
new file mode 100644
index 0000000..dd0f760
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/OptionalFeaturesPage.java
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.internal.operations.FeatureHierarchyElement;
+import org.eclipse.update.internal.operations.JobRoot;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIImages;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.parts.DefaultContentProvider;
+import org.eclipse.update.internal.ui.parts.SWTUtil;
+import org.eclipse.update.operations.IInstallFeatureOperation;
+
+public class OptionalFeaturesPage extends BannerPage implements IDynamicPage {
+	private CheckboxTreeViewer treeViewer;
+	private Button selectAllButton;
+	private Button deselectAllButton;
+	private IInstallConfiguration config;
+	private JobRoot[] jobRoots;
+
+	class TreeContentProvider
+		extends DefaultContentProvider
+		implements ITreeContentProvider {
+
+		public Object[] getChildren(Object parent) {
+			if (parent instanceof JobRoot) {
+				return ((JobRoot) parent).getElements();
+			}
+			if (parent instanceof FeatureHierarchyElement) {
+				FeatureHierarchyElement fe = (FeatureHierarchyElement) parent;
+				Object root = fe.getRoot();
+				boolean oldFeature = false;
+				if (root instanceof JobRoot) {
+					IInstallFeatureOperation job = ((JobRoot)root).getJob();
+					boolean patch = UpdateUtils.isPatch(job.getFeature());
+					oldFeature = job.getOldFeature() != null;
+					return fe.getChildren(oldFeature, patch, config);
+				}
+			}
+			return new Object[0];
+		}
+
+		public Object getParent(Object child) {
+			return null;
+		}
+
+		public boolean hasChildren(Object parent) {
+			return getChildren(parent).length > 0;
+		}
+
+		public Object[] getElements(Object input) {
+			if (jobRoots == null)
+				return new Object[0];
+			return jobRoots;
+		}
+	}
+
+	class TreeLabelProvider extends LabelProvider {
+		public String getText(Object obj) {
+			if (obj instanceof JobRoot) {
+				IFeature feature = ((JobRoot) obj).getJob().getFeature();
+				return feature.getLabel()
+					+ " " //$NON-NLS-1$
+					+ feature.getVersionedIdentifier().getVersion().toString();
+			}
+			if (obj instanceof FeatureHierarchyElement) {
+				String name = ((FeatureHierarchyElement) obj).getLabel();
+				if (name != null)
+					return name;
+			}
+
+			return super.getText(obj);
+		}
+		public Image getImage(Object obj) {
+			return UpdateUI.getDefault().getLabelProvider().get(
+				UpdateUIImages.DESC_FEATURE_OBJ);
+		}
+	}
+
+	/**
+	 * Constructor for ReviewPage2
+	 */
+	public OptionalFeaturesPage(IInstallConfiguration config) {
+		super("OptionalFeatures"); //$NON-NLS-1$
+		setTitle(UpdateUIMessages.InstallWizard_OptionalFeaturesPage_title);
+		setDescription(UpdateUIMessages.InstallWizard_OptionalFeaturesPage_desc);
+		this.config = config;
+		UpdateUI.getDefault().getLabelProvider().connect(this);
+	}
+
+	public void setJobs(IInstallFeatureOperation[] jobs) {
+		jobRoots = new JobRoot[jobs.length];
+		for (int i = 0; i < jobs.length; i++) {
+			jobRoots[i] = new JobRoot(jobs[i]);
+		}
+	}
+
+	public void dispose() {
+		UpdateUI.getDefault().getLabelProvider().disconnect(this);
+		super.dispose();
+	}
+
+
+	public Control createContents(Composite parent) {
+		Composite client = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginWidth = layout.marginHeight = 0;
+		client.setLayout(layout);
+
+		createCheckboxTreeViewer(client);
+
+		selectAllButton = new Button(client, SWT.PUSH);
+		selectAllButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				selectAll(true);
+			}
+		});
+		selectAllButton.setText(UpdateUIMessages.InstallWizard_OptionalFeaturesPage_selectAll);
+		GridData gd =
+			new GridData(
+				GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING);
+		selectAllButton.setLayoutData(gd);
+		SWTUtil.setButtonDimensionHint(selectAllButton);
+
+		deselectAllButton = new Button(client, SWT.PUSH);
+		deselectAllButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				selectAll(false);
+			}
+		});
+		deselectAllButton.setText(UpdateUIMessages.InstallWizard_OptionalFeaturesPage_deselectAll);
+		gd =
+			new GridData(
+				GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING);
+		deselectAllButton.setLayoutData(gd);
+		SWTUtil.setButtonDimensionHint(deselectAllButton);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(client, "org.eclipse.update.ui.MultiOptionalFeaturesPage2"); //$NON-NLS-1$
+		
+		Dialog.applyDialogFont(parent);
+		
+		return client;
+	}
+
+	private void createCheckboxTreeViewer(Composite parent) {
+		Label label = new Label(parent, SWT.NULL);
+		label.setText(UpdateUIMessages.InstallWizard_OptionalFeaturesPage_treeLabel);
+		GridData gd = new GridData();
+		gd.horizontalSpan = 2;
+		label.setLayoutData(gd);
+		treeViewer =
+			new CheckboxTreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+		gd = new GridData(GridData.FILL_BOTH);
+		gd.verticalSpan = 2;
+		treeViewer.getTree().setLayoutData(gd);
+		treeViewer.setContentProvider(new TreeContentProvider());
+		treeViewer.setLabelProvider(new TreeLabelProvider());
+		treeViewer.addCheckStateListener(new ICheckStateListener() {
+			public void checkStateChanged(CheckStateChangedEvent e) {
+				handleChecked(e.getElement(), e.getChecked());
+			}
+		});
+		treeViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
+		treeViewer.setInput(this);
+	}
+
+	public void setVisible(boolean visible) {
+		if (visible) {
+			treeViewer.setInput(jobRoots);
+			initializeStates();
+		}
+		super.setVisible(visible);
+		if (visible) {
+			treeViewer.getTree().setFocus();
+		}		
+	}
+
+	private void initializeStates() {
+		ArrayList checked = new ArrayList();
+		ArrayList grayed = new ArrayList();
+		ArrayList editable = new ArrayList();
+
+		for (int i = 0; i < jobRoots.length; i++) {
+			checked.add(jobRoots[i]);
+			grayed.add(jobRoots[i]);
+			boolean update = jobRoots[i].getJob().getOldFeature() != null;
+			initializeStates(update, jobRoots[i].getElements(), checked, grayed, editable);
+		}
+		treeViewer.setCheckedElements(checked.toArray());
+		treeViewer.setGrayedElements(grayed.toArray());
+		selectAllButton.setEnabled(editable.size()>0);
+		deselectAllButton.setEnabled(editable.size()>0);
+	}
+
+	private void initializeStates(
+		boolean update,
+		Object[] elements,
+		ArrayList checked,
+		ArrayList grayed,
+		ArrayList editable) {
+
+		for (int i = 0; i < elements.length; i++) {
+			FeatureHierarchyElement element =
+				(FeatureHierarchyElement) elements[i];
+			if (element.isChecked())
+				checked.add(element);
+			if (!element.isEditable())
+				grayed.add(element);
+			else
+				editable.add(element);
+			initializeStates(update, element.getChildren(), checked, grayed, editable);
+		}
+	}
+
+	private void selectAll(boolean value) {
+		ArrayList selected = new ArrayList();
+		for (int i = 0; i < jobRoots.length; i++) {
+			IInstallFeatureOperation job = jobRoots[i].getJob();
+			selected.add(job);
+			Object[] elements = jobRoots[i].getElements();
+			for (int j = 0; j < elements.length; j++) {
+				FeatureHierarchyElement element = (FeatureHierarchyElement) elements[j];
+				selectAll(job.getOldFeature() != null, element, selected, value);
+			}
+		}
+		treeViewer.setCheckedElements(selected.toArray());
+	}
+
+	private void selectAll(
+		boolean update,
+		FeatureHierarchyElement ref,
+		ArrayList selected,
+		boolean value) {
+
+		if (!ref.isOptional()) {
+			selected.add(ref);
+		} else {
+			if (ref.isEditable()) {
+				ref.setChecked(value);
+				if (value)
+					selected.add(ref);
+			} else if (ref.isChecked()) {
+				selected.add(ref);
+			}
+		}
+		Object[] included = ref.getChildren();
+		for (int i = 0; i < included.length; i++) {
+			selectAll(update, (FeatureHierarchyElement) included[i], selected, value);
+		}
+	}
+
+	private void handleChecked(Object element, boolean checked) {
+		if (element instanceof JobRoot) {
+			treeViewer.setChecked(element, !checked);
+			return;
+		}
+		FeatureHierarchyElement fe = (FeatureHierarchyElement) element;
+
+		if (!fe.isEditable())
+			treeViewer.setChecked(element, !checked);
+		else {
+			// update the result
+			fe.setChecked(checked);
+		}
+	}
+	
+	public IFeature[] getUnconfiguredOptionalFeatures(IInstallFeatureOperation job, IConfiguredSite targetSite) {
+		for (int i = 0; i < jobRoots.length; i++) {
+			if (job.equals(jobRoots[i].getJob())) {
+				return jobRoots[i].getUnconfiguredOptionalFeatures(config, targetSite);
+			}
+		}
+		return new IFeature[0];
+	}
+	
+	public IFeatureReference[] getCheckedOptionalFeatures(IInstallFeatureOperation currentJob) {
+		HashSet set = new HashSet();
+		JobRoot jobRoot = null;
+
+		for (int i = 0; i < jobRoots.length; i++) {
+			if (currentJob.equals(jobRoots[i].getJob())) {
+				jobRoot = jobRoots[i];
+				break;
+			}
+		}
+		if (jobRoot == null)
+			return new IFeatureReference[0];
+
+		IInstallFeatureOperation job = jobRoot.getJob();
+		boolean update = job.getOldFeature() != null;
+		boolean patch = UpdateUtils.isPatch(job.getFeature());
+		FeatureHierarchyElement[] elements = jobRoot.getElements();
+		for (int i = 0; i < elements.length; i++) {
+			elements[i].addCheckedOptionalFeatures(update, patch, config, set);
+		}
+		return (IFeatureReference[]) set.toArray(new IFeatureReference[set.size()]);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizard.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizard.java
new file mode 100644
index 0000000..8622831
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizard.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.internal.ui.UpdateUIImages;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+
+public class ReplaceFeatureVersionWizard extends Wizard {
+	private ReplaceFeatureVersionWizardPage page;
+
+	public ReplaceFeatureVersionWizard(IFeature currentFeature, IFeature[] features) {
+		setWindowTitle(UpdateUIMessages.SwapFeatureWizard_title); 
+		setDefaultPageImageDescriptor(UpdateUIImages.DESC_UPDATE_WIZ);
+		page = new ReplaceFeatureVersionWizardPage(currentFeature, features);
+	}
+
+	public void addPages() {
+		addPage(page);
+	}
+	
+	public boolean performFinish() {
+		return page.performFinish();
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizardPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizardPage.java
new file mode 100644
index 0000000..e643d57
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReplaceFeatureVersionWizardPage.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.lang.reflect.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.operation.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.wizard.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.operations.*;
+
+
+public class ReplaceFeatureVersionWizardPage extends WizardPage {
+	
+	private IFeature currentFeature;
+	private IFeature[] features;
+	private TableViewer tableViewer;
+
+	public ReplaceFeatureVersionWizardPage(IFeature currentFeature, IFeature[] features) {
+		super("SwapFeature"); //$NON-NLS-1$
+		setTitle(UpdateUIMessages.SwapFeatureWizardPage_title); 
+		setDescription(UpdateUIMessages.SwapFeatureWizardPage_desc); 
+		this.currentFeature = currentFeature;
+		this.features = features;
+	}
+
+	public void createControl(Composite parent) {
+		Composite tableContainer = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = layout.marginWidth = 0;
+		tableContainer.setLayout(layout);
+
+		Label label = new Label(tableContainer, SWT.NONE);
+		label.setText(UpdateUIMessages.SwapFeatureWizardPage_label); 
+
+		Table table = new Table(tableContainer, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL);
+		table.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		tableViewer = new TableViewer(table);
+		tableViewer.setLabelProvider(new LabelProvider() {
+			public Image getImage(Object element) {
+				UpdateLabelProvider provider =
+					UpdateUI.getDefault().getLabelProvider();
+				return provider.get(UpdateUIImages.DESC_UNCONF_FEATURE_OBJ, 0);
+			}
+			public String getText(Object element) {
+				IFeature feature = (IFeature) element;
+				return feature.getLabel() + " " + feature.getVersionedIdentifier().getVersion().toString(); //$NON-NLS-1$
+			}
+		});
+		
+		tableViewer.setContentProvider(new IStructuredContentProvider() {
+			public Object[] getElements(Object element) {
+				return features;
+			}
+			public void dispose() {
+			}
+			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			}
+		});
+		
+		tableViewer.setSorter(new ViewerSorter() {
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				PluginVersionIdentifier v1 = ((IFeature)e1).getVersionedIdentifier().getVersion();
+				PluginVersionIdentifier v2 = ((IFeature)e2).getVersionedIdentifier().getVersion();
+				return v1.isGreaterOrEqualTo(v2) ? -1 : 1;
+			}
+		});
+		
+		tableViewer.addFilter(new ViewerFilter() {
+			public boolean select(Viewer viewer, Object parentElement, Object element) {
+				String version =
+					((IFeature) element).getVersionedIdentifier().getVersion().toString();
+				return !version.equals(
+					currentFeature.getVersionedIdentifier().getVersion().toString());
+			}
+		});
+
+		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				IStructuredSelection ssel = (IStructuredSelection)tableViewer.getSelection();
+				if (ssel == null)
+					return;
+				IFeature chosenFeature = (IFeature)ssel.getFirstElement();
+				IStatus validationStatus =
+					OperationsManager.getValidator().validatePendingReplaceVersion(currentFeature, chosenFeature);
+				setPageComplete(validationStatus == null || validationStatus.getCode() == IStatus.WARNING);
+		
+				if (validationStatus == null) {
+					setErrorMessage(null);
+				} else if (validationStatus.getCode() == IStatus.WARNING) {
+					setErrorMessage(null);
+					setMessage(validationStatus.getMessage(), IMessageProvider.WARNING);
+				} else {
+					setErrorMessage(validationStatus.getMessage());
+				}
+			}
+		});
+		
+		tableViewer.setInput(currentFeature);
+		tableViewer.getTable().select(0);
+		setControl(tableContainer);
+		
+		Dialog.applyDialogFont(tableContainer);
+	}
+
+	public boolean performFinish() {
+		IStructuredSelection ssel = (IStructuredSelection)tableViewer.getSelection();
+		IFeature chosenFeature = (IFeature)ssel.getFirstElement();
+		
+		return swap(currentFeature, chosenFeature);
+	}
+	
+	private boolean swap(final IFeature currentFeature, final IFeature anotherFeature) {
+//		IStatus status =
+//			OperationsManager.getValidator().validatePendingReplaceVersion(currentFeature, anotherFeature);
+//		if (status != null) {
+//			ErrorDialog.openError(
+//				UpdateUI.getActiveWorkbenchShell(),
+//				null,
+//				null,
+//				status);
+//			return false;
+//		}
+
+		IRunnableWithProgress operation = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor)
+				throws InvocationTargetException {
+				IOperation revertOperation =
+					OperationsManager
+						.getOperationFactory()
+						.createReplaceFeatureVersionOperation(currentFeature, anotherFeature);
+				boolean restarting = false;
+				try {
+					boolean restartNeeded = revertOperation.execute(monitor, null);
+					restarting = UpdateUI.requestRestart(restartNeeded);
+				} catch (CoreException e) {
+					throw new InvocationTargetException(e);
+				} finally {
+					//if the system is already shutdown, ending the monitor here will fail
+					if (!restarting)
+						monitor.done();
+				}
+			}
+		};
+		try {
+			getContainer().run(false, true, operation);
+			return true;
+		} catch (InvocationTargetException e) {
+			Throwable targetException = e.getTargetException();
+			if (targetException instanceof InstallAbortedException) {
+				return true;
+			} else {
+				UpdateUI.logException(e);
+			}
+			return false;
+		} catch (InterruptedException e) {
+			return false;
+		}
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ResizableInstallWizardDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ResizableInstallWizardDialog.java
new file mode 100644
index 0000000..3ed230a
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ResizableInstallWizardDialog.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.wizard.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.internal.ui.parts.*;
+import org.eclipse.update.operations.*;
+
+public class ResizableInstallWizardDialog extends WizardDialog {
+	private String title;
+	
+	/**
+	 * Creates a new resizable wizard dialog.
+	 */
+	public ResizableInstallWizardDialog(Shell parent, IWizard wizard, String title) {
+		super(parent, wizard);
+		setShellStyle(getShellStyle() | SWT.RESIZE);
+		this.title = title;
+	}	
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.window.Window#create()
+	 */
+	public void create() {
+		super.create();
+		
+		getShell().setText(title);
+		SWTUtil.setDialogSize(this, 600, 500);
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.window.Window#open()
+	 */
+	public int open() {
+		IStatus status = OperationsManager.getValidator().validatePlatformConfigValid();
+		if (status != null) {
+			ErrorDialog.openError(
+					getShell(),
+					null,
+					null,
+					status);
+			return IDialogConstants.ABORT_ID;
+		}
+		
+		return super.open();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizard.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizard.java
new file mode 100644
index 0000000..e5e9743
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizard.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.jface.wizard.*;
+import org.eclipse.update.internal.ui.*;
+
+/**
+ * @author Wassim Melhem
+ */
+public class RevertConfigurationWizard extends Wizard {
+	
+	RevertConfigurationWizardPage page;
+
+	public RevertConfigurationWizard() {
+		super();
+		setWindowTitle(UpdateUIMessages.RevertConfigurationWizard_wtitle); 
+		setDefaultPageImageDescriptor(UpdateUIImages.DESC_CONFIG_WIZ);
+	}
+	
+	public void addPages() {
+		page = new RevertConfigurationWizardPage();
+		addPage(page);
+	}
+
+	public boolean performFinish() {
+		return page.performFinish();
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizardPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizardPage.java
new file mode 100644
index 0000000..025037e
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/RevertConfigurationWizardPage.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.lang.reflect.*;
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.operation.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.wizard.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.core.*;
+import org.eclipse.update.core.model.*;
+import org.eclipse.update.internal.core.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.operations.*;
+
+
+public class RevertConfigurationWizardPage extends WizardPage {
+
+	private TableViewer activitiesViewer;
+	private TableViewer configViewer;
+	public static Color blueBGColor;
+	private SashForm sashForm;
+
+	public RevertConfigurationWizardPage() {
+		super("RevertConfiguration"); //$NON-NLS-1$
+		setTitle(UpdateUIMessages.RevertConfigurationWizardPage_title); 
+		setDescription(UpdateUIMessages.RevertConfigurationWizardPage_desc); 
+		blueBGColor = new Color(null, 238,238,255);
+		
+	}
+
+	public void createControl(Composite parent) {
+		sashForm = new SashForm(parent, SWT.VERTICAL);
+		sashForm.setLayout(new GridLayout());
+		sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		createConfigurationsSection(sashForm);
+		createActivitiesSection(sashForm);
+		setControl(sashForm);
+
+		Object element = configViewer.getElementAt(0);
+		if (element != null)
+			configViewer.setSelection(new StructuredSelection(element));
+		Dialog.applyDialogFont(sashForm);
+	}
+
+	private void createConfigurationsSection(Composite parent) {
+		Composite tableContainer = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = layout.marginWidth = 0;
+		tableContainer.setLayout(layout);
+		tableContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		Label label = new Label(tableContainer, SWT.NONE);
+		label.setText(UpdateUIMessages.RevertConfigurationWizardPage_label); 
+
+		Table table = new Table(tableContainer, SWT.BORDER | SWT.V_SCROLL);
+		table.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		configViewer = new TableViewer(table);
+		configViewer.setLabelProvider(new LabelProvider() {
+			public Image getImage(Object element) {
+				UpdateLabelProvider provider =
+					UpdateUI.getDefault().getLabelProvider();
+				return provider.get(UpdateUIImages.DESC_CONFIG_OBJ, 0);
+			}
+			public String getText(Object element) {
+				return Utilities.format(
+					((IInstallConfiguration) element).getCreationDate());
+			}
+
+		});
+		configViewer.setContentProvider(new IStructuredContentProvider() {
+			public Object[] getElements(Object element) {
+				ArrayList result = new ArrayList();
+				ILocalSite localSite = (ILocalSite) element;
+				IInstallConfiguration current =	localSite.getCurrentConfiguration();
+				IInstallConfiguration[] configurations = localSite.getConfigurationHistory();
+				for (int i = configurations.length - 1; i >= 0; i--) {
+					if (!current.equals(configurations[i])) {
+						result.add(configurations[i]);
+					}
+				}
+				return result.toArray();
+			}
+			
+			public void dispose() {
+			}
+
+			public void inputChanged(
+				Viewer viewer,
+				Object oldInput,
+				Object newInput) {
+			}
+
+		});
+
+		configViewer
+			.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent e) {
+				IStructuredSelection ssel =	(IStructuredSelection) e.getSelection();
+				InstallConfiguration currentConfig = (InstallConfiguration)ssel.getFirstElement();
+				activitiesViewer.setInput(currentConfig);
+				activitiesViewer.refresh();
+				TableItem[] items = activitiesViewer.getTable().getItems();
+				for (int i =0; i<items.length; i++){
+					IActivity activity = (IActivity)items[i].getData();
+					// for now, we test exact config match. If needed, we can also compare dates, etc.
+					if (((InstallConfiguration)activity.getInstallConfiguration()).equals(currentConfig))
+						items[i].setBackground(blueBGColor);
+					else
+						items[i].setBackground(activitiesViewer.getControl().getBackground());
+				}
+			}
+		});
+
+		try {
+			configViewer.setInput(SiteManager.getLocalSite());
+		} catch (CoreException e1) {
+		}
+	}
+
+	private void createActivitiesSection(Composite parent) {
+		final Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout gridLayout = new GridLayout();
+		gridLayout.marginHeight = gridLayout.marginWidth = 0;
+		composite.setLayout(gridLayout);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		composite.setLayoutData(gd);
+
+
+
+		Label label = new Label(composite, SWT.NONE);
+		label.setText(
+			UpdateUIMessages.RevertConfigurationWizardPage_activities); 
+
+		TableLayoutComposite tlComposite= new TableLayoutComposite(composite, SWT.NONE);
+		tlComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+		activitiesViewer = ActivitiesTableViewer.createViewer(tlComposite, false);
+
+		tlComposite.addColumnData(new ColumnPixelData(16, true, true));
+		tlComposite.addColumnData(new ColumnWeightData(2, 150, true));
+		tlComposite.addColumnData(new ColumnWeightData(5, 200, true));
+		tlComposite.addColumnData(new ColumnWeightData(4, 100, true));
+
+		//activitiesViewer.getTable().setLayout(layout);
+
+		TableItem[] configs = configViewer.getTable().getItems();
+		if (configs.length >0)
+			activitiesViewer.setInput(configs[0].getData());
+		
+		composite.addControlListener(new ControlAdapter() {
+			public void controlResized(ControlEvent e) {
+				int sashHeight = getSashForm().getSize().y;
+				int sashWidth = getSashForm().getSize().x;
+				if (composite.getSize().y > (sashHeight*0.85) && composite.getSize().x > (sashWidth*0.5)){
+					getSashForm().setOrientation(SWT.HORIZONTAL);
+				} else {
+					getSashForm().setOrientation(SWT.VERTICAL);
+				}
+			}
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.IDialogPage#dispose()
+	 */
+	public void dispose() {
+		blueBGColor.dispose();
+	}
+	
+	public SashForm getSashForm(){
+		return sashForm;
+	}
+	public boolean performFinish() {
+		Shell shell = getContainer().getShell();
+		boolean result =
+			MessageDialog.openQuestion(
+				shell,
+				shell.getText(),
+				UpdateUIMessages.RevertConfigurationWizardPage_question); 
+		if (!result)
+			return false;
+
+		boolean finish = performRevert();
+		if (finish) {
+			PlatformUI.getWorkbench().restart();
+		}
+		return finish;
+	}
+
+	public boolean performRevert() {
+
+		IStructuredSelection ssel =
+			(IStructuredSelection) configViewer.getSelection();
+		final IInstallConfiguration target =
+			(IInstallConfiguration) ssel.getFirstElement();
+
+		IStatus status =
+			OperationsManager.getValidator().validatePendingRevert(target);
+		if (status != null && status.getCode() == IStatus.ERROR) {
+			ErrorDialog.openError(
+				UpdateUI.getActiveWorkbenchShell(),
+				null,
+				null,
+				status);
+			return false;
+		}
+
+		IRunnableWithProgress operation = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor)
+				throws InvocationTargetException {
+				IOperation revertOperation =
+					OperationsManager
+						.getOperationFactory()
+						.createRevertConfigurationOperation(
+						target,
+						new UIProblemHandler());
+				try {
+					revertOperation.execute(monitor, null);
+				} catch (CoreException e) {
+					throw new InvocationTargetException(e);
+				} finally {
+					monitor.done();
+				}
+			}
+		};
+		try {
+			getContainer().run(false, true, operation);
+			return true;
+		} catch (InvocationTargetException e) {
+			Throwable targetException = e.getTargetException();
+			if (targetException instanceof InstallAbortedException) {
+				return true;
+			} else {
+				UpdateUI.logException(e);
+			}
+			return false;
+		} catch (InterruptedException e) {
+			return false;
+		}
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReviewPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReviewPage.java
new file mode 100644
index 0000000..bffeab7
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReviewPage.java
@@ -0,0 +1,1662 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.DialogPage;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.PropertyDialogAction;
+import org.eclipse.ui.forms.HyperlinkSettings;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.widgets.ScrolledFormText;
+import org.eclipse.update.core.ICategory;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.IFeatureReference;
+import org.eclipse.update.core.IImport;
+import org.eclipse.update.core.IIncludedFeatureReference;
+import org.eclipse.update.core.IPluginEntry;
+import org.eclipse.update.core.ISiteFeatureReference;
+import org.eclipse.update.core.IURLEntry;
+import org.eclipse.update.core.Utilities;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.eclipse.update.internal.core.ExtendedSite;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.internal.operations.FeatureStatus;
+import org.eclipse.update.internal.operations.OperationValidator;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.operations.OperationValidator.InternalImport;
+import org.eclipse.update.internal.operations.OperationValidator.RequiredFeaturesResult;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIImages;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.FeatureReferenceAdapter;
+import org.eclipse.update.internal.ui.model.SimpleFeatureAdapter;
+import org.eclipse.update.internal.ui.model.SiteBookmark;
+import org.eclipse.update.internal.ui.model.SiteCategory;
+import org.eclipse.update.internal.ui.parts.DefaultContentProvider;
+import org.eclipse.update.internal.ui.parts.SWTUtil;
+import org.eclipse.update.internal.ui.parts.SharedLabelProvider;
+import org.eclipse.update.operations.IInstallFeatureOperation;
+import org.eclipse.update.operations.IUpdateModelChangedListener;
+import org.eclipse.update.operations.OperationsManager;
+import org.eclipse.update.search.IUpdateSearchSite;
+import org.eclipse.update.search.UpdateSearchRequest;
+
+public class ReviewPage	extends BannerPage {
+
+	private Label label;
+	private ArrayList jobs;
+	private Label counterLabel;
+	private IStatus validationStatus;
+	private Collection problematicFeatures = new HashSet();
+	// feature that was recently selected or null
+	private IFeature newlySelectedFeature;
+	// 
+	private FeatureStatus lastDisplayedStatus;
+	private PropertyDialogAction propertiesAction;
+	private ScrolledFormText descLabel;
+	private Button statusButton;
+	private Button moreInfoButton;
+	private Button propertiesButton;
+	private Button selectRequiredFeaturesButton;
+	private Button filterCheck;
+	private Button filterOlderVersionCheck;
+	private ContainmentFilter filter = new ContainmentFilter();
+	private LatestVersionFilter olderVersionFilter = new LatestVersionFilter();
+	private UpdateSearchRequest searchRequest;
+	//private int LABEL_ORDER = 1;
+	//private int VERSION_ORDER = 1;
+	//private int PROVIDER_ORDER = 1;
+    private ContainerCheckedTreeViewer treeViewer;
+    private boolean initialized;
+    private boolean isUpdateSearch;
+  
+    
+    class TreeContentProvider extends DefaultContentProvider implements
+            ITreeContentProvider {
+
+        public Object[] getElements(Object parent) {
+            return getSites();
+        }
+
+        public Object[] getChildren(final Object parent) {
+            if (parent instanceof SiteBookmark) {
+                SiteBookmark bookmark = (SiteBookmark) parent;
+                bookmark.getSite(null); // triggers catalog creation
+                Object[] children = bookmark.getCatalog(true,null);
+                ArrayList nonEmptyCategories = new ArrayList(children.length);
+                for (int i=0; i<children.length; i++)
+                    if (hasChildren(children[i]))
+                        nonEmptyCategories.add(children[i]);
+                return nonEmptyCategories.toArray();
+            } else if (parent instanceof SiteCategory) {
+                SiteCategory category = (SiteCategory)parent;
+                //return category.getChildren();
+                Object[] children = category.getChildren();
+                ArrayList list = new ArrayList(children.length);
+                for (int i=0; i<children.length; i++) {
+                    if (children[i] instanceof FeatureReferenceAdapter) {
+                        try {
+                            IInstallFeatureOperation job = findJob((FeatureReferenceAdapter)children[i]);
+                            if (job != null)
+                                list.add(job);
+                        } catch (CoreException e) {
+                            UpdateCore.log(e.getStatus());
+                        }
+                    }
+                }
+                return list.toArray();
+            }
+            return new Object[0];
+        }
+
+        public Object getParent(Object element) {
+            if (element instanceof SiteCategory)
+                return ((SiteCategory) element).getBookmark();
+            if (element instanceof IInstallFeatureOperation) {
+                IFeature f = ((IInstallFeatureOperation)element).getFeature();
+                ISiteFeatureReference fr = f.getSite().getFeatureReference(f);
+                ICategory[] categories = fr.getCategories();
+//                if (categories != null && categories.length > 0)
+//                    return categories[0];
+                SiteBookmark[] sites = (SiteBookmark[])((ITreeContentProvider)treeViewer.getContentProvider()).getElements(null);
+                for (int i=0; i<sites.length; i++) {
+                	try {
+                		if (sites[i].getSite(false, null).getURL() != f.getSite().getSiteContentProvider().getURL()) {
+                		    // if the site has mirrors check if this is from the mirror that user selected
+                			if (sites[i].getSite(false, null) instanceof ExtendedSite) {
+                				ExtendedSite site = (ExtendedSite)sites[i].getSite(false, null);
+                				IURLEntry siteMirror = site.getSelectedMirror();
+                				if (siteMirror != null && siteMirror.getURL().toExternalForm().equals(f.getSite().getSiteContentProvider().getURL().toExternalForm())) { 
+                					// this is the site so proceed with the loop
+                				} else {
+                					continue;
+                				}
+                			} else {
+                				continue;
+                			}
+                		}
+                	} catch (CoreException ce) {
+                		return null;
+                	}
+                    Object[] children = sites[i].getCatalog(true, null);
+                    for (int j = 0; j<children.length; j++) {
+                        if (!(children[j] instanceof SiteCategory))
+                            continue;
+                        for (int c=0; c < categories.length; c++)
+                            if (categories[c].getName().equals(((SiteCategory)children[j]).getName()))
+                                return children[j];
+                    }
+                }
+            }
+
+            return null;
+        }
+
+        public boolean hasChildren(Object element) {
+            return (element instanceof SiteBookmark || (
+                    element instanceof SiteCategory && getChildren(element).length > 0));
+        }
+
+        private SiteBookmark[] getSites() {
+            if (searchRequest == null)
+                return new SiteBookmark[0];
+            else if (searchRequest.getScope().getSearchSites() == null ||
+                searchRequest.getScope().getSearchSites().length == 0) {
+                // this is an update search, so see if there are any jobs first,
+                // and get their sites
+                if (jobs != null) {
+                    ArrayList sitesList = new ArrayList(jobs.size());
+                    for (int i = 0; i < jobs.size(); i++) {
+                        IInstallFeatureOperation op = (IInstallFeatureOperation) jobs
+                                .get(i);
+                        // we need a label for the site, so try to get it from the old
+                        // feature update url
+                        String label = null;
+                        IFeature[] existingFeatures = UpdateUtils
+                                .getInstalledFeatures(op.getFeature(), true);
+                        if (existingFeatures != null
+                                && existingFeatures.length > 0) {
+                            IURLEntry entry = op.getFeature()
+                                    .getUpdateSiteEntry();
+                            label = entry.getAnnotation();
+                        }
+                        if (label == null)
+                            label = op.getFeature().getSite().getURL().toExternalForm();
+                                    
+                        SiteBookmark bookmark = new SiteBookmark(label,
+                                op.getFeature().getSite().getURL(), false);
+                        if (sitesList.contains(bookmark))
+                            continue;
+                        else
+                            sitesList.add(bookmark);
+                        
+                    }
+                    if (!sitesList.isEmpty())
+                        return (SiteBookmark[]) sitesList
+                                .toArray(new SiteBookmark[sitesList.size()]);
+                }
+                return new SiteBookmark[0];
+            } else {
+                // search for features
+                IUpdateSearchSite[] sites = searchRequest.getScope().getSearchSites();
+                SiteBookmark[] siteBookmarks = new SiteBookmark[sites.length];
+                for (int i = 0; i < sites.length; i++)
+                    siteBookmarks[i] = new SiteBookmark(sites[i].getLabel(),
+                            sites[i].getURL(), false);
+                return siteBookmarks;
+            }
+        }
+    }
+
+    class TreeLabelProvider extends SharedLabelProvider {
+
+        public Image getImage(Object obj) {
+            if (obj instanceof SiteBookmark)
+                return UpdateUI.getDefault().getLabelProvider().get(
+                        UpdateUIImages.DESC_SITE_OBJ);
+            if (obj instanceof SiteCategory)
+                return UpdateUI.getDefault().getLabelProvider().get(
+                        UpdateUIImages.DESC_CATEGORY_OBJ);
+            if (obj instanceof IInstallFeatureOperation) {
+                IFeature feature = ((IInstallFeatureOperation) obj).getFeature();
+                boolean patch = feature.isPatch();
+                
+                //boolean problematic=problematicFeatures.contains(feature) && treeViewer.getChecked(obj);
+                boolean featureIsProblematic = isFeatureProblematic(feature);
+                boolean problematic = treeViewer.getChecked(obj) && featureIsProblematic;
+                
+                if (!problematic && featureIsProblematic) {
+                	Object parent = ((TreeContentProvider)treeViewer.getContentProvider()).getParent(obj);
+                	if(parent == null)
+                		return super.getImage(obj);
+                	problematic = treeViewer.getChecked(parent) && !treeViewer.getGrayed(parent);
+                }
+                
+                if (patch) {
+                    return get(UpdateUIImages.DESC_EFIX_OBJ, problematic? F_ERROR : 0);
+                } else {
+                    return get(UpdateUIImages.DESC_FEATURE_OBJ, problematic? F_ERROR : 0);
+                }
+            }
+            return super.getImage(obj);
+
+        }
+
+        public String getText(Object obj) {
+            if (obj instanceof SiteBookmark) 
+                return ((SiteBookmark) obj).getLabel();
+            /*
+            if (obj instanceof SiteCategory)
+                return obj.toString();
+                */
+            if (obj instanceof IInstallFeatureOperation) {
+                IInstallFeatureOperation job = (IInstallFeatureOperation) obj;
+                IFeature feature = job.getFeature();
+                return feature.getLabel() + " " + feature //$NON-NLS-1$
+                            .getVersionedIdentifier()
+                            .getVersion()
+                            .toString();
+            }
+            return super.getText(obj);
+        }
+    }
+
+    class ModelListener implements IUpdateModelChangedListener {
+        public void objectChanged(Object object, String property) {
+            treeViewer.refresh();
+            checkItems();
+        }
+
+        public void objectsAdded(Object parent, Object[] children) {
+            treeViewer.refresh();
+            checkItems();
+        }
+
+        public void objectsRemoved(Object parent, Object[] children) {
+            treeViewer.refresh();
+            checkItems();
+        }
+        
+        private void checkItems() {
+            TreeItem[] items = treeViewer.getTree().getItems();
+            for (int i = 0; i < items.length; i++) {
+                SiteBookmark bookmark = (SiteBookmark) items[i].getData();
+                treeViewer.setChecked(bookmark, bookmark.isSelected());
+                String[] ignoredCats = bookmark.getIgnoredCategories();
+                treeViewer.setGrayed(bookmark, ignoredCats.length > 0
+                        && bookmark.isSelected());
+            }
+        }
+    }
+
+	class ContainmentFilter extends ViewerFilter {
+		
+		private IInstallFeatureOperation[] selectedJobs;
+		
+		public boolean select(Viewer viewer, Object parent, Object element) {
+            if (element instanceof IInstallFeatureOperation) {
+                return !isContained((IInstallFeatureOperation) element) || isSelected( selectedJobs, (IInstallFeatureOperation)element);
+            } else if ( (element instanceof SiteCategory) || (element instanceof SiteBookmark)){
+            	Object[] children = ((ITreeContentProvider)((ContainerCheckedTreeViewer)viewer).getContentProvider()).getChildren(element);
+            	for ( int i = 0; i < children.length; i++) {
+            		if (select(viewer, element, children[i])) {
+            			return true;
+            		}
+            	}
+            	return false;
+            }
+        
+            return true;
+		}
+		
+		private boolean isContained(IInstallFeatureOperation job) {
+			VersionedIdentifier vid = job.getFeature().getVersionedIdentifier();
+
+			for (int i = 0; i < jobs.size(); i++) {
+				IInstallFeatureOperation candidate = (IInstallFeatureOperation) jobs.get(i);
+				if (candidate.equals(job))
+					continue;
+				IFeature feature = candidate.getFeature();
+				if (includes(feature, vid,null))
+					return true;
+			}
+			return false;
+		}
+		private boolean includes(IFeature feature, VersionedIdentifier vid, ArrayList cycleCandidates) {
+			try {
+				if (cycleCandidates == null)
+					cycleCandidates = new ArrayList();
+				if (cycleCandidates.contains(feature))
+					throw Utilities.newCoreException(NLS.bind(UpdateUIMessages.InstallWizard_ReviewPage_cycle, feature.getVersionedIdentifier().toString()), null);
+				else
+					cycleCandidates.add(feature);
+				IFeatureReference[] irefs =
+					feature.getIncludedFeatureReferences();
+				for (int i = 0; i < irefs.length; i++) {
+					IFeatureReference iref = irefs[i];
+					IFeature ifeature = UpdateUtils.getIncludedFeature(feature, iref);
+					VersionedIdentifier ivid =
+						ifeature.getVersionedIdentifier();
+					if (ivid.equals(vid))
+						return true;
+					if (includes(ifeature, vid, cycleCandidates))
+						return true;
+				}
+				return false;
+			} catch (CoreException e) {
+				return false;
+			} finally {
+				// after this feature has been DFS-ed, it is no longer a cycle candidate
+				cycleCandidates.remove(feature);
+			}
+		}
+
+
+		public IInstallFeatureOperation[] getSelectedJobs() {
+			return selectedJobs;
+		}
+		
+
+		public void setSelectedJobs(IInstallFeatureOperation[] selectedJobs) {
+			this.selectedJobs = selectedJobs;
+		}
+
+	
+	}
+
+	class LatestVersionFilter extends ViewerFilter {
+		
+		private IInstallFeatureOperation[] selectedJobs;
+		
+		public boolean select(Viewer viewer, Object parent, Object element) {
+						
+            if (element instanceof IInstallFeatureOperation) {
+                return isLatestVersion((IInstallFeatureOperation) element) || isSelected( selectedJobs, (IInstallFeatureOperation)element);
+            } else if ( (element instanceof SiteCategory) || (element instanceof SiteBookmark)){
+            	Object[] children = ((ITreeContentProvider)((ContainerCheckedTreeViewer)viewer).getContentProvider()).getChildren(element);
+            	for ( int i = 0; i < children.length; i++) {
+            		if (select(viewer, element, children[i])) {
+            			return true;
+            		}
+            	}
+                return false;
+            }
+            
+            return true;
+		}
+		
+		private boolean isLatestVersion(IInstallFeatureOperation job) {
+			IFeature feature = job.getFeature();
+			for (int i = 0; i < jobs.size(); i++) {
+				IInstallFeatureOperation candidateJob = (IInstallFeatureOperation) jobs.get(i);
+				if (candidateJob.equals(job))
+					continue;
+				IFeature candidate = candidateJob.getFeature();
+				if (feature.getSite() != job.getFeature().getSite())
+					continue;
+				if (!feature.getVersionedIdentifier().getIdentifier().equals(candidate.getVersionedIdentifier().getIdentifier()))
+					continue;
+				if (!feature.getVersionedIdentifier().getVersion().isGreaterOrEqualTo(candidate.getVersionedIdentifier().getVersion()))
+					return false;
+			}
+			return true;
+		}
+		
+		public IInstallFeatureOperation[] getSelectedJobs() {
+			return selectedJobs;
+		}
+		
+		public void setSelectedJobs(IInstallFeatureOperation[] selectedJobs) {
+			this.selectedJobs = selectedJobs;
+		}
+		
+		
+	}
+	
+	class FeaturePropertyDialogAction extends PropertyDialogAction {
+		private IStructuredSelection selection;
+
+		public FeaturePropertyDialogAction(
+			Shell shell,
+			ISelectionProvider provider) {
+			super(shell, provider);
+		}
+
+		public IStructuredSelection getStructuredSelection() {
+			return selection;
+		}
+
+		public void selectionChanged(IStructuredSelection selection) {
+			this.selection = selection;
+		}
+
+	}
+	/**
+	 * Constructor for ReviewPage2
+	 */
+	public ReviewPage(boolean isUpdateSearch, UpdateSearchRequest searchRequest, ArrayList jobs) {
+		super("Review"); //$NON-NLS-1$
+        this.isUpdateSearch = isUpdateSearch;
+        this.jobs = jobs;
+        if (this.jobs==null) this.jobs = new ArrayList();
+        this.searchRequest = searchRequest;
+        
+		setTitle(UpdateUIMessages.InstallWizard_ReviewPage_title); 
+		setDescription(UpdateUIMessages.InstallWizard_ReviewPage_desc); 
+		UpdateUI.getDefault().getLabelProvider().connect(this);
+		setBannerVisible(false);
+	}
+
+	public void dispose() {
+		UpdateUI.getDefault().getLabelProvider().disconnect(this);
+		super.dispose();
+	}
+
+	public void setVisible(boolean visible) {
+		super.setVisible(visible);
+		
+		// when searching for updates, only nested patches can be shown.
+		// when searching for features, features and patches can be shown
+		String filterText = filterCheck.getText();
+		String filterFeatures = UpdateUIMessages.InstallWizard_ReviewPage_filterFeatures; 
+		String filterPatches = UpdateUIMessages.InstallWizard_ReviewPage_filterPatches; 
+
+		if (isUpdateSearch && filterText.equals(filterFeatures))
+			filterCheck.setText(filterPatches);
+		else if ( !isUpdateSearch && filterText.equals(filterPatches))
+			filterCheck.setText(filterFeatures);
+		
+		if (visible && !initialized) {
+            initialized = true;
+//			jobs.clear();
+
+//			setDescription(UpdateUI.getString("InstallWizard.ReviewPage.searching")); //$NON-NLS-1$;
+//			label.setText(UpdateUI.getString("")); //$NON-NLS-1$
+
+			getShell().getDisplay().asyncExec(new Runnable() {
+				public void run() {
+//					searchRunner.runSearch();
+					performPostSearchProcessing();
+				}
+			});
+		}
+	}
+
+	private void performPostSearchProcessing() {
+		BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
+			public void run() {
+				if (treeViewer != null) {
+//                    treeViewer.refresh();
+//                    treeViewer.getTree().layout(true);
+					if (isUpdateSearch) {
+						selectTrueUpdates();
+					}
+				}
+				pageChanged();
+				
+				int totalCount = jobs != null ? jobs.size(): 0;
+				if(totalCount >0) {
+					setDescription(UpdateUIMessages.InstallWizard_ReviewPage_desc); 
+					label.setText(UpdateUIMessages.InstallWizard_ReviewPage_label); 
+				} else {
+					if (isUpdateSearch)
+						setDescription(UpdateUIMessages.InstallWizard_ReviewPage_zeroUpdates); 
+					else
+						setDescription(UpdateUIMessages.InstallWizard_ReviewPage_zeroFeatures); 
+					label.setText(""); //$NON-NLS-1$
+				}
+			}
+		});
+	}
+	
+	private void selectTrueUpdates() {
+		ArrayList trueUpdates = new ArrayList();
+		for (int i=0; i<jobs.size(); i++) {
+			IInstallFeatureOperation job = (IInstallFeatureOperation)jobs.get(i);
+			if (!UpdateUtils.isPatch(job.getFeature()))
+				trueUpdates.add(job);
+		}
+		treeViewer.setCheckedElements(trueUpdates.toArray()); 
+		validateSelection(new NullProgressMonitor());
+	}	
+
+	/**
+	 * @see DialogPage#createControl(Composite)
+	 */
+	public Control createContents(Composite parent) {
+		Composite client = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginWidth = layout.marginHeight = 0;
+		client.setLayout(layout);
+		label = new Label(client, SWT.NULL);
+		label.setText(UpdateUIMessages.InstallWizard_ReviewPage_label); 
+		GridData gd = new GridData();
+		gd.horizontalSpan = 2;
+		label.setLayoutData(gd);
+
+        createTreeViewer(client);
+
+		Composite comp = new Composite(client, SWT.NONE);
+		layout = new GridLayout();
+		layout.marginWidth = layout.marginHeight = 0;
+		comp.setLayout(layout);
+		comp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+				
+		Composite buttonContainer = new Composite(comp, SWT.NULL);
+		gd = new GridData(GridData.FILL_VERTICAL);
+		buttonContainer.setLayoutData(gd);
+		layout = new GridLayout();
+		layout.marginWidth = 0;
+		layout.marginHeight = 0; //30?
+		buttonContainer.setLayout(layout);
+		buttonContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		Button button = new Button(buttonContainer, SWT.PUSH);
+		button.setText(UpdateUIMessages.InstallWizard_ReviewPage_deselectAll); 
+		gd =
+			new GridData(
+				GridData.HORIZONTAL_ALIGN_FILL
+					| GridData.VERTICAL_ALIGN_BEGINNING);
+		button.setLayoutData(gd);
+		SWTUtil.setButtonDimensionHint(button);
+		button.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleDeselectAll();
+			}
+		});
+
+		moreInfoButton = new Button(buttonContainer, SWT.PUSH);
+		moreInfoButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_moreInfo); 
+		gd =
+			new GridData(
+				GridData.HORIZONTAL_ALIGN_FILL
+					| GridData.VERTICAL_ALIGN_BEGINNING);
+		moreInfoButton.setLayoutData(gd);
+		SWTUtil.setButtonDimensionHint(moreInfoButton);
+		moreInfoButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleMoreInfo();
+			}
+		});
+		moreInfoButton.setEnabled(false);
+		
+		
+		propertiesButton = new Button(buttonContainer, SWT.PUSH);
+		propertiesButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_properties); 
+		gd =
+			new GridData(
+				GridData.HORIZONTAL_ALIGN_FILL
+					| GridData.VERTICAL_ALIGN_BEGINNING);
+		propertiesButton.setLayoutData(gd);
+		SWTUtil.setButtonDimensionHint(propertiesButton);
+		propertiesButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleProperties();
+			}
+		});
+		propertiesButton.setEnabled(false);
+
+		selectRequiredFeaturesButton = new Button(buttonContainer, SWT.PUSH);
+		selectRequiredFeaturesButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_selectRequired);
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL
+				| GridData.VERTICAL_ALIGN_BEGINNING);
+		selectRequiredFeaturesButton.setLayoutData(gd);
+		SWTUtil.setButtonDimensionHint(selectRequiredFeaturesButton);
+		selectRequiredFeaturesButton
+				.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						BusyIndicator.showWhile(e.display, new Runnable() {
+							public void run() {
+								Object[] elements = treeViewer.getExpandedElements();
+								treeViewer.expandAll();
+								treeViewer.setExpandedElements(elements);
+								selectRequiredFeatures();
+								updateItemCount();
+							}
+						});
+					}
+				});
+
+		statusButton = new Button(buttonContainer, SWT.PUSH);
+		statusButton.setText(UpdateUIMessages.InstallWizard_ReviewPage_showStatus); 
+		gd =
+			new GridData(
+				GridData.HORIZONTAL_ALIGN_FILL
+					| GridData.VERTICAL_ALIGN_BEGINNING);
+		statusButton.setLayoutData(gd);
+		SWTUtil.setButtonDimensionHint(statusButton);
+		statusButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				showStatus();
+			}
+		});
+
+		//new Label(client, SWT.NULL);
+
+		counterLabel = new Label(client, SWT.NULL);
+		gd = new GridData();
+		gd.horizontalSpan = 2;
+		counterLabel.setLayoutData(gd);
+
+		filterOlderVersionCheck = new Button(client, SWT.CHECK);
+		filterOlderVersionCheck.setText(UpdateUIMessages.InstallWizard_ReviewPage_filterOlderFeatures); 
+		filterOlderVersionCheck.setSelection(true);
+		treeViewer.addFilter(olderVersionFilter);
+		filterOlderVersionCheck.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+
+				IInstallFeatureOperation[] jobs = getSelectedJobs();
+				
+				if (filterOlderVersionCheck.getSelection())
+					treeViewer.addFilter(olderVersionFilter);
+				else 
+					treeViewer.removeFilter(olderVersionFilter);
+				
+				olderVersionFilter.setSelectedJobs(jobs);				
+				pageChanged(jobs);
+			}
+		});
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.horizontalSpan = 2;
+		filterOlderVersionCheck.setLayoutData(gd);
+		
+		filterCheck = new Button(client, SWT.CHECK);
+		filterCheck.setText(UpdateUIMessages.InstallWizard_ReviewPage_filterFeatures); 
+		filterCheck.setSelection(false);
+		//tableViewer.addFilter(filter);
+		filterCheck.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				
+				IInstallFeatureOperation[] jobs = getSelectedJobs();
+				
+				if (filterCheck.getSelection()) {
+					// make sure model is local
+					if (downloadIncludedFeatures()) {
+						treeViewer.addFilter(filter);
+					} else {
+						filterCheck.setSelection(false);
+					}
+				} else {
+					treeViewer.removeFilter(filter);
+				}
+				
+				filter.setSelectedJobs(jobs);
+				
+				pageChanged(jobs);
+			}
+		});
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.horizontalSpan = 2;
+		filterCheck.setLayoutData(gd);
+		
+		pageChanged();
+
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(client, "org.eclipse.update.ui.MultiReviewPage2"); //$NON-NLS-1$
+
+		Dialog.applyDialogFont(parent);
+
+		return client;
+	}
+
+    private void createTreeViewer(final Composite parent) {
+        SashForm sform = new SashForm(parent, SWT.VERTICAL);
+        GridData gd = new GridData(GridData.FILL_BOTH);
+        gd.widthHint = 250;
+        gd.heightHint =100;
+        sform.setLayoutData(gd);
+        
+        treeViewer = new ContainerCheckedTreeViewer(sform, SWT.H_SCROLL | SWT.V_SCROLL
+                | SWT.BORDER);
+        treeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
+        treeViewer.setContentProvider(new TreeContentProvider());
+        treeViewer.setLabelProvider(new TreeLabelProvider());
+        treeViewer.setInput(UpdateUI.getDefault().getUpdateModel());
+
+        treeViewer
+            .addSelectionChangedListener(new ISelectionChangedListener() {
+            public void selectionChanged(SelectionChangedEvent e) {
+                handleSelectionChanged((IStructuredSelection) e.getSelection());
+            }
+        });
+        
+        treeViewer.addCheckStateListener(new ICheckStateListener() {
+            public void checkStateChanged(CheckStateChangedEvent event) {
+    			/*
+				 * validateSelection(); Object site =
+				 * getSite(event.getElement()); ArrayList descendants = new
+				 * ArrayList(); collectDescendants(site, descendants); Object[]
+				 * nodes = new Object[descendants.size()]; for (int i = 0; i <
+				 * nodes.length; i++) nodes[i] = descendants.get(i);
+				 * treeViewer.update(nodes, null); updateItemCount();
+				 */
+				try {
+					getContainer().run(true, true,
+							getCheckStateOperation(event, parent.getDisplay()));
+					getContainer().updateButtons();
+					updateStatusButton();
+				} catch (InvocationTargetException e) {
+					UpdateUI.logException(e);
+				} catch (InterruptedException e) {
+					UpdateUI.logException(e);
+				}
+            }
+        });
+        
+      descLabel = new ScrolledFormText(sform, true);
+      descLabel.setText(""); //$NON-NLS-1$
+      descLabel.setBackground(parent.getBackground());
+      HyperlinkSettings settings = new HyperlinkSettings(parent.getDisplay());
+      descLabel.getFormText().setHyperlinkSettings(settings);
+      descLabel.getFormText().addHyperlinkListener(new HyperlinkAdapter() {
+    	  public void linkActivated(HyperlinkEvent e) {
+    		  Object href = e.getHref();
+    		  if (href==null)
+    			  return;
+    		  try {
+    			  URL url = new URL(href.toString());
+    			  PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(url);
+    		  }
+    		  catch (PartInitException ex) {
+    			  UpdateUI.logException(ex);
+    		  }
+    		  catch (MalformedURLException ex) {
+    			  UpdateUI.logException(ex);
+    		  }
+    	  }
+      });
+      
+      gd = new GridData(SWT.FILL, SWT.FILL, true, true);
+      gd.horizontalSpan = 1;
+      descLabel.setLayoutData(gd);
+      
+      sform.setWeights(new int[] {10, 2});
+    }
+    
+	private IRunnableWithProgress getCheckStateOperation(
+			final CheckStateChangedEvent event, final Display display) {
+		return new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) {
+				monitor.beginTask(UpdateUIMessages.ReviewPage_validating,
+						IProgressMonitor.UNKNOWN);
+				validateSelection(monitor);
+				if (monitor.isCanceled()) {
+					undoStateChange(event);
+					monitor.done();
+					return;
+				}
+				Object site = getSite(event.getElement());
+				ArrayList descendants = new ArrayList();
+				collectDescendants(site, descendants, monitor);
+				final Object[] nodes = new Object[descendants.size()];
+				if (monitor.isCanceled()) {
+					undoStateChange(event);
+					monitor.done();
+					return;
+				}
+				for (int i = 0; i < nodes.length; i++)
+					nodes[i] = descendants.get(i);
+				display.syncExec(new Runnable() {
+					public void run() {
+						treeViewer.update(nodes, null);
+						updateItemCount();
+					}
+				});
+				monitor.done();
+			}
+		};
+	}
+	
+	private void undoStateChange(final CheckStateChangedEvent e) {
+		treeViewer.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+				treeViewer.setChecked(e.getElement(), !e.getChecked());
+			}
+		});
+	}
+    
+    private void handleSelectionChanged(IStructuredSelection ssel) {
+        
+        Object item = ssel.getFirstElement();
+        String description = null;
+        if (item instanceof SiteBookmark) {
+            description = ((SiteBookmark)item).getDescription();
+        } else if (item instanceof SiteCategory) {
+            IURLEntry descEntry = ((SiteCategory)item).getCategory().getDescription();
+            if (descEntry != null)
+                description = descEntry.getAnnotation();
+        } else if (item instanceof IInstallFeatureOperation) {
+            jobSelected(ssel);
+            return;
+        }
+
+        if (description == null)
+            description = ""; //$NON-NLS-1$
+        //descLabel.setText(UpdateManagerUtils.getWritableXMLString(description), false, true);
+        updateDescription(description);
+        propertiesButton.setEnabled(false);
+        moreInfoButton.setEnabled(false);
+    }
+
+/*	
+	private void fillContextMenu(IMenuManager manager) {
+		if (treeViewer.getSelection().isEmpty()) return;
+		Action action = new Action(UpdateUIMessages.InstallWizard_ReviewPage_prop) { 
+			public void run() {
+				handleProperties();
+			}
+		};
+		manager.add(action);
+	}
+*/
+
+	private void jobSelected(IStructuredSelection selection) {
+		IInstallFeatureOperation job = (IInstallFeatureOperation) selection.getFirstElement();
+		IFeature feature = job != null ? job.getFeature() : null;
+		IURLEntry descEntry = feature != null ? feature.getDescription() : null;
+		String desc = null;
+		if (descEntry != null)
+			desc = descEntry.getAnnotation();
+		if (desc == null)
+			desc = ""; //$NON-NLS-1$
+		//descLabel.setText(UpdateManagerUtils.getWritableXMLString(desc));
+		updateDescription(desc);
+		propertiesButton.setEnabled(feature != null);
+		moreInfoButton.setEnabled(job != null && getMoreInfoURL(job) != null);
+	}
+	
+	private void updateDescription(String text) {
+		descLabel.getFormText().setText(UpdateManagerUtils.getWritableXMLString(text), false, true);
+		descLabel.reflow(true);
+	}
+	
+	private void pageChanged() {
+		pageChanged(this.getSelectedJobs());
+	}
+	
+	private void pageChanged( IInstallFeatureOperation[] jobsSelected) {
+	
+		if (jobsSelected.length == 0) {
+			lastDisplayedStatus = null;
+			setErrorMessage(null);
+			setPageComplete(false);
+			setValidationStatus(null);
+			problematicFeatures.clear();
+		}
+		treeViewer.setCheckedElements(jobsSelected);
+		//validateSelection();
+        treeViewer.refresh();
+        treeViewer.setCheckedElements(jobsSelected);
+        updateItemCount();
+	}
+	
+	private void setValidationStatus(IStatus newValidationStatus) {
+		this.validationStatus = newValidationStatus;
+		updateStatusButton();
+	}
+	
+	private void updateStatusButton() {
+		statusButton.getDisplay().syncExec(new Runnable() {
+			public void run() {
+				boolean newState = validationStatus != null && validationStatus.getSeverity() != IStatus.OK;
+				statusButton.setEnabled(newState);
+			}
+		});
+	}
+	
+	private void updateItemCount() {
+		updateItemCount(-1, -1);
+	}
+	
+	private int getSelectedJobsUniqueCount() {
+		Object[] checkedElements = getSelectedJobs();
+		Set set = new HashSet();
+		for (int i=0; i<checkedElements.length; i++) {
+			IInstallFeatureOperation job = (IInstallFeatureOperation)checkedElements[i];
+			IFeature feature = job.getFeature();
+			if (set.contains(feature))
+				continue;
+			set.add(feature);
+		}
+		return set.size();
+	}
+
+	private void updateItemCount(int checkedCount, int totalCount) {
+		if (checkedCount == -1) {
+			checkedCount = getSelectedJobsUniqueCount();
+		}
+		if (totalCount == -1) {
+			totalCount = jobs.size();
+		}
+		String total = "" + totalCount; //$NON-NLS-1$
+		String selected = "" + checkedCount; //$NON-NLS-1$
+		counterLabel.setText(
+			NLS.bind(UpdateUIMessages.InstallWizard_ReviewPage_counter, (new String[] { selected, total })));	
+        counterLabel.getParent().layout();
+	}
+
+//	private void handleSelectAll(boolean select) {
+//		treeViewer.setAllChecked(select);
+////		 make sure model is local (download using progress monitor from container)
+//		downloadIncludedFeatures(); 
+//			
+//		treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
+//			public void run() {
+//				pageChanged();
+//			}
+//		});
+//	}
+
+//  private void handleSelectAll(boolean select) {
+//  treeViewer.setAllChecked(select);
+////     make sure model is local (download using progress monitor from container)
+//  downloadIncludedFeatures(); 
+//      
+//  treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
+//      public void run() {
+//          pageChanged();
+//      }
+//  });
+//}
+
+   private void handleDeselectAll() {
+        //treeViewer.setCheckedElements(new Object[0]);
+         IInstallFeatureOperation[] selectedJobs = getSelectedJobs();
+         for( int i = 0; i < selectedJobs.length; i++)
+        	 treeViewer.setChecked( selectedJobs[i], false);
+        // make sure model is local (download using progress monitor from
+        // container)
+//        downloadIncludedFeatures();
+
+        treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
+            public void run() {
+                pageChanged();
+            }
+        });
+}
+    
+	private void handleProperties() {
+		final IStructuredSelection selection =
+			(IStructuredSelection) treeViewer.getSelection();
+
+		final IInstallFeatureOperation job =
+			(IInstallFeatureOperation) selection.getFirstElement();
+		if (propertiesAction == null) {
+			propertiesAction =
+				new FeaturePropertyDialogAction(getShell(), treeViewer);
+		}
+
+		BusyIndicator
+			.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
+			public void run() {
+				SimpleFeatureAdapter adapter =
+					new SimpleFeatureAdapter(job.getFeature());
+				propertiesAction.selectionChanged(
+					new StructuredSelection(adapter));
+				propertiesAction.run();
+			}
+		});
+	}
+
+	private String getMoreInfoURL(IInstallFeatureOperation job) {
+		IURLEntry desc = job.getFeature().getDescription();
+		if (desc != null) {
+			URL url = desc.getURL();
+			return (url == null) ? null : url.toString();
+		}
+		return null;
+	}
+
+	private void handleMoreInfo() {
+		IStructuredSelection selection =
+			(IStructuredSelection) treeViewer.getSelection();
+		final IInstallFeatureOperation selectedJob =
+			(IInstallFeatureOperation) selection.getFirstElement();
+		BusyIndicator
+			.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
+			public void run() {
+				String urlName = getMoreInfoURL(selectedJob);
+				UpdateUI.showURL(urlName);
+			}
+		});
+	}
+
+	private IStatus selectRequiredFeatures() {
+		
+		IInstallFeatureOperation[] jobs = getSelectedJobs();
+		RequiredFeaturesResult requiredFeaturesResult = ((OperationValidator)OperationsManager
+				.getValidator()).getRequiredFeatures(jobs);
+		setValidationStatus(requiredFeaturesResult.getStatus());
+		Set requiredFeatures = requiredFeaturesResult.getRequiredFeatures();
+		problematicFeatures.clear();
+		
+		Iterator requiredFeaturesIterator = requiredFeatures.iterator();
+		ArrayList toBeInstalled = new ArrayList();
+		
+		while (requiredFeaturesIterator.hasNext()) {
+			IImport requiredFeature = ((InternalImport)requiredFeaturesIterator.next()).getImport();
+
+			IInstallFeatureOperation currentFeatureSelected = null;
+			TreeItem[] items = treeViewer.getTree().getItems();
+			for (int i = 0; i < items.length; i++) {
+				TreeItem[] siteRootContent = items[i].getItems();
+				for (int j = 0; j < siteRootContent.length; j++) {
+					if (siteRootContent[j].getData() instanceof SiteCategory) {
+						
+						if ( !treeViewer.getChecked(siteRootContent[j].getData())) {
+							// this category has not been checked at all so we have to create its features
+							treeViewer.createChildren(siteRootContent[j]);
+						}
+						TreeItem[] features = siteRootContent[j].getItems();
+						if ((features.length > 0) && (features[0].getData() == null)) {
+							// this category has been checked but not visited yet so restore the features in it
+							treeViewer.createChildren(siteRootContent[j]);
+							treeViewer.updateChildrenItems(siteRootContent[j]);
+							features = siteRootContent[j].getItems();
+						}
+						
+						for (int k = 0; k < features.length; k++) {
+							currentFeatureSelected = decideOnFeatureSelection(
+									requiredFeature,
+									(IInstallFeatureOperation) features[k]
+											.getData(), currentFeatureSelected);
+						}
+					} else if (siteRootContent[j].getData() instanceof IInstallFeatureOperation) {
+						currentFeatureSelected = decideOnFeatureSelection(
+								requiredFeature,
+								(IInstallFeatureOperation) siteRootContent[j]
+										.getData(), currentFeatureSelected);
+					}
+				}
+			}
+
+			if (currentFeatureSelected != null)
+				toBeInstalled.add(currentFeatureSelected);
+		}
+
+		if (!toBeInstalled.isEmpty()) {
+			Iterator toBeInstalledIterator = toBeInstalled.iterator();
+			while (toBeInstalledIterator.hasNext()) {
+				IInstallFeatureOperation current = (IInstallFeatureOperation)toBeInstalledIterator.next();
+				treeViewer.setChecked(current, true);			
+			}
+			return selectRequiredFeatures();
+		} else {
+			problematicFeatures.clear();
+			if (validationStatus != null) {
+				IStatus[] status = validationStatus.getChildren();
+				for (int i = 0; i < status.length; i++) {
+					IStatus singleStatus = status[i];
+					if (isSpecificStatus(singleStatus)) {
+						IFeature f = ((FeatureStatus) singleStatus)
+								.getFeature();
+						problematicFeatures.add(f);
+					}
+				}
+			}
+
+			setPageComplete(validationStatus == null
+					|| validationStatus.getSeverity() == IStatus.WARNING);
+
+			lastDisplayedStatus = null;
+			updateWizardMessage();
+			
+			treeViewer.update(getSelectedJobs(), null);
+			return validationStatus;
+		}
+	}
+
+	public IInstallFeatureOperation[] getSelectedJobs() {      
+        Object[] selected = treeViewer.getCheckedElements();
+        ArrayList selectedJobs = new ArrayList(selected.length);
+        for (int i=0; i<selected.length; i++)
+            if (selected[i] instanceof IInstallFeatureOperation)
+                selectedJobs.add(selected[i]);
+        return (IInstallFeatureOperation[])selectedJobs.toArray(new IInstallFeatureOperation[selectedJobs.size()]);
+	}
+	
+	public void validateSelection(IProgressMonitor monitor) {
+		IInstallFeatureOperation[] jobs;
+
+		final IInstallFeatureOperation[][] bag = new IInstallFeatureOperation[1][];
+		treeViewer.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+				bag[0] = getSelectedJobs();
+			}
+		});
+		if (monitor.isCanceled()) return;
+		jobs = bag[0];
+		setValidationStatus(OperationsManager.getValidator()
+				.validatePendingChanges(jobs));
+		problematicFeatures.clear();
+		if (monitor.isCanceled()) return;
+		if (validationStatus != null) {
+			IStatus[] status = validationStatus.getChildren();
+			for (int i = 0; i < status.length; i++) {
+				IStatus singleStatus = status[i];
+				if (isSpecificStatus(singleStatus)) {
+					IFeature f = ((FeatureStatus) singleStatus).getFeature();
+					problematicFeatures.add(f);
+				}
+			}
+		}
+		if (monitor.isCanceled())
+				return;
+		treeViewer.getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+				setPageComplete(validationStatus == null
+						|| validationStatus.getSeverity() == IStatus.WARNING);
+/*
+				statusButton.setEnabled(validationStatus != null
+						&& validationStatus.getSeverity() != IStatus.OK);
+						*/
+
+				updateWizardMessage();
+			}
+		});
+	}
+
+	private void showStatus() {
+		if (validationStatus != null) {
+			new StatusDialog().open();
+		}
+
+	}
+	/**
+	 * Check whether status is relevant to show for
+	 * a specific feature or is a other problem
+	 * @param status
+	 * @return true if status is FeatureStatus with
+	 * specified feature and certain error codes
+	 */
+	private boolean isSpecificStatus(IStatus status){
+		if(!(status instanceof FeatureStatus)){
+			return false;
+		}
+		if(status.getSeverity()!=IStatus.ERROR){
+			return false;
+		}
+		FeatureStatus featureStatus = (FeatureStatus) status;
+		if(featureStatus.getFeature()==null){
+			return false;
+		}
+		return 0!= (featureStatus.getCode()
+				& FeatureStatus.CODE_CYCLE
+				+ FeatureStatus.CODE_ENVIRONMENT
+				+ FeatureStatus.CODE_EXCLUSIVE
+				+ FeatureStatus.CODE_OPTIONAL_CHILD
+				+ FeatureStatus.CODE_PREREQ_FEATURE
+				+ FeatureStatus.CODE_PREREQ_PLUGIN);
+	}
+	/**
+	 * Update status in the wizard status area
+	 */
+	private void updateWizardMessage() {
+		
+		if (validationStatus == null) {
+			lastDisplayedStatus=null;
+			setErrorMessage(null);
+		} else if (validationStatus.getSeverity() == IStatus.WARNING) {
+			lastDisplayedStatus=null;
+			setErrorMessage(null);
+			setMessage(validationStatus.getMessage(), IMessageProvider.WARNING);
+		} else {
+			// 1.  Feature selected, creating a problem for it, show status for it
+			if(newlySelectedFeature !=null){
+				IStatus[] status = validationStatus.getChildren();
+				for(int s =0; s< status.length; s++){
+					if(isSpecificStatus(status[s])){
+						FeatureStatus featureStatus = (FeatureStatus)status[s];
+						if(newlySelectedFeature.equals(featureStatus.getFeature())){
+							lastDisplayedStatus=featureStatus;
+							setErrorMessage(featureStatus.getMessage());
+							return;
+						}
+					}
+				}
+			}
+			
+			// 2.  show old status if possible (it is still valid)
+			if(lastDisplayedStatus !=null){
+				IStatus[] status = validationStatus.getChildren();
+				for(int i=0; i<status.length; i++){
+					if(lastDisplayedStatus.equals(status[i])){
+						//lastDisplayedStatus=lastDisplayedStatus;
+						//setErrorMessage(status[i].getMessage());
+						return;
+					}
+				}
+				lastDisplayedStatus = null;
+			}
+			
+			// 3.  pick the first problem that is specific to some feature
+			IStatus[] status = validationStatus.getChildren();
+			for(int s =0; s< status.length; s++){
+				if(isSpecificStatus(status[s])){
+					lastDisplayedStatus = (FeatureStatus)status[s];
+					setErrorMessage(status[s].getMessage());
+					return;
+				}
+			}
+				
+			// 4.  display the first problem (no problems specify a feature)
+			if(status.length>0){
+				IStatus singleStatus=status[0];
+				setErrorMessage(singleStatus.getMessage());
+			}else{
+			// 5. not multi or empty multi status
+				setErrorMessage(UpdateUIMessages.InstallWizard_ReviewPage_invalid_long); 
+			}
+		}
+	}
+
+	class StatusDialog extends ErrorDialog {
+//		Button detailsButton;
+		public StatusDialog() {
+			super(getContainer().getShell(), UpdateUIMessages.InstallWizard_ReviewPage_invalid_short, null, 
+					validationStatus, IStatus.OK | IStatus.INFO
+							| IStatus.WARNING | IStatus.ERROR);
+		}
+//		protected Button createButton(
+//				Composite parent,
+//				int id,
+//				String label,
+//				boolean defaultButton) {
+//			Button b = super.createButton(parent, id, label, defaultButton);
+//			if(IDialogConstants.DETAILS_ID == id){
+//				detailsButton = b;
+//			}
+//			return b;
+//		}
+		public void create() {
+			super.create();
+			buttonPressed(IDialogConstants.DETAILS_ID);
+//			if(detailsButton!=null){
+//				detailsButton.dispose();
+//			}
+		}
+	}
+
+	/**
+	 * @return true, if completed, false if canceled by the user
+	 */
+	private boolean downloadIncludedFeatures() {
+		try {
+			Downloader downloader = new Downloader(jobs);
+			getContainer().run(true, true, downloader);
+			return !downloader.isCanceled();
+		} catch (InvocationTargetException ite) {
+		} catch (InterruptedException ie) {
+		}
+		return true;
+	}
+	/**
+	 * Runnable to resolve included feature references.
+	 */
+	class Downloader implements IRunnableWithProgress {
+		boolean canceled = false;
+		/**
+		 * List of IInstallFeatureOperation
+		 */
+		ArrayList operations;
+		public Downloader(ArrayList installOperations) {
+			operations = installOperations;
+		}
+		public boolean isCanceled() {
+			return canceled;
+		}
+		public void run(IProgressMonitor monitor)
+				throws InvocationTargetException, InterruptedException {
+			for (int i = 0; i < operations.size(); i++) {
+				IInstallFeatureOperation candidate = (IInstallFeatureOperation) operations
+						.get(i);
+				IFeature feature = candidate.getFeature();
+				try {
+					IFeatureReference[] irefs = feature
+							.getRawIncludedFeatureReferences();
+					for (int f = 0; f < irefs.length; f++) {
+						if (monitor.isCanceled()) {
+							canceled = true;
+							return;
+						}
+						IFeatureReference iref = irefs[f];
+						iref.getFeature(monitor);
+					}
+				} catch (CoreException e) {
+				}
+			}
+			if (monitor.isCanceled()) {
+				canceled = true;
+			}
+		}
+	}
+    
+    private IInstallFeatureOperation findJob(FeatureReferenceAdapter feature)
+            throws CoreException {
+        if (jobs == null)
+            return null;
+        for (int i = 0; i < jobs.size(); i++)
+            if (((IInstallFeatureOperation) jobs.get(i)).getFeature()
+                    .getVersionedIdentifier().equals(feature.getFeatureReference()
+                    .getVersionedIdentifier()))
+                return (IInstallFeatureOperation) jobs.get(i);
+
+        return null;
+    }
+    
+    private Object getSite(Object object) {
+        ITreeContentProvider provider = (ITreeContentProvider)treeViewer.getContentProvider();
+        while (object != null && !(object instanceof SiteBookmark)) {
+            object = provider.getParent(object);
+        }
+        return object;
+    }
+    
+	private void collectDescendants(Object root, ArrayList list,
+			IProgressMonitor monitor) {
+		ITreeContentProvider provider = (ITreeContentProvider) treeViewer
+				.getContentProvider();
+		Object[] children = provider.getChildren(root);
+		if (children != null && children.length > 0)
+			for (int i = 0; i < children.length; i++) {
+				if (monitor.isCanceled())
+					return;
+				list.add(children[i]);
+				collectDescendants(children[i], list, monitor);
+			}
+	}
+
+	
+	public boolean isFeatureGood(IImport requiredFeature, IFeature feature) {
+		return isFeatureGood(requiredFeature, feature, new ArrayList());
+	}
+	
+	public boolean isFeatureGood(IImport prereq, IFeature feature, List visitedFeatures) {
+
+		if (prereq.getKind() == IImport.KIND_FEATURE) { 
+			if ((!prereq.getVersionedIdentifier().getIdentifier().equals(
+					feature.getVersionedIdentifier().getIdentifier()))) {
+				IIncludedFeatureReference[] iifr = null;
+				try {
+					iifr = feature.getIncludedFeatureReferences();
+				} catch (CoreException e) {
+					UpdateUI.logException(e);
+					//	if we can not get included features then they can not satisfy requirement, so just ignore them
+					return false;
+				}
+				if (iifr == null) {
+					return false;
+				}
+				
+				for(int i = 0; i < iifr.length; i++) {
+					IFeature current;
+					try {
+						current = UpdateUtils.getIncludedFeature(feature, iifr[i]);
+					} catch (CoreException e) {
+						// if we can not get feature then it can not satisfy requirement, so just ignore it
+						UpdateUI.logException(e);
+						continue;
+					}
+					if (!visitedFeatures.contains(current)) {
+						visitedFeatures.add(current);
+						if (isFeatureGood(prereq, current, visitedFeatures)) {
+							return true;
+						}
+					}
+				}
+				
+				return false;
+			}
+
+			int rule = (prereq.getRule() != IImport.RULE_NONE) ? prereq.getRule() : IImport.RULE_COMPATIBLE;
+
+			switch (rule) {
+			case IImport.RULE_PERFECT: return feature.getVersionedIdentifier().getVersion().isPerfect(
+								prereq.getVersionedIdentifier()
+								.getVersion());
+			case IImport.RULE_EQUIVALENT:
+						return feature.getVersionedIdentifier().getVersion()
+						.isEquivalentTo(
+								prereq.getVersionedIdentifier()
+								.getVersion());
+			case IImport.RULE_COMPATIBLE:
+				return feature.getVersionedIdentifier().getVersion()
+						.isCompatibleWith(
+								prereq.getVersionedIdentifier()
+								.getVersion());
+			case IImport.RULE_GREATER_OR_EQUAL:
+						return feature.getVersionedIdentifier().getVersion()
+						.isGreaterOrEqualTo(
+								prereq.getVersionedIdentifier()
+								.getVersion());
+			}
+
+			return false;
+		} else {
+			if ((prereq.getKind() == IImport.KIND_PLUGIN)) { 
+				return checkIfFeatureHasPlugin( prereq, feature);
+			}
+			return false;
+		}
+	}
+	
+	private boolean checkIfFeatureHasPlugin(IImport requiredFeature, IFeature feature)  {
+		
+		IPluginEntry[] plugins = feature.getPluginEntries();
+		try {			
+			List includedPlugins = getPluginEntriesFromIncludedFeatures(feature, new ArrayList(), new ArrayList());
+			includedPlugins.addAll(Arrays.asList(plugins));
+			plugins = (IPluginEntry[])includedPlugins.toArray( new IPluginEntry[includedPlugins.size()]);
+		} catch( CoreException ce) {
+			UpdateUI.logException(ce);
+			// ignore this plugins can not sutisfy requirement anyways
+		}
+		if (plugins == null) {
+			return false;
+		}
+		
+		for(int i = 0; i < plugins.length; i++) {
+			if (isMatch(plugins[i].getVersionedIdentifier(), requiredFeature.getVersionedIdentifier(), requiredFeature.getIdRule())) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+
+	private List getPluginEntriesFromIncludedFeatures(IFeature feature, List plugins, List visitedFeatures) throws CoreException {
+		IIncludedFeatureReference[] iifr = feature.getIncludedFeatureReferences();
+		for(int i = 0; i < iifr.length; i++) {
+			IFeature current = UpdateUtils.getIncludedFeature( feature, iifr[i]);
+			if (!visitedFeatures.contains(current)) {
+				IPluginEntry[] pluginEntries = current.getPluginEntries();
+				plugins.addAll(Arrays.asList(pluginEntries));
+				visitedFeatures.add(current);
+				getPluginEntriesFromIncludedFeatures(current, plugins, visitedFeatures);
+			}
+		}
+		
+		return plugins;
+	}
+
+	// vid1 = feature
+	// vid2 = requiredFeature
+	private boolean isMatch( VersionedIdentifier vid1, VersionedIdentifier vid2, int rule) {
+		
+		if (!vid1.getIdentifier().equals(vid2.getIdentifier())) {
+			return false;
+		}
+		if ( vid2.getVersion().getMajorComponent() == 0 && vid2.getVersion().getMinorComponent() == 0 && vid2.getVersion().getServiceComponent() == 0 ) {
+			//version is ignored
+			return true;
+		}
+		switch (rule) {
+		case IImport.RULE_PERFECT:
+			return vid1.getVersion().isPerfect(vid2.getVersion());
+		case IImport.RULE_EQUIVALENT:
+			return vid1.getVersion().isEquivalentTo(vid2.getVersion());
+		case IImport.RULE_COMPATIBLE:
+			return vid1.getVersion().isCompatibleWith(vid2.getVersion());
+		case IImport.RULE_GREATER_OR_EQUAL:
+			return vid1.getVersion().isGreaterOrEqualTo(vid2.getVersion());
+		}
+		return false;
+	}
+
+	public boolean isFeatureBetter(IInstallFeatureOperation feature,
+			IInstallFeatureOperation currentFeatureSelected) {
+
+		if (currentFeatureSelected == null)
+			return true;
+		// If the feature is the same, pick the newer one
+		if (currentFeatureSelected.getFeature().getVersionedIdentifier().getIdentifier().equals(
+				feature.getFeature().getVersionedIdentifier().getIdentifier())) {
+			return !currentFeatureSelected.getFeature().getVersionedIdentifier()
+			.getVersion().isGreaterOrEqualTo(
+					feature.getFeature().getVersionedIdentifier()
+							.getVersion());			
+		}
+		else {
+			// Different features.
+			// Pick a feature with smaller number of plug-ins
+			NullProgressMonitor monitor = new NullProgressMonitor();
+			int currentNumber = getTotalNumberOfPluginEntries(currentFeatureSelected.getFeature(), monitor);
+			int newNumber = getTotalNumberOfPluginEntries(feature.getFeature(), monitor);
+			return newNumber<currentNumber;
+		}
+	}
+	
+	private int getTotalNumberOfPluginEntries(IFeature feature, IProgressMonitor monitor) {
+		int count = 0;
+		try {
+			count = feature.getPluginEntryCount();
+			IIncludedFeatureReference [] irefs = feature.getIncludedFeatureReferences();
+			for (int i=0; i<irefs.length; i++) {
+				IFeature child = irefs[i].getFeature(monitor);
+				count += getTotalNumberOfPluginEntries(child, monitor);
+			}
+		}
+		catch (CoreException e) {
+		}
+		return count;
+	}
+
+	public IInstallFeatureOperation decideOnFeatureSelection(
+			IImport requiredFeature, IInstallFeatureOperation feature,
+			IInstallFeatureOperation currentFeatureSelected) {
+
+		if (isFeatureGood(requiredFeature, feature.getFeature()) && isFeatureBetter(feature, currentFeatureSelected)) {
+				return feature;
+		} else {
+			return currentFeatureSelected;
+		}
+	}
+	
+	private boolean isFeatureProblematic(IFeature feature) {
+		
+		if ( problematicFeatures.contains(feature) )
+			return true;
+		
+		IImport[] iimports = feature.getImports();
+		
+		for(int i = 0; i < iimports.length; i++) {
+			Iterator problematicFeatures = this.problematicFeatures.iterator();
+			while(problematicFeatures.hasNext()) {
+				if (iimports[i].getVersionedIdentifier().equals( ((IFeature)problematicFeatures.next()).getVersionedIdentifier()) ) {
+					return true;
+				}
+			}
+		}
+		try {
+			Iterator includedFeatures = OperationValidator.computeFeatureSubtree(feature, null, null, false, new ArrayList(), null ).iterator();
+			while (includedFeatures.hasNext()) {
+				Iterator problematicFeatures = this.problematicFeatures.iterator();		
+				VersionedIdentifier currentIncludedFeaturesVI = ((IFeature)includedFeatures.next()).getVersionedIdentifier();
+				while (problematicFeatures.hasNext()) {
+					Object currentProblematicFeatures = problematicFeatures.next();
+					if (currentProblematicFeatures instanceof IFeature) {
+						VersionedIdentifier currentProblematicFeaturesVI = ((IFeature)currentProblematicFeatures).getVersionedIdentifier();						
+						if (currentProblematicFeaturesVI.equals( currentIncludedFeaturesVI) ) {
+							return true;
+						}
+					}
+				}
+			}
+		} catch (CoreException ce) {
+		}
+ 		return false;
+	}
+	
+	private boolean isSelected( IInstallFeatureOperation[] selectedJobs, IInstallFeatureOperation iInstallFeatureOperation) {
+		
+		if (selectedJobs == null)
+			return false;
+		
+		for( int i = 0; i < selectedJobs.length; i++) {
+			
+			if (iInstallFeatureOperation.getFeature().getVersionedIdentifier().equals(selectedJobs[i].getFeature().getVersionedIdentifier()) &&
+				iInstallFeatureOperation.getFeature().getSite().getURL().equals(selectedJobs[i].getFeature().getSite().getURL())) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ShowActivitiesDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ShowActivitiesDialog.java
new file mode 100644
index 0000000..80229d7
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ShowActivitiesDialog.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.text.DateFormat;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.core.SiteManager;
+import org.eclipse.update.internal.core.InstallConfiguration;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+
+
+
+public class ShowActivitiesDialog extends Dialog {
+	private TableViewer activitiesViewer;
+
+	// location configuration
+	private IDialogSettings dialogSettings;
+	private Point dialogLocation;
+	private Point dialogSize;
+
+	/**
+	 * @param parentShell
+	 */
+	public ShowActivitiesDialog(Shell parentShell) {
+		super(parentShell);
+		setShellStyle(SWT.RESIZE | SWT.MIN | SWT.MAX | SWT.APPLICATION_MODAL);
+		readConfiguration();
+	}
+	
+	public void create() {
+		super.create();
+		// dialog location 
+		if (dialogLocation != null)
+			getShell().setLocation(dialogLocation);
+		
+		// dialog size
+		if (dialogSize != null)
+			getShell().setSize(dialogSize);
+		else
+			getShell().setSize(500,500);
+		
+		
+		applyDialogFont(buttonBar);
+		getButton(IDialogConstants.OK_ID).setFocus();
+	}
+
+	protected Control createDialogArea(Composite parent) {
+		Composite container = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		layout.makeColumnsEqualWidth = false;
+		container.setLayout(layout);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.grabExcessHorizontalSpace = true;
+		gd.grabExcessVerticalSpace = true;
+		container.setLayoutData(gd);
+		createDescriptionSection(container);
+		createActivitiesViewer(container);
+		Dialog.applyDialogFont(container);
+		return container;
+	}
+
+	protected Control createDescriptionSection(Composite parent){
+		Composite container = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.makeColumnsEqualWidth = false;
+		container.setLayout(layout);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		container.setLayoutData(gd);
+		try {
+			Label targetLabel = new Label(container, SWT.NONE);
+			targetLabel.setText(UpdateUIMessages.ShowActivitiesDialog_date); 
+			Label target = new Label(container, SWT.NONE);
+			DateFormat df = DateFormat.getDateTimeInstance();
+			String localizedDate = df.format(SiteManager.getLocalSite().getCurrentConfiguration().getCreationDate());
+			target.setText(localizedDate);
+			
+			Label urlLabel = new Label(container, SWT.NONE);
+			urlLabel.setText(UpdateUIMessages.ShowActivitiesDialog_loc); 
+			Label url = new Label(container, SWT.NONE);
+			url.setText(((InstallConfiguration)SiteManager.getLocalSite().getCurrentConfiguration()).getURL().getFile());
+			
+			
+		} catch (CoreException e) {
+			UpdateUI.logException(e);
+		}
+		return container;
+	}
+	protected Control createActivitiesViewer(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout gridLayout = new GridLayout();
+		gridLayout.marginHeight = gridLayout.marginWidth = 4;
+		composite.setLayout(gridLayout);
+
+		GridData gd = new GridData(GridData.FILL_BOTH);
+//		gd.grabExcessHorizontalSpace = true;
+//		gd.grabExcessVerticalSpace = true;
+
+		composite.setLayoutData(gd);
+
+		
+		Label label = new Label(composite, SWT.NONE);
+		label.setText(UpdateUIMessages.ShowActivitiesDialog_label); 
+		activitiesViewer = ActivitiesTableViewer.createViewer(composite, true);
+
+		TableLayout layout = new TableLayout();
+		layout.addColumnData(new ColumnWeightData(8, 20, false));
+		layout.addColumnData(new ColumnWeightData(50, 160, true));
+		layout.addColumnData(new ColumnWeightData(50, 183, true));
+		layout.addColumnData(new ColumnWeightData(50, 100, true));
+
+		activitiesViewer.getTable().setLayout(layout);
+		try {
+			activitiesViewer.setInput(SiteManager.getLocalSite().getCurrentConfiguration());
+		} catch (CoreException e) {
+		}
+		Dialog.applyDialogFont(composite);
+		return composite;
+	}
+
+	protected void createButtonsForButtonBar(Composite parent) {
+		// create OK button only by default
+		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+	}
+
+	public boolean close() {
+		storeSettings();
+		return super.close();
+	}
+	
+	/**
+	 * Stores the current state in the dialog settings.
+	 * @since 2.0
+	 */
+	private void storeSettings() {
+		writeConfiguration();
+	}
+	/**
+	 * Returns the dialog settings object used to share state
+	 * between several event detail dialogs.
+	 * 
+	 * @return the dialog settings to be used
+	 */
+	private IDialogSettings getDialogSettings() {
+		IDialogSettings settings = UpdateUI.getDefault().getDialogSettings();
+		dialogSettings = settings.getSection(getClass().getName());
+		if (dialogSettings == null)
+			dialogSettings= settings.addNewSection(getClass().getName());
+		return dialogSettings;
+	}
+
+	/**
+	 * Initializes itself from the dialog settings with the same state
+	 * as at the previous invocation.
+	 */
+	private void readConfiguration() {
+		IDialogSettings s= getDialogSettings();
+		try {
+			int x= s.getInt("x"); //$NON-NLS-1$
+			int y= s.getInt("y"); //$NON-NLS-1$
+			dialogLocation= new Point(x, y);
+			
+			x = s.getInt("width"); //$NON-NLS-1$
+			y = s.getInt("height"); //$NON-NLS-1$
+			dialogSize = new Point(x,y);
+		} catch (NumberFormatException e) {
+			dialogLocation= null;
+			dialogSize = null;
+		}
+	}
+	
+	private void writeConfiguration(){
+		IDialogSettings s = getDialogSettings();
+		Point location = getShell().getLocation();
+		s.put("x", location.x); //$NON-NLS-1$
+		s.put("y", location.y); //$NON-NLS-1$
+		
+		Point size = getShell().getSize();
+		s.put("width", size.x); //$NON-NLS-1$
+		s.put("height", size.y); //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/SitePage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/SitePage.java
new file mode 100644
index 0000000..bfba7e4
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/SitePage.java
@@ -0,0 +1,557 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.net.URL;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.HyperlinkSettings;
+import org.eclipse.ui.forms.widgets.ScrolledFormText;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.core.UpdateManagerUtils;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIImages;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.model.DiscoveryFolder;
+import org.eclipse.update.internal.ui.model.SiteBookmark;
+import org.eclipse.update.internal.ui.model.SiteCategory;
+import org.eclipse.update.internal.ui.model.UpdateModel;
+import org.eclipse.update.internal.ui.parts.SWTUtil;
+import org.eclipse.update.operations.IUpdateModelChangedListener;
+import org.eclipse.update.search.EnvironmentFilter;
+import org.eclipse.update.search.UpdateSearchRequest;
+import org.eclipse.update.search.UpdateSearchScope;
+
+public class SitePage extends BannerPage implements ISearchProvider {
+
+	class SitesLabelProvider extends LabelProvider {
+
+		public Image getImage(Object obj) {
+			if (obj instanceof SiteBookmark)
+				return UpdateUI.getDefault().getLabelProvider().get(
+					UpdateUIImages.DESC_SITE_OBJ);
+			return super.getImage(obj);
+		}
+
+		public String getText(Object obj) {
+			if (obj instanceof SiteBookmark) {
+				return ((SiteBookmark) obj).getLabel();
+			}
+			return super.getText(obj);
+		}
+	}
+
+	class ModelListener implements IUpdateModelChangedListener {
+		public void objectChanged(Object object, String property) {
+			viewer.refresh();
+			checkItems();
+		}
+
+		public void objectsAdded(Object parent, Object[] children) {
+            viewer.refresh();
+			checkItems();
+		}
+
+		public void objectsRemoved(Object parent, Object[] children) {
+			viewer.refresh();
+			checkItems();
+		}
+	}
+
+	private static DiscoveryFolder discoveryFolder = new DiscoveryFolder();
+	private CheckboxTableViewer viewer;
+	private ScrolledFormText descLabel;
+	private Button addSiteButton;
+	private Button addLocalButton;
+	private Button addLocalZippedButton;
+	private Button editButton;
+	private Button removeButton;
+	private Button exportButton;
+	private Button importButton;
+	private Button envFilterCheck;
+	private Button automaticallySelectMirrorsCheckbox;
+	private EnvironmentFilter envFilter;
+	private UpdateSearchRequest searchRequest;
+	private ModelListener modelListener;
+	
+	private boolean automaticallySelectMirrors = true;
+
+	public SitePage(UpdateSearchRequest searchRequest) {
+		super("SitePage"); //$NON-NLS-1$
+        this.searchRequest = searchRequest;
+		setTitle(UpdateUIMessages.SitePage_title); 
+		setDescription(UpdateUIMessages.SitePage_desc); 
+		UpdateUI.getDefault().getLabelProvider().connect(this);
+    	envFilter = new EnvironmentFilter();
+
+		modelListener = new ModelListener();
+		UpdateUI.getDefault().getUpdateModel().addUpdateModelChangedListener(
+			modelListener);
+	}
+
+	private void toggleEnvFilter(boolean add) {
+		if (add)
+			searchRequest.addFilter(envFilter);
+		else
+			searchRequest.removeFilter(envFilter);
+	}
+
+	public void dispose() {
+		UpdateUI.getDefault().getLabelProvider().disconnect(this);
+		UpdateUI
+			.getDefault()
+			.getUpdateModel()
+			.removeUpdateModelChangedListener(
+			modelListener);
+		super.dispose();
+	}
+
+	/*
+	 * (non-Javadoc) @see
+	 * org.eclipse.update.internal.ui.wizards.BannerPage#createContents(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createContents(Composite parent) {
+		Composite client = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		client.setLayout(layout);
+
+		Label label = new Label(client, SWT.NULL);
+		label.setText(UpdateUIMessages.SitePage_label); 
+		GridData gd = new GridData();
+		gd.horizontalSpan = 2;
+		label.setLayoutData(gd);
+
+		createViewer(client);
+
+		Composite buttonContainer = new Composite(client, SWT.NULL);
+		buttonContainer.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+		layout = new GridLayout();
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		buttonContainer.setLayout(layout);
+
+		addSiteButton = new Button(buttonContainer, SWT.PUSH);
+		addSiteButton.setText(UpdateUIMessages.SitePage_addUpdateSite); 
+		addSiteButton.setLayoutData(
+			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		SWTUtil.setButtonDimensionHint(addSiteButton);
+		addSiteButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleAddSite();
+			}
+		});
+
+		addLocalButton = new Button(buttonContainer, SWT.PUSH);
+		addLocalButton.setText(UpdateUIMessages.SitePage_addLocalSite); 
+		addLocalButton.setLayoutData(
+			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		SWTUtil.setButtonDimensionHint(addLocalButton);
+		addLocalButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleAddLocal();
+			}
+		});
+
+		addLocalZippedButton = new Button(buttonContainer, SWT.PUSH);
+		addLocalZippedButton.setText(UpdateUIMessages.SitePage_addLocalZippedSite); 
+		addLocalZippedButton.setLayoutData(
+			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		SWTUtil.setButtonDimensionHint(addLocalZippedButton);
+		addLocalZippedButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleAddLocalZipped();
+			}
+		});
+		
+		// separator
+		new Label(buttonContainer, SWT.None);
+		
+		editButton = new Button(buttonContainer, SWT.PUSH);
+		editButton.setText(UpdateUIMessages.SitePage_edit); 
+		editButton.setEnabled(false);
+		editButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		SWTUtil.setButtonDimensionHint(editButton);
+		editButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleEdit();
+			}
+		});
+
+		removeButton = new Button(buttonContainer, SWT.PUSH);
+		removeButton.setText(UpdateUIMessages.SitePage_remove); 
+		removeButton.setEnabled(false);
+		removeButton.setLayoutData(
+			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		SWTUtil.setButtonDimensionHint(removeButton);
+		removeButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleRemove();
+			}
+		});
+		
+		// separator
+		new Label(buttonContainer, SWT.None);
+		
+		importButton = new Button(buttonContainer, SWT.PUSH);
+		importButton.setText(UpdateUIMessages.SitePage_import); 
+		importButton.setLayoutData(
+			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		SWTUtil.setButtonDimensionHint(importButton);
+		importButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleImport();
+			}
+		});
+		
+		exportButton = new Button(buttonContainer, SWT.PUSH);
+		exportButton.setText(UpdateUIMessages.SitePage_export); 
+		exportButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		SWTUtil.setButtonDimensionHint(exportButton);
+		exportButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleExport();
+			}
+		});
+
+		descLabel = new ScrolledFormText(client, true);
+		descLabel.setText(""); //$NON-NLS-1$
+		descLabel.setBackground(parent.getBackground());
+		HyperlinkSettings settings = new HyperlinkSettings(parent.getDisplay());
+		descLabel.getFormText().setHyperlinkSettings(settings);
+		
+		gd = new GridData(SWT.FILL, SWT.FILL, true, true);
+		gd.horizontalSpan = 1;
+        gd.heightHint = 30;
+		descLabel.setLayoutData(gd);
+		
+		envFilterCheck = new Button(client, SWT.CHECK);
+		envFilterCheck.setText(UpdateUIMessages.SitePage_ignore); 
+		envFilterCheck.setSelection(true);
+		toggleEnvFilter(true);
+		envFilterCheck.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				toggleEnvFilter(envFilterCheck.getSelection());
+			}
+		});
+		gd = new GridData();
+		gd.horizontalSpan = 2;
+        gd.verticalAlignment = SWT.BOTTOM;
+		envFilterCheck.setLayoutData(gd);
+
+		
+		automaticallySelectMirrorsCheckbox = new Button(client, SWT.CHECK);
+		automaticallySelectMirrorsCheckbox.setText(UpdateUIMessages.SitePage_automaticallySelectMirrors); 
+		automaticallySelectMirrorsCheckbox.setSelection(true);
+		automaticallySelectMirrorsCheckbox.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				automaticallySelectMirrors = automaticallySelectMirrorsCheckbox.getSelection();
+				UpdateCore.getPlugin().getPluginPreferences().setValue(UpdateCore.P_AUTOMATICALLY_CHOOSE_MIRROR, automaticallySelectMirrors);
+			}
+		});
+		gd = new GridData();
+		gd.horizontalSpan = 2;
+        gd.verticalAlignment = SWT.BOTTOM;
+        automaticallySelectMirrorsCheckbox.setLayoutData(gd);
+		
+		Dialog.applyDialogFont(parent);
+
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(client, "org.eclipse.update.ui.SitePage"); //$NON-NLS-1$
+
+		return client;
+	}
+
+	private void createViewer(Composite parent) {
+		viewer =
+			CheckboxTableViewer.newCheckList(
+				parent,
+				SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+		viewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
+		viewer.setContentProvider(new IStructuredContentProvider() {
+			public Object[] getElements(Object parent) {
+				return getAllSiteBookmarks();
+			}
+
+			public void dispose() {
+			}
+
+			public void inputChanged(Viewer viewer, Object oldInput,
+					Object newInput) {
+			}
+		});
+		viewer.setLabelProvider(new SitesLabelProvider());
+		viewer.setInput(UpdateUI.getDefault().getUpdateModel());
+		
+		// bug # 83212
+		viewer.setSorter( new ViewerSorter());
+		
+		
+		initializeItems();
+
+		viewer.addCheckStateListener(new ICheckStateListener() {
+			public void checkStateChanged(CheckStateChangedEvent e) {
+				Object element = e.getElement();
+				if (element instanceof SiteBookmark)
+					handleSiteChecked((SiteBookmark) element, e.getChecked());
+			}
+		});
+
+		viewer
+			.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent e) {
+				handleSelectionChanged((IStructuredSelection) e.getSelection());
+			}
+		});
+
+	}
+
+	private void initializeItems() {
+		checkItems();
+		updateSearchRequest();
+	}
+
+	private void checkItems() {
+		TableItem[] items = viewer.getTable().getItems();
+		for (int i = 0; i < items.length; i++) {
+			SiteBookmark bookmark = (SiteBookmark) items[i].getData();
+			viewer.setChecked(bookmark, bookmark.isSelected());
+		}
+	}
+
+	private void handleAddSite() {
+		NewUpdateSiteDialog dialog = new NewUpdateSiteDialog(getShell(), getAllSiteBookmarks());
+		dialog.create();
+		dialog.getShell().setText(UpdateUIMessages.SitePage_new); 
+		if (dialog.open() == NewUpdateSiteDialog.OK)
+			updateSearchRequest();
+	}
+
+	private void handleAddLocal() {
+		SiteBookmark siteBookmark = LocalSiteSelector.getLocaLSite(getShell(), this.getAllSiteBookmarks());
+		if (siteBookmark != null) {
+			if (handleNameEdit(siteBookmark) == EditSiteDialog.OK) {
+				siteBookmark.setSelected(true);
+				UpdateModel model = UpdateUI.getDefault().getUpdateModel();
+				model.addBookmark(siteBookmark);
+				model.saveBookmarks();
+				updateSearchRequest();
+			}
+		}
+		return;
+	}
+
+	private void handleAddLocalZipped() {
+		SiteBookmark siteBookmark = LocalSiteSelector
+				.getLocaLZippedSite(getShell(), this.getAllSiteBookmarks());
+		if (siteBookmark != null) {
+			if (handleNameEdit(siteBookmark) == EditSiteDialog.OK) {
+				siteBookmark.setSelected(true);
+				UpdateModel model = UpdateUI.getDefault().getUpdateModel();
+				model.addBookmark(siteBookmark);
+				model.saveBookmarks();
+				updateSearchRequest();
+			}
+		}
+		return;
+	}
+
+	private void handleRemove() {
+		BusyIndicator
+			.showWhile(viewer.getControl().getDisplay(), new Runnable() {
+			public void run() {
+				UpdateModel updateModel =
+					UpdateUI.getDefault().getUpdateModel();
+				IStructuredSelection ssel =
+					(IStructuredSelection) viewer.getSelection();
+				SiteBookmark bookmark = (SiteBookmark) ssel.getFirstElement();
+				String selName = bookmark.getLabel();
+				boolean answer = MessageDialog
+								.openQuestion(
+										getShell(),
+										UpdateUIMessages.SitePage_remove_location_conf_title, 
+										UpdateUIMessages.SitePage_remove_location_conf
+												+ " " + selName); //$NON-NLS-1$
+
+				if (answer && !bookmark.isReadOnly()) {
+					updateModel.removeBookmark(bookmark);
+					updateSearchRequest();
+				}
+			}
+		});
+	}
+
+	private void handleEdit() {
+		IStructuredSelection ssel =
+			(IStructuredSelection) viewer.getSelection();
+		SiteBookmark bookmark = (SiteBookmark) ssel.getFirstElement();
+		URL oldURL = bookmark.getURL();
+		EditSiteDialog dialog = new EditSiteDialog(getShell(), bookmark, getAllSiteBookmarks());
+		dialog.create();
+		String title = bookmark.isLocal() ? UpdateUIMessages.SitePage_dialogEditLocal : UpdateUIMessages.SitePage_dialogEditUpdateSite; 
+																																				  // //$NON-NLS-2$
+		dialog.getShell().setText(title);
+		if (dialog.open() == EditSiteDialog.OK ) {
+			URL newURL = bookmark.getURL();
+			if (!UpdateManagerUtils.sameURL(oldURL, newURL)) {
+				UpdateModel model = UpdateUI.getDefault().getUpdateModel();
+				model.fireObjectChanged(bookmark, null);
+				updateSearchRequest();	
+			}
+		}
+	}
+
+	private void handleImport() {
+		SiteBookmark[] siteBookmarks = SitesImportExport.getImportedBookmarks(getShell());
+		if (siteBookmarks != null && siteBookmarks.length > 0) {
+			UpdateModel model = UpdateUI.getDefault().getUpdateModel();
+			SiteBookmark[] currentBookmarks = getAllSiteBookmarks();
+			for (int i=0; i<siteBookmarks.length; i++) {
+				boolean siteExists = false;
+				for (int j=0; !siteExists && j<currentBookmarks.length; j++)
+					if (currentBookmarks[j].getURL().equals(siteBookmarks[i].getURL()))
+						siteExists = true;
+				if (!siteExists)
+					model.addBookmark(siteBookmarks[i]);
+			}
+			model.saveBookmarks();
+			updateSearchRequest();
+		}
+		return;
+	}
+	
+	private void handleExport() {
+		SitesImportExport.exportBookmarks(getShell(), getAllSiteBookmarks());
+	}
+	
+	private int handleNameEdit(SiteBookmark bookmark) {
+		EditSiteDialog dialog = new EditSiteDialog(getShell(), bookmark, getAllSiteBookmarks(), true);
+		dialog.create();
+		String title = bookmark.isLocal() ? UpdateUIMessages.SitePage_dialogEditLocal : UpdateUIMessages.SitePage_dialogEditUpdateSite; 
+		// //$NON-NLS-2$
+		dialog.getShell().setText(title);
+		int rc = dialog.open();
+		return rc;
+	}
+
+	private void handleSiteChecked(SiteBookmark bookmark, boolean checked) {
+		if (bookmark.isUnavailable()) {
+			bookmark.setSelected(false);
+			viewer.setChecked(bookmark, false);
+			return;
+		}
+		
+		bookmark.setSelected(checked);
+		updateSearchRequest();
+	}
+
+
+	private void handleSelectionChanged(IStructuredSelection ssel) {
+		boolean enable = false;
+		Object item = ssel.getFirstElement();
+		String description = null;
+		if (item instanceof SiteBookmark) {
+			enable = !((SiteBookmark) item).isReadOnly();
+			description = ((SiteBookmark)item).getDescription();
+		} else if (item instanceof SiteCategory) {
+//			IURLEntry descEntry = ((SiteCategory)item).getCategory().getDescription();
+//			if (descEntry != null)
+//				description = descEntry.getAnnotation();
+		}
+		editButton.setEnabled(enable);
+		removeButton.setEnabled(enable);
+
+		if (description == null)
+			description = ""; //$NON-NLS-1$
+		descLabel.setText(UpdateManagerUtils.getWritableXMLString(description));
+	}
+
+	private void updateSearchRequest() {
+		Object[] checked = viewer.getCheckedElements();
+
+		UpdateSearchScope scope = new UpdateSearchScope();
+		int nsites = 0;
+
+		for (int i = 0; i < checked.length; i++) {
+			if (checked[i] instanceof SiteBookmark) {
+				SiteBookmark bookmark = (SiteBookmark) checked[i];
+				scope.addSearchSite(
+					bookmark.getLabel(),
+					bookmark.getURL(),
+					bookmark.getIgnoredCategories());
+				nsites++;
+			}
+		}
+		searchRequest.setScope(scope);
+		setPageComplete(nsites > 0);
+	}
+
+	public UpdateSearchRequest getSearchRequest() {
+		return searchRequest;
+	}
+    
+	public void setVisible(boolean value) {
+		super.setVisible(value);
+		if (value) {
+			// Reset all unavailable sites, so they can be tried again if the user wants it
+			SiteBookmark[] bookmarks = getAllSiteBookmarks();
+			for (int i=0; i<bookmarks.length; i++) {
+				if (bookmarks[i].isUnavailable())
+					bookmarks[i].setUnavailable(false);
+			}
+			automaticallySelectMirrors = UpdateCore.getPlugin().getPluginPreferences().getBoolean(UpdateCore.P_AUTOMATICALLY_CHOOSE_MIRROR);
+			automaticallySelectMirrorsCheckbox.setSelection(automaticallySelectMirrors);
+		}
+	}
+	
+	private SiteBookmark[] getAllSiteBookmarks() {
+		UpdateModel model = UpdateUI.getDefault().getUpdateModel();
+		Object[] bookmarks = model.getBookmarkLeafs();
+		Object[] sitesToVisit =
+			discoveryFolder.getChildren(discoveryFolder);
+		SiteBookmark[] all = new SiteBookmark[bookmarks.length + sitesToVisit.length];
+		System.arraycopy(bookmarks, 0, all, 0, bookmarks.length);
+		System.arraycopy(
+			sitesToVisit,
+			0,
+			all,
+			bookmarks.length,
+			sitesToVisit.length);
+		return all;
+	}
+
+	public boolean isPageComplete() {
+		return viewer.getCheckedElements().length != 0;
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/SitesImportExport.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/SitesImportExport.java
new file mode 100644
index 0000000..a184af2
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/SitesImportExport.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.io.*;
+import java.util.Vector;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.update.internal.ui.*;
+import org.eclipse.update.internal.ui.model.*;
+
+/**
+ */
+public class SitesImportExport {
+
+	static String lastLocation = null;
+	
+	public SitesImportExport() {
+		super();
+	}
+	
+
+	public static SiteBookmark[] getImportedBookmarks(Shell parent) {
+		FileDialog dialog = new FileDialog(parent);
+		dialog.setText(
+			UpdateUIMessages.LocalSiteSelector_dialogMessageImport); 
+
+		dialog.setFilterExtensions(new String[] { "*.xml", "*" }); //$NON-NLS-1$ //$NON-NLS-2$
+
+		SiteBookmark[] siteBookmarks = null;
+
+		String bookmarksFile = dialog.open();
+		while (bookmarksFile != null && siteBookmarks == null) {
+			File file = new File(bookmarksFile);
+			siteBookmarks = createImportedBookmarks(file);
+			if (siteBookmarks == null || siteBookmarks.length == 0) {
+				MessageDialog.openInformation(
+					parent,
+					UpdateUIMessages.LocalSiteSelector_importInfoTitle, 
+					UpdateUIMessages.LocalSiteSelector_importInfoMessage); 
+				bookmarksFile = dialog.open();
+			} else {
+				break;
+			}
+		}
+		return siteBookmarks;
+	}
+
+	public static void exportBookmarks(Shell parent, SiteBookmark[] siteBookmarks) {
+		FileDialog dialog = new FileDialog(parent, SWT.SAVE);
+		dialog.setText(
+			UpdateUIMessages.LocalSiteSelector_dialogMessageExport); 
+
+		dialog.setFileName("bookmarks.xml"); //$NON-NLS-1$
+
+		String bookmarksFile = dialog.open();
+		if (bookmarksFile == null)
+			return;
+		
+		Vector bookmarks = new Vector(siteBookmarks.length);
+		for (int i=0; i<siteBookmarks.length; i++)
+			bookmarks.add(siteBookmarks[i]);
+		BookmarkUtil.store(bookmarksFile, bookmarks);
+	}
+	
+	/**
+	 * Creates bookmarks out from the given file
+	 * 
+	 * @param file
+	 * @return
+	 */
+	static SiteBookmark[] createImportedBookmarks(File file) {
+		Vector bookmarks = new Vector();
+		BookmarkUtil.parse(file.getAbsolutePath(), bookmarks);
+		return BookmarkUtil.getBookmarks(bookmarks);
+	}
+
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/TableLayoutComposite.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/TableLayoutComposite.java
new file mode 100644
index 0000000..a1aa4f4
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/TableLayoutComposite.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.ColumnWeightData;
+
+/**
+ * A special composite to layout columns inside a table. The composite is needed since we have
+ * to layout the columns "before" the actual table gets layouted. Hence we can't use a normal
+ * layout manager.
+ */
+public class TableLayoutComposite extends Composite {
+
+	private List columns= new ArrayList();
+	
+	/**
+	 * The number of extra pixels taken as horizontal trim by the table column. 
+	 * To ensure there are N pixels available for the content of the column,
+	 * assign N+COLUMN_TRIM for the column width.
+	 * 
+	 * @since 3.1
+	 */
+	private static int COLUMN_TRIM = "carbon".equals(SWT.getPlatform()) ? 24 : 3; //$NON-NLS-1$
+
+	/**
+	 * Creates a new <code>TableLayoutComposite</code>.
+	 */
+	public TableLayoutComposite(Composite parent, int style) {
+		super(parent, style);
+        addControlListener(new ControlAdapter() {
+            public void controlResized(ControlEvent e) {
+                Rectangle area= getClientArea();
+                Table table= (Table)getChildren()[0];
+                Point preferredSize= computeTableSize(table);
+                int width= area.width - 2 * table.getBorderWidth();
+                if (preferredSize.y > area.height) {
+                    // Subtract the scrollbar width from the total column width
+                    // if a vertical scrollbar will be required
+                    Point vBarSize = table.getVerticalBar().getSize();
+                    width -= vBarSize.x;
+                }
+                layoutTable(table, width, area, table.getSize().x < area.width);
+            }
+        });
+	}
+	
+	/**
+	 * Adds a new column of data to this table layout.
+	 *
+	 * @param data the column layout data
+	 */
+	public void addColumnData(ColumnLayoutData data) {
+		columns.add(data);
+	}
+	
+	//---- Helpers -------------------------------------------------------------------------------------
+	
+	private Point computeTableSize(Table table) {
+		Point result= table.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+		
+		int width= 0;
+		int size= columns.size();
+		for (int i= 0; i < size; ++i) {
+			ColumnLayoutData layoutData= (ColumnLayoutData) columns.get(i);
+			if (layoutData instanceof ColumnPixelData) {
+				ColumnPixelData col= (ColumnPixelData) layoutData;
+				width += col.width;
+				if (col.addTrim) {
+					width += COLUMN_TRIM;
+				}
+			} else if (layoutData instanceof ColumnWeightData) {
+				ColumnWeightData col= (ColumnWeightData) layoutData;
+				width += col.minimumWidth;
+			} else {
+				Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
+			}
+		}
+		if (width > result.x)
+			result.x= width;
+		return result;
+	}
+	
+	private void layoutTable(Table table, int width, Rectangle area, boolean increase) {
+		// XXX: Layout is being called with an invalid value the first time
+		// it is being called on Linux. This method resets the
+		// Layout to null so we make sure we run it only when
+		// the value is OK.
+		if (width <= 1)
+			return;
+
+		TableColumn[] tableColumns= table.getColumns();
+		int size= Math.min(columns.size(), tableColumns.length);
+		int[] widths= new int[size];
+		int fixedWidth= 0;
+		int numberOfWeightColumns= 0;
+		int totalWeight= 0;
+
+		// First calc space occupied by fixed columns
+		for (int i= 0; i < size; i++) {
+			ColumnLayoutData col= (ColumnLayoutData) columns.get(i);
+			if (col instanceof ColumnPixelData) {
+				ColumnPixelData cpd = (ColumnPixelData) col;
+				int pixels = cpd.width;
+				if (cpd.addTrim) {
+					pixels += COLUMN_TRIM;
+				}
+				widths[i]= pixels;
+				fixedWidth += pixels;
+			} else if (col instanceof ColumnWeightData) {
+				ColumnWeightData cw= (ColumnWeightData) col;
+				numberOfWeightColumns++;
+				// first time, use the weight specified by the column data, otherwise use the actual width as the weight
+				// int weight = firstTime ? cw.weight : tableColumns[i].getWidth();
+				int weight= cw.weight;
+				fixedWidth+=cw.minimumWidth;
+				totalWeight += weight;
+			} else {
+				Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
+			}
+		}
+
+		// Do we have columns that have a weight
+		if (numberOfWeightColumns > 0) {
+			// Now distribute the rest to the columns with weight.
+			int rest= width - fixedWidth;
+			int totalDistributed= 0;
+			for (int i= 0; i < size; ++i) {
+				ColumnLayoutData col= (ColumnLayoutData) columns.get(i);
+				if (col instanceof ColumnWeightData) {
+					ColumnWeightData cw= (ColumnWeightData) col;
+					// calculate weight as above
+					// int weight = firstTime ? cw.weight : tableColumns[i].getWidth();
+					int weight= cw.weight;
+					int sparePixels= totalWeight == 0 ? 0 : weight * rest / totalWeight;
+					int newWidth = cw.minimumWidth;
+					if (sparePixels >0 )
+						newWidth += sparePixels;
+					totalDistributed += newWidth;
+					widths[i]= newWidth;
+				}
+			}
+
+			// Distribute any remaining pixels to columns with weight.
+			int diff= rest - totalDistributed;
+			for (int i= 0; diff > 0; ++i) {
+				if (i == size)
+					i= 0;
+				ColumnLayoutData col= (ColumnLayoutData) columns.get(i);
+				if (col instanceof ColumnWeightData) {
+					++widths[i];
+					--diff;
+				}
+			}
+		}
+		
+		if (increase) {
+			table.setSize(area.width, area.height);
+		}
+		for (int i= 0; i < size; i++) {
+			tableColumns[i].setWidth(widths[i]);
+		}
+		if (!increase) {
+			table.setSize(area.width, area.height);
+		}
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/TargetPage.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/TargetPage.java
new file mode 100644
index 0000000..95423eb
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/TargetPage.java
@@ -0,0 +1,833 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.configuration.IInstallConfigurationChangedListener;
+import org.eclipse.update.configuration.LocalSystemInfo;
+import org.eclipse.update.core.IFeature;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.internal.core.ConfiguredSite;
+import org.eclipse.update.internal.core.UpdateCore;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateLabelProvider;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIImages;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.parts.DefaultContentProvider;
+import org.eclipse.update.internal.ui.parts.SWTUtil;
+import org.eclipse.update.operations.IInstallFeatureOperation;
+
+public class TargetPage extends BannerPage implements IDynamicPage {
+	
+	private static final int FEATURE_NAME_COLUMN = 0;
+	private static final int FEATURE_VERSION_COLUMN = 1;
+	private static final int FEATURE_SIZE_COLUMN = 2;
+	private static final int INSTALLATION_DIRECTORY_COLUMN = 3;
+	
+	private float featureNameColumnProcetange = 0.25f;
+	private float featureVersionColumnProcetange = 0.25f;
+	private float featureSizeColumnProcetange = 0.15f;
+	
+	private TableViewer jobViewer;
+	private IInstallConfiguration config;
+	private Label requiredSpaceLabel;
+	private Label availableSpaceLabel;
+	private IInstallFeatureOperation[] jobs;
+    //private IInstallFeatureOperation currentJob;
+    private Label installLocation;
+    private Button changeLocation;
+    private IConfiguredSite [] addedSites;
+    
+    private boolean isUpdate; // whether the wizard is updating a feature or installing a new one
+
+	class JobsContentProvider
+		extends DefaultContentProvider
+		implements IStructuredContentProvider {
+		public Object[] getElements(Object parent) {
+			return jobs;
+		}
+	}
+
+	class JobsLabelProvider
+		extends LabelProvider
+		implements ITableLabelProvider {
+			
+		public Image getColumnImage(Object obj, int col) {
+			
+			if (col > 0) {
+				return null;
+			}
+			
+			UpdateLabelProvider provider = UpdateUI.getDefault().getLabelProvider();
+
+			IInstallFeatureOperation job = (IInstallFeatureOperation) obj;
+			ImageDescriptor base =
+				job.getFeature().isPatch()
+					? UpdateUIImages.DESC_EFIX_OBJ
+					: UpdateUIImages.DESC_FEATURE_OBJ;
+			int flags = 0;
+			if (job.getTargetSite() == null)
+				flags = UpdateLabelProvider.F_ERROR;
+			return provider.get(base, flags);
+		}
+
+		public String getColumnText(Object obj, int col) {
+			
+			IFeature feature = ((IInstallFeatureOperation) obj).getFeature();
+			IConfiguredSite csite =((IInstallFeatureOperation)obj).getTargetSite(); 
+			ISite site = csite!=null?csite.getSite():null;
+			if (col == FEATURE_NAME_COLUMN) {				
+				return feature.getLabel();
+			} else if (col == FEATURE_VERSION_COLUMN) {
+				return feature.getVersionedIdentifier().getVersion().toString();
+			} else if (col == FEATURE_SIZE_COLUMN) {
+				if (site==null)
+					return ""; //$NON-NLS-1$
+				long requiredSpace = site.getDownloadSizeFor(feature) + site.getInstallSizeFor(feature);
+				return getSizeString(requiredSpace);
+			} else if (col == INSTALLATION_DIRECTORY_COLUMN) {
+				if (site==null)
+					return ""; //$NON-NLS-1$
+				return site.getURL().getFile().toString();
+			}
+			return ""; //$NON-NLS-1$
+		}
+	}
+	
+	class JobViewerSorter extends ViewerSorter {
+		
+		
+		private static final int ASCENDING = 0;
+
+		private static final int DESCENDING = 1;
+
+		private int column;
+
+		private int direction;
+
+		public void doSort(int column) {
+
+			if (column == this.column) {
+				direction = 1 - direction;
+			} else {
+				this.column = column;
+				direction = ASCENDING;
+			}
+		}
+
+		/**
+		 * Compares the object for sorting
+		 */
+		public int compare(Viewer viewer, Object o1, Object o2) {
+
+			int rc = 0;
+			
+			IFeature feature1 = ((IInstallFeatureOperation) o1).getFeature();
+			IFeature feature2 = ((IInstallFeatureOperation) o2).getFeature();
+
+			String featureName1 = feature1.getLabel();
+			String featureName2 = feature2.getLabel();
+			
+			String featureId1 = feature1.getVersionedIdentifier().getVersion().toString();
+			String featureId2 = feature2.getVersionedIdentifier().getVersion().toString();
+
+			String installationDirectory1 = ((IInstallFeatureOperation)o1).getTargetSite().getSite().getURL().getFile().toString();
+			String installationDirectory2 = ((IInstallFeatureOperation)o2).getTargetSite().getSite().getURL().getFile().toString();
+
+			switch (column) {
+			case FEATURE_NAME_COLUMN:
+				rc = collator.compare(featureName1, featureName2);
+				break;
+			case FEATURE_VERSION_COLUMN:
+				rc = collator.compare(featureId1, featureId2);
+				break;
+			case INSTALLATION_DIRECTORY_COLUMN:
+				rc = collator.compare(installationDirectory1, installationDirectory2);
+				break;
+			}
+
+			// If descending order, flip the direction
+			if (direction == DESCENDING)
+				rc = -rc;
+
+			return rc;
+		}
+	}
+	
+	class ConfigListener implements IInstallConfigurationChangedListener {
+		public void installSiteAdded(IConfiguredSite csite) {
+			
+			// set the site as target for all jobs without a target
+			for (int i=0; jobs != null && i<jobs.length; i++)
+				if (jobs[i].getTargetSite() == null && getSiteVisibility(csite, jobs[i])) {
+					jobs[i].setTargetSite(csite);
+				}
+
+			jobViewer.refresh();
+		}
+
+		public void installSiteRemoved(IConfiguredSite csite) {
+			// remove the target site for all jobs that use it
+			// set the site as target for all jobs without a target
+			boolean refreshJobs = false;
+			for (int i=0; jobs != null && i<jobs.length; i++)
+				if (jobs[i].getTargetSite() == csite) {
+					jobs[i].setTargetSite(null);
+					refreshJobs = true;
+				}
+				
+			pageChanged();
+			
+			jobViewer.refresh();
+			if (refreshJobs) {
+				jobViewer.getControl().setFocus();
+			}
+		}
+	}
+
+	/**
+	 * Constructor for ReviewPage2
+	 */
+	public TargetPage(IInstallConfiguration config, boolean isUpdate) {
+		super("Target"); //$NON-NLS-1$
+		setTitle(UpdateUIMessages.InstallWizard_TargetPage_title); 
+		setDescription(UpdateUIMessages.InstallWizard_TargetPage_desc); 
+		this.config = config;
+		UpdateUI.getDefault().getLabelProvider().connect(this);
+		this.isUpdate = isUpdate;
+	}
+
+	public void setJobs(IInstallFeatureOperation[] jobs) {
+		//we need only unique features
+		//using Set here allows us to get rid of a duplicate elements
+		Set jobsSet = new HashSet();
+		for (int i = 0; i < jobs.length; i++) {
+			jobsSet.add(jobs[i]);
+		}
+		
+		this.jobs = (IInstallFeatureOperation[]) jobsSet.toArray(new IInstallFeatureOperation[jobsSet.size()]);
+	}
+
+	public void dispose() {
+		UpdateUI.getDefault().getLabelProvider().disconnect(this);
+//		config.removeInstallConfigurationChangedListener(configListener);
+		super.dispose();
+	}
+
+	public Control createContents(Composite parent) {
+		Composite client = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 3;
+		layout.marginWidth = layout.marginHeight = 0;
+		client.setLayout(layout);
+		client.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		Label label = new Label(client, SWT.NULL);
+		label.setText(UpdateUIMessages.InstallWizard_TargetPage_jobsLabel); 
+		createJobViewer(client);
+
+		label = new Label(client, SWT.NULL);
+		label.setText(UpdateUIMessages.InstallWizard_TargetPage_location); 
+        GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+        label.setLayoutData(gd);
+
+		installLocation = new Label(client, SWT.NULL);
+        installLocation.setText(""); //$NON-NLS-1$
+        gd = new GridData(GridData.FILL_HORIZONTAL);
+        installLocation.setLayoutData(gd);
+        
+        changeLocation = new Button(client, SWT.PUSH);
+        changeLocation.setText(UpdateUIMessages.InstallWizard_TargetPage_location_change); 
+        changeLocation.addSelectionListener(new SelectionAdapter() {
+            public void widgetSelected(SelectionEvent e) {
+                changeLocationOfFeatures();
+            }
+
+			
+        });
+			
+		Composite status = new Composite(client, SWT.NULL);
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.horizontalSpan = 3;
+		status.setLayoutData(gd);
+		layout = new GridLayout();
+		layout.numColumns = 2;
+		status.setLayout(layout);
+		label = new Label(status, SWT.NULL);
+		label.setText(UpdateUIMessages.InstallWizard_TargetPage_requiredSpace); 
+		requiredSpaceLabel = new Label(status, SWT.NULL);
+		requiredSpaceLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		label = new Label(status, SWT.NULL);
+		label.setText(UpdateUIMessages.InstallWizard_TargetPage_availableSpace); 
+		availableSpaceLabel = new Label(status, SWT.NULL);
+		availableSpaceLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(client, "org.eclipse.update.ui.MultiTargetPage2"); //$NON-NLS-1$
+		
+		Dialog.applyDialogFont(parent);
+		
+		return client;
+	}
+
+	private void createJobViewer(Composite parent) {
+		
+		final Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.MULTI | SWT.RESIZE | SWT.FULL_SELECTION);
+		
+		TableColumn featureNameColumn = new TableColumn(table, SWT.LEFT, FEATURE_NAME_COLUMN);
+		featureNameColumn.setText(UpdateUIMessages.TargetPage_FeatureNameColumn); 
+		featureNameColumn.setWidth(75);
+		
+		TableColumn featureVersionColumn = new TableColumn(table, SWT.LEFT, FEATURE_VERSION_COLUMN);
+		featureVersionColumn.setText(UpdateUIMessages.TargetPage_Feature_Version); 
+		featureVersionColumn.setWidth(75);
+		
+		TableColumn featureSizeColumn = new TableColumn(table, SWT.LEFT, FEATURE_SIZE_COLUMN);
+		featureSizeColumn.setText(UpdateUIMessages.TargetPage_Feature_Size); 
+		featureSizeColumn.setWidth(75);
+		
+		TableColumn featureLocationColumn = new TableColumn(table, SWT.LEFT, INSTALLATION_DIRECTORY_COLUMN);
+		featureLocationColumn.setText(UpdateUIMessages.TargetPage_InstallationDirectoryColumn); 
+		featureLocationColumn.setWidth(75);
+		jobViewer = new TableViewer(table);
+		
+		//jobViewer = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.MULTI);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+        gd.horizontalSpan = 3;
+		gd.widthHint = 150;
+		gd.heightHint = 200;
+		jobViewer.getTable().setLayoutData(gd);
+		jobViewer.setContentProvider(new JobsContentProvider());
+		jobViewer.setLabelProvider(new JobsLabelProvider());
+		jobViewer.setSorter(new JobViewerSorter());
+		
+		jobViewer.addDoubleClickListener(new IDoubleClickListener() {
+				public void doubleClick(DoubleClickEvent event) {
+					changeLocationOfFeatures();				
+				}
+			}
+		);
+		
+		table.addListener(SWT.MenuDetect, new Listener() {
+		      public void handleEvent(Event event) {
+		    	  Menu menu = new Menu (getShell(), SWT.POP_UP);
+					MenuItem item = new MenuItem (menu, SWT.PUSH);
+					item.setText(UpdateUIMessages.InstallWizard_TargetPage_location_change);
+					item.addListener(SWT.Selection, new Listener () {
+							public void handleEvent (Event e) {
+								changeLocationOfFeatures();
+							}
+						}
+					);
+					menu.setLocation (event.x, event.y);
+					menu.setVisible (true);
+		      }
+			}
+		);
+		featureNameColumn.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent event) {
+					((JobViewerSorter) jobViewer.getSorter()).doSort(FEATURE_NAME_COLUMN);
+					jobViewer.refresh();
+				}
+		    }
+		);
+		
+		featureVersionColumn.addSelectionListener(new SelectionAdapter() {
+		      	public void widgetSelected(SelectionEvent event) {
+		      		((JobViewerSorter) jobViewer.getSorter()).doSort(FEATURE_VERSION_COLUMN);
+		      		jobViewer.refresh();
+		      	}
+		    }
+		);
+		
+		featureSizeColumn.addSelectionListener(new SelectionAdapter() {
+		      	public void widgetSelected(SelectionEvent event) {
+		      		((JobViewerSorter) jobViewer.getSorter()).doSort(FEATURE_SIZE_COLUMN);
+		      		jobViewer.refresh();
+		      	}
+		    }
+		);
+		
+		featureLocationColumn.addSelectionListener(new SelectionAdapter() {
+		      	public void widgetSelected(SelectionEvent event) {
+		      		((JobViewerSorter) jobViewer.getSorter()).doSort(INSTALLATION_DIRECTORY_COLUMN);
+		      		jobViewer.refresh();
+		      	}
+		    }
+		);
+		
+		table.addControlListener(new ControlAdapter() {
+			public void controlResized(ControlEvent e) {
+
+
+				Rectangle area = table.getClientArea();
+				Point preferredSize = table.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+				int tableWidth = area.width - 3 * table.getBorderWidth();
+				if (preferredSize.y > area.height + table.getHeaderHeight()){
+					Point vBarSize = table.getVerticalBar().getSize();
+					tableWidth -= vBarSize.x;
+				}		
+				
+				TableColumn featureNameColumn = table.getColumn(FEATURE_NAME_COLUMN);
+				TableColumn featureVersionColumn = table.getColumn(FEATURE_VERSION_COLUMN);
+				TableColumn featureSizeColumn = table.getColumn(FEATURE_SIZE_COLUMN);
+				TableColumn featureLocationColumn = table.getColumn(INSTALLATION_DIRECTORY_COLUMN);
+
+				featureNameColumn.setWidth((int)(tableWidth * featureNameColumnProcetange));
+				featureVersionColumn.setWidth((int)(tableWidth * featureVersionColumnProcetange));
+				featureSizeColumn.setWidth((int)(tableWidth * featureSizeColumnProcetange));
+				featureLocationColumn.setWidth(tableWidth - featureNameColumn.getWidth() - featureVersionColumn.getWidth() - featureSizeColumn.getWidth());		    	
+
+				
+				featureNameColumnProcetange = featureNameColumn.getWidth() / (float)tableWidth;
+				featureVersionColumnProcetange = featureVersionColumn.getWidth() / (float)tableWidth;
+				featureSizeColumnProcetange = featureSizeColumn.getWidth() / (float)tableWidth;
+			}
+		});
+
+
+		jobViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				updateStatus();
+
+			}
+		});
+		
+		table.setHeaderVisible(true);
+	    table.setLinesVisible(true);
+	}
+
+	public void setVisible(boolean visible) {
+		if (visible) {
+			initializeDefaultTargetSites();
+			jobViewer.setInput(jobs);
+			if (jobViewer.getSelection().isEmpty() && jobs.length > 0)
+				jobViewer.setSelection(new StructuredSelection(jobs[0]));
+		}
+		
+		super.setVisible(visible);
+	}
+
+	private void verifyNotEmpty(boolean empty) {
+		String errorMessage = null;
+		if (empty)
+			errorMessage = UpdateUIMessages.InstallWizard_TargetPage_location_empty; 
+		setErrorMessage(errorMessage);
+		setPageComplete(!empty);
+	}
+
+
+	private void updateStatus() {
+		
+		IStructuredSelection selectedJobs = (IStructuredSelection)jobViewer.getSelection();
+		IInstallFeatureOperation selectedJob = (IInstallFeatureOperation)selectedJobs.getFirstElement();
+	
+		requiredSpaceLabel.setText(""); //$NON-NLS-1$
+		availableSpaceLabel.setText(""); //$NON-NLS-1$
+		installLocation.setText(""); //$NON-NLS-1$
+		
+		if (selectedJob == null) {
+			return;
+		}
+		
+		IConfiguredSite site = selectedJob.getTargetSite(); /*(IConfiguredSite) element;*/
+		File file = new File(site.getSite().getURL().getFile());
+		long available = -1;
+		long required = -1;
+		if (areAllTargetSitesSame()) {
+			available = LocalSystemInfo.getFreeSpace(file);
+			required = computeRequiredSizeFor(site);
+			//add the download size to space required to do operation since all plugins and nonplugin data will be downloaded first
+			required += computeDownloadSizeFor(site); 
+			installLocation.setText(new File(selectedJob.getTargetSite().getSite().getURL().getFile()).toString());
+		}		
+		
+		if (available == LocalSystemInfo.SIZE_UNKNOWN)
+			available = -1;
+		
+		requiredSpaceLabel.setText(getSizeString(required));
+		availableSpaceLabel.setText(getSizeString(available));
+		
+		
+		//if the available space was retireved from the OS and the required space is greater that the available space, do not let the user continue
+		if(available != LocalSystemInfo.SIZE_UNKNOWN && required > available){
+			this.setPageComplete(false);
+			//TODO: set error message: "...not enough space..."
+		}else
+			this.setPageComplete(true);
+	}
+	
+	private boolean areAllTargetSitesSame() {
+		IStructuredSelection selectedJobs = (IStructuredSelection)jobViewer.getSelection();
+		Iterator iterator = selectedJobs.iterator();
+		URL site = null;
+		if (iterator != null) {
+			while(iterator.hasNext()) {
+				IInstallFeatureOperation current = (IInstallFeatureOperation) iterator.next();				
+				if (site != null) {
+					if (!site.equals(current.getTargetSite().getSite().getURL())) {
+						return false;
+					}
+				} else {
+					site = current.getTargetSite().getSite().getURL();
+				}
+			}
+			return true;
+		}
+		return false;
+	}
+
+	private String getSizeString(long size) {
+		if (size <= 0) {
+			return UpdateUIMessages.InstallWizard_TargetPage_unknownSize;
+		} else {
+			double order = 1024.0;
+			double sizeInMB = size / order;
+			double sizeInGB = size / order / order;
+			if ( sizeInMB < 1) {
+				return NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_size_KB, "" + size); //$NON-NLS-1$
+			} else {
+				String pattern = "#.##"; //$NON-NLS-1$
+				DecimalFormat formatter = new DecimalFormat(pattern);
+				if (sizeInGB < 1) {					
+					return NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_size_MB, formatter.format(sizeInMB));
+				} else {
+					return NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_size_GB, formatter.format(sizeInGB));
+				}
+			}
+		}
+	}
+
+	private long computeRequiredSizeFor(IConfiguredSite site) {
+		long totalSize = 0;
+		for (int i = 0; i < jobs.length; i++) {
+			if (site.equals(jobs[i].getTargetSite())) {
+				long jobSize = site.getSite().getInstallSizeFor(jobs[i].getFeature());
+				if (jobSize == -1)
+					return -1;
+				totalSize += jobSize;
+			}
+		}
+		return totalSize;
+	}
+	
+	private long computeDownloadSizeFor(IConfiguredSite site) {
+		long totalSize = 0;
+		for (int i = 0; i < jobs.length; i++) {
+			if (site.equals(jobs[i].getTargetSite())) {
+				long jobSize = site.getSite().getDownloadSizeFor(jobs[i].getFeature());
+				if (jobSize == -1)
+					return -1;
+				totalSize += jobSize;
+			}
+		}
+		return totalSize;
+	}
+
+	private void pageChanged() {
+		boolean empty = false;
+		for (int i=0; jobs!=null && i<jobs.length; i++) {
+			if (jobs[i].getTargetSite() == null) {
+				empty = true;
+				break;
+			}
+		
+			IFeature feature = jobs[i].getFeature();
+			if (feature.isPatch()) {
+				// Patches must go together with the features
+				// they are patching.
+				
+				// Check current jobs
+				IInstallFeatureOperation patchedFeatureJob = findPatchedFeature(feature);
+				if (patchedFeatureJob != null
+					&& patchedFeatureJob.getTargetSite() != null
+					&& !jobs[i].getTargetSite().equals(patchedFeatureJob.getTargetSite())) {
+					String msg = NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_patchError, (new String[] {
+                    feature.getLabel(),
+                    patchedFeatureJob.getFeature().getLabel()}));
+					setErrorMessage(msg);
+					setPageComplete(false);
+					return;
+				}
+				// Check installed features
+				IFeature patchedFeature = UpdateUtils.getPatchedFeature(feature);
+				if (patchedFeature != null  
+					&& !jobs[i].getTargetSite().equals(patchedFeature.getSite().getCurrentConfiguredSite())) {
+					String msg = NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_patchError2, (new String[] {
+                    feature.getLabel(),
+                    patchedFeature.getLabel(),
+                    patchedFeature.getSite().getCurrentConfiguredSite().getSite().getURL().getFile()}));
+					setErrorMessage(msg);
+					setPageComplete(false);
+					return;
+				}
+			}
+		}
+		verifyNotEmpty(empty);
+	}
+	
+	
+	private  boolean getSiteVisibility(IConfiguredSite site, IInstallFeatureOperation job) {
+		// Do not allow installing into a non-updateable site
+		if (!site.isUpdatable())
+			return false;
+		
+		// If affinity site is known, only it should be shown
+		IConfiguredSite affinitySite = UpdateUtils.getAffinitySite(config, job.getFeature());
+		if (affinitySite != null) {
+			// Must compare referenced sites because
+			// configured sites themselves may come from 
+			// different configurations
+			return site.getSite().equals(affinitySite.getSite());
+		}
+		
+		// Co-locate updates with the old feature
+		if (job.getOldFeature() != null) {
+			IConfiguredSite oldSite = UpdateUtils.getSiteWithFeature(config, job.getOldFeature().getVersionedIdentifier().getIdentifier());
+			return (site == oldSite);
+		}
+
+		// Allow installing into any site that is updateable and there is no affinity specified
+		return true;
+	}
+	
+	private void initializeDefaultTargetSites() {
+		
+		
+		IConfiguredSite mostReceantlyUsedSite = getMostReceantlyUsedSite();
+		for (int i = 0; i < jobs.length; i++) {
+			if (jobs[i].getTargetSite() != null)
+				continue;
+			
+			IConfiguredSite affinitySite =	UpdateUtils.getAffinitySite(config, jobs[i].getFeature());
+			if (affinitySite != null) {
+				jobs[i].setTargetSite(affinitySite);
+				continue;
+			}
+
+			IConfiguredSite defaultSite = UpdateUtils.getDefaultTargetSite(config, jobs[i], false);
+			if (defaultSite != null) {
+				jobs[i].setTargetSite(defaultSite);
+				continue;
+			}
+			
+			if (mostReceantlyUsedSite != null) {
+				jobs[i].setTargetSite(mostReceantlyUsedSite);
+				continue;
+			}
+			
+			IConfiguredSite csite = getFirstTargetSite(jobs[i]);
+			if (csite == null && Platform.getInstallLocation().isReadOnly() && isUpdate == false) {
+				// there are no updateable sites, the installation location is read-only and we are installing a new feature
+				// make an update site in the configuration area
+				String configurationLocation = Platform.getConfigurationLocation().getURL().getFile();
+				File site = new File(configurationLocation);
+				if (!ConfiguredSite.canWrite(site)) {
+					// if we cannot write to the configuration area then make an update site in the user's home directory
+					site = new File(System.getProperty("user.home") + File.separator + ".eclipse" + File.separator + //$NON-NLS-1$ //$NON-NLS-2$
+							Platform.getProduct().getId() + File.separator + "updates"); //$NON-NLS-1$
+				}
+				try {
+					csite = config.createConfiguredSite(site);
+					config.addConfiguredSite(csite);
+					IStatus status = csite.verifyUpdatableStatus();
+					if (!status.isOK())
+						throw new CoreException(status);
+				} catch (CoreException e) {
+					// there was a problem, the user must choose an installation site
+					csite = null;
+					// no need to check if the directory exists because File.delete() returns false if it's not there
+					deleteDir(site);
+				}
+			}
+
+			jobs[i].setTargetSite(csite);
+		}
+	}
+	
+		private boolean deleteDir(File dir) {
+		if (dir.isDirectory()) {
+			String[] files = dir.list();
+			for (int i = 0; i < files.length; i++) {
+				if (!deleteDir(new File(dir, files[i]))) {
+					return false;
+				}
+			}
+		}
+		return dir.delete();
+	}
+	
+	private IConfiguredSite getMostReceantlyUsedSite() {
+		IDialogSettings master = UpdateUI.getDefault().getDialogSettings();
+		IDialogSettings section = master.getSection(TargetSiteDialog.MOST_RECEANTLY_USED_SITE_URL);
+		if (section == null) {
+			return null;
+		}
+		String mostReceantlyUsedSiteURLString = section.get(TargetSiteDialog.MOST_RECEANTLY_USED_SITE_URL); 
+		if (mostReceantlyUsedSiteURLString == null) {
+			return null;
+		}
+		
+		URL mostReceantlyUsedSiteURL = null;
+		try {
+			mostReceantlyUsedSiteURL = new URL(mostReceantlyUsedSiteURLString);
+		} catch (MalformedURLException mue) {
+			UpdateCore.log("Url format is wrong for the mostReceantlyUsedSiteURL in preferences", mue); //$NON-NLS-1$
+			mue.printStackTrace();
+			return null;
+		}
+		IConfiguredSite[] sites = config.getConfiguredSites();
+		for (int i = 0; i < sites.length; i++) {
+			IConfiguredSite configuredSite = sites[i];
+			if (mostReceantlyUsedSiteURL.equals(configuredSite.getSite().getURL())) {
+				return configuredSite;
+			}
+		}
+		return null;
+	}
+	
+
+	private IConfiguredSite getFirstTargetSite(IInstallFeatureOperation job) {
+		IConfiguredSite[] sites = config.getConfiguredSites();
+		for (int i = 0; i < sites.length; i++) {
+			IConfiguredSite csite = sites[i];
+			if (getSiteVisibility(csite, job) && csite.getSite().getCurrentConfiguredSite().verifyUpdatableStatus().isOK())
+				return csite;
+		}
+		return null;
+	}
+	
+	public IInstallFeatureOperation findPatchedFeature(IFeature patch) {
+		for (int i=0; i<jobs.length; i++) {
+			IFeature target = jobs[i].getFeature();
+			if (!target.equals(patch) && UpdateUtils.isPatch(target, patch))
+				return jobs[i];
+		}
+		return null;
+            }
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.wizard.IWizardPage#isPageComplete()
+     */
+    public boolean isPageComplete() {
+        // check if all jobs have a target site set
+        for (int i = 0; jobs != null && i < jobs.length; i++) {
+            if (jobs[i].getTargetSite() == null)
+                return false;
+        }
+        return super.isPageComplete();
+    }
+
+    /**
+     * @param job
+     */
+/*    private void setTargetLocation(IInstallFeatureOperation job) {
+        if (job != null && job.getTargetSite() != null) {
+            installLocation.setText(new File(job.getTargetSite().getSite().getURL().getFile()).toString());
+            updateStatus(job.getTargetSite());
+        }
+    }*/
+    
+    private IInstallFeatureOperation[] toJobArray(Iterator selectedJobs) {
+		
+    	if (selectedJobs == null) 
+    		return new IInstallFeatureOperation[0];
+    	
+    	ArrayList result = new ArrayList();
+    	
+    	while (selectedJobs.hasNext()) {
+    		result.add(selectedJobs.next());
+    	}
+    	
+    	return (IInstallFeatureOperation[])result.toArray(new IInstallFeatureOperation[result.size()]);
+	}
+
+	private void changeLocationOfFeatures() {
+		IStructuredSelection selection = (IStructuredSelection) jobViewer.getSelection();
+		if (selection == null)
+		    return;
+		Iterator selectedJob = selection.iterator();
+		if (selectedJob == null) 
+		    return;
+		
+		TargetSiteDialog dialog = new TargetSiteDialog(getShell(), config, toJobArray(selection.iterator()));
+		dialog.create();
+
+		SWTUtil.setDialogSize(dialog, 400, 300);
+		
+		dialog.getShell().setText(UpdateUIMessages.SitePage_new); 
+		if ( dialog.open() == Dialog.OK) {
+			pageChanged();
+			jobViewer.refresh();
+			updateStatus();
+			addedSites = dialog.getAddedSites();
+		}
+	}
+	
+	void removeAddedSites() {
+		if (addedSites!=null) {
+			for (int i=0; i<addedSites.length; i++) {
+				config.removeConfiguredSite(addedSites[i]);
+			}
+		}
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/TargetSiteDialog.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/TargetSiteDialog.java
new file mode 100644
index 0000000..341534f
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/TargetSiteDialog.java
@@ -0,0 +1,376 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Observable;
+import java.util.Observer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.update.configuration.IConfiguredSite;
+import org.eclipse.update.configuration.IInstallConfiguration;
+import org.eclipse.update.core.ISite;
+import org.eclipse.update.internal.operations.UpdateUtils;
+import org.eclipse.update.internal.ui.UpdateLabelProvider;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.UpdateUIMessages;
+import org.eclipse.update.internal.ui.parts.DefaultContentProvider;
+import org.eclipse.update.internal.ui.parts.SWTUtil;
+import org.eclipse.update.operations.IInstallFeatureOperation;
+
+public class TargetSiteDialog extends Dialog {
+	protected static final String MOST_RECEANTLY_USED_SITE_URL = "mostReceantlyUsedSiteURL"; //$NON-NLS-1$
+	private TableViewer siteViewer;
+	private IInstallConfiguration config;
+	private Button addButton;
+	private Button deleteButton;
+    private IInstallFeatureOperation[] jobs;
+    private WorkingCopy workingCopy;
+    
+    class WorkingCopy extends Observable {
+    	private ArrayList sites=new ArrayList();
+    	private ArrayList added=new ArrayList();
+    	private IConfiguredSite targetSite;
+
+    	public WorkingCopy() {
+    		Object [] initial = config.getConfiguredSites();
+    		for (int i=0; i<initial.length; i++)
+    			sites.add(initial[i]);
+    		for (int i=0; i<jobs.length; i++) {
+    			IConfiguredSite jsite = jobs[i].getTargetSite();
+    			if (targetSite==null)
+    				targetSite = jsite;
+    			else
+    				if (!targetSite.equals(jsite))
+    					targetSite = null;
+    		}
+    	}
+    	
+    	public void addSite(IConfiguredSite site) {
+    		sites.add(site);
+    		added.add(site);
+    		setChanged();
+    		notifyObservers(site);
+    		clearChanged();
+    	}
+    	
+    	public void removeSite(IConfiguredSite site) {
+    		sites.remove(site);
+    		added.remove(site);
+    		setChanged();
+    		notifyObservers(site);
+    		clearChanged();
+    	}
+    	
+    	public boolean isNewlyAdded(IConfiguredSite site) {
+    		return added.contains(site);
+    	}
+    	
+    	public void commit() {
+    		// add new sites to the config
+    		for (int i=0; i<added.size(); i++) {
+    			config.addConfiguredSite((IConfiguredSite)added.get(i));
+    		}
+    		// set selected site to the job
+    		for (int i=0; i<jobs.length; i++) {
+    			jobs[i].setTargetSite(targetSite);
+    		}
+    	}
+    	
+    	public IConfiguredSite [] getSites() {
+    		return (IConfiguredSite[])sites.toArray(new IConfiguredSite[sites.size()]);
+    	}
+    	
+    	public IConfiguredSite [] getAddedSites() {
+    		return (IConfiguredSite[])added.toArray(new IConfiguredSite[added.size()]);
+    	}    	
+    	
+    	public IConfiguredSite getTargetSite() {
+    		return targetSite;
+    	}
+    	
+    	public void setTargetSite(IConfiguredSite site) {
+    		this.targetSite = site;
+    	}
+    }
+    
+    class SitesContentProvider extends DefaultContentProvider implements IStructuredContentProvider {
+		public Object[] getElements(Object parent) {
+			return workingCopy.getSites();
+		}
+	}
+	
+	class SitesLabelProvider extends LabelProvider implements ITableLabelProvider {
+		
+		public Image getColumnImage(Object obj, int col) {
+			UpdateLabelProvider provider = UpdateUI.getDefault().getLabelProvider();
+			return provider.getLocalSiteImage((IConfiguredSite) obj);
+		}
+	
+		public String getColumnText(Object obj, int col) {
+			if (col == 0) {
+				ISite site = ((IConfiguredSite) obj).getSite();
+				return new File(site.getURL().getFile()).toString();
+			}
+			return null;
+		}
+	}
+
+
+	/**
+	 * Constructor for ReviewPage2
+	 */
+	public TargetSiteDialog(Shell parentShell, IInstallConfiguration config, IInstallFeatureOperation[] jobs) {
+        super(parentShell);
+		this.config = config;
+		UpdateUI.getDefault().getLabelProvider().connect(this);
+		this.jobs = jobs;
+		workingCopy = new WorkingCopy();
+	}
+
+	public boolean close() {
+		UpdateUI.getDefault().getLabelProvider().disconnect(this);
+		return super.close();
+	}
+
+    public Control createDialogArea(Composite parent) {
+    	Composite client = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginWidth = layout.marginHeight = 10;
+		client.setLayout(layout);
+		client.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		Composite leftPanel = new Composite(client, SWT.NULL);
+		GridLayout centerLayout = new GridLayout();
+		centerLayout.numColumns = 1;
+		centerLayout.marginWidth = centerLayout.marginHeight = 0;
+		leftPanel.setLayout(centerLayout);
+		leftPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
+        
+		Label label = new Label(leftPanel, SWT.NULL);
+		label.setText(UpdateUIMessages.InstallWizard_TargetPage_siteLabel); 
+		createSiteViewer(leftPanel);
+
+		Composite rightPanel = new Composite(client, SWT.NULL);
+		GridLayout rightLayout = new GridLayout();
+		rightLayout.numColumns = 1;
+		rightLayout.marginWidth = rightLayout.marginHeight = 0;
+		rightPanel.setLayout(rightLayout);
+		rightPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+
+		new Label(rightPanel, SWT.NULL);
+		Composite buttonContainer = new Composite(rightPanel, SWT.NULL);
+		GridLayout blayout = new GridLayout();
+		blayout.marginWidth = blayout.marginHeight = 0;
+		buttonContainer.setLayout(blayout);
+		buttonContainer.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+		
+		addButton = new Button(buttonContainer, SWT.PUSH);
+		addButton.setText(UpdateUIMessages.InstallWizard_TargetPage_new); 
+		addButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				addTargetLocation();
+			}
+		});
+
+		addButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		SWTUtil.setButtonDimensionHint(addButton);
+		
+		deleteButton = new Button(buttonContainer, SWT.PUSH);
+		deleteButton.setText(UpdateUIMessages.InstallWizard_TargetPage_delete); 
+		deleteButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				try {
+					removeSelection();
+				}
+				catch (CoreException ex) {
+					UpdateUI.logException(ex);
+				}
+			}
+		});
+		deleteButton.setEnabled(false);
+		deleteButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		SWTUtil.setButtonDimensionHint(deleteButton);		
+
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(client, "org.eclipse.update.ui.MultiTargetPage2"); //$NON-NLS-1$
+		Dialog.applyDialogFont(parent);
+        
+        siteViewer.setInput(jobs[0]);
+        IConfiguredSite affinitySite = UpdateUtils.getDefaultTargetSite(config, jobs[0], true);
+        if (jobs[0].getTargetSite() != null) 
+        	siteViewer.setSelection(new StructuredSelection(jobs[0].getTargetSite()));
+        addButton.setEnabled(affinitySite == null);
+        
+        return client;
+	}
+
+	private void createSiteViewer(Composite parent) {
+		siteViewer = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.widthHint = 200;
+		siteViewer.getTable().setLayoutData(gd);
+		siteViewer.setContentProvider(new SitesContentProvider());
+		siteViewer.setLabelProvider(new SitesLabelProvider());
+		siteViewer.addFilter(new ViewerFilter() {
+			public boolean select(Viewer v, Object parent, Object obj) {
+				IInstallFeatureOperation job = (IInstallFeatureOperation) siteViewer.getInput();
+				return getSiteVisibility((IConfiguredSite) obj, job);
+			}
+		});
+		siteViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				IStructuredSelection ssel = (IStructuredSelection) event.getSelection();
+				selectTargetSite(ssel);
+				updateButtons(ssel);
+			}
+		});
+		workingCopy.addObserver(new Observer() {
+			public void update(Observable arg0, Object arg1) {
+				siteViewer.refresh();
+			}
+		});
+	}
+	
+    protected void okPressed() {
+    	workingCopy.commit();
+        super.okPressed();
+    }
+    
+	protected void createButtonsForButtonBar(Composite parent) {
+		super.createButtonsForButtonBar(parent);
+		updateButtons((IStructuredSelection)siteViewer.getSelection());
+	}
+
+	private void updateButtons(IStructuredSelection selection) {
+		deleteButton.setEnabled(canDelete(selection));
+		Button okButton = getButton(IDialogConstants.OK_ID);
+		if (okButton!=null)
+			okButton.setEnabled(!selection.isEmpty());
+	}
+	
+	private boolean canDelete(IStructuredSelection selection) {
+		if (selection.isEmpty()) return false;
+		for (Iterator iter = selection.iterator(); iter.hasNext();) {
+			IConfiguredSite site = (IConfiguredSite)iter.next();
+			if (!workingCopy.isNewlyAdded(site))
+				return false;
+		}
+		return true;
+	}
+
+	private void selectTargetSite(IStructuredSelection selection) {
+		IConfiguredSite site = (IConfiguredSite) selection.getFirstElement();
+		if (site!=null) {
+			IDialogSettings master = UpdateUI.getDefault().getDialogSettings();
+			IDialogSettings section = master.getSection(MOST_RECEANTLY_USED_SITE_URL);
+			if (section==null)
+				section = master.addNewSection(MOST_RECEANTLY_USED_SITE_URL);
+			section.put(MOST_RECEANTLY_USED_SITE_URL, site.getSite().getURL().toExternalForm());
+			workingCopy.setTargetSite(site);
+		}
+	}
+
+	private void addTargetLocation() {
+		DirectoryDialog dd = new DirectoryDialog(getShell());
+		dd.setMessage(UpdateUIMessages.InstallWizard_TargetPage_location_message); 
+		String path = dd.open();
+		if (path != null) {
+			addConfiguredSite(getShell(), config, new File(path));
+		}
+	}
+	
+	private void removeSelection() throws CoreException {
+		IStructuredSelection selection = (IStructuredSelection) siteViewer.getSelection();
+		for (Iterator iter = selection.iterator(); iter.hasNext();) {
+			IConfiguredSite targetSite = (IConfiguredSite) iter.next();
+			workingCopy.removeSite(targetSite);
+		}
+		siteViewer.refresh();
+	}
+
+	private IConfiguredSite addConfiguredSite(Shell shell, IInstallConfiguration config, File file) {
+		try {
+			IConfiguredSite csite = config.createConfiguredSite(file);
+			IStatus status = csite.verifyUpdatableStatus();
+			if (status.isOK())
+				workingCopy.addSite(csite);
+			else 
+				throw new CoreException(status);
+            siteViewer.setSelection(new StructuredSelection(csite));
+            siteViewer.getControl().setFocus();
+			return csite;
+		} catch (CoreException e) {
+			String title = UpdateUIMessages.InstallWizard_TargetPage_location_error_title; 
+			ErrorDialog.openError(shell, title, null, e.getStatus());
+			UpdateUI.logException(e,false);
+			return null;
+		}
+	}
+	
+	private  boolean getSiteVisibility(IConfiguredSite site, IInstallFeatureOperation job) {
+		// Do not allow installing into a non-updateable site
+		if (!site.isUpdatable())
+			return false;
+		
+		// If affinity site is known, only it should be shown
+		IConfiguredSite affinitySite = UpdateUtils.getAffinitySite(config, job.getFeature());
+		if (affinitySite != null) {
+			// Must compare referenced sites because
+			// configured sites themselves may come from 
+			// different configurations
+			return site.getSite().equals(affinitySite.getSite());
+		}
+		
+		// Co-locate updates with the old feature
+		if (job.getOldFeature() != null) {
+			IConfiguredSite oldSite = UpdateUtils.getSiteWithFeature(config, job.getOldFeature().getVersionedIdentifier().getIdentifier());
+			return (site == oldSite);
+		}
+
+		// Allow installing into any site that is updateable and there is no affinity specified
+		return true;
+	}
+	
+	public IConfiguredSite [] getAddedSites() {
+		return workingCopy.getAddedSites();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/UIProblemHandler.java b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/UIProblemHandler.java
new file mode 100644
index 0000000..b4c084e
--- /dev/null
+++ b/update/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/UIProblemHandler.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.wizards;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.update.configuration.*;
+import org.eclipse.update.internal.ui.*;
+
+/**
+ *
+ */
+public class UIProblemHandler implements IProblemHandler {
+
+	/*
+	 * @see IProblemHandler#reportProblem(String)
+	 */
+	public boolean reportProblem(String problemText) {
+		String title = UpdateUIMessages.Revert_ProblemDialog_title; 
+		return MessageDialog.openQuestion(UpdateUI.getActiveWorkbenchShell(), title, problemText);
+	}
+}
diff --git a/update/org.eclipse.update.ui/src_webapp/org/eclipse/update/internal/ui/servlets/InstallServlet.java b/update/org.eclipse.update.ui/src_webapp/org/eclipse/update/internal/ui/servlets/InstallServlet.java
new file mode 100644
index 0000000..c555b0e
--- /dev/null
+++ b/update/org.eclipse.update.ui/src_webapp/org/eclipse/update/internal/ui/servlets/InstallServlet.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.servlets;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.update.core.VersionedIdentifier;
+import org.eclipse.update.internal.search.SiteSearchCategory;
+import org.eclipse.update.internal.ui.UpdateUI;
+import org.eclipse.update.internal.ui.parts.SWTUtil;
+import org.eclipse.update.internal.ui.servlets.ServletsUtil;
+import org.eclipse.update.internal.ui.wizards.InstallWizard;
+import org.eclipse.update.operations.OperationsManager;
+import org.eclipse.update.search.BackLevelFilter;
+import org.eclipse.update.search.EnvironmentFilter;
+import org.eclipse.update.search.UpdateSearchRequest;
+import org.eclipse.update.search.UpdateSearchScope;
+import org.eclipse.update.search.VersionedIdentifiersFilter;
+
+/**
+ *
+ * To change this generated comment edit the template variable "typecomment":
+ * Window>Preferences>Java>Templates.
+ * To enable and disable the creation of type comments go to
+ * Window>Preferences>Java>Code Generation.
+ */
+public class InstallServlet extends HttpServlet {
+	private ServletConfig servletConfig;
+	public static final String SERVLET_NAME = "/InstallServlet"; //$NON-NLS-1$
+
+	public void init(ServletConfig config) throws ServletException {
+		this.servletConfig = config;
+	}
+
+	public void destroy() {
+	}
+
+	public ServletConfig getServletConfig() {
+		return servletConfig;
+	}
+
+	public String getServletInfo() {
+		return "Eclipse Install servlet"; //$NON-NLS-1$
+	}
+
+	public void service(
+		HttpServletRequest servletRequest,
+		HttpServletResponse servletResponse)
+		throws ServletException, IOException {
+		PrintWriter writer =
+			ServletsUtil.createResponsePrologue(servletResponse);
+		execute(writer, servletRequest);
+		ServletsUtil.createResponseEpilogue(
+			servletRequest,
+			servletResponse,
+			writer);
+	}
+
+	/**
+	 * Method execute.
+	 * @param servletRequest
+	 */
+	private void execute(
+		PrintWriter writer,
+		HttpServletRequest servletRequest) {
+		String serverURL = servletRequest.getParameter("server"); //$NON-NLS-1$
+		String license = servletRequest.getParameter("license"); //$NON-NLS-1$
+		boolean needLicensePage = true;
+		if (license != null && license.equalsIgnoreCase("false")) //$NON-NLS-1$
+			needLicensePage = false;
+
+		String[] versionedIds = servletRequest.getParameterValues("feature"); //$NON-NLS-1$
+
+		if (serverURL == null) {
+			createPageError(writer, UpdateUI.getString("InstallServlet.unknownServerURL")); //$NON-NLS-1$
+			return;
+		}
+		if (versionedIds == null) {
+			createPageError(writer, UpdateUI.getString("InstallServlet.noFeatures")); //$NON-NLS-1$
+			return;
+		}
+		if (OperationsManager.isInProgress()) {
+			ServletsUtil.createError(writer, UpdateUI.getString("InstallServlet.inProgress"), null); //$NON-NLS-1$
+			return;
+		}
+//		if (DetailsForm.isInProgress()) {
+//			ServletsUtil.createError(writer, UpdateUI.getString("InstallServlet.inProgress"), null);
+//			return;
+//		}
+		try {
+			URL url = new URL(serverURL);
+			VersionedIdentifier[] vids =
+				computeVersionedIdentifiers(versionedIds);
+			boolean success =
+				executeInstall(writer, url, vids, needLicensePage);
+			if (success)
+				ServletsUtil.createInfo(writer);
+		} catch (MalformedURLException e) {
+			createPageError(writer, UpdateUI.getFormattedMessage("InstallServlet.incorrectURLFormat", //$NON-NLS-1$
+			serverURL.toString()));
+		}
+	}
+
+	private void createPageError(PrintWriter writer, String problem) {
+		ServletsUtil.createError(writer, problem, UpdateUI.getString("InstallServlet.contactWebmaster")); //$NON-NLS-1$
+	}
+
+	private VersionedIdentifier[] computeVersionedIdentifiers(String[] array) {
+		ArrayList result = new ArrayList();
+		for (int i = 0; i < array.length; i++) {
+			String id_version = array[i];
+			int sep = id_version.lastIndexOf('_');
+			if (sep == -1)
+				continue;
+			String id = id_version.substring(0, sep);
+			String version = id_version.substring(sep + 1);
+			VersionedIdentifier vid = new VersionedIdentifier(id, version);
+			result.add(vid);
+		}
+		return (VersionedIdentifier[]) result.toArray(
+			new VersionedIdentifier[result.size()]);
+	}
+
+	private boolean executeInstall(
+		final PrintWriter writer,
+		final URL siteURL,
+		final VersionedIdentifier[] vids,
+		final boolean needLicensePage) {
+
+		Display display = SWTUtil.getStandardDisplay();
+		final boolean[] result = new boolean[] { false };
+
+		display.syncExec(new Runnable() {
+			public void run() {
+				final Shell shell = UpdateUI.getActiveWorkbenchShell();
+				BusyIndicator.showWhile(shell.getDisplay(), new Runnable() {
+					public void run() {
+						result[0] =
+							doExecuteInstall(
+								writer,
+								shell,
+								siteURL,
+								vids,
+								needLicensePage);
+					}
+				});
+			}
+		});
+		return result[0];
+	}
+
+	private boolean doExecuteInstall(
+		PrintWriter writer,
+		final Shell shell,
+		URL siteURL,
+		VersionedIdentifier[] vids,
+		final boolean needLicensePage) {
+			
+		shell.forceActive();
+
+		UpdateSearchScope searchScope = new UpdateSearchScope();
+		searchScope.addSearchSite(
+			siteURL.toString(),
+			siteURL,
+			new String[0]);
+
+		final UpdateSearchRequest searchRequest =
+			new UpdateSearchRequest(
+				new SiteSearchCategory(),
+				searchScope);
+	
+		searchRequest.addFilter(new VersionedIdentifiersFilter(vids));
+		searchRequest.addFilter(new EnvironmentFilter());
+		searchRequest.addFilter(new BackLevelFilter());
+
+		shell.getDisplay().asyncExec(new Runnable() {
+			public void run() {
+				openWizard(shell, searchRequest);
+			}
+		});	
+		return true;
+	}
+
+
+	private void openWizard(Shell shell, UpdateSearchRequest searchRequest) {
+		InstallWizard wizard = new InstallWizard(searchRequest);
+		WizardDialog dialog = new ResizableWizardDialog(shell, wizard);
+		dialog.create();
+//		dialog.getShell().setText(
+//			UpdateUI.getString(KEY_OPTIONAL_INSTALL_TITLE));
+		dialog.getShell().setSize(600, 500);
+		dialog.open();
+		if (wizard.isSuccessfulInstall())
+			UpdateUI.requestRestart();
+	}
+}
diff --git a/update/org.eclipse.update.ui/src_webapp/org/eclipse/update/internal/ui/servlets/ServletsUtil.java b/update/org.eclipse.update.ui/src_webapp/org/eclipse/update/internal/ui/servlets/ServletsUtil.java
new file mode 100644
index 0000000..755718f
--- /dev/null
+++ b/update/org.eclipse.update.ui/src_webapp/org/eclipse/update/internal/ui/servlets/ServletsUtil.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ *******************************************************************************/
+package org.eclipse.update.internal.ui.servlets;
+
+import java.io.*;
+import java.util.*;
+
+import javax.servlet.http.*;
+
+import org.eclipse.core.boot.*;
+import org.eclipse.update.internal.ui.*;
+
+/**
+ */
+public class ServletsUtil {
+
+	public static String getServerInfo(HttpServletRequest servletRequest) {
+		String host = servletRequest.getServerName();
+		int port = servletRequest.getServerPort();
+		String context = servletRequest.getContextPath();
+
+		Enumeration atts = servletRequest.getParameterNames();
+		StringBuffer buff = new StringBuffer();
+		for (; atts.hasMoreElements();) {
+			String attName = (String) atts.nextElement();
+			Object attValue = servletRequest.getParameter(attName);
+			buff.append(attName + "=" + "\"" + attValue + "\"+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		}
+		return host + ":" + port + context + "?" + buff.toString(); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	public static PrintWriter createResponsePrologue(HttpServletResponse response)
+		throws IOException {
+		response.setContentType("text/html"); //$NON-NLS-1$
+		PrintWriter writer = response.getWriter();
+		String title = UpdateUI.getString("ServletsUtil.responseTitle"); //$NON-NLS-1$
+		writer.println(
+			"" //$NON-NLS-1$
+				+ "<!DOCTYPE HTML PUBLIC \" -//W3C//DTD HTML 4.0 Transitional//EN\">" //$NON-NLS-1$
+				+ "\n <HTML> \n <HEAD> \n" //$NON-NLS-1$
+				+ "<TITLE>"+title+"</TITLE>\n" //$NON-NLS-1$ //$NON-NLS-2$
+				+ "<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n" //$NON-NLS-1$
+				+ "</HEAD>"); //$NON-NLS-1$
+		writer.println(" <BODY topmargin=\"0\" leftmargin=\"0\">"); //$NON-NLS-1$
+		return writer;
+	}
+
+	public static void createError(
+		PrintWriter writer,
+		String problem,
+		String resolution) {
+		createHeading(writer, UpdateUI.getString("ServletsUtil.updateFailed")); //$NON-NLS-1$
+		startTextArea(writer);
+		createParagraph(writer, UpdateUI.getString("ServletsUtil.problem"), problem); //$NON-NLS-1$
+		if (resolution != null) {
+			writer.println("<p>"); //$NON-NLS-1$
+			createParagraph(writer, UpdateUI.getString("ServletsUtil.whatToDo"), resolution); //$NON-NLS-1$
+		}
+		endTextArea(writer);
+	}
+
+	public static void createParagraph(
+		PrintWriter writer,
+		String heading,
+		String text) {
+		writer.print("<b><font color=\"#5B78AC\">"); //$NON-NLS-1$
+		writer.print(heading);
+		writer.println("</b></font><br>"); //$NON-NLS-1$
+		writer.println(text);
+	}
+
+	public static void createInfo(PrintWriter writer) {
+		createHeading(writer, UpdateUI.getString("ServletsUtil.updateInProgress")); //$NON-NLS-1$
+		startTextArea(writer);
+		writer.println(
+			UpdateUI.getString("ServletsUtil.updateInitiated")); //$NON-NLS-1$
+		endTextArea(writer);
+	}
+	
+	private static boolean isWin32() {
+		return BootLoader.getWS().equals("win32"); //$NON-NLS-1$
+	}
+
+	private static void startTextArea(PrintWriter writer) {
+		writer.println(
+			"<table border=\"0\" width=\"100%\" cellspacing=\"5\" cellpadding=\"5\">"); //$NON-NLS-1$
+		writer.println("<tr>"); //$NON-NLS-1$
+		writer.print("<td width=\"100%\">"); //$NON-NLS-1$
+		if (isWin32())
+			writer.println("<font face=\"MS Sans Serif\" size=\"1\">"); //$NON-NLS-1$
+		else
+			writer.println(""); //$NON-NLS-1$
+	}
+	private static void endTextArea(PrintWriter writer) {
+		if (isWin32())
+			writer.println("</font>"); //$NON-NLS-1$
+		writer.println("</td>"); //$NON-NLS-1$
+		writer.println("</tr>"); //$NON-NLS-1$
+		writer.println("</table>"); //$NON-NLS-1$
+	}
+
+	public static void createHeading(PrintWriter writer, String title) {
+		writer.println(
+			"<table cols=1 width=\"588\" cellspacing=\"0\" cellpadding=\"0\">"); //$NON-NLS-1$
+		writer.println("<tr>"); //$NON-NLS-1$
+		writer.println(
+			"<td background=\"images/form_banner.jpg\" width=\"580\" height=\"30\">"); //$NON-NLS-1$
+		writer.print("<p><b><font size=\"3\" face=\"Tahoma\">&nbsp;"); //$NON-NLS-1$
+		writer.print(title);
+		writer.println("</font></b></p>"); //$NON-NLS-1$
+		writer.println("</td>"); //$NON-NLS-1$
+		writer.println("</tr>"); //$NON-NLS-1$
+
+		writer.println("<tr>"); //$NON-NLS-1$
+		writer.println(
+			"<td width=\"580\"><img border=\"0\" src=\"images/form_underline.jpg\" width=\"600\" height=\"15\"></td>"); //$NON-NLS-1$
+		writer.println("</td>"); //$NON-NLS-1$
+		writer.println("</tr>"); //$NON-NLS-1$
+		writer.println("</table>"); //$NON-NLS-1$
+	}
+
+	public static void createResponseEpilogue(
+		HttpServletRequest request,
+		HttpServletResponse response,
+		PrintWriter writer) {
+
+		String backURL = getOriginatingURL(request);
+		if (backURL != null) {
+			startTextArea(writer);
+			String backText = UpdateUI.getString("ServletsUtil.back"); //$NON-NLS-1$
+			writer.print("<img border=\"0\" src=\"images/backward_nav.gif\"/><a href=\""); //$NON-NLS-1$
+			writer.print(getOriginatingURL(request));
+			writer.print("\">"+backText+"</a>"); //$NON-NLS-1$ //$NON-NLS-2$
+			endTextArea(writer);
+		}
+		writer.println(" </BODY> "); //$NON-NLS-1$
+		writer.println("</HTML>"); //$NON-NLS-1$
+		writer.close();
+	}
+	private static String getOriginatingURL(HttpServletRequest request) {
+		return request.getParameter("backURL"); //$NON-NLS-1$
+	}
+}
diff --git a/update/org.eclipse.update.ui/webapp/WEB-INF/.cvsignore b/update/org.eclipse.update.ui/webapp/WEB-INF/.cvsignore
new file mode 100644
index 0000000..90b07e9
--- /dev/null
+++ b/update/org.eclipse.update.ui/webapp/WEB-INF/.cvsignore
@@ -0,0 +1 @@
+classes
diff --git a/update/org.eclipse.update.ui/webapp/WEB-INF/lib/.cvsignore b/update/org.eclipse.update.ui/webapp/WEB-INF/lib/.cvsignore
new file mode 100644
index 0000000..64292a3
--- /dev/null
+++ b/update/org.eclipse.update.ui/webapp/WEB-INF/lib/.cvsignore
@@ -0,0 +1 @@
+update-servlets.jar
diff --git a/update/org.eclipse.update.ui/webapp/WEB-INF/web.xml b/update/org.eclipse.update.ui/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..ff84774
--- /dev/null
+++ b/update/org.eclipse.update.ui/webapp/WEB-INF/web.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+
+<!DOCTYPE web-app
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
+    "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
+
+<web-app>
+
+    <servlet>
+        <servlet-name>install</servlet-name>
+        <servlet-class>org.eclipse.update.internal.ui.servlets.InstallServlet</servlet-class>
+    </servlet>
+    
+	<servlet-mapping>
+		<servlet-name>install</servlet-name>
+		<url-pattern>/install</url-pattern>
+	</servlet-mapping>
+
+</web-app>
\ No newline at end of file
diff --git a/update/org.eclipse.update.ui/webapp/images/backward_nav.gif b/update/org.eclipse.update.ui/webapp/images/backward_nav.gif
new file mode 100644
index 0000000..85188b7
--- /dev/null
+++ b/update/org.eclipse.update.ui/webapp/images/backward_nav.gif
Binary files differ
diff --git a/update/org.eclipse.update.ui/webapp/images/form_banner.jpg b/update/org.eclipse.update.ui/webapp/images/form_banner.jpg
new file mode 100644
index 0000000..253e2d2
--- /dev/null
+++ b/update/org.eclipse.update.ui/webapp/images/form_banner.jpg
Binary files differ
diff --git a/update/org.eclipse.update.ui/webapp/images/form_underline.jpg b/update/org.eclipse.update.ui/webapp/images/form_underline.jpg
new file mode 100644
index 0000000..0ff3d0b
--- /dev/null
+++ b/update/org.eclipse.update.ui/webapp/images/form_underline.jpg
Binary files differ
diff --git a/update/org.eclipse.update/.project b/update/org.eclipse.update/.project
new file mode 100644
index 0000000..7560f76
--- /dev/null
+++ b/update/org.eclipse.update/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.update</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update/README.TXT b/update/org.eclipse.update/README.TXT
new file mode 100644
index 0000000..3f3537c
--- /dev/null
+++ b/update/org.eclipse.update/README.TXT
@@ -0,0 +1,2 @@
+This bundle is obsolete. Functionality from this bundle was split into the
+org.eclipse.update.core and org.eclipse.update.ui bundles in the Eclipse 2.1 release.
\ No newline at end of file