*** empty log message ***
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/.classpath b/bundles/org.eclipse.wst.xsl.jaxp.launching/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/.classpath
@@ -0,0 +1,7 @@
+<?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.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/.project b/bundles/org.eclipse.wst.xsl.jaxp.launching/.project
new file mode 100644
index 0000000..8dea7ec
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.wst.xsl.jaxp.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>
+	</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/bundles/org.eclipse.wst.xsl.jaxp.launching/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.wst.xsl.jaxp.launching/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b8d9369
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Wed Jul 30 16:38:51 BST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/JREDefaultAttributes.properties b/bundles/org.eclipse.wst.xsl.jaxp.launching/JREDefaultAttributes.properties
new file mode 100644
index 0000000..9c244d2
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/JREDefaultAttributes.properties
@@ -0,0 +1,10 @@
+###############################################################################
+# Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+###############################################################################
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/JREDefaultOutputProperties.properties b/bundles/org.eclipse.wst.xsl.jaxp.launching/JREDefaultOutputProperties.properties
new file mode 100644
index 0000000..ad23e9d
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/JREDefaultOutputProperties.properties
@@ -0,0 +1,40 @@
+###############################################################################
+# Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+###############################################################################
+
+method=method
+method.DESC="xml" | "html" | "text" | qname-but-not-ncname 
+
+version=version
+version.DESC=specifies the version of the output method
+
+indent=indent
+indent.DESC=specifies whether the XSLT processor may add additional whitespace when outputting the result tree; the value must be yes or no
+
+encoding=encoding
+encoding.DESC=specifies the preferred character encoding that the XSLT processor should use to encode sequences of characters as sequences of bytes; the value of the attribute should be treated case-insensitively; the value must contain only characters in the range #x21 to #x7E (i.e. printable ASCII characters); the value should either be a charset registered with the Internet Assigned Numbers Authority [IANA], [RFC2278] or start with X-
+
+media-type=media-type
+media-type.DESC=specifies the media type (MIME content type) of the data that results from outputting the result tree; the charset parameter should not be specified explicitly; instead, when the top-level media type is text, a charset parameter should be added according to the character encoding actually used by the output method
+
+doctype-system=doctype-system
+doctype-system.DESC=specifies the system identifier to be used in the document type declaration
+
+doctype-public=doctype-public
+doctype-public.DESC=specifies the public identifier to be used in the document type declaration
+
+omit-xml-declaration=omit-xml-declaration
+omit-xml-declaration.DESC=specifies whether the XSLT processor should output an XML declaration; the value must be yes or no
+
+standalone=standalone
+standalone.DESC=specifies whether the XSLT processor should output a standalone document declaration; the value must be yes or no
+
+cdata-section-elements=cdata-section-elements
+cdata-section-elements.DESC=specifies a list of the names of elements whose text node children should be output using CDATA sections
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.xsl.jaxp.launching/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d8d35d3
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name.0
+Bundle-SymbolicName: org.eclipse.wst.xsl.jaxp.launching;singleton:=true
+Bundle-Version: 0.5.0.qualifier
+Bundle-Activator: org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.variables;bundle-version="3.2.100",
+ org.eclipse.debug.core;bundle-version="3.4.0",
+ org.eclipse.jdt.launching;bundle-version="3.4.0",
+ org.eclipse.wst.xsl.launching;bundle-version="0.5.0",
+ org.eclipse.wst.xsl.jaxp.debug;bundle-version="0.5.0",
+ org.eclipse.jface;bundle-version="3.4.0",
+ org.eclipse.ui;bundle-version="3.4.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-Vendor: %Bundle-Vendor.0
+Export-Package: org.eclipse.wst.xsl.jaxp.launching
+Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/about.html b/bundles/org.eclipse.wst.xsl.jaxp.launching/about.html
new file mode 100644
index 0000000..ed30003
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/about.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+
+<BODY lang="EN-US">
+
+<H3>About This Content</H3>
+
+<P>August, 2008</P>
+
+<H3>License</H3>
+
+<P>The Eclipse Foundation makes available all content in this plug-in 
+("Content"). Unless otherwise indicated below, the Content is provided to you 
+under the terms and conditions of the Eclipse Public License Version 1.0 
+("EPL"). A copy of the EPL is available at
+<A href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</A>. 
+For purposes of the EPL, "Program" will mean the Content.</P>
+
+<P>If you did not receive this Content directly from the Eclipse Foundation, the 
+Content is being redistributed by another party ("Redistributor") and different 
+terms and conditions may apply to your use of any object code in the Content. 
+Check the Redistributor’s license that was provided with the Content. If no such 
+license exists, contact the Redistributor. Unless otherwise indicated below, the 
+terms and conditions of the EPL still apply to any source code in the Content 
+and such source code may be obtained at
+<A href="http://www.eclipse.org/">http://www.eclipse.org/</A>.</P>
+
+</BODY>
+</HTML>
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/build.properties b/bundles/org.eclipse.wst.xsl.jaxp.launching/build.properties
new file mode 100644
index 0000000..dcb663a
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/build.properties
@@ -0,0 +1,11 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               about.html,\
+               schema/,\
+               JREDefaultAttributes.properties,\
+               JREDefaultOutputProperties.properties,\
+               plugin.properties,\
+               log4j.debug.properties
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/log4j.debug.properties b/bundles/org.eclipse.wst.xsl.jaxp.launching/log4j.debug.properties
new file mode 100644
index 0000000..62dfb61
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/log4j.debug.properties
@@ -0,0 +1,10 @@
+# Set root logger level to DEBUG and its appenders are A1 and A2
+log4j.rootLogger=ERROR, A2
+
+# A2 is set to be a ConsoleAppender
+log4j.appender.A2=org.apache.log4j.ConsoleAppender
+
+# A2 uses PatternLayout.
+log4j.appender.A2.layout=org.apache.log4j.PatternLayout
+log4j.appender.A2.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{1} %x - %m%n
+
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.properties b/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.properties
new file mode 100644
index 0000000..0a819e0
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.properties
@@ -0,0 +1,5 @@
+Bundle-Vendor.0 = Eclipse.org
+Bundle-Name.0 = XSL JAXP Launching (Incubating)
+launchDelegate.name.0 = JAXP
+processorType.label.1 = JRE Default
+processor.label.1 = JRE Instance Default
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.xml b/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.xml
new file mode 100644
index 0000000..91e2643
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension-point id="debugger" name="debugger" schema="schema/debugger.exsd"/>
+   <extension-point id="invoke" name="invoke" schema="schema/invoke.exsd"/>
+   <extension-point id="processor" name="processor" schema="schema/processor.exsd"/>
+   <extension-point id="processorType" name="processorType" schema="schema/processorType.exsd"/>
+ <extension
+       point="org.eclipse.debug.core.launchDelegates">
+    <launchDelegate
+          delegate="org.eclipse.wst.xsl.jaxp.launching.internal.JAXPJavaLaunchConfigurationDelegate"
+          delegateDescription="The XSLT Launcher for JAXP supports running and debugging transformations using JAXP-compliant XSLT processors"
+          id="org.eclipse.wst.xsl.launching.internal.jaxp.JAXPLaunchConfigurationDelegate"
+          modes="run, debug"
+          name="%launchDelegate.name.0"
+          type="org.eclipse.wst.xsl.launching.launchConfigurationType">
+    </launchDelegate>    
+ </extension>
+     	
+	<extension point="org.eclipse.core.runtime.preferences">
+		<initializer
+			class="org.eclipse.wst.xsl.jaxp.launching.internal.PreferenceInitializer">
+		</initializer>
+	</extension>
+ 
+	<extension point="org.eclipse.wst.xsl.jaxp.launching.invoke">
+		<invoker id="org.eclipse.wst.xsl.launching.jaxp.invoke"
+			class="org.eclipse.wst.xsl.jaxp.debug.invoker.internal.JAXPSAXProcessorInvoker"
+			classpath="${eclipse_orbit:org.eclipse.wst.xsl.jaxp.debug};${eclipse_orbit:org.apache.commons.logging};${eclipse_orbit:org.apache.log4j}" />
+	</extension>
+
+  	<extension
+	       point="org.eclipse.wst.xsl.jaxp.launching.processorType">
+     <processorType
+            attributeProperties="JREDefaultAttributes.properties"
+            id="org.eclipse.wst.xsl.launching.processorType.jreDefault"
+            label="%processorType.label.1"
+            outputProperties="JREDefaultOutputProperties.properties" />
+	 </extension>
+
+	<extension
+	         point="org.eclipse.wst.xsl.jaxp.launching.processor">
+        <processor
+              classpath=""
+              id="org.eclipse.wst.xsl.launching.jre.default"
+              label="%processor.label.1"
+              processorTypeId="org.eclipse.wst.xsl.launching.processorType.jreDefault"
+              supports="1.0"/>
+	 </extension>
+ 
+</plugin>
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/debugger.exsd b/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/debugger.exsd
new file mode 100644
index 0000000..672af9e
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/debugger.exsd
@@ -0,0 +1,125 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xsl.launching.jaxp" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.wst.xsl.launching.jaxp" id="debugger" name="XSLT Debugger"/>
+      </appinfo>
+      <documentation>
+         &lt;b&gt;This extension point is internal and should not be used by any other plugins.&lt;/b&gt;
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="debugger" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="debugger">
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="classpath" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="processorTypeId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="className" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="transformerFactoryClass" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="javax.xml.transform.TransformerFactory:"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         &lt;b&gt;This extension point is internal and should not be used by any other plugins.&lt;/b&gt;
+      </documentation>
+   </annotation>
+
+
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2007 Chase Technology Ltd - &lt;a href=&quot;http://www.chasetechnology.co.uk&quot;&gt;http://www.chasetechnology.co.uk&lt;/a&gt;.&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/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/invoke.exsd b/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/invoke.exsd
new file mode 100644
index 0000000..2707e22
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/invoke.exsd
@@ -0,0 +1,101 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xsl.launching.jaxp" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.wst.xsl.launching.jaxp" id="invoke" name="XSLT Processor Invoker"/>
+      </appinfo>
+      <documentation>
+         &lt;b&gt;This extension point is internal and should not be used by any other plugins.&lt;/b&gt;
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="invoker"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="invoker">
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Unique id for this invoker
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  A class that implements the IProcessorInvoker interface
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="classpath" type="string" use="required">
+            <annotation>
+               <documentation>
+                  A semi-colon separated list of jars relative to the root of the contributing plugin. One of the jars must contain the Invoker class named in the class attribute.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         &lt;b&gt;This extension point is internal and should not be used by any other plugins.&lt;/b&gt;
+      </documentation>
+   </annotation>
+
+
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2007 Chase Technology Ltd - &lt;a href=&quot;http://www.chasetechnology.co.uk&quot;&gt;http://www.chasetechnology.co.uk&lt;/a&gt;.&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/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/processor.exsd b/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/processor.exsd
new file mode 100644
index 0000000..e0c1e2e
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/processor.exsd
@@ -0,0 +1,142 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xsl.launching.jaxp" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.wst.xsl.launching.jaxp" id="processor" name="XSLT Processor"/>
+      </appinfo>
+      <documentation>
+         Contribute a Java XSLT processor instance (e.g. Xalan 2.7.0). The extension point primarily defines the classpath to be used when launching an XSLT transformation.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="processor" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="processor">
+      <annotation>
+         <appinfo>
+            <meta.element labelAttribute="label"/>
+         </appinfo>
+      </annotation>
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="label" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="processorTypeId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="classpath" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="debuggerId" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="supports" type="string" use="required">
+            <annotation>
+               <documentation>
+                  A comma-separated list of supported XSLT versions e.g. 1.0,2.0
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         &lt;pre&gt;
+   &lt;extension
+         point=&quot;org.eclipse.wst.xsl.launching.processor&quot;&gt;
+      &lt;processor
+            classpath=&quot;xalan2.7.0.jar;serializer2.7.0.jar&quot;
+            id=&quot;org.eclipse.wst.xsl.launching.xalan.2_7_0&quot;
+            label=&quot;Xalan 2.7.0&quot;
+            processorTypeId=&quot;org.eclipse.wst.xsl.xalan.processorType&quot;
+            debuggerId=&quot;org.eclipse.wst.xsl.xalan.debugger&quot;
+            supports=&quot;1.0&quot;&gt;
+      &lt;/processor&gt;
+   &lt;/extension&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2007 Chase Technology Ltd - &lt;a href=&quot;http://www.chasetechnology.co.uk&quot;&gt;http://www.chasetechnology.co.uk&lt;/a&gt;.&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/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/processorType.exsd b/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/processorType.exsd
new file mode 100644
index 0000000..b48eb2d
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/schema/processorType.exsd
@@ -0,0 +1,160 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.xsl.launching.jaxp" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.wst.xsl.launching.jaxp" id="processorType" name="XSLT Processor Type"/>
+      </appinfo>
+      <documentation>
+         Contribute a Java XSLT processor type (e.g. Xalan, Saxon). The processor type defines which JAXP attributes and output properies are supported.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="processorType" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="processorType">
+      <annotation>
+         <appinfo>
+            <meta.element labelAttribute="label"/>
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="transformerFactory" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Unique id for the processor type
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="label" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Name for display in the UI
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="outputProperties" type="string">
+            <annotation>
+               <documentation>
+                  Location of a properties file containing the list of the processors output properties. Must be a path relative to the root of the bundle.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="attributeProperties" type="string">
+            <annotation>
+               <documentation>
+                  Location of a properties file containing the list of the attributes supported by this processor. Must be a path relative to the root of the bundle.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="transformerFactory">
+      <annotation>
+         <documentation>
+            A TransformerFactory for this type
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="factoryClass" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The fully-qualified transformer factory class
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="javax.xml.transform.TransformerFactory:"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         &lt;pre&gt;
+   &lt;extension
+         point=&quot;org.eclipse.wst.xsl.launching.processorType&quot;&gt;
+      &lt;processorType
+            attributeProperties=&quot;XalanAttributes.properties&quot;
+            id=&quot;org.eclipse.wst.xsl.xalan.processorType&quot;
+            label=&quot;Xalan&quot;
+            outputProperties=&quot;XalanOutputProperties.properties&quot;
+            transformerFactory=&quot;org.apache.xalan.processor.TransformerFactoryImpl&quot;&gt;
+      &lt;/processorType&gt;
+   &lt;/extension&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2007 Chase Technology Ltd - &lt;a href=&quot;http://www.chasetechnology.co.uk&quot;&gt;http://www.chasetechnology.co.uk&lt;/a&gt;.&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/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IAttribute.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IAttribute.java
new file mode 100644
index 0000000..467914b
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IAttribute.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * A attribute supported by an XSLT processor. 
+ * 
+ * @author Doug Satchwell
+ */
+public interface IAttribute
+{
+	/**
+	 * Constant for attributes of type <code>string</code>
+	 * @see #getType()
+	 */
+	String TYPE_STRING = "string"; //$NON-NLS-1$
+	
+	/**
+	 * Constant for attributes of type <code>boolean</code>
+	 * @see #getType()
+	 */
+	String TYPE_BOOLEAN = "boolean"; //$NON-NLS-1$
+	
+	/**
+	 * Constant for attributes of type <code>int</code>
+	 * @see #getType()
+	 */
+	String TYPE_INT = "int"; //$NON-NLS-1$
+	
+	/**
+	 * Constant for attributes of type <code>double</code>
+	 * @see #getType()
+	 */
+	String TYPE_DOUBLE = "double"; //$NON-NLS-1$
+	
+	/**
+	 * Constant for attributes of type <code>float</code>
+	 * @see #getType()
+	 */
+	String TYPE_FLOAT = "float"; //$NON-NLS-1$
+	
+	/**
+	 * Constant for attributes of type <code>class</code>
+	 * @see #getType()
+	 */
+	String TYPE_CLASS = "class"; //$NON-NLS-1$
+	
+	/**
+	 * Constant for attributes of type <code>object</code>
+	 * @see #getType()
+	 */
+	String TYPE_OBJECT = "object"; //$NON-NLS-1$
+
+	/**
+	 * Get the URI for this attribute
+	 * @return the attribute URI
+	 */
+	String getURI();
+
+	/**
+	 * Get a description for this attribute
+	 * @return the attribute description
+	 */
+	String getDescription();
+
+	/**
+	 * Get the type of this attribute. Will match one of the TYPE constants in this interface.
+	 * @return the attribute type: one of <code>TYPE_STRING</code>, <code>TYPE_BOOLEAN</code>, 
+	 * <code>TYPE_INT</code>, <code>TYPE_DOUBLE</code>, <code>TYPE_FLOAT</code>, <code>TYPE_CLASS</code>, 
+	 * or <code>TYPE_OBJECT</code>
+	 */
+	String getType();
+
+	/**
+	 * Determine whether the given value is a valid one for this attribute.
+	 * @return an <code>IStatus</code> with severity <code>OK</code> if valid, or <code>ERROR</code> if invalid.
+	 */
+	IStatus validateValue(String value);
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IDebugger.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IDebugger.java
new file mode 100644
index 0000000..5502f95
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IDebugger.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+/**
+ * An XSLT debugger. Typically this will have been 
+ * contributed via the <code>org.eclipse.wst.xsl.launching.debugger</code> extension point.
+ * 
+ * @author Doug Satchwell
+ */
+public interface IDebugger
+{
+	/**
+	 * Get the unique id for this debugger.
+	 * @return debugger id
+	 */
+	String getId();
+
+	/**
+	 * Get the set of bundle-relative jar files to add to the classpath. 
+	 * @return array of bundle-relative jars
+	 */
+	String[] getClassPath();
+
+	/**
+	 * Get a unique name for this debugger
+	 * @return the name for the debugger
+	 */
+	String getName();
+
+	/**
+	 * Get the processor type that this debugger is associated with
+	 * @return the processor type
+	 */
+	IProcessorType getProcessorType();
+
+	/**
+	 * Get the class name for this debugger
+	 * @return the class name
+	 */
+	String getClassName();
+	
+	/**
+	 * Get the transformer factory this debugger is associated with
+	 * @return the transformer factory
+	 */
+	String getTransformerFactory();
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IOutputProperty.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IOutputProperty.java
new file mode 100644
index 0000000..9bd2c76
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IOutputProperty.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+/**
+ * An output property supported by an XSLT processor. 
+ * 
+ * @author Doug Satchwell
+ */
+public interface IOutputProperty
+{
+	/**
+	 * Get the URI of this output property. 
+	 * @return a unique URI
+	 */
+	String getURI();
+
+	/**
+	 * Get a description for this output property. 
+	 * @return a description
+	 */
+	String getDescription();
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorInstall.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorInstall.java
new file mode 100644
index 0000000..4cab27b
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorInstall.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+/**
+ * An instance of an XSLT processor (e.g. Xalan 2.7.0).
+ * 
+ * @see IProcessorInstall
+ * @author Doug Satchwell
+ */
+public interface IProcessorInstall
+{
+	/**
+	 * Get the unqiue id of this install
+	 * @return the unique id
+	 */
+	String getId();
+
+	/**
+	 * Get the name of this install
+	 * @return the name of this install
+	 */
+	String getName();
+
+	/**
+	 * Get the the processor type associated with this install
+	 * @return the processor type id
+	 */
+	IProcessorType getProcessorType();
+
+	/**
+	 * Get the jar files for this processor
+	 * @return a set of jar files
+	 */
+	IProcessorJar[] getProcessorJars();
+
+	/**
+	 * Get whether this install has been contributed via the <code>org.eclipse.wst.xsl.launching.processor</code> extension point.
+	 * @return <code>true</code> if contributed via the extension point, otherwise <code>false</code>.
+	 */
+	boolean isContributed();
+
+	/**
+	 * Get the list of supported XSLT versions
+	 * @return <code>true</code> if this install has a debugger, otherwise <code>false</code>.
+	 */
+	// TODO deprecate and use boolean supports instaed
+	String getSupports();
+
+	/**
+	 * Get whether this install supports the specified xslt version.
+	 * @return <code>true</code> if this install supports the version, otherwise <code>false</code>.
+	 */
+	boolean supports(String xsltVersion);
+
+	/**
+	 * Get the debugger associated with this install
+	 * @return the debugger, or null if no debugger has been set
+	 */
+	IDebugger getDebugger();
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorInvoker.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorInvoker.java
new file mode 100644
index 0000000..540101a
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorInvoker.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+public interface IProcessorInvoker
+{
+	String getId();
+
+	String getInvokerClassName();
+
+	String[] getClasspathEntries();
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorJar.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorJar.java
new file mode 100644
index 0000000..53052bb
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorJar.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * A jar file for an XSLT processor
+ * 
+ * @see IProcessorInstall
+ * @author Doug Satchwell
+ */
+public interface IProcessorJar
+{
+	/**
+	 * The path may be relative or absolute; in the workspace or external.
+	 * @return the path to this jar
+	 */
+	IPath getPath();
+
+	/**
+	 * The URL will always be absolute and can be opened.
+	 * @return a URL to the jar
+	 */
+	URL asURL();
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorType.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorType.java
new file mode 100644
index 0000000..d13e700
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/IProcessorType.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+import java.util.Map;
+
+/**
+ * A particular type of XSLT Processor (e.g. Xalan) for which there may be any number of installs.
+ * 
+ * @see IProcessorInstall
+ * @author Doug Satchwell
+ */
+public interface IProcessorType
+{
+	String getId();
+
+	String getLabel();
+
+	boolean isJREDefault();
+
+	ITransformerFactory[] getTransformerFactories();
+
+	IAttribute[] getAttributes();
+
+	Map<String, String> getAttributeValues();
+
+	IOutputProperty[] getOutputProperties();
+
+	Map<String, String> getOutputPropertyValues();
+
+	ITransformerFactory getDefaultTransformerFactory();
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/ITransformerFactory.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/ITransformerFactory.java
new file mode 100644
index 0000000..64716ab
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/ITransformerFactory.java
@@ -0,0 +1,7 @@
+package org.eclipse.wst.xsl.jaxp.launching;
+
+public interface ITransformerFactory
+{
+	String getName();
+	String getFactoryClass();
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/JAXPLaunchConfigurationConstants.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/JAXPLaunchConfigurationConstants.java
new file mode 100644
index 0000000..a1cf82d
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/JAXPLaunchConfigurationConstants.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+
+public class JAXPLaunchConfigurationConstants
+{
+	public static final String INVOKER_DESCRIPTOR = JAXPLaunchingPlugin.PLUGIN_ID + ".INVOKER_DESCRIPTOR"; //$NON-NLS-1$
+	public static final String ATTR_PROCESSOR = JAXPLaunchingPlugin.PLUGIN_ID + ".ATTR_PROCESSOR"; //$NON-NLS-1$	
+	public static final String ATTR_OUTPUT_PROPERTIES = JAXPLaunchingPlugin.PLUGIN_ID + ".ATTR_OUTPUT_PROPERTIES"; //$NON-NLS-1$
+	public static final String ATTR_ATTRIBUTES = JAXPLaunchingPlugin.PLUGIN_ID + ".ATTR_ATTRIBUTES"; //$NON-NLS-1$
+	public static final String ATTR_DEFAULT_DEBUGGING_INSTALL_ID = JAXPLaunchingPlugin.PLUGIN_ID + ".ATTR_DEFAULT_DEBUGGING_INSTALL_ID"; //$NON-NLS-1$
+	public static final String ATTR_USE_DEFAULT_PROCESSOR = JAXPLaunchingPlugin.PLUGIN_ID + ".ATTR_USE_DEFAULT_PROCESSOR"; //$NON-NLS-1$
+	public static final String ATTR_TRANSFORMER_FACTORY = JAXPLaunchingPlugin.PLUGIN_ID + ".ATTR_TRANSFORMER_FACTORY";
+
+	public static final String XALAN_TYPE_ID = "org.eclipse.wst.xsl.xalan.processorType"; //$NON-NLS-1$
+	public static final String SAXON_TYPE_ID = "org.eclipse.wst.xsl.saxon.processorType"; //$NON-NLS-1$
+	public static final String SAXON_1_0_TYPE_ID = "org.eclipse.wst.xsl.saxon_1_0.processorType"; //$NON-NLS-1$
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/JAXPRuntime.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/JAXPRuntime.java
new file mode 100644
index 0000000..ba1dd11
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/JAXPRuntime.java
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+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.Preferences;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.xsl.jaxp.launching.internal.FeaturePreferences;
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+import org.eclipse.wst.xsl.jaxp.launching.internal.OutputPropertyPreferences;
+import org.eclipse.wst.xsl.jaxp.launching.internal.ProcessorJar;
+import org.eclipse.wst.xsl.jaxp.launching.internal.ProcessorPreferences;
+import org.eclipse.wst.xsl.jaxp.launching.internal.registry.DebuggerRegistry;
+import org.eclipse.wst.xsl.jaxp.launching.internal.registry.InvokerRegistry;
+import org.eclipse.wst.xsl.jaxp.launching.internal.registry.ProcessorRegistry;
+import org.eclipse.wst.xsl.jaxp.launching.internal.registry.ProcessorTypeRegistry;
+
+public class JAXPRuntime
+{
+	public static final String PREF_PROCESSOR_XML = "PREF_PROCESSOR_XML"; //$NON-NLS-1$
+	public static final String PREF_FEATURE_XML = "PREF_FEATURE_XML"; //$NON-NLS-1$
+	public static final String PREF_OUTPUT_PROPERTIES_XML = "PREF_OUTPUT_PROPERTIES_XML"; //$NON-NLS-1$
+	public static final String JRE_DEFAULT_PROCESSOR_ID = "org.eclipse.wst.xsl.launching.jre.default"; //$NON-NLS-1$
+	public static final String JRE_DEFAULT_PROCESSOR_TYPE_ID = "org.eclipse.wst.xsl.launching.processorType.jreDefault"; //$NON-NLS-1$
+
+	private static byte[] NEXT_ID_LOCK = new byte[0];
+	private static byte[] REGISTRY_LOCK = new byte[0];
+
+	private static int lastStandinID;
+	private static ProcessorTypeRegistry processorTypeRegistry;
+	private static ProcessorRegistry processorRegistry;
+	private static InvokerRegistry invokerRegistry;
+	private static DebuggerRegistry debuggerRegistry;
+
+	private static ProcessorTypeRegistry getProcessorTypeRegistry()
+	{
+		synchronized (REGISTRY_LOCK)
+		{
+			if (processorTypeRegistry == null)
+				processorTypeRegistry = new ProcessorTypeRegistry();
+		}
+		return processorTypeRegistry;
+	}
+
+	public static ProcessorRegistry getProcessorRegistry()
+	{
+		synchronized (REGISTRY_LOCK)
+		{
+			if (processorRegistry == null)
+				processorRegistry = new ProcessorRegistry();
+		}
+		return processorRegistry;
+	}
+
+	private static InvokerRegistry getInvokerRegistry()
+	{
+		synchronized (REGISTRY_LOCK)
+		{
+			if (invokerRegistry == null)
+				invokerRegistry = new InvokerRegistry();
+		}
+		return invokerRegistry;
+	}
+
+	private static DebuggerRegistry getDebuggerRegistry()
+	{
+		synchronized (REGISTRY_LOCK)
+		{
+			if (debuggerRegistry == null)
+				debuggerRegistry = new DebuggerRegistry();
+		}
+		return debuggerRegistry;
+	}
+	
+	private static void savePreferences()
+	{
+		JAXPLaunchingPlugin.getDefault().savePluginPreferences();
+		synchronized (REGISTRY_LOCK)
+		{
+			// force the registries to be re-initialised next time it is required
+			processorRegistry = null;
+			processorTypeRegistry = null;
+		}
+	}
+
+	/**
+	 * Find a unique processor install id. Check existing 'real' processors, as
+	 * well as the last id used for a standin.
+	 */
+	public static String createUniqueProcessorId(IProcessorType type)
+	{
+		IProcessorInstall[] installs = JAXPRuntime.getProcessors(type.getId());
+		String id = null;
+		synchronized (NEXT_ID_LOCK)
+		{
+			do
+			{
+				id = String.valueOf(++lastStandinID);
+			}
+			while (isTaken(id, installs));
+		}
+		return id;
+	}
+
+	public static IProcessorJar createProcessorJar(IPath path)
+	{
+		return new ProcessorJar(path);
+	}
+
+	private static boolean isTaken(String id, IProcessorInstall[] installs)
+	{
+		for (IProcessorInstall install : installs)
+		{
+			if (install.getId().equals(id))
+				return true;
+		}
+		return false;
+	}
+
+	public static IDebugger[] getDebuggers()
+	{
+		return getDebuggerRegistry().getDebuggers();
+	}
+
+	public static IDebugger getDebugger(String id)
+	{
+		return getDebuggerRegistry().getDebugger(id);
+	}
+
+	public static IProcessorInstall[] getProcessors()
+	{
+		return getProcessorRegistry().getProcessors();
+	}
+
+	public static IProcessorInstall[] getProcessors(String typeId)
+	{
+		return getProcessorRegistry().getProcessors(typeId);
+	}
+
+	public static IProcessorInstall getProcessor(String processorId)
+	{
+		IProcessorInstall[] processors = getProcessors();
+		for (IProcessorInstall install : processors)
+		{
+			if (install.getId().equals(processorId))
+				return install;
+		}
+		return null;
+	}
+
+	public static IProcessorInstall getDefaultProcessor()
+	{
+		return getProcessorRegistry().getDefaultProcessor();
+	}
+
+	public static IProcessorInstall getJREDefaultProcessor()
+	{
+		return getProcessorRegistry().getJREDefaultProcessor();
+	}
+
+	public static IProcessorType[] getProcessorTypes()
+	{
+		return getProcessorTypeRegistry().getProcessorTypes();
+	}
+
+	public static IProcessorType[] getProcessorTypesExclJREDefault()
+	{
+		return getProcessorTypeRegistry().getProcessorTypesExclJREDefault();
+	}
+
+	public static IProcessorType getProcessorType(String id)
+	{
+		return getProcessorTypeRegistry().getProcessorType(id);
+	}
+
+	public static IProcessorInvoker getProcessorInvoker(String invokerId)
+	{
+		return getInvokerRegistry().getProcessorInvoker(invokerId);
+	}
+
+	public static IProcessorInvoker[] getProcessorInvokers()
+	{
+		return getInvokerRegistry().getProcessorInvokers();
+	}
+
+	private static Preferences getPreferences()
+	{
+		return JAXPLaunchingPlugin.getDefault().getPluginPreferences();
+	}
+
+	public static void saveFeaturePreferences(Map<IProcessorType, Map<String, String>> typeFeatures, IProgressMonitor monitor) throws CoreException
+	{
+		if (monitor.isCanceled())
+			return;
+		try
+		{
+			monitor.beginTask(Messages.getString("XSLTRuntime.5"), 100); //$NON-NLS-1$
+			FeaturePreferences prefs = new FeaturePreferences();
+			Map<String,Map<String,String>> typeIdFeatures = new HashMap<String,Map<String,String>>(typeFeatures.size());
+			for (IProcessorType type : typeFeatures.keySet())
+			{
+				Map<String,String> values = typeFeatures.get(type);
+				typeIdFeatures.put(type.getId(), values);
+			}
+			prefs.setTypeFeatures(typeIdFeatures);
+			String xml = prefs.getAsXML();
+			monitor.worked(40);
+			if (monitor.isCanceled())
+				return;
+			JAXPRuntime.getPreferences().setValue(JAXPRuntime.PREF_FEATURE_XML, xml);
+			monitor.worked(30);
+			if (monitor.isCanceled())
+				return;
+			JAXPRuntime.savePreferences();
+			monitor.worked(30);
+		}
+		catch (Exception e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR,JAXPLaunchingPlugin.PLUGIN_ID,Messages.getString("XSLTRuntime.6"),e)); //$NON-NLS-1$
+		}
+		finally
+		{
+			monitor.done();
+		}
+	}
+
+	public static void saveOutputPropertyPreferences(Map<IProcessorType, Map<String,String>> typeProperties, IProgressMonitor monitor) throws CoreException
+	{
+		if (monitor.isCanceled())
+			return;
+		try
+		{
+			monitor.beginTask(Messages.getString("XSLTRuntime.7"), 100); //$NON-NLS-1$
+			OutputPropertyPreferences prefs = new OutputPropertyPreferences();
+			for (IProcessorType type : typeProperties.keySet())
+			{
+				prefs.setOutputPropertyValues(type.getId(), typeProperties.get(type));
+			}
+			String xml = prefs.getAsXML();
+			monitor.worked(40);
+			if (monitor.isCanceled())
+				return;
+			JAXPRuntime.getPreferences().setValue(JAXPRuntime.PREF_OUTPUT_PROPERTIES_XML, xml);
+			monitor.worked(30);
+			if (monitor.isCanceled())
+				return;
+			JAXPRuntime.savePreferences();
+			monitor.worked(30);
+		}
+		catch (Exception e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR,JAXPLaunchingPlugin.PLUGIN_ID,Messages.getString("XSLTRuntime.8"),e)); //$NON-NLS-1$
+		}
+		finally
+		{
+			monitor.done();
+		}
+	}
+
+	public static void saveProcessorPreferences(IProcessorInstall[] installs, IProcessorInstall defaultInstall, IProgressMonitor monitor) throws CoreException
+	{
+		if (monitor.isCanceled())
+			return;
+		try
+		{
+			monitor.beginTask(Messages.getString("XSLTRuntime.9"), 100); //$NON-NLS-1$
+			ProcessorPreferences prefs = new ProcessorPreferences();
+			if (defaultInstall != null)
+				prefs.setDefaultProcessorId(defaultInstall.getId());
+			prefs.setProcessors(new ArrayList<IProcessorInstall>(Arrays.asList(installs)));
+			String xml = prefs.getAsXML();
+			monitor.worked(40);
+			if (monitor.isCanceled())
+				return;
+			JAXPRuntime.getPreferences().setValue(JAXPRuntime.PREF_PROCESSOR_XML, xml);
+			monitor.worked(30);
+			if (monitor.isCanceled())
+				return;
+			JAXPRuntime.savePreferences();
+			monitor.worked(30);
+		}
+		catch (Exception e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR,JAXPLaunchingPlugin.PLUGIN_ID,Messages.getString("XSLTRuntime.10"),e)); //$NON-NLS-1$
+		}
+		finally
+		{
+			monitor.done();
+		}
+	}
+
+	public static Map<String,String> createDefaultOutputProperties(String typeId)
+	{
+		Map<String,String> props = new HashMap<String,String>();
+		if (JRE_DEFAULT_PROCESSOR_TYPE_ID.equals(typeId))
+			props.put("indent", "yes"); //$NON-NLS-1$ //$NON-NLS-2$
+		else if (JAXPLaunchConfigurationConstants.XALAN_TYPE_ID.equals(typeId))
+		{
+			props.put("indent", "yes"); //$NON-NLS-1$ //$NON-NLS-2$
+			props.put("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		else if (JAXPLaunchConfigurationConstants.SAXON_TYPE_ID.equals(typeId))
+		{
+			props.put("indent", "yes"); //$NON-NLS-1$ //$NON-NLS-2$
+			props.put("{http://saxon.sf.net/}indent-spaces", "4"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		else if (JAXPLaunchConfigurationConstants.SAXON_1_0_TYPE_ID.equals(typeId))
+		{
+			props.put("indent", "yes"); //$NON-NLS-1$ //$NON-NLS-2$
+			props.put("{http://saxon.sf.net/}indent-spaces", "4"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		return props;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/LaunchAttributes.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/LaunchAttributes.java
new file mode 100644
index 0000000..a23335b
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/LaunchAttributes.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.xsl.launching.config.LaunchAttribute;
+import org.eclipse.wst.xsl.launching.config.PreferenceUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class LaunchAttributes
+{
+	private final Set<LaunchAttribute> attributes = new HashSet<LaunchAttribute>();
+
+	public Set<LaunchAttribute> getAttributes()
+	{
+		return attributes;
+	}
+
+	public void addAttribute(LaunchAttribute attribute)
+	{
+		attributes.add(attribute);
+	}
+
+	public LaunchAttribute getAttribute(String uri)
+	{
+		for (Iterator<LaunchAttribute> iter = attributes.iterator(); iter.hasNext();)
+		{
+			LaunchAttribute tv = (LaunchAttribute) iter.next();
+			if (tv.uri.equals(uri))
+				return tv;
+		}
+		return null;
+	}
+
+	public void removeAtribute(String uri)
+	{
+		for (Iterator<LaunchAttribute> iter = attributes.iterator(); iter.hasNext();)
+		{
+			LaunchAttribute attribute = (LaunchAttribute) iter.next();
+			if (attribute.uri.equals(uri))
+				iter.remove();
+		}
+	}
+
+	public String toXML() throws ParserConfigurationException, IOException, TransformerException
+	{
+		Document doc = PreferenceUtil.getDocument();
+
+		Element attributesEl = doc.createElement("Attributes"); //$NON-NLS-1$
+		doc.appendChild(attributesEl);
+
+		for (Iterator<LaunchAttribute> iter = attributes.iterator(); iter.hasNext();)
+		{
+			LaunchAttribute attribute = (LaunchAttribute) iter.next();
+			Element attributeEl = doc.createElement("Attribute"); //$NON-NLS-1$
+			attributeEl.setAttribute("name", attribute.uri); //$NON-NLS-1$
+			attributeEl.setAttribute("type", attribute.type); //$NON-NLS-1$
+			attributeEl.setAttribute("value", attribute.value); //$NON-NLS-1$
+			attributesEl.appendChild(attributeEl);
+		}
+
+		return PreferenceUtil.serializeDocument(doc);
+	}
+
+	public static LaunchAttributes fromXML(InputStream inputStream) throws CoreException
+	{
+		Document doc = PreferenceUtil.getDocument(inputStream);
+
+		LaunchAttributes pdef = new LaunchAttributes();
+
+		Element attributesEl = doc.getDocumentElement();
+
+		NodeList attributeEls = attributesEl.getElementsByTagName("Attribute"); //$NON-NLS-1$
+		for (int i = 0; i < attributeEls.getLength(); i++)
+		{
+			Element attributeEl = (Element) attributeEls.item(i);
+			String name = attributeEl.getAttribute("name"); //$NON-NLS-1$
+			String type = attributeEl.getAttribute("type"); //$NON-NLS-1$
+			String value = attributeEl.getAttribute("value"); //$NON-NLS-1$
+			pdef.addAttribute(new LaunchAttribute(name, type, value));
+		}
+
+		return pdef;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/LaunchProperties.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/LaunchProperties.java
new file mode 100644
index 0000000..d999eb1
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/LaunchProperties.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.xsl.launching.config.PreferenceUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class LaunchProperties
+{
+	private final Map<String, String> properties = new HashMap<String, String>();
+
+	public Map<String, String> getProperties()
+	{
+		return properties;
+	}
+
+	public void setProperty(String name, String value)
+	{
+		properties.put(name, value);
+	}
+
+	public String getProperty(String name)
+	{
+		return (String) properties.get(name);
+	}
+
+	public void removeProperty(String name)
+	{
+		properties.remove(name);
+	}
+
+	public String toXML() throws ParserConfigurationException, IOException, TransformerException
+	{
+		Document doc = PreferenceUtil.getDocument();
+
+		Element propertysEl = doc.createElement("Properties"); //$NON-NLS-1$
+		doc.appendChild(propertysEl);
+
+		for (Map.Entry<String, String> property : properties.entrySet())
+		{
+			String name = property.getKey();
+			String value = property.getValue();
+			Element propertyEl = doc.createElement("Property"); //$NON-NLS-1$
+			propertyEl.setAttribute("name", name); //$NON-NLS-1$
+			propertyEl.setAttribute("value", value); //$NON-NLS-1$
+			propertysEl.appendChild(propertyEl);
+		}
+
+		return PreferenceUtil.serializeDocument(doc);
+	}
+
+	public static LaunchProperties fromXML(InputStream inputStream) throws CoreException
+	{
+		Document doc = PreferenceUtil.getDocument(inputStream);
+
+		LaunchProperties pdef = new LaunchProperties();
+
+		Element propertysEl = doc.getDocumentElement();
+
+		NodeList propertyEls = propertysEl.getElementsByTagName("Property"); //$NON-NLS-1$
+		for (int i = 0; i < propertyEls.getLength(); i++)
+		{
+			Element propertyEl = (Element) propertyEls.item(i);
+			String name = propertyEl.getAttribute("name"); //$NON-NLS-1$
+			String value = propertyEl.getAttribute("value"); //$NON-NLS-1$
+			pdef.setProperty(name, value);
+		}
+
+		return pdef;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/Messages.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/Messages.java
new file mode 100644
index 0000000..d454fb5
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/Messages.java
@@ -0,0 +1,22 @@
+package org.eclipse.wst.xsl.jaxp.launching;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+	private static final String BUNDLE_NAME = "org.eclipse.wst.xsl.jaxp.launching.messages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+			.getBundle(BUNDLE_NAME);
+
+	private Messages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/ProcessorInstall.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/ProcessorInstall.java
new file mode 100644
index 0000000..6ee8717
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/ProcessorInstall.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching;
+
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+import org.eclipse.wst.xsl.jaxp.launching.internal.PluginProcessorJar;
+import org.eclipse.wst.xsl.jaxp.launching.internal.Utils;
+
+public class ProcessorInstall implements IProcessorInstall
+{
+	private final String id;
+	private String name;
+	private String type;
+	private IProcessorJar[] jars;
+	private final boolean contributed;
+	private String debuggerId;
+	private String supports;
+
+	public ProcessorInstall(String id, String label, String typeId, IProcessorJar[] jars, String debuggerId, String supports, boolean contributed)
+	{
+		this.id = id;
+		name = label;
+		type = typeId;
+		this.debuggerId = debuggerId;
+		this.contributed = contributed;
+		this.jars = jars;
+		this.supports = supports;
+	}
+
+	public String getId()
+	{
+		return id;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+
+	public IProcessorJar[] getProcessorJars()
+	{
+		return jars;
+	}
+
+	public void setProcessorJars(IProcessorJar[] jars)
+	{
+		this.jars = jars;
+	}
+
+	public String getProcessorTypeId()
+	{
+		return type;
+	}
+
+	public IProcessorType getProcessorType()
+	{
+		return JAXPRuntime.getProcessorType(type);
+	}
+
+	public void setProcessorTypeId(String id)
+	{
+		type = id;
+	}
+
+	public boolean isContributed()
+	{
+		return contributed;
+	}
+
+	public static IProcessorJar[] createJars(String bundleId, String classpath)
+	{
+		IProcessorJar[] jars;
+		if (classpath == null)
+			return new IProcessorJar[0];
+		String[] jarstring = classpath.split(";"); //$NON-NLS-1$
+		jars = new IProcessorJar[jarstring.length];
+		for (int i = 0; i < jarstring.length; i++)
+		{
+			String jar = jarstring[i];
+			try
+			{
+				if (jar.startsWith("${eclipse_orbit:") && jar.endsWith("}")) //$NON-NLS-1$ //$NON-NLS-2$
+				{
+					jar = jar.substring("${eclipse_orbit:".length()); //$NON-NLS-1$
+					jar = jar.substring(0,jar.length()-1);
+					//jar = Utils.getFileLocation(jar,"");
+					jars[i] = new PluginProcessorJar(jar, null);
+				}
+				else
+				{
+					jar = Utils.getFileLocation(bundleId,jar);
+					jars[i] = new PluginProcessorJar(bundleId, new Path(jar));
+				}
+			}
+			catch (CoreException e)
+			{
+				JAXPLaunchingPlugin.log(e);
+			}
+		}
+		return jars;
+	}
+
+	public boolean hasDebugger()
+	{
+		return debuggerId != null;
+	}
+
+	public boolean supports(String xsltVersion)
+	{
+		return supports.indexOf(xsltVersion) >= 0;
+	}
+
+	public String getSupports()
+	{
+		return supports;
+	}
+
+	public void setSupports(String supports)
+	{
+		this.supports = supports;
+	}
+
+	public IDebugger getDebugger()
+	{
+		return JAXPRuntime.getDebugger(debuggerId);
+	}
+
+	public void setDebuggerId(String debuggerId)
+	{
+		this.debuggerId = debuggerId;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/Attribute.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/Attribute.java
new file mode 100644
index 0000000..7be3541
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/Attribute.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.xsl.jaxp.launching.IAttribute;
+
+public class Attribute implements IAttribute, Comparable<Object>
+{
+	private final String uri;
+	private final String description;
+	private final String type;
+
+	public Attribute(String uri, String type, String description)
+	{
+		this.uri = uri;
+		this.type = type;
+		this.description = description;
+	}
+
+	public String getDescription()
+	{
+		return description;
+	}
+
+	public String getType()
+	{
+		return type;
+	}
+
+	public String getURI()
+	{
+		return uri;
+	}
+
+	public IStatus validateValue(String value)
+	{
+		IStatus status = null;
+		if (TYPE_BOOLEAN.equals(type))
+		{
+			boolean valid = "true".equals(value) || "false".equals(value); //$NON-NLS-1$ //$NON-NLS-2$
+			if (!valid)
+				status = new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, 0, Messages.getString("Attribute.2"), null); //$NON-NLS-1$
+		}
+		else if (TYPE_INT.equals(type))
+		{
+			try
+			{
+				Integer.parseInt(value);
+			}
+			catch (NumberFormatException e)
+			{
+				status = new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, 0, Messages.getString("Attribute.1"), null); //$NON-NLS-1$
+			}
+		}
+		else if (TYPE_DOUBLE.equals(type))
+		{
+			try
+			{
+				Double.parseDouble(value);
+			}
+			catch (NumberFormatException e)
+			{
+				status = new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, 0, Messages.getString("Attribute.0"), null); //$NON-NLS-1$
+			}
+		}
+		else if (TYPE_FLOAT.equals(type))
+		{
+			try
+			{
+				Float.parseFloat(value);
+			}
+			catch (NumberFormatException e)
+			{
+				status = new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, 0, Messages.getString("Attribute.5"), null); //$NON-NLS-1$
+			}
+		}
+		else if (TYPE_CLASS.equals(type) || TYPE_OBJECT.equals(type))
+		{
+			//status = JavaConventions.validateJavaTypeName(value);
+		}
+		return status;
+	}
+
+	public int compareTo(Object o)
+	{
+		if (o instanceof IAttribute)
+		{
+			IAttribute f = (IAttribute) o;
+			return f.getURI().compareTo(getURI());
+		}
+		return 0;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/DebuggerDescriptor.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/DebuggerDescriptor.java
new file mode 100644
index 0000000..421dc71
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/DebuggerDescriptor.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import org.eclipse.wst.xsl.jaxp.launching.IDebugger;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorType;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPRuntime;
+
+public class DebuggerDescriptor implements IDebugger
+{
+	private final String[] classpath;
+	private final String id;
+	private final String bundleId;
+	private final String name;
+	private final String processorTypeId;
+	private final String className;
+	private final String transformerFactory;
+
+	public DebuggerDescriptor(String id, String bundleId, String className, String[] classpath, String name, String processorTypeId, String transformerFactory)
+	{
+		this.id = id;
+		this.classpath = classpath;
+		this.bundleId = bundleId;
+		this.name = name;
+		this.processorTypeId = processorTypeId;
+		this.className = className;
+		this.transformerFactory = transformerFactory;
+	}
+
+	public String getClassName()
+	{
+		return className;
+	}
+
+	public String[] getClassPath()
+	{
+		return ProcessorInvokerDescriptor.createEntries(bundleId, classpath);
+	}
+
+	public String getId()
+	{
+		return id;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+	public IProcessorType getProcessorType()
+	{
+		return JAXPRuntime.getProcessorType(processorTypeId);
+	}
+
+	public String getTransformerFactory()
+	{
+		return transformerFactory;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/FeaturePreferences.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/FeaturePreferences.java
new file mode 100644
index 0000000..0a17c5f
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/FeaturePreferences.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.xsl.launching.config.PreferenceUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class FeaturePreferences
+{
+	private Map<String, Map<String, String>> typeFeatures;
+
+	public Map<String, String> getFeaturesValues(String typeId)
+	{
+		return typeFeatures.get(typeId);
+	}
+
+	public void setTypeFeatures(Map<String, Map<String, String>> typeFeatures)
+	{
+		this.typeFeatures = typeFeatures;
+	}
+
+	public String getAsXML() throws ParserConfigurationException, IOException, TransformerException
+	{
+		Document doc = PreferenceUtil.getDocument();
+		Element config = doc.createElement("featurePreferences");  //$NON-NLS-1$
+		doc.appendChild(config);
+		
+		for (String typeId : typeFeatures.keySet())
+		{
+			Element processorTypeElement = typeAsElement(doc, typeId);
+			Map<String, String> featureValues = typeFeatures.get(typeId);
+			featureValuesAsElement(doc, processorTypeElement, featureValues);
+			config.appendChild(processorTypeElement);
+		}
+
+		// Serialize the Document and return the resulting String
+		return PreferenceUtil.serializeDocument(doc);
+	}
+
+	public static FeaturePreferences fromXML(InputStream inputStream) throws CoreException
+	{
+		FeaturePreferences prefs = new FeaturePreferences();
+
+		// Do the parsing and obtain the top-level node
+		Document doc = PreferenceUtil.getDocument(inputStream);
+		Element config = doc.getDocumentElement();
+
+		Map<String, Map<String, String>> typeFeatures = new HashMap<String, Map<String, String>>();
+		Element[] processorTypeEls = PreferenceUtil.getChildElements(config, "processorType"); //$NON-NLS-1$
+		for (int i = 0; i < processorTypeEls.length; ++i)
+		{
+			Element processorTypeEl = processorTypeEls[i];
+			String type = elementAsType(processorTypeEl);
+			Map<String, String> featureValues = elementAsFeatureValues(processorTypeEl);
+			typeFeatures.put(type, featureValues);
+		}
+
+		prefs.setTypeFeatures(typeFeatures);
+
+		return prefs;
+	}
+
+	private static String elementAsType(Element parent)
+	{
+		String id = parent.getAttribute("id"); //$NON-NLS-1$
+		return id;
+	}
+
+	private static Element typeAsElement(Document doc, String type)
+	{
+		Element element = doc.createElement("processorType"); //$NON-NLS-1$
+		element.setAttribute("id", type); //$NON-NLS-1$
+		return element;
+	}
+
+	private static Map<String, String> elementAsFeatureValues(Element element)
+	{
+		Element[] featureEls = PreferenceUtil.getChildElements(element, "feature"); //$NON-NLS-1$
+		Map<String, String> featureValues = new HashMap<String, String>(featureEls.length);
+		for (Element featureEl : featureEls)
+		{
+			String uri = featureEl.getAttribute("uri"); //$NON-NLS-1$
+			String value = featureEl.getAttribute("value"); //$NON-NLS-1$
+			featureValues.put(uri, value);
+		}
+		return featureValues;
+	}
+
+	private static void featureValuesAsElement(Document doc, Element featuresEl, Map<String, String> featureValues)
+	{
+		if (featureValues != null)
+		{
+			for (Map.Entry<String,String> entry2 : featureValues.entrySet())
+			{
+				String uri = (String) entry2.getKey();
+				String value = (String) entry2.getValue();
+				Element element = doc.createElement("feature"); //$NON-NLS-1$
+				element.setAttribute("uri", uri); //$NON-NLS-1$
+				element.setAttribute("value", value); //$NON-NLS-1$
+				featuresEl.appendChild(element);
+			}
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPJavaLaunchConfigurationDelegate.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPJavaLaunchConfigurationDelegate.java
new file mode 100644
index 0000000..24d890c
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPJavaLaunchConfigurationDelegate.java
@@ -0,0 +1,443 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+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.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.IDebugEventSetListener;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.ISourceLocator;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.jdt.launching.IVMRunner;
+import org.eclipse.jdt.launching.JavaLaunchDelegate;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.xsl.jaxp.launching.IDebugger;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorInstall;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorInvoker;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorJar;
+import org.eclipse.wst.xsl.jaxp.launching.ITransformerFactory;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPLaunchConfigurationConstants;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPRuntime;
+import org.eclipse.wst.xsl.launching.model.IXSLConstants;
+import org.eclipse.wst.xsl.launching.model.XSLDebugTarget;
+
+public class JAXPJavaLaunchConfigurationDelegate extends JavaLaunchDelegate implements IDebugEventSetListener
+{
+	private String mode;
+	LaunchHelper launchHelper;
+	
+	@Override
+	public synchronized void launch(ILaunchConfiguration configuration, final String mode, final ILaunch launch, IProgressMonitor monitor) throws CoreException
+	{
+		this.mode = mode;
+		launchHelper.save(getLaunchConfigFile());
+		
+		// set the launch name
+		IProcessorInstall install = getProcessorInstall(configuration, mode);
+		String tfactory = getTransformerFactory(install);
+		String name = install.getName();
+		if (tfactory != null)
+			name += "[" + tfactory + "]";
+		launch.setAttribute("launchName", name);
+
+		// the super.launch will add a Java source director if we set it to null here
+		final ISourceLocator configuredLocator = launch.getSourceLocator();
+		launch.setSourceLocator(null);
+
+		super.launch(configuration, mode, launch, monitor);
+		
+		// now get the java source locator
+		final ISourceLocator javaSourceLookupDirector = (ISourceLocator)launch.getSourceLocator();
+		// now add our own participant to the java director
+		launch.setSourceLocator(new ISourceLocator(){
+
+			public Object getSourceElement(IStackFrame stackFrame) 
+			{
+				// simply look at one and then the other
+				Object sourceElement = javaSourceLookupDirector.getSourceElement(stackFrame);
+				if (sourceElement == null)
+					sourceElement = configuredLocator.getSourceElement(stackFrame);
+				return sourceElement;
+			}});
+		
+//		IJavaDebugTarget javaTarget = (IJavaDebugTarget)launch.getDebugTarget();
+//		launch.removeDebugTarget(javaTarget);
+		
+		IDebugTarget javaTarget = launch.getDebugTarget();
+		IDebugTarget xslTarget = new XSLDebugTarget(launch, launch.getProcesses()[0], launchHelper);
+		
+		// remove java as the primary target and make xsl the primary target
+		launch.removeDebugTarget(javaTarget);
+		launch.addDebugTarget(xslTarget);
+		// add this here to make java the non-primary target
+	//	launch.addDebugTarget(javaTarget);
+		
+	//	launch.addDebugTarget(new JavaXSLDebugTarget(launch, launch.getProcesses()[0], launchHelper, javaTarget));
+		
+
+	}
+
+	/**
+	 * Get the Java breakpoint and the XSL breakpoints
+	 */
+	@Override
+	protected IBreakpoint[] getBreakpoints(ILaunchConfiguration configuration)
+	{
+		IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
+		if (!breakpointManager.isEnabled())
+			return null;
+		
+		IBreakpoint[] javaBreakpoints = super.getBreakpoints(configuration);
+		IBreakpoint[] xslBreakpoints = breakpointManager.getBreakpoints(IXSLConstants.ID_XSL_DEBUG_MODEL);
+		IBreakpoint[] breakpoints = new IBreakpoint[javaBreakpoints.length+xslBreakpoints.length];
+		System.arraycopy(javaBreakpoints, 0, breakpoints, 0, javaBreakpoints.length);
+		System.arraycopy(xslBreakpoints, 0, breakpoints, javaBreakpoints.length, xslBreakpoints.length);
+		
+		return breakpoints;
+	}
+
+	@Override
+	public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException
+	{
+		this.launchHelper = new LaunchHelper(configuration);
+		if (mode.equals(ILaunchManager.DEBUG_MODE))
+		{
+			// TODO don't like having UI code in the launching plugin...where else can it go?
+			final IProcessorInstall install = getProcessorInstall(configuration, ILaunchManager.RUN_MODE);
+			if (install.getDebugger() == null)
+			{
+				final boolean[] result = new boolean[]
+				{ false };
+				// open a dialog for choosing a different install that does have
+				// an associated debugger
+				PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable()
+				{
+					public void run()
+					{
+						String debuggingInstallId = JAXPLaunchingPlugin.getDefault().getPluginPreferences().getString(JAXPLaunchConfigurationConstants.ATTR_DEFAULT_DEBUGGING_INSTALL_ID);
+						IProcessorInstall processor = JAXPRuntime.getProcessor(debuggingInstallId);
+
+						IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+						
+						String title = Messages.getString("XSLTLaunchConfigurationDelegate.0"); //$NON-NLS-1$
+						String message = Messages.getString("XSLTLaunchConfigurationDelegate.1") + install.getName() + Messages.getString("XSLTLaunchConfigurationDelegate.2") //$NON-NLS-1$ //$NON-NLS-2$
+								+ Messages.getString("XSLTLaunchConfigurationDelegate.3") + processor.getName() + Messages.getString("XSLTLaunchConfigurationDelegate.4");//$NON-NLS-1$ //$NON-NLS-2$
+						
+						MessageDialog dialog = new MessageDialog(dw.getShell(), title, null, message, MessageDialog.QUESTION,
+								new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); // yes is the default
+						
+				        result[0] = dialog.open() == 0;
+					}
+				});
+				return result[0];
+			}
+			else
+			{
+				String debuggerTF = install.getDebugger().getTransformerFactory();
+				String installTF = launchHelper.getTransformerFactory() == null ? null : launchHelper.getTransformerFactory().getFactoryClass();
+				if (!debuggerTF.equals(installTF))
+				{
+					PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable()
+					{
+						public void run()
+						{
+							IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+							
+							String title = Messages.getString("Change Transformer Factory");
+							String message = install.getName() + " must use the " + launchHelper.getTransformerFactory().getName() + " transformer factory when debugging.\n"
+									+ "Be aware that this may give different results to the " + launchHelper.getTransformerFactory().getName() + " transformer factory configured for this launch configuration.";
+							
+							MessageDialog dialog = new MessageDialog(dw.getShell(), title, null, message, MessageDialog.WARNING,
+									new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); // yes is the default
+							dialog.open();
+						}
+					});
+				}
+			}
+		}
+		return super.preLaunchCheck(configuration, mode, monitor);
+	}
+
+	@Override
+	public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException
+	{
+		// comment this out in order to get java debugging as well as XSL debugging
+//		if (ILaunchManager.DEBUG_MODE.equals(mode))
+//			return super.getVMRunner(configuration, ILaunchManager.RUN_MODE);
+		return super.getVMRunner(configuration, mode);
+	}
+
+	private File getLaunchConfigFile()
+	{
+		IPath launchPath = Platform.getStateLocation(JAXPLaunchingPlugin.getDefault().getBundle()).append("launch"); //$NON-NLS-1$
+		File launchDir = launchPath.toFile();
+		if (!launchDir.exists())
+			launchDir.mkdir();
+		File file = new File(launchDir, "launch.xml"); //$NON-NLS-1$
+		return file;
+	}
+
+	@Override
+	public IPath getWorkingDirectoryPath(ILaunchConfiguration configuration) throws CoreException
+	{
+		// TODO changes are afoot so that working directory can be gotten from the Common launch tab
+		
+//		String path = configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_PROCESSOR_WORKING_DIR, (String) null);
+//		if (path != null)
+//		{
+//			path = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(path);
+//			return new Path(path);
+//		}
+		return null;
+	}
+
+	private IProcessorInvoker getProcessorInvokerDescriptor(ILaunchConfiguration configuration) throws CoreException
+	{
+		String invokerId = configuration.getAttribute(JAXPLaunchConfigurationConstants.INVOKER_DESCRIPTOR, (String) null);
+		if (invokerId == null)
+			invokerId = "org.eclipse.wst.xsl.launching.jaxp.invoke"; //$NON-NLS-1$
+		return JAXPRuntime.getProcessorInvoker(invokerId);
+	}
+
+	public static IProcessorInstall getProcessorInstall(ILaunchConfiguration configuration, String mode) throws CoreException
+	{
+		IProcessorInstall install = LaunchHelper.getProcessorInstall(configuration);
+		if (mode.equals(ILaunchManager.DEBUG_MODE) && install.getDebugger() == null)
+		{
+			String debuggingInstallId = JAXPLaunchingPlugin.getDefault().getPluginPreferences().getString(JAXPLaunchConfigurationConstants.ATTR_DEFAULT_DEBUGGING_INSTALL_ID);
+			install = JAXPRuntime.getProcessor(debuggingInstallId);
+		}
+		return install;
+	}
+
+	@Override
+	public String getMainTypeName(ILaunchConfiguration configuration) throws CoreException
+	{
+		if (ILaunchManager.DEBUG_MODE.equals(mode))
+			return "org.eclipse.wst.xsl.jaxp.debug.debugger.DebugRunner"; //$NON-NLS-1$
+		return "org.eclipse.wst.xsl.jaxp.debug.invoker.internal.Main"; //$NON-NLS-1$
+	}
+
+	@Override
+	public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException
+	{
+		// classname, sourceurl, output file
+		IProcessorInvoker invoker = getProcessorInvokerDescriptor(configuration);
+		String clazz = invoker.getInvokerClassName();
+
+		StringBuffer sb = new StringBuffer();
+		sb.append(clazz);
+		sb.append(" "); //$NON-NLS-1$
+		sb.append("\"" + getLaunchConfigFile().getAbsolutePath() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+		sb.append(" "); //$NON-NLS-1$
+		sb.append("\"" + launchHelper.getSource() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+		sb.append(" "); //$NON-NLS-1$
+		sb.append("\"" + launchHelper.getTarget().getAbsolutePath() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+		if (ILaunchManager.DEBUG_MODE.equals(mode))
+		{
+			IProcessorInstall install = getProcessorInstall(configuration, mode);
+			if (install.getDebugger() != null)
+			{
+				IDebugger debugger = install.getDebugger();
+				String className = debugger.getClassName();
+				sb.append(" -debug ").append(className).append(" "); //$NON-NLS-1$ //$NON-NLS-2$
+				sb.append(launchHelper.getRequestPort());
+				sb.append(" ").append(launchHelper.getEventPort()); //$NON-NLS-1$
+				sb.append(" ").append(launchHelper.getGeneratePort()); //$NON-NLS-1$
+			}
+		}
+
+		return sb.toString();
+	}
+
+	@Override
+	public String[] getClasspath(ILaunchConfiguration configuration) throws CoreException
+	{
+		// get the classpath defined by the user
+		String[] userClasspath = super.getClasspath(configuration);
+
+		// get the classpath required for the transformation
+		IProcessorInvoker invoker = getProcessorInvokerDescriptor(configuration);
+		List<String> invokerCP = new ArrayList<String>();
+		for (String entry : invoker.getClasspathEntries())
+		{
+			invokerCP.add(entry);
+		}
+
+		// add the debugger...
+		IProcessorInstall install = getProcessorInstall(configuration, mode);
+		if (ILaunchManager.DEBUG_MODE.equals(mode) && install.getDebugger() != null)
+		{
+			String[] jars = install.getDebugger().getClassPath();
+			for (String jar : jars)
+			{
+				invokerCP.add(jar);
+			}
+		}
+
+		String[] invokerClasspath = (String[]) invokerCP.toArray(new String[0]);
+
+		// add them together
+		String[] classpath = new String[userClasspath.length + invokerClasspath.length];
+		System.arraycopy(invokerClasspath, 0, classpath, 0, invokerClasspath.length);
+		System.arraycopy(userClasspath, 0, classpath, invokerClasspath.length, userClasspath.length);
+
+		return classpath;
+	}
+
+	@Override
+	public String getVMArguments(ILaunchConfiguration configuration) throws CoreException
+	{
+		String vmargs = super.getVMArguments(configuration);
+
+		IProcessorInstall install = getProcessorInstall(configuration, mode);
+		if (install != null && !install.getProcessorType().isJREDefault())
+		{
+			// clear the endorsed dir
+			File tempDir = getEndorsedDir();
+			if (tempDir.exists())
+			{
+				File[] children = tempDir.listFiles();
+				for (File child : children)
+				{
+					child.delete();
+				}
+				tempDir.delete();
+			}
+			tempDir.mkdir();
+
+			// move the required jars to the endorsed dir
+			IProcessorJar[] jars = install.getProcessorJars();
+			for (int i = 0; i < jars.length; i++)
+			{
+				URL entry = jars[i].asURL();
+				if (entry == null)
+					throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("XSLTLaunchConfigurationDelegate.23") + jars[i], null)); //$NON-NLS-1$
+				File file = new File(tempDir, "END_" + i + ".jar"); //$NON-NLS-1$ //$NON-NLS-2$
+				moveFile(entry, file);
+			}
+			// add the endorsed dir
+			vmargs += " -Djava.endorsed.dirs=\"" + tempDir.getAbsolutePath() + "\""; //$NON-NLS-1$ //$NON-NLS-2$
+			
+			String tfactory = getTransformerFactory(install);
+			if (tfactory != null)
+				vmargs += " -Djavax.xml.transform.TransformerFactory=" + tfactory; //$NON-NLS-1$
+			
+			if (ILaunchManager.DEBUG_MODE.equals(mode))
+			{
+				// in debug mode, set the logging to ERROR. This prevents the console from popping up on top of the result view!
+				try
+				{
+					URL url = FileLocator.resolve(FileLocator.find(Platform.getBundle(JAXPLaunchingPlugin.PLUGIN_ID), new Path("/log4j.debug.properties"), null));
+					vmargs += " -Dlog4j.configuration=\""+url.toExternalForm()+"\""; //$NON-NLS-1$
+				}
+				catch (IOException e)
+				{
+					JAXPLaunchingPlugin.log(e);
+				}
+			}
+		}
+		return vmargs;
+	}
+	
+	private String getTransformerFactory(IProcessorInstall install)
+	{
+		String tfactory = null;
+		if (ILaunchManager.DEBUG_MODE.equals(mode))
+			tfactory = install.getDebugger().getTransformerFactory();
+		else
+		{
+			ITransformerFactory t = launchHelper.getTransformerFactory();
+			if (t != null)
+				tfactory = t.getFactoryClass();
+		}
+		return tfactory;
+	}
+
+	private File getEndorsedDir()
+	{
+		IPath tempLocation = Platform.getStateLocation(JAXPLaunchingPlugin.getDefault().getBundle()).append("endorsed"); //$NON-NLS-1$
+		return tempLocation.toFile();
+	}
+
+	private static void moveFile(URL src, File target) throws CoreException
+	{
+		BufferedOutputStream bos = null;
+		BufferedInputStream bis = null;
+		try
+		{
+			bos = new BufferedOutputStream(new FileOutputStream(target));
+			bis = new BufferedInputStream(src.openStream());
+			while (bis.available() > 0)
+			{
+				int size = bis.available();
+				if (size > 1024)
+					size = 1024;
+				byte[] b = new byte[size];
+				bis.read(b, 0, b.length);
+				bos.write(b);
+			}
+		}
+		catch (IOException e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("XSLTLaunchConfigurationDelegate.7") + src + Messages.getString("XSLTLaunchConfigurationDelegate.31") + target, e)); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		finally
+		{
+			if (bis != null)
+			{
+				try
+				{
+					bis.close();
+				}
+				catch (IOException e)
+				{
+					JAXPLaunchingPlugin.log(e);
+				}
+			}
+			if (bos != null)
+			{
+				try
+				{
+					bos.close();
+				}
+				catch (IOException e)
+				{
+					JAXPLaunchingPlugin.log(e);
+				}
+			}
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPLaunchingPlugin.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPLaunchingPlugin.java
new file mode 100644
index 0000000..17ddda7
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPLaunchingPlugin.java
@@ -0,0 +1,62 @@
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class JAXPLaunchingPlugin extends Plugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.wst.xsl.jaxp.launching";
+
+	// The shared instance
+	private static JAXPLaunchingPlugin plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public JAXPLaunchingPlugin() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static JAXPLaunchingPlugin getDefault() {
+		return plugin;
+	}
+
+	public static void log(Exception e)
+	{
+		getDefault().getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, 0, "", e)); //$NON-NLS-1$
+	}
+
+	public static void log(CoreException e)
+	{
+		getDefault().getLog().log(e.getStatus());
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/LaunchHelper.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/LaunchHelper.java
new file mode 100644
index 0000000..39a6392
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/LaunchHelper.java
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.wst.xsl.jaxp.debug.invoker.PipelineDefinition;
+import org.eclipse.wst.xsl.jaxp.debug.invoker.TransformDefinition;
+import org.eclipse.wst.xsl.jaxp.debug.invoker.TypedValue;
+import org.eclipse.wst.xsl.jaxp.launching.IAttribute;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorInstall;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorType;
+import org.eclipse.wst.xsl.jaxp.launching.ITransformerFactory;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPLaunchConfigurationConstants;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPRuntime;
+import org.eclipse.wst.xsl.jaxp.launching.LaunchAttributes;
+import org.eclipse.wst.xsl.jaxp.launching.LaunchProperties;
+import org.eclipse.wst.xsl.launching.config.BaseLaunchHelper;
+import org.eclipse.wst.xsl.launching.config.LaunchAttribute;
+import org.eclipse.wst.xsl.launching.config.LaunchTransform;
+import org.eclipse.wst.xsl.launching.config.Messages;
+import org.eclipse.wst.xsl.launching.config.PreferenceUtil;
+import org.w3c.dom.Document;
+
+public class LaunchHelper extends BaseLaunchHelper
+{
+	private final LaunchAttributes attributes;
+	private final LaunchProperties outputProperties;
+	private final ITransformerFactory transformerFactory;
+
+	public LaunchHelper(ILaunchConfiguration configuration) throws CoreException
+	{
+		super(configuration);
+		attributes = hydrateAttributes(configuration);
+		outputProperties = hydrateOutputProperties(configuration);
+		transformerFactory = hydrateTransformerFactory(configuration);
+	}
+
+	public LaunchProperties getProperties()
+	{
+		return outputProperties;
+	}
+
+	public LaunchAttributes getAttributes()
+	{
+		return attributes;
+	}
+
+	public void save(File file) throws CoreException
+	{
+		BufferedWriter writer = null;
+		try
+		{
+			// ensure it exists
+			file.createNewFile();
+			writer = new BufferedWriter(new FileWriter(file));
+			PipelineDefinition pdef = new PipelineDefinition();
+			for (Iterator<?> iter = attributes.getAttributes().iterator(); iter.hasNext();)
+			{
+				LaunchAttribute att = (LaunchAttribute) iter.next();
+				pdef.addAttribute(new TypedValue(att.uri, TypedValue.TYPE_STRING, att.value));
+			}
+			for (Iterator<?> iter = pipeline.getTransformDefs().iterator(); iter.hasNext();)
+			{
+				LaunchTransform lt = (LaunchTransform) iter.next();
+				TransformDefinition tdef = new TransformDefinition();
+				URL url = pathToURL(lt.getLocation());
+				tdef.setStylesheetURL(url.toExternalForm());
+				tdef.setResolverClass(lt.getResolver());
+				for (Iterator<?> iterator = lt.getParameters().iterator(); iterator.hasNext();)
+				{
+					LaunchAttribute att = (LaunchAttribute) iterator.next();
+					tdef.addParameter(new TypedValue(att.uri, TypedValue.TYPE_STRING, att.getResolvedValue()));
+				}
+				// set the output props for the LAST transform only
+				if (!iter.hasNext())
+				{
+					for (Map.Entry<String, String> entry : outputProperties.getProperties().entrySet())
+					{
+						String name = entry.getKey();
+						String value = entry.getValue();
+						if (name != null && value != null)
+							tdef.setOutputProperty(name, value);
+					}
+				}
+				pdef.addTransformDef(tdef);
+			}
+
+			Document doc = pdef.toXML();
+			String s = PreferenceUtil.serializeDocument(doc);
+			writer.write(s);
+		}
+		catch (FileNotFoundException e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("LaunchHelper.0"), e)); //$NON-NLS-1$
+		}
+		catch (IOException e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("LaunchHelper.1"), e)); //$NON-NLS-1$
+		}
+		catch (ParserConfigurationException e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, "ParserConfigurationException", e)); //$NON-NLS-1$
+		}
+		catch (TransformerException e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, "TransformerException", e)); //$NON-NLS-1$
+		}
+		finally
+		{
+			if (writer != null)
+			{
+				try
+				{
+					writer.close();
+				}
+				catch (IOException e)
+				{
+					JAXPLaunchingPlugin.log(e);
+				}
+			}
+		}
+	}
+
+	public static LaunchProperties hydrateOutputProperties(ILaunchConfiguration configuration) throws CoreException
+	{
+		LaunchProperties properties = null;
+		boolean usePreferenceProperties = false; //configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_USE_PROPERTIES_FROM_PREFERENCES, true);
+		IProcessorType pt = getProcessorInstall(configuration).getProcessorType();
+		if (usePreferenceProperties)
+		{
+			properties = new LaunchProperties();
+			for (Map.Entry<String, String> entry : pt.getOutputPropertyValues().entrySet())
+			{
+				String name = (String) entry.getKey();
+				String value = (String) entry.getValue();
+				properties.setProperty(name, value);
+			}
+		}
+		else
+		{
+			String s = configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_OUTPUT_PROPERTIES, (String) null);
+			if (s != null && s.length() > 0)
+			{
+				ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());
+				properties = LaunchProperties.fromXML(inputStream);
+			}
+		}
+		return properties;
+	}
+
+	private static LaunchAttributes hydrateAttributes(ILaunchConfiguration configuration) throws CoreException
+	{
+		LaunchAttributes attributes = null;
+		boolean useDefaultAttributes = false; //configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_USE_FEATURES_FROM_PREFERENCES, true);
+		if (useDefaultAttributes)
+		{
+			attributes = new LaunchAttributes();
+			IProcessorType pt = getProcessorInstall(configuration).getProcessorType();
+			Map<String, String> fvals = pt.getAttributeValues();
+			for (Map.Entry<String, String> entry : fvals.entrySet())
+			{
+				String uri = (String) entry.getKey();
+				IAttribute attribute = getAttribute(pt.getAttributes(), uri);
+				attributes.addAttribute(new LaunchAttribute(uri, "string", (String) entry.getValue()));
+			}
+		}
+		else
+		{
+			String s = configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_ATTRIBUTES, (String) null);
+			if (s != null && s.length() > 0)
+			{
+				ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());
+				attributes = LaunchAttributes.fromXML(inputStream);
+			}
+		}
+		return attributes;
+	}
+
+	private static IAttribute getAttribute(IAttribute[] attributes, String uri)
+	{
+		for (IAttribute attribute : attributes)
+		{
+			if (attribute.getURI().equals(uri))
+				return attribute;
+		}
+		return null;
+	}
+
+
+	public static IProcessorInstall getProcessorInstall(ILaunchConfiguration configuration) throws CoreException
+	{
+		boolean useDefaultProcessor = configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_USE_DEFAULT_PROCESSOR, true);
+		if (useDefaultProcessor)
+			return JAXPRuntime.getDefaultProcessor();
+		String processorId = configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_PROCESSOR, ""); //$NON-NLS-1$
+		IProcessorInstall processor = JAXPRuntime.getProcessor(processorId);
+		return processor;
+	}
+
+	private static ITransformerFactory hydrateTransformerFactory(ILaunchConfiguration configuration) throws CoreException
+	{
+		IProcessorType type = getProcessorInstall(configuration).getProcessorType();
+		boolean useDefaultFactory = configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_USE_DEFAULT_PROCESSOR, true);
+		if (useDefaultFactory)
+			return type.getDefaultTransformerFactory();
+		
+		String factoryId = configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_TRANSFORMER_FACTORY, (String)null);
+		if (factoryId == null)
+			return null;
+		
+		for (ITransformerFactory factory : type.getTransformerFactories())
+		{
+			if (factory.getFactoryClass().equals(factoryId))
+				return factory;
+		}
+		return null;
+	}
+
+	public ITransformerFactory getTransformerFactory()
+	{
+		return transformerFactory;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/Messages.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/Messages.java
new file mode 100644
index 0000000..a058701
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/Messages.java
@@ -0,0 +1,22 @@
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+	private static final String BUNDLE_NAME = "org.eclipse.wst.xsl.jaxp.launching.internal.messages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+			.getBundle(BUNDLE_NAME);
+
+	private Messages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/OutputProperty.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/OutputProperty.java
new file mode 100644
index 0000000..c00c96f
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/OutputProperty.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import org.eclipse.wst.xsl.jaxp.launching.IOutputProperty;
+
+public class OutputProperty implements IOutputProperty
+{
+	private final String name;
+	private final String desc;
+
+	public OutputProperty(String key, String desc)
+	{
+		this.name = key;
+		this.desc = desc;
+	}
+
+	public String getDescription()
+	{
+		return desc;
+	}
+
+	public String getURI()
+	{
+		return name;
+	}
+
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/OutputPropertyPreferences.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/OutputPropertyPreferences.java
new file mode 100644
index 0000000..4073133
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/OutputPropertyPreferences.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.xsl.launching.config.PreferenceUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class OutputPropertyPreferences
+{
+	private final Map<String, Map<String,String>> typeProperties = new HashMap<String, Map<String,String>>();
+
+	public Map<String,String> getOutputPropertyValues(String typeId)
+	{
+		return typeProperties.get(typeId);
+	}
+
+	public void setOutputPropertyValues(String typeId, Map<String,String> properties)
+	{
+		typeProperties.put(typeId, properties);
+	}
+
+	public String getAsXML() throws ParserConfigurationException, IOException, TransformerException
+	{
+		Document doc = PreferenceUtil.getDocument();
+		Element config = doc.createElement("outputPropertyPreferences"); //$NON-NLS-1$
+		doc.appendChild(config);
+
+		for (String type : typeProperties.keySet())
+		{
+			Element processorTypeElement = typeAsElement(doc, type);
+			Map<String,String> propertyValues = typeProperties.get(type);
+			featureValuesAsElement(doc, processorTypeElement, propertyValues);
+			config.appendChild(processorTypeElement);
+		}
+
+		// Serialize the Document and return the resulting String
+		return PreferenceUtil.serializeDocument(doc);
+	}
+
+	public static OutputPropertyPreferences fromXML(InputStream inputStream) throws CoreException
+	{
+		OutputPropertyPreferences prefs = new OutputPropertyPreferences();
+
+		// Do the parsing and obtain the top-level node
+		Document doc = PreferenceUtil.getDocument(inputStream);
+		Element config = doc.getDocumentElement();
+
+		Element[] processorTypeEls = PreferenceUtil.getChildElements(config, "processorType"); //$NON-NLS-1$
+		for (int i = 0; i < processorTypeEls.length; ++i)
+		{
+			Element processorTypeEl = processorTypeEls[i];
+			String type = elementAsType(processorTypeEl);
+			Map<String,String> featureValues = elementAsPropertyValues(processorTypeEl);
+			prefs.setOutputPropertyValues(type, featureValues);
+		}
+
+		return prefs;
+	}
+
+	private static String elementAsType(Element parent)
+	{
+		String id = parent.getAttribute("id"); //$NON-NLS-1$
+		return id;
+	}
+
+	private static Element typeAsElement(Document doc, String type)
+	{
+		Element element = doc.createElement("processorType"); //$NON-NLS-1$
+		element.setAttribute("id", type); //$NON-NLS-1$
+		return element;
+	}
+
+	private static Map<String, String> elementAsPropertyValues(Element element)
+	{
+		Element[] propertyEls = PreferenceUtil.getChildElements(element, "property"); //$NON-NLS-1$
+		Map<String, String> propertyValues = new HashMap<String,String>();
+		for (Element featureEl : propertyEls)
+		{
+			String name = featureEl.getAttribute("name"); //$NON-NLS-1$
+			String value = featureEl.getAttribute("value"); //$NON-NLS-1$
+			propertyValues.put(name, value);
+		}
+		return propertyValues;
+	}
+
+	private static void featureValuesAsElement(Document doc, Element featuresEl, Map<String, String> propertyValues)
+	{
+		if (propertyValues != null)
+		{
+			for (Map.Entry<String, String> entry : propertyValues.entrySet())
+			{
+				String name = entry.getKey();
+				String value = entry.getValue();
+				Element element = doc.createElement("property"); //$NON-NLS-1$
+				element.setAttribute("name", name); //$NON-NLS-1$
+				element.setAttribute("value", value); //$NON-NLS-1$
+				featuresEl.appendChild(element);
+			}
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/PluginProcessorJar.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/PluginProcessorJar.java
new file mode 100644
index 0000000..15f1026
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/PluginProcessorJar.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorJar;
+import org.osgi.framework.Bundle;
+
+public class PluginProcessorJar implements IProcessorJar
+{
+	private final String pluginId;
+	private final IPath path;
+
+	public PluginProcessorJar(String pluginId, IPath path)
+	{
+		this.pluginId = pluginId;
+		this.path = path;
+	}
+
+	public URL asURL()
+	{
+		URL url = null;
+		try
+		{
+			// FIXME very clumsy way to get location orbit jar file
+			// There is surely a better way, but I can'd find it.
+			if (path == null)
+			{
+				url = Platform.getBundle(pluginId).getEntry("/"); //$NON-NLS-1$
+				url = FileLocator.resolve(url);
+				String s = url.getPath();
+				if (s.endsWith("!/")) //$NON-NLS-1$
+				{
+					s = s.substring(0,s.length()-2);
+				}
+				url = new URL(s);
+			}
+			else
+			{
+				Bundle bundle = Platform.getBundle(pluginId);
+				IPath jarPath = new Path("/" + path); //$NON-NLS-1$
+				url = FileLocator.find(bundle, jarPath, null);
+				if (url != null)
+					url = FileLocator.resolve(url);
+			}
+		}
+		catch (IOException e)
+		{
+			JAXPLaunchingPlugin.log(e);
+		}
+		return url;
+	}
+
+	public IPath getPath()
+	{
+		return path;
+	}
+
+	@Override
+	public String toString()
+	{
+		return "Plugin " + pluginId + Messages.getString("PluginProcessorJar.0") + path; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/PreferenceInitializer.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/PreferenceInitializer.java
new file mode 100644
index 0000000..0bf1bca
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/PreferenceInitializer.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPLaunchConfigurationConstants;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPRuntime;
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer
+{
+
+	@Override
+	public void initializeDefaultPreferences()
+	{
+		IEclipsePreferences node = new DefaultScope().getNode(JAXPLaunchingPlugin.PLUGIN_ID);
+
+		ProcessorPreferences prefs = new ProcessorPreferences();
+		prefs.setDefaultProcessorId(JAXPRuntime.JRE_DEFAULT_PROCESSOR_ID);
+
+		OutputPropertyPreferences outputPrefs = new OutputPropertyPreferences();
+		outputPrefs.setOutputPropertyValues(JAXPRuntime.JRE_DEFAULT_PROCESSOR_TYPE_ID, JAXPRuntime.createDefaultOutputProperties(JAXPRuntime.JRE_DEFAULT_PROCESSOR_TYPE_ID));
+		outputPrefs.setOutputPropertyValues(JAXPLaunchConfigurationConstants.XALAN_TYPE_ID, JAXPRuntime.createDefaultOutputProperties(JAXPLaunchConfigurationConstants.XALAN_TYPE_ID));
+		outputPrefs.setOutputPropertyValues(JAXPLaunchConfigurationConstants.SAXON_TYPE_ID, JAXPRuntime.createDefaultOutputProperties(JAXPLaunchConfigurationConstants.SAXON_TYPE_ID));
+		outputPrefs.setOutputPropertyValues(JAXPLaunchConfigurationConstants.SAXON_1_0_TYPE_ID, JAXPRuntime.createDefaultOutputProperties(JAXPLaunchConfigurationConstants.SAXON_1_0_TYPE_ID));
+
+		try
+		{
+			String xml = prefs.getAsXML();
+			node.put(JAXPRuntime.PREF_PROCESSOR_XML, xml);
+
+			xml = outputPrefs.getAsXML();
+			node.put(JAXPRuntime.PREF_OUTPUT_PROPERTIES_XML, xml);
+
+			node.put(JAXPLaunchConfigurationConstants.ATTR_DEFAULT_DEBUGGING_INSTALL_ID, "org.eclipse.wst.xsl.launching.xalan.processor"); //$NON-NLS-1$
+		}
+		catch (ParserConfigurationException e)
+		{
+			JAXPLaunchingPlugin.log(e);
+		}
+		catch (IOException e)
+		{
+			JAXPLaunchingPlugin.log(e);
+		}
+		catch (TransformerException e)
+		{
+			JAXPLaunchingPlugin.log(e);
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorInvokerDescriptor.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorInvokerDescriptor.java
new file mode 100644
index 0000000..eb93ad9
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorInvokerDescriptor.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorInvoker;
+
+public class ProcessorInvokerDescriptor implements IProcessorInvoker
+{
+
+	private final String invokerClass;
+	private final String[] classpath;
+	private final String id;
+	private final String bundleId;
+
+	public ProcessorInvokerDescriptor(String id, String bundleId, String invokerClass, String[] classpath)
+	{
+		this.id = id;
+		this.bundleId = bundleId;
+		this.invokerClass = invokerClass;
+		this.classpath = classpath;
+	}
+
+	public String[] getClasspathEntries()
+	{
+		return createEntries(bundleId,classpath);
+	}
+	
+	public static String[] createEntries(String bundleId, String[] classpath)
+	{
+		List<String> entries = new ArrayList<String>();
+		try {
+			// if in dev mode, use the bin dir
+			if (Platform.inDevelopmentMode())
+				entries.add(Utils.getFileLocation(bundleId, "/bin")); //$NON-NLS-1$
+			for (String jar : classpath)
+			{
+				String entry = null;
+				if (jar.startsWith("${eclipse_orbit:") && jar.endsWith("}")) //$NON-NLS-1$ //$NON-NLS-2$
+				{
+					jar = jar.substring("${eclipse_orbit:".length()); //$NON-NLS-1$
+					jar = jar.substring(0,jar.length()-1);
+					try
+					{
+						File bundleFile = FileLocator.getBundleFile(Platform.getBundle(jar));
+						if (bundleFile.isDirectory())
+							entry = Utils.getPluginLocation(jar) + "/bin";
+						else
+							entry = Utils.getPluginLocation(jar);
+					}
+					catch (IOException e)
+					{}
+				}
+				else
+				{
+					entry = Utils.getFileLocation(bundleId,jar);
+				}
+				if (entry!=null)
+					entries.add(entry);
+			}
+		} 
+		catch (CoreException e) 
+		{
+			JAXPLaunchingPlugin.log(e);
+		}
+		return entries.toArray(new String[0]);
+	}
+
+	/**
+	 * The name of the class that implements IProcessorInvoker
+	 */
+	public String getInvokerClassName()
+	{
+		return invokerClass;
+	}
+
+	public String getId()
+	{
+		return id;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorJar.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorJar.java
new file mode 100644
index 0000000..fe1c76a
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorJar.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorJar;
+
+public class ProcessorJar implements IProcessorJar
+{
+	private final IPath path;
+
+	public ProcessorJar(IPath path)
+	{
+		this.path = path;
+	}
+
+	public URL asURL()
+	{
+		URL url = null;
+		try
+		{
+			// first try to resolve as workspace-relative path
+			IPath rootPath = ResourcesPlugin.getWorkspace().getRoot().getLocation();
+			File file = new File(rootPath.append(path).toOSString());
+			if (file.exists())
+				url = file.toURL();
+			else
+			{
+				// now try to resolve as an absolute path
+				file = new File(path.toOSString());
+				url = file.toURL();
+			}
+		}
+		catch (MalformedURLException e)
+		{
+			JAXPLaunchingPlugin.log(e);
+		}
+		return url;
+	}
+
+	public IPath getPath()
+	{
+		return path;
+	}
+
+	@Override
+	public String toString()
+	{
+		return path.toString();
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorPreferences.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorPreferences.java
new file mode 100644
index 0000000..3472278
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorPreferences.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorInstall;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorJar;
+import org.eclipse.wst.xsl.jaxp.launching.ProcessorInstall;
+import org.eclipse.wst.xsl.launching.config.PreferenceUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+public class ProcessorPreferences
+{
+	private String defaultProcessorId;
+	private List<IProcessorInstall> processors = new ArrayList<IProcessorInstall>();
+
+	public void setProcessors(List<IProcessorInstall> processors)
+	{
+		this.processors = processors;
+	}
+
+	public List<IProcessorInstall> getProcessors()
+	{
+		return processors;
+	}
+
+	public String getDefaultProcessorId()
+	{
+		return defaultProcessorId;
+	}
+
+	public void setDefaultProcessorId(String defaultProcessorId)
+	{
+		this.defaultProcessorId = defaultProcessorId;
+	}
+
+	public String getAsXML() throws ParserConfigurationException, IOException, TransformerException
+	{
+		Document doc = PreferenceUtil.getDocument();
+		Element config = doc.createElement("processorSettings");  //$NON-NLS-1$
+		doc.appendChild(config);
+
+		// Set the defaultVM attribute on the top-level node
+		if (defaultProcessorId != null)
+		{
+			config.setAttribute("defaultProcessor", defaultProcessorId);  //$NON-NLS-1$
+		}
+
+		for (Iterator<IProcessorInstall> iter = processors.iterator(); iter.hasNext();)
+		{
+			IProcessorInstall install = (IProcessorInstall) iter.next();
+			if (!install.isContributed())
+			{
+				Element vmTypeElement = installAsElement(doc, install);
+				config.appendChild(vmTypeElement);
+			}
+		}
+
+		// Serialize the Document and return the resulting String
+		return PreferenceUtil.serializeDocument(doc);
+	}
+
+	public static ProcessorPreferences fromXML(InputStream inputStream) throws CoreException
+	{
+		ProcessorPreferences prefs = new ProcessorPreferences();
+
+		Document doc = PreferenceUtil.getDocument(inputStream);
+		Element config = doc.getDocumentElement();
+
+		// Populate the default VM-related fields
+		prefs.setDefaultProcessorId(config.getAttribute("defaultProcessor")); //$NON-NLS-1$
+
+		List<IProcessorInstall> processors = new ArrayList<IProcessorInstall>();
+		// Traverse the parsed structure and populate the VMType to VM Map
+		Element[] processorEls = PreferenceUtil.getChildElements(config, "processor"); //$NON-NLS-1$
+		for (int i = 0; i < processorEls.length; ++i)
+		{
+			IProcessorInstall processor = elementAsInstall(processorEls[i]);
+			processors.add(processor);
+		}
+
+		prefs.setProcessors(processors);
+
+		return prefs;
+	}
+
+	private static IProcessorInstall elementAsInstall(Element parent)
+	{
+		String id = parent.getAttribute("id"); //$NON-NLS-1$
+		String label = parent.getAttribute("label"); //$NON-NLS-1$
+		String typeId = parent.getAttribute("type"); //$NON-NLS-1$
+		String supports = parent.getAttribute("supports"); //$NON-NLS-1$
+		String debuggerId = parent.getAttribute("debuggerId"); //$NON-NLS-1$
+
+		IProcessorJar[] jars = null;
+		Element[] jarsEls = PreferenceUtil.getChildElements(parent, "jars"); //$NON-NLS-1$
+		if (jarsEls.length == 1)
+		{
+			jars = elementAsJars(jarsEls[0]);
+		}
+		IProcessorInstall install = new ProcessorInstall(id, label, typeId, jars, debuggerId, supports, false);
+		return install;
+	}
+
+	private static Element installAsElement(Document doc, IProcessorInstall install)
+	{
+		Element element = doc.createElement("processor"); //$NON-NLS-1$
+		element.setAttribute("id", install.getId()); //$NON-NLS-1$
+		element.setAttribute("label", install.getName()); //$NON-NLS-1$
+		element.setAttribute("type", install.getProcessorType().getId()); //$NON-NLS-1$
+		element.setAttribute("supports", install.getSupports()); //$NON-NLS-1$
+		element.setAttribute("debuggerId", install.getDebugger() != null ? install.getDebugger().getId() : null); //$NON-NLS-1$
+		element.appendChild(jarsAsElement(doc, install.getProcessorJars()));
+		return element;
+	}
+
+	private static IProcessorJar[] elementAsJars(Element element)
+	{
+		Element[] jarEls = PreferenceUtil.getChildElements(element, "jar"); //$NON-NLS-1$
+		List<ProcessorJar> jars = new ArrayList<ProcessorJar>(jarEls.length);
+		for (Element jarEl : jarEls)
+		{
+			Node node = jarEl.getFirstChild();
+			if (node != null && node.getNodeType() == Node.TEXT_NODE)
+			{
+				String path = ((Text) node).getNodeValue();
+				jars.add(new ProcessorJar(Path.fromPortableString(path)));
+			}
+		}
+		return (IProcessorJar[]) jars.toArray(new IProcessorJar[0]);
+	}
+
+	private static Element jarsAsElement(Document doc, IProcessorJar[] jars)
+	{
+		Element jarsEl = doc.createElement("jars");  //$NON-NLS-1$
+		for (IProcessorJar jar : jars)
+		{
+			if (jar != null && jar.getPath() != null)
+			{
+				Element jarEl = doc.createElement("jar"); //$NON-NLS-1$
+				Text text = doc.createTextNode(jar.getPath().toPortableString());
+				jarEl.appendChild(text);
+				jarsEl.appendChild(jarEl);
+			}
+		}
+		return jarsEl;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorType.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorType.java
new file mode 100644
index 0000000..1136929
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/ProcessorType.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.xsl.jaxp.launching.IAttribute;
+import org.eclipse.wst.xsl.jaxp.launching.IOutputProperty;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorType;
+import org.eclipse.wst.xsl.jaxp.launching.ITransformerFactory;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPRuntime;
+
+public class ProcessorType implements IProcessorType
+{
+	private static final String DESC_SUFFIX = ".DESC"; //$NON-NLS-1$
+	private static final String TYPE_SUFFIX = ".TYPE"; //$NON-NLS-1$
+
+	private final String id;
+	private final String name;
+	private final ITransformerFactory[] transformerFactories;
+	private final URL attributePropertiesURL;
+	private final URL outputPropertiesURL;
+
+	private IAttribute[] attributes;
+	private IOutputProperty[] outputProperties;
+	private Map<String, String> outputPropertyValues;
+	private Map<String, String> attributeValues;
+
+	public ProcessorType(String id, String name, URL attributePropertiesURL, URL outputPropertiesURL, Map<String, String> attributeValues, Map<String, String> outputPropertyValues, ITransformerFactory[] transformerFactories)
+	{
+		this.id = id;
+		this.name = name;
+		this.attributePropertiesURL = attributePropertiesURL;
+		this.outputPropertiesURL = outputPropertiesURL;
+		this.attributeValues = attributeValues;
+		this.transformerFactories = transformerFactories;
+		this.outputPropertyValues = outputPropertyValues;
+	}
+
+	public String getId()
+	{
+		return id;
+	}
+
+	public String getLabel()
+	{
+		return name;
+	}
+
+	public Map<String, String> getAttributeValues()
+	{
+		return attributeValues;
+	}
+
+	public IAttribute[] getAttributes()
+	{
+		if (attributes == null)
+		{
+			if (attributePropertiesURL != null)
+				attributes = loadAttributes();
+			else
+				attributes = new IAttribute[0];
+		}
+		return attributes;
+	}
+
+	public Map<String,String> getOutputPropertyValues()
+	{
+		return outputPropertyValues;
+	}
+
+	public boolean isJREDefault()
+	{
+		return JAXPRuntime.JRE_DEFAULT_PROCESSOR_TYPE_ID.equals(id);
+	}
+
+	public ITransformerFactory[] getTransformerFactories()
+	{
+		return transformerFactories;
+	}
+	
+	public ITransformerFactory getDefaultTransformerFactory()
+	{
+		if (transformerFactories.length > 0)
+			return transformerFactories[0];
+		return null;
+	}
+
+	public IOutputProperty[] getOutputProperties()
+	{
+		if (outputProperties == null)
+		{
+			if (outputPropertiesURL != null)
+				outputProperties = loadOutputProperties();
+			else
+				outputProperties = new IOutputProperty[0];
+		}
+		return outputProperties;
+	}
+
+	private IOutputProperty[] loadOutputProperties()
+	{
+		BufferedInputStream is = null;
+		List<OutputProperty> outputs = new ArrayList<OutputProperty>();
+		Properties props = new Properties();
+		try
+		{
+
+			is = new BufferedInputStream(outputPropertiesURL.openStream());
+			props.load(is);
+			for (Object element : props.keySet())
+			{
+				String key = (String) element;
+				if (!key.endsWith(DESC_SUFFIX))
+				{
+					String name = key;
+					String uri = props.getProperty(key);
+					String desc = props.getProperty(key + DESC_SUFFIX);
+					if (uri != null && name != null && desc != null)
+					{
+						OutputProperty prop = new OutputProperty(uri.trim(), desc);
+						outputs.add(prop);
+					}
+					else
+					{
+						JAXPLaunchingPlugin.log(new CoreException(new Status(IStatus.WARNING, JAXPLaunchingPlugin.PLUGIN_ID, Messages.getString("ProcessorType.2") + outputPropertiesURL //$NON-NLS-1$
+								+ Messages.getString("ProcessorType.3") + key))); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+		catch (IOException e)
+		{
+			JAXPLaunchingPlugin.log(e);
+		}
+		finally
+		{
+			if (is != null)
+			{
+				try
+				{
+					is.close();
+				}
+				catch (IOException e)
+				{
+					JAXPLaunchingPlugin.log(e);
+				}
+			}
+		}
+		return (IOutputProperty[]) outputs.toArray(new IOutputProperty[0]);
+	}
+
+	private IAttribute[] loadAttributes()
+	{
+		BufferedInputStream is = null;
+		List<Attribute> attributesList = new ArrayList<Attribute>();
+		try
+		{
+			is = new BufferedInputStream(attributePropertiesURL.openStream());
+			Properties props = new Properties();
+			props.load(is);
+
+			for (Object element : props.keySet())
+			{
+				String key = (String) element;
+				if (!key.endsWith(DESC_SUFFIX) && !key.endsWith(TYPE_SUFFIX))
+				{
+					String uri = props.getProperty(key);
+					String type = props.getProperty(key + TYPE_SUFFIX);
+					String desc = props.getProperty(key + DESC_SUFFIX);
+					if (uri != null && type != null && desc != null)
+					{
+						Attribute attribute = new Attribute(uri.trim(), type.trim(), desc);
+						attributesList.add(attribute);
+					}
+					else
+					{
+						JAXPLaunchingPlugin.log(new CoreException(new Status(IStatus.WARNING, JAXPLaunchingPlugin.PLUGIN_ID, Messages.getString("ProcessorType.4") + attributePropertiesURL //$NON-NLS-1$
+								+ Messages.getString("ProcessorType.5") + key))); //$NON-NLS-1$
+					}
+				}
+			}
+
+		}
+		catch (IOException e)
+		{
+			JAXPLaunchingPlugin.log(e);
+		}
+		finally
+		{
+			if (is != null)
+			{
+				try
+				{
+					is.close();
+				}
+				catch (IOException e)
+				{
+					JAXPLaunchingPlugin.log(e);
+				}
+			}
+		}
+		IAttribute[] attributes = (IAttribute[]) attributesList.toArray(new IAttribute[0]);
+		Arrays.sort(attributes);
+		return attributes;
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/TransformerFactory.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/TransformerFactory.java
new file mode 100644
index 0000000..4049d42
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/TransformerFactory.java
@@ -0,0 +1,27 @@
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import org.eclipse.wst.xsl.jaxp.launching.ITransformerFactory;
+
+public class TransformerFactory implements ITransformerFactory
+{
+	private final String factoryClass;
+	private final String name;
+	
+	public TransformerFactory(String name,String factoryClass)
+	{
+		super();
+		this.factoryClass = factoryClass;
+		this.name = name;
+	}
+
+	public String getFactoryClass()
+	{
+		return factoryClass;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/Utils.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/Utils.java
new file mode 100644
index 0000000..8e2ebc4
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/Utils.java
@@ -0,0 +1,57 @@
+package org.eclipse.wst.xsl.jaxp.launching.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+
+public class Utils
+{
+
+	public static String getFileLocation(String bundleId, String path) throws CoreException
+	{
+		String location = null;
+		try
+		{
+			URL url = FileLocator.find(Platform.getBundle(bundleId), new Path(path), null);
+			if (url != null)
+			{
+				URL fileUrl = FileLocator.toFileURL(url);
+				File file = new File(fileUrl.getFile());
+				location = file.getAbsolutePath();
+			}
+		}
+		catch (IOException e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("Utils.0") + path + Messages.getString("Utils.1") + bundleId, e)); //$NON-NLS-1$ //$NON-NLS-2$
+		} 
+		return location;
+	}
+
+	public static String getPluginLocation(String bundleId) throws CoreException
+	{
+		String location = null;
+		try
+		{
+			URL url = new URL("platform:/plugin/"+bundleId);
+			if (url != null)
+			{
+				URL fileUrl = FileLocator.toFileURL(url);
+				File file = new File(fileUrl.getFile());
+				location = file.getAbsolutePath();
+			}
+		}
+		catch (IOException e)
+		{
+			throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("Utils.0") + bundleId + Messages.getString("Utils.1") + bundleId, e)); //$NON-NLS-1$ //$NON-NLS-2$
+		} 
+		return location;
+	}
+
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/messages.properties b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/messages.properties
new file mode 100644
index 0000000..bdf2af0
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/messages.properties
@@ -0,0 +1,21 @@
+Attribute.0=Value must be a double
+Attribute.1=Value must be an integer
+Attribute.2=Valid values are 'true' or 'false'
+Attribute.5=Value must be a float
+PluginProcessorJar.0=, path 
+ProcessorType.2=Output properties file 
+ProcessorType.3=\ not configured properly for key 
+ProcessorType.4=Attribute properties file 
+ProcessorType.5=\ not configured properly for key 
+Utils.0=Error determining jar file location: 
+Utils.1=\ from bundle: 
+XSLTLaunchConfigurationDelegate.0=Switch to Default Debugger
+XSLTLaunchConfigurationDelegate.1=The 
+XSLTLaunchConfigurationDelegate.2=\ XSLT processor does not support debugging.\n
+XSLTLaunchConfigurationDelegate.23=Could not locate jar file 
+XSLTLaunchConfigurationDelegate.3=Would you like to debug using the default 
+XSLTLaunchConfigurationDelegate.31=\ to 
+XSLTLaunchConfigurationDelegate.4=\ processor instead?
+XSLTLaunchConfigurationDelegate.5=launch
+XSLTLaunchConfigurationDelegate.6=launch.xml
+XSLTLaunchConfigurationDelegate.7=Error copying url 
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/AbstractRegistryReader.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/AbstractRegistryReader.java
new file mode 100644
index 0000000..233802a
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/AbstractRegistryReader.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+
+public abstract class AbstractRegistryReader
+{
+	public static final String ATT_CLASS = "class"; //$NON-NLS-1$
+	public static final String TAG_DESCRIPTION = "description"; //$NON-NLS-1$
+
+	protected static void logError(IConfigurationElement element, String text)
+	{
+		IExtension extension = element.getDeclaringExtension();
+		StringBuffer buf = new StringBuffer();
+		buf.append("Plugin " + extension.getNamespaceIdentifier() + Messages.getString("AbstractRegistryReader.3") + extension.getExtensionPointUniqueIdentifier()); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("\n" + text); //$NON-NLS-1$
+		JAXPLaunchingPlugin.log(new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.OK, buf.toString(), null)));
+	}
+
+	protected static void logMissingAttribute(IConfigurationElement element, String attributeName)
+	{
+		logError(element, Messages.getString("AbstractRegistryReader.5") + attributeName + Messages.getString("AbstractRegistryReader.6")); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	protected static void logMissingElement(IConfigurationElement element, String elementName)
+	{
+		logError(element, Messages.getString("AbstractRegistryReader.7") + elementName + Messages.getString("AbstractRegistryReader.8")); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	protected static void logUnknownElement(IConfigurationElement element)
+	{
+		logError(element, Messages.getString("AbstractRegistryReader.9") + element.getName()); //$NON-NLS-1$
+	}
+
+	public static IExtension[] orderExtensions(IExtension[] extensions)
+	{
+		IExtension[] sortedExtension = new IExtension[extensions.length];
+		System.arraycopy(extensions, 0, sortedExtension, 0, extensions.length);
+		Comparator<IExtension> comparer = new Comparator<IExtension>()
+		{
+			public int compare(IExtension arg0, IExtension arg1)
+			{
+				String s1 = arg0.getNamespaceIdentifier();
+				String s2 = arg1.getNamespaceIdentifier();
+				return s1.compareToIgnoreCase(s2);
+			}
+		};
+		Collections.sort(Arrays.asList(sortedExtension), comparer);
+		return sortedExtension;
+	}
+
+	protected abstract boolean readElement(IConfigurationElement element);
+
+	protected void readElementChildren(IConfigurationElement element)
+	{
+		readElements(element.getChildren());
+	}
+
+	protected void readElements(IConfigurationElement[] elements)
+	{
+		for (int i = 0; i < elements.length; i++)
+		{
+			if (!readElement(elements[i]))
+				logUnknownElement(elements[i]);
+		}
+	}
+
+	protected void readExtension(IExtension extension)
+	{
+		readElements(extension.getConfigurationElements());
+	}
+
+	public void readRegistry(IExtensionRegistry registry, String pluginId, String extensionPoint)
+	{
+		IExtensionPoint point = registry.getExtensionPoint(pluginId, extensionPoint);
+		if (point == null)
+			return;
+		IExtension[] extensions = point.getExtensions();
+		extensions = orderExtensions(extensions);
+		for (IExtension element : extensions)
+			readExtension(element);
+	}
+
+	public static String getDescription(IConfigurationElement configElement)
+	{
+		IConfigurationElement[] children = configElement.getChildren(TAG_DESCRIPTION);
+		if (children.length >= 1)
+		{
+			return children[0].getValue();
+		}
+		return ""; //$NON-NLS-1$
+	}
+
+	public static String getClassValue(IConfigurationElement configElement, String classAttributeName)
+	{
+		String className = configElement.getAttribute(classAttributeName);
+		if (className != null)
+			return className;
+		IConfigurationElement[] candidateChildren = configElement.getChildren(classAttributeName);
+		if (candidateChildren.length == 0)
+			return null;
+
+		return candidateChildren[0].getAttribute(ATT_CLASS);
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/DebuggerRegistry.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/DebuggerRegistry.java
new file mode 100644
index 0000000..02142ab
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/DebuggerRegistry.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.wst.xsl.jaxp.launching.IDebugger;
+import org.eclipse.wst.xsl.jaxp.launching.internal.DebuggerDescriptor;
+
+public class DebuggerRegistry
+{
+	private final Map<String, DebuggerDescriptor> debuggers = new HashMap<String, DebuggerDescriptor>();
+
+	public DebuggerRegistry()
+	{
+		DebuggerRegistryReader registryReader = new DebuggerRegistryReader();
+		registryReader.addConfigs(this);
+	}
+
+	public IDebugger getDebugger(String id)
+	{
+		return (IDebugger) debuggers.get(id);
+	}
+
+	public IDebugger[] getDebuggers()
+	{
+		return (IDebugger[]) debuggers.values().toArray(new IDebugger[0]);
+	}
+
+	public void addDebugger(DebuggerDescriptor desc)
+	{
+		debuggers.put(desc.getId(), desc);
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/DebuggerRegistryReader.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/DebuggerRegistryReader.java
new file mode 100644
index 0000000..98b9ee8
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/DebuggerRegistryReader.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xsl.jaxp.launching.internal.DebuggerDescriptor;
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+
+public class DebuggerRegistryReader extends AbstractRegistryReader
+{
+	public static final String TAG_DEBUGGER = "debugger"; //$NON-NLS-1$
+	public static final String ATT_ID = "id"; //$NON-NLS-1$
+	public static final String ATT_CLASSNAME = "className"; //$NON-NLS-1$
+	public static final String ATT_CLASSPATH = "classpath"; //$NON-NLS-1$
+	public static final String ATT_NAME = "name"; //$NON-NLS-1$
+	public static final String ATT_PROCESSOR_TYPE_ID = "processorTypeId"; //$NON-NLS-1$
+	public static final String ATT_TRANSFORMER_FACTORY = "transformerFactoryClass"; //$NON-NLS-1$
+
+	private DebuggerRegistry registry;
+
+	@Override
+	protected boolean readElement(IConfigurationElement element)
+	{
+		if (!element.getName().equals(TAG_DEBUGGER))
+			return false;
+
+		String id = element.getAttribute(ATT_ID);
+		if (id == null)
+		{
+			logMissingAttribute(element, ATT_ID);
+			return true;
+		}
+
+		String className = element.getAttribute(ATT_CLASSNAME);
+		if (className == null)
+		{
+			logMissingAttribute(element, ATT_CLASSNAME);
+			return true;
+		}
+
+		String classpath = element.getAttribute(ATT_CLASSPATH);
+		if (classpath == null)
+		{
+			logMissingAttribute(element, ATT_CLASSPATH);
+			return true;
+		}
+
+		String[] entries = classpath.split(";"); //$NON-NLS-1$
+		for (int i = 0; i < entries.length; i++)
+		{
+			String string = entries[i];
+			entries[i] = string.trim();
+		}
+
+		String name = element.getAttribute(ATT_NAME);
+		if (name == null)
+		{
+			logMissingAttribute(element, ATT_NAME);
+			return true;
+		}
+
+		String processorTypeId = element.getAttribute(ATT_PROCESSOR_TYPE_ID);
+		if (processorTypeId == null)
+		{
+			logMissingAttribute(element, ATT_PROCESSOR_TYPE_ID);
+			return true;
+		}
+		String tFact = element.getAttribute(ATT_TRANSFORMER_FACTORY);
+
+		registry.addDebugger(new DebuggerDescriptor(id, element.getContributor().getName(), className, entries, name, processorTypeId, tFact));
+
+		return true;
+	}
+
+	public void readElement(DebuggerRegistry registry, IConfigurationElement element)
+	{
+		this.registry = registry;
+		readElement(element);
+	}
+
+	public void addConfigs(DebuggerRegistry registry)
+	{
+		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+		this.registry = registry;
+		readRegistry(extensionRegistry, JAXPLaunchingPlugin.PLUGIN_ID, "debugger"); //$NON-NLS-1$
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/InvokerRegistry.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/InvokerRegistry.java
new file mode 100644
index 0000000..9a40916
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/InvokerRegistry.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorInvoker;
+
+public class InvokerRegistry
+{
+	private final Map<String, IProcessorInvoker> invokers = new HashMap<String, IProcessorInvoker>();
+
+	public InvokerRegistry()
+	{
+		InvokerRegistryReader registryReader = new InvokerRegistryReader();
+		registryReader.addConfigs(this);
+	}
+
+	public IProcessorInvoker getProcessorInvoker(String id)
+	{
+		return (IProcessorInvoker) invokers.get(id);
+	}
+
+	public IProcessorInvoker[] getProcessorInvokers()
+	{
+		return (IProcessorInvoker[]) invokers.values().toArray(new IProcessorInvoker[0]);
+	}
+
+	public void addInvokerDescriptor(IProcessorInvoker desc)
+	{
+		invokers.put(desc.getId(), desc);
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/InvokerRegistryReader.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/InvokerRegistryReader.java
new file mode 100644
index 0000000..b9e6137
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/InvokerRegistryReader.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+import org.eclipse.wst.xsl.jaxp.launching.internal.ProcessorInvokerDescriptor;
+
+public class InvokerRegistryReader extends AbstractRegistryReader
+{
+	public static final String TAG_INVOKE = "invoker"; //$NON-NLS-1$
+	public static final String ATT_ID = "id"; //$NON-NLS-1$
+	public static final String ATT_CLASS = "class"; //$NON-NLS-1$
+	public static final String ATT_CLASSPATH = "classpath"; //$NON-NLS-1$
+
+	private InvokerRegistry registry;
+
+	@Override
+	protected boolean readElement(IConfigurationElement element)
+	{
+		if (!element.getName().equals(TAG_INVOKE))
+			return false;
+
+		String id = element.getAttribute(ATT_ID);
+		if (id == null)
+		{
+			logMissingAttribute(element, ATT_ID);
+			return true;
+		}
+
+		String classname = element.getAttribute(ATT_CLASS);
+		if (classname == null)
+		{
+			logMissingAttribute(element, ATT_CLASS);
+			return true;
+		}
+
+		String classpath = element.getAttribute(ATT_CLASSPATH);
+		if (classpath == null)
+		{
+			logMissingAttribute(element, ATT_CLASSPATH);
+			return true;
+		}
+
+		String[] entries = classpath.split(";"); //$NON-NLS-1$
+		for (int i = 0; i < entries.length; i++)
+		{
+			String string = entries[i];
+			entries[i] = string.trim();
+		}
+
+		registry.addInvokerDescriptor(new ProcessorInvokerDescriptor(id, element.getContributor().getName(), classname, entries));
+
+		return true;
+	}
+
+	public void readElement(InvokerRegistry registry, IConfigurationElement element)
+	{
+		this.registry = registry;
+		readElement(element);
+	}
+
+	public void addConfigs(InvokerRegistry registry)
+	{
+		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+		this.registry = registry;
+		readRegistry(extensionRegistry, JAXPLaunchingPlugin.PLUGIN_ID, "invoke"); //$NON-NLS-1$
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/Messages.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/Messages.java
new file mode 100644
index 0000000..b8c8eb9
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/Messages.java
@@ -0,0 +1,22 @@
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+	private static final String BUNDLE_NAME = "org.eclipse.wst.xsl.jaxp.launching.internal.registry.messages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+			.getBundle(BUNDLE_NAME);
+
+	private Messages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorRegistry.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorRegistry.java
new file mode 100644
index 0000000..1a7ee25
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorRegistry.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorInstall;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorJar;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPRuntime;
+import org.eclipse.wst.xsl.jaxp.launching.ProcessorInstall;
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+import org.eclipse.wst.xsl.jaxp.launching.internal.ProcessorPreferences;
+
+public class ProcessorRegistry
+{
+	private final List<ProcessorInstall> contributedInstalls = new ArrayList<ProcessorInstall>();
+	private List<IProcessorInstall> userInstalls = new ArrayList<IProcessorInstall>();
+	private IProcessorInstall defaultProcessor;
+	private IProcessorInstall jreDefaultProcessor;
+	private IProcessorInstall[] installs;
+
+	public ProcessorRegistry()
+	{
+		initializeFromStorage();
+	}
+
+	private void initializeFromStorage()
+	{
+		// read from the registry
+		ProcessorRegistryReader registryReader = new ProcessorRegistryReader();
+		registryReader.addConfigs(this);
+		// find the jre default
+		for (Iterator<ProcessorInstall> iter = contributedInstalls.iterator(); iter.hasNext();)
+		{
+			IProcessorInstall install = (IProcessorInstall) iter.next();
+			if (install.getId().equals(JAXPRuntime.JRE_DEFAULT_PROCESSOR_ID))
+			{
+				jreDefaultProcessor = install;
+				break;
+			}
+		}
+		// read from the preferences
+		addPersistedVMs();
+	}
+
+	private void addPersistedVMs()
+	{
+		// Try retrieving the VM preferences from the preference store
+		String vmXMLString = JAXPLaunchingPlugin.getDefault().getPluginPreferences().getString(JAXPRuntime.PREF_PROCESSOR_XML);
+
+		// If the preference was found, load VMs from it into memory
+		if (vmXMLString.length() > 0)
+		{
+			try
+			{
+				ByteArrayInputStream inputStream = new ByteArrayInputStream(vmXMLString.getBytes());
+				ProcessorPreferences prefs = ProcessorPreferences.fromXML(inputStream);
+				String defaultProcessorId = prefs.getDefaultProcessorId();
+				userInstalls = prefs.getProcessors();
+				for (Iterator<IProcessorInstall> iter = userInstalls.iterator(); iter.hasNext();)
+				{
+					IProcessorInstall install = (IProcessorInstall) iter.next();
+					if (install.getId().equals(defaultProcessorId))
+					{
+						defaultProcessor = install;
+					}
+				}
+				if (defaultProcessor == null)
+				{
+					for (Iterator<ProcessorInstall> iter = contributedInstalls.iterator(); iter.hasNext();)
+					{
+						IProcessorInstall install = (IProcessorInstall) iter.next();
+						if (defaultProcessor == null && install.getId().equals(defaultProcessorId))
+						{
+							defaultProcessor = install;
+						}
+					}
+				}
+			}
+			catch (CoreException e)
+			{
+				JAXPLaunchingPlugin.log(e);
+			}
+		}
+		// make the JRE the default default
+		if (defaultProcessor == null)
+		{
+			defaultProcessor = jreDefaultProcessor;
+		}
+	}
+
+	public void addProcessor(String bundleId, String id, String label, String processorTypeId, String classpath, String debuggerId, String supports)
+	{
+		IProcessorJar[] jars = ProcessorInstall.createJars(bundleId, classpath);
+		contributedInstalls.add(new ProcessorInstall(id, label, processorTypeId, jars, debuggerId, supports, true));
+	}
+
+	public void addProcessor(IProcessorInstall install)
+	{
+		if (!install.isContributed())
+			userInstalls.add(install);
+		IProcessorInstall[] newinstalls = new IProcessorInstall[installs.length + 1];
+		System.arraycopy(installs, 0, newinstalls, 0, installs.length);
+		newinstalls[installs.length] = install;
+		installs = newinstalls;
+	}
+
+	public void removeProcessor(int index)
+	{
+		IProcessorInstall removed = installs[index];
+		if (!removed.isContributed())
+			userInstalls.remove(removed);
+		IProcessorInstall[] newinstalls = new IProcessorInstall[installs.length - 1];
+		System.arraycopy(installs, 0, newinstalls, 0, index);
+		System.arraycopy(installs, index + 1, newinstalls, index, newinstalls.length - index);
+		installs = newinstalls;
+	}
+
+	public IProcessorInstall[] getProcessors()
+	{
+		if (installs == null)
+		{
+			installs = new IProcessorInstall[contributedInstalls.size() + userInstalls.size()];
+			int startIndex = 0;
+			for (int i = 0; i < contributedInstalls.size(); i++)
+			{
+				installs[i] = (IProcessorInstall) contributedInstalls.get(i);
+				startIndex = i + 1;
+			}
+			for (int i = 0; i < userInstalls.size(); i++)
+			{
+				installs[startIndex + i] = (IProcessorInstall) userInstalls.get(i);
+			}
+		}
+		return installs;
+	}
+
+	public IProcessorInstall[] getProcessors(String id)
+	{
+		IProcessorInstall[] installs = getProcessors();
+		List<IProcessorInstall> result = new ArrayList<IProcessorInstall>();
+		for (IProcessorInstall type : installs)
+		{
+			if (type.getProcessorType().getId().equals(id))
+				result.add(type);
+		}
+		return (IProcessorInstall[]) result.toArray(new IProcessorInstall[0]);
+	}
+
+	public void setDefaultProcessor(IProcessorInstall defaultInstall)
+	{
+		defaultProcessor = defaultInstall;
+	}
+
+	public IProcessorInstall getDefaultProcessor()
+	{
+		return defaultProcessor;
+	}
+
+	public IProcessorInstall getJREDefaultProcessor()
+	{
+		return jreDefaultProcessor;
+	}
+
+	public IProcessorInstall[] getContributedProcessors()
+	{
+		return (IProcessorInstall[]) contributedInstalls.toArray(new IProcessorInstall[0]);
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorRegistryReader.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorRegistryReader.java
new file mode 100644
index 0000000..1be3d31
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorRegistryReader.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+
+public class ProcessorRegistryReader extends AbstractRegistryReader
+{
+	public static final String TAG_processor = "processor"; //$NON-NLS-1$
+	public static final String ATT_ID = "id"; //$NON-NLS-1$
+	public static final String ATT_LABEL = "label"; //$NON-NLS-1$
+	public static final String ATT_TYPE_ID = "processorTypeId"; //$NON-NLS-1$
+	public static final String ATT_DEBUGGER_ID = "debuggerId"; //$NON-NLS-1$
+	public static final String ATT_CLASSPATH = "classpath"; //$NON-NLS-1$
+	public static final String ATT_SUPPORTS = "supports"; //$NON-NLS-1$
+
+	private ProcessorRegistry registry;
+
+	@Override
+	protected boolean readElement(IConfigurationElement element)
+	{
+		if (!element.getName().equals(TAG_processor))
+			return false;
+
+		String id = element.getAttribute(ATT_ID);
+		if (id == null)
+		{
+			logMissingAttribute(element, ATT_ID);
+			return true;
+		}
+
+		String label = element.getAttribute(ATT_LABEL);
+		if (label == null)
+		{
+			logMissingAttribute(element, ATT_LABEL);
+			return true;
+		}
+
+		String processorTypeId = element.getAttribute(ATT_TYPE_ID);
+		if (processorTypeId == null)
+		{
+			logMissingAttribute(element, ATT_TYPE_ID);
+			return true;
+		}
+
+		String classpath = element.getAttribute(ATT_CLASSPATH);
+		if (classpath == null)
+		{
+			logMissingAttribute(element, ATT_CLASSPATH);
+			return true;
+		}
+
+		String debuggerId = element.getAttribute(ATT_DEBUGGER_ID);
+
+		String supports = element.getAttribute(ATT_SUPPORTS);
+		if (classpath == null)
+		{
+			logMissingAttribute(element, ATT_SUPPORTS);
+			return true;
+		}
+
+		registry.addProcessor(element.getContributor().getName(), id, label, processorTypeId, classpath, debuggerId, supports);
+
+		return true;
+	}
+
+	public void readElement(ProcessorRegistry registry, IConfigurationElement element)
+	{
+		this.registry = registry;
+		readElement(element);
+	}
+
+	public void addConfigs(ProcessorRegistry registry)
+	{
+		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+		this.registry = registry;
+		readRegistry(extensionRegistry, JAXPLaunchingPlugin.PLUGIN_ID, "processor"); //$NON-NLS-1$
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorTypeRegistry.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorTypeRegistry.java
new file mode 100644
index 0000000..1e3e520
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorTypeRegistry.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import java.io.ByteArrayInputStream;
+import java.net.URL;
+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.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xsl.jaxp.launching.IProcessorType;
+import org.eclipse.wst.xsl.jaxp.launching.ITransformerFactory;
+import org.eclipse.wst.xsl.jaxp.launching.JAXPRuntime;
+import org.eclipse.wst.xsl.jaxp.launching.internal.FeaturePreferences;
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+import org.eclipse.wst.xsl.jaxp.launching.internal.OutputPropertyPreferences;
+import org.eclipse.wst.xsl.jaxp.launching.internal.ProcessorType;
+import org.eclipse.wst.xsl.jaxp.launching.internal.TransformerFactory;
+
+public class ProcessorTypeRegistry
+{
+	protected static final String DESC_SUFFIX = ".DESC"; //$NON-NLS-1$
+	protected static final String TYPE_SUFFIX = ".TYPE"; //$NON-NLS-1$
+
+	private final List<IConfigurationElement> elements = new ArrayList<IConfigurationElement>();
+	private IProcessorType[] installTypes;
+
+	public ProcessorTypeRegistry()
+	{
+		ProcessorTypeRegistryReader registryReader = new ProcessorTypeRegistryReader();
+		registryReader.addConfigs(this);
+	}
+
+	public IProcessorType[] getProcessorTypes()
+	{
+		if (installTypes == null)
+		{
+			List<ProcessorType> types = new ArrayList<ProcessorType>();
+			String featureXMLString = JAXPLaunchingPlugin.getDefault().getPluginPreferences().getString(JAXPRuntime.PREF_FEATURE_XML);
+			// If the preference was found, load VMs from it into memory
+			FeaturePreferences prefs = null;
+			if (featureXMLString.length() > 0)
+			{
+				try
+				{
+					ByteArrayInputStream inputStream = new ByteArrayInputStream(featureXMLString.getBytes());
+					prefs = FeaturePreferences.fromXML(inputStream);
+				}
+				catch (CoreException e)
+				{
+					JAXPLaunchingPlugin.log(e);
+				}
+			}
+
+			String propXMLString = JAXPLaunchingPlugin.getDefault().getPluginPreferences().getString(JAXPRuntime.PREF_OUTPUT_PROPERTIES_XML);
+			// If the preference was found, load VMs from it into memory
+			OutputPropertyPreferences outputprefs = null;
+			if (propXMLString.length() > 0)
+			{
+				try
+				{
+					ByteArrayInputStream inputStream = new ByteArrayInputStream(propXMLString.getBytes());
+					outputprefs = OutputPropertyPreferences.fromXML(inputStream);
+				}
+				catch (CoreException e)
+				{
+					JAXPLaunchingPlugin.log(e);
+				}
+			}
+
+			for (Iterator<IConfigurationElement> iter = elements.iterator(); iter.hasNext();)
+			{
+				IConfigurationElement element = (IConfigurationElement) iter.next();
+				String id = element.getAttribute(ProcessorTypeRegistryReader.ATT_ID);
+				String label = element.getAttribute(ProcessorTypeRegistryReader.ATT_LABEL);
+				Map<String, String> featureValues = new HashMap<String, String>();
+				Map<String, String> propertyValues = new HashMap<String, String>();
+				if (prefs != null && prefs.getFeaturesValues(id) != null)
+					featureValues.putAll(prefs.getFeaturesValues(id));
+				if (outputprefs != null && outputprefs.getOutputPropertyValues(id) != null)
+					propertyValues.putAll(outputprefs.getOutputPropertyValues(id));
+
+				String outputProperties = element.getAttribute(ProcessorTypeRegistryReader.ATT_OUTPUT_PROPERTIES);
+				URL outputPropertiesURL = FileLocator.find(Platform.getBundle(element.getContributor().getName()), new Path(outputProperties), null);
+				String featureProperties = element.getAttribute(ProcessorTypeRegistryReader.ATT_ATTRIBUTE_PROPERTIES);
+				URL featurePropertiesURL = FileLocator.find(Platform.getBundle(element.getContributor().getName()), new Path(featureProperties), null);
+				
+				List<ITransformerFactory> transFactoryList = new ArrayList<ITransformerFactory>();
+				IConfigurationElement[] transFactEls = element.getChildren(ProcessorTypeRegistryReader.EL_TRANSFORMER_FACTORY);
+				for (IConfigurationElement transFactEl : transFactEls)
+				{
+					String transFactoryName = transFactEl.getAttribute(ProcessorTypeRegistryReader.ATT_TRANSFORMER_FACTORY_NAME);
+					String transFactoryClass = transFactEl.getAttribute(ProcessorTypeRegistryReader.ATT_TRANSFORMER_FACTORY_CLASS);
+					transFactoryList.add(new TransformerFactory(transFactoryName,transFactoryClass));
+				}
+				
+				types.add(new ProcessorType(id, label, featurePropertiesURL, outputPropertiesURL, featureValues, propertyValues, transFactoryList.toArray(new ITransformerFactory[0])));
+			}
+			installTypes = types.toArray(new IProcessorType[0]);
+		}
+		return installTypes;
+	}
+
+	public IProcessorType[] getProcessorTypesExclJREDefault()
+	{
+		IProcessorType[] installTypes = getProcessorTypes();
+		List<IProcessorType> exclTypes = new ArrayList<IProcessorType>(installTypes.length - 1);
+		for (IProcessorType type : installTypes)
+		{
+			if (!type.isJREDefault())
+				exclTypes.add(type);
+		}
+		return (IProcessorType[]) exclTypes.toArray(new IProcessorType[0]);
+	}
+
+	public void addType(IConfigurationElement element)
+	{
+		elements.add(element);
+	}
+
+	public IProcessorType getProcessorType(String id)
+	{
+		IProcessorType[] installTypes = getProcessorTypes();
+		for (IProcessorType type : installTypes)
+		{
+			if (type.getId().equals(id))
+				return type;
+		}
+		return null;
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorTypeRegistryReader.java b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorTypeRegistryReader.java
new file mode 100644
index 0000000..201e2f6
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/ProcessorTypeRegistryReader.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.jaxp.launching.internal.registry;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.xsl.jaxp.launching.internal.JAXPLaunchingPlugin;
+
+public class ProcessorTypeRegistryReader extends AbstractRegistryReader
+{
+	public static final String TAG_processorType = "processorType"; //$NON-NLS-1$
+	public static final String ATT_ID = "id"; //$NON-NLS-1$
+	public static final String ATT_LABEL = "label"; //$NON-NLS-1$
+	public static final String ATT_OUTPUT_PROPERTIES = "outputProperties"; //$NON-NLS-1$
+	public static final String ATT_ATTRIBUTE_PROPERTIES = "attributeProperties"; //$NON-NLS-1$
+	public static final String EL_TRANSFORMER_FACTORY = "transformerFactory";
+	public static final String ATT_TRANSFORMER_FACTORY_NAME = "name";
+	public static final String ATT_TRANSFORMER_FACTORY_CLASS = "factoryClass";
+
+	private ProcessorTypeRegistry registry;
+
+	@Override
+	protected boolean readElement(IConfigurationElement element)
+	{
+		if (!element.getName().equals(TAG_processorType))
+			return false;
+
+		String id = element.getAttribute(ATT_ID);
+		if (id == null)
+		{
+			logMissingAttribute(element, ATT_ID);
+			return true;
+		}
+
+		String label = element.getAttribute(ATT_LABEL);
+		if (label == null)
+		{
+			logMissingAttribute(element, ATT_LABEL);
+			return true;
+		}
+
+		String outputProperties = element.getAttribute(ATT_OUTPUT_PROPERTIES);
+		if (outputProperties == null)
+		{
+			logMissingAttribute(element, ATT_OUTPUT_PROPERTIES);
+			return true;
+		}
+
+		String featureProperties = element.getAttribute(ATT_ATTRIBUTE_PROPERTIES);
+		if (featureProperties == null)
+		{
+			logMissingAttribute(element, ATT_ATTRIBUTE_PROPERTIES);
+			return true;
+		}
+
+		registry.addType(element);
+
+		return true;
+	}
+
+	public void readElement(ProcessorTypeRegistry registry, IConfigurationElement element)
+	{
+		this.registry = registry;
+		readElement(element);
+	}
+
+	protected void addConfigs(ProcessorTypeRegistry registry)
+	{
+		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+		this.registry = registry;
+		readRegistry(extensionRegistry, JAXPLaunchingPlugin.PLUGIN_ID, "processorType"); //$NON-NLS-1$
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/messages.properties b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/messages.properties
new file mode 100644
index 0000000..6a64057
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/registry/messages.properties
@@ -0,0 +1,6 @@
+AbstractRegistryReader.3=, extension 
+AbstractRegistryReader.5=Required attribute '
+AbstractRegistryReader.6=' not defined
+AbstractRegistryReader.7=Required sub element '
+AbstractRegistryReader.8=' not defined
+AbstractRegistryReader.9=Unknown extension tag found: 
diff --git a/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/messages.properties b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/messages.properties
new file mode 100644
index 0000000..5d604fa
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/messages.properties
@@ -0,0 +1,6 @@
+XSLTRuntime.10=Failed to save process preferences
+XSLTRuntime.5=Saving attributes...
+XSLTRuntime.6=Failed to save attribute preferences
+XSLTRuntime.7=Saving properties...
+XSLTRuntime.8=Failed to save output property preferences
+XSLTRuntime.9=Saving processors...