[182654] Separate preview server into own plugin
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/.classpath b/plugins/org.eclipse.jst.server.preview.adapter/.classpath
new file mode 100644
index 0000000..ce73933
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/.cvsignore b/plugins/org.eclipse.jst.server.preview.adapter/.cvsignore
new file mode 100644
index 0000000..c0cf45b
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/.cvsignore
@@ -0,0 +1,8 @@
+bin
+build.xml
+org.eclipse.jst.server.core_3.0.0.jar
+sjavacore.jar
+temp.folder
+@dot
+src.zip
+javaCompiler...args
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/.options b/plugins/org.eclipse.jst.server.preview.adapter/.options
new file mode 100644
index 0000000..c0ef0b3
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/.options
@@ -0,0 +1,7 @@
+# Debugging options for the org.eclipse.jst.server.core plugin
+
+# Turn on general debugging
+org.eclipse.jst.server.core/debug=true
+
+# Turn on general debugging
+org.eclipse.jst.server.core/publishing=false
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/.project b/plugins/org.eclipse.jst.server.preview.adapter/.project
new file mode 100644
index 0000000..1e67cda
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jst.server.preview.adapter</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..c8be432
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Fri Nov 10 17:11:35 HST 2006
+eclipse.preferences.version=1
+encoding/<project>=ISO-8859-1
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..267ae57
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,74 @@
+#Fri Feb 23 21:15:39 EST 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=error
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,*.testsuite,*.deploy,*.location,*.execution,*.datapool,*.artifact,*.html,*.svg
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=disabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=1000
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=error
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.4
+org.eclipse.jdt.core.incompatibleJDKLevel=warning
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..c39847e
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,3 @@
+#Fri Feb 23 21:15:38 EST 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?>\n<templates/>
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.pde.prefs b/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..08a60e5
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,14 @@
+#Sat Apr 22 18:36:14 EDT 2006
+compilers.incompatible-environment=0
+compilers.p.build=0
+compilers.p.deprecated=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/META-INF/MANIFEST.MF b/plugins/org.eclipse.jst.server.preview.adapter/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2a07162
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.jst.server.adapter.preview;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.jst.server.preview.internal.PreviewPlugin
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Export-Package: org.eclipse.jst.server.preview.internal;x-friends:="org.eclipse.jst.server.ui"
+Require-Bundle: org.eclipse.jdt.core;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.jdt.launching;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.wst.server.core;bundle-version="[1.0.103,1.1.0)",
+ org.eclipse.jst.server.core;bundle-version="[1.0.204,1.1.0)",
+ org.eclipse.jst.common.project.facet.core;bundle-version="[1.1,2.0.0)",
+ org.eclipse.debug.ui;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.wst.server.ui;bundle-version="[1.0.103,1.1.0)",
+ org.eclipse.wst.common.project.facet.ui;bundle-version="[1.1.0,1.3.0)",
+ org.eclipse.jdt.debug.ui;bundle-version="[3.2.100,4.0.0)"
+Eclipse-LazyStart: true
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/about.html b/plugins/org.eclipse.jst.server.preview.adapter/about.html
new file mode 100644
index 0000000..4ec5989
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/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>May 2, 2006</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/plugins/org.eclipse.jst.server.preview.adapter/build.properties b/plugins/org.eclipse.jst.server.preview.adapter/build.properties
new file mode 100644
index 0000000..ac83d71
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/build.properties
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = plugin.xml,\
+               plugin.properties,\
+               .,\
+               META-INF/,\
+               about.html
+bin.excludes = bin/**,\
+               @dot/**,\
+               temp.folder/**
+source.. = src/
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/icons/obj16/preview.gif b/plugins/org.eclipse.jst.server.preview.adapter/icons/obj16/preview.gif
new file mode 100644
index 0000000..b51ae39
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/icons/obj16/preview.gif
Binary files differ
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/plugin.properties b/plugins/org.eclipse.jst.server.preview.adapter/plugin.properties
new file mode 100644
index 0000000..7740776
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/plugin.properties
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+pluginName=JEE Preview Server Support
+providerName=Eclipse.org
+
+previewRuntimeTypeName=J2EE Preview
+previewRuntimeTypeDescription=A runtime for building J2EE web modules.
+
+previewServerTypeName=J2EE Preview
+previewServerTypeDescription=A server to preview J2EE web modules.
+
+previewLaunchConfigurationType=J2EE Preview
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/plugin.xml b/plugins/org.eclipse.jst.server.preview.adapter/plugin.xml
new file mode 100644
index 0000000..fdbd6e0
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/plugin.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<plugin>
+  <extension point="org.eclipse.wst.server.core.runtimeTypes">
+    <runtimeType
+       id="org.eclipse.jst.server.preview.runtime"
+       name="%previewRuntimeTypeName"
+       description="%previewRuntimeTypeDescription"
+       class="org.eclipse.jst.server.preview.internal.core.PreviewRuntime">
+       <moduleType
+         types="wst.web"
+         versions="1.0"/>
+       <moduleType
+         types="jst.web"
+         versions="2.2,2.3,2.4,2.5"/>
+       <moduleType
+         types="jst.utility"
+         versions="1.0"/>
+    </runtimeType>
+  </extension>
+
+  <extension point="org.eclipse.wst.server.core.serverTypes">
+     <serverType
+       id="org.eclipse.jst.server.preview.server"
+       name="%previewServerTypeName"
+       description="%previewServerTypeDescription"
+       supportsRemoteHosts="false"
+       runtime="true"
+       initialState="stopped"
+       hasConfiguration="false"
+       launchModes="run,debug,profile"
+       launchConfigId="org.eclipse.jst.server.core.preview.launchConfigurationType"
+       runtimeTypeId="org.eclipse.jst.server.preview.runtime"
+       class="org.eclipse.jst.server.preview.internal.core.PreviewServer"
+       behaviourClass="org.eclipse.jst.server.preview.internal.core.PreviewServerBehaviour"/>
+  </extension>
+ 
+  <extension point="org.eclipse.jst.server.core.runtimeClasspathProviders">
+    <runtimeClasspathProvider
+      id="org.eclipse.jst.server.preview.runtimeTarget"
+      runtimeTypeIds="org.eclipse.jst.server.preview.runtime"
+      class="org.eclipse.jst.server.preview.internal.core.PreviewRuntimeClasspathProvider"/>
+  </extension>
+
+  <extension point="org.eclipse.wst.common.project.facet.core.runtimes">
+    <runtime-component-type
+       id="org.eclipse.jst.server.preview.runtime"/>
+
+    <runtime-component-version
+       type="org.eclipse.jst.server.preview.runtime"
+       version="1.0"/>
+
+    <adapter>
+      <runtime-component
+         id="org.eclipse.jst.server.preview.runtime"/>
+      <factory
+         class="org.eclipse.jst.server.core.internal.RuntimeClasspathProvider$Factory"/>
+      <type
+         class="org.eclipse.jst.common.project.facet.core.IClasspathProvider"/>
+    </adapter>
+
+    <supported>
+      <runtime-component
+         id="org.eclipse.jst.server.preview.runtime"
+         version="1.0"/>
+      <facet
+         id="wst.web"
+         version="1.0"/>
+      <facet
+         id="jst.web"
+         version="2.2,2.3,2.4,2.5"/>
+      <facet
+         id="jst.utility"
+         version="1.0"/>
+    </supported>
+  </extension>
+
+  <extension point="org.eclipse.jst.server.core.runtimeFacetMappings">
+    <runtimeFacetMapping
+      runtimeTypeId="org.eclipse.jst.server.preview.runtime"
+      runtime-component="org.eclipse.jst.server.preview.runtime"
+      version="1.0"/>
+  </extension>
+
+  <extension point="org.eclipse.debug.core.sourcePathComputers">
+     <sourcePathComputer
+        id="org.eclipse.jst.server.preview.sourcePathComputer"
+        class="org.eclipse.jst.server.preview.internal.core.PreviewSourcePathComputerDelegate"/>
+  </extension>
+
+  <extension point="org.eclipse.debug.core.launchConfigurationTypes">
+     <launchConfigurationType
+        id="org.eclipse.jst.server.preview.launchConfigurationType"
+        name="%previewLaunchConfigurationType"
+        delegate="org.eclipse.jst.server.preview.internal.core.PreviewLaunchConfigurationDelegate"
+        modes="run,debug,profile"
+        sourceLocatorId="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"
+        sourcePathComputerId="org.eclipse.jst.server.preview.sourcePathComputer"/>
+  </extension>
+
+  <extension point="org.eclipse.wst.server.core.launchableAdapters">
+    <launchableAdapter
+      id="org.eclipse.jst.server.preview"
+      class="org.eclipse.jst.server.preview.internal.core.PreviewLaunchableAdapterDelegate"/>
+  </extension>
+
+<!--
+<extension point="org.eclipse.wst.server.core.internalStartup">
+  <startup
+    id="org.eclipse.jst.server.core.startup"
+    class="org.eclipse.jst.server.core.internal.preview.PreviewStartup"/>
+</extension>
+-->
+
+
+  <extension point="org.eclipse.wst.server.ui.serverImages">
+     <image
+        id="org.eclipse.jst.server.preview"
+        typeIds="org.eclipse.jst.server.preview.runtime,org.eclipse.jst.server.preview.server"
+        icon="icons/obj16/preview.gif"/>
+  </extension>
+
+  <extension point="org.eclipse.wst.common.project.facet.ui.images">
+    <image runtime-component-type="org.eclipse.jst.server.preview.runtime"
+       path="icons/obj16/preview.gif"/>
+  </extension>
+
+  <extension point="org.eclipse.wst.common.project.facet.core.runtimes">
+    <adapter>
+      <runtime-component id="org.eclipse.jst.server.preview.runtime"/>
+      <factory class="org.eclipse.wst.server.ui.internal.facets.RuntimeLabelProvider$Factory"/>
+      <type class="org.eclipse.wst.common.project.facet.ui.IRuntimeComponentLabelProvider"/>
+    </adapter>
+  </extension>
+  
+  <extension point="org.eclipse.debug.ui.launchConfigurationTypeImages">
+    <launchConfigurationTypeImage
+      id="org.eclipse.jst.server.preview.launchConfigurationTypeImage"
+      configTypeID="org.eclipse.jst.server.preview.launchConfigurationType"
+      icon="icons/obj16/preview.gif">
+    </launchConfigurationTypeImage>
+  </extension>
+
+  <extension point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+    <launchConfigurationTabGroup
+      id="org.eclipse.jst.server.preview.launchConfigurationTabGroup"
+      type="org.eclipse.jst.server.preview.launchConfigurationType"
+      class="org.eclipse.jst.server.preview.internal.ui.PreviewLaunchConfigurationTabGroup">
+    </launchConfigurationTabGroup>
+  </extension>
+</plugin>
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/IMemento.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/IMemento.java
new file mode 100644
index 0000000..b4d862b
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/IMemento.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal;
+
+import java.util.List;
+/**
+ * Interface to a memento used for saving the important state of an object
+ * in a form that can be persisted in the file system.
+ * <p>
+ * Mementos were designed with the following requirements in mind:
+ * <ol>
+ *  <li>Certain objects need to be saved and restored across platform sessions.
+ *    </li>
+ *  <li>When an object is restored, an appropriate class for an object might not
+ *    be available. It must be possible to skip an object in this case.</li>
+ *  <li>When an object is restored, the appropriate class for the object may be
+ *    different from the one when the object was originally saved. If so, the
+ *    new class should still be able to read the old form of the data.</li>
+ * </ol>
+ * </p>
+ * <p>
+ * Mementos meet these requirements by providing support for storing a
+ * mapping of arbitrary string keys to primitive values, and by allowing
+ * mementos to have other mementos as children (arranged into a tree).
+ * A robust external storage format based on XML is used.
+ * </p><p>
+ * The key for an attribute may be any alpha numeric value.  However, the
+ * value of <code>TAG_ID</code> is reserved for internal use.
+ * </p><p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IMemento {
+	/**
+	 * Special reserved key used to store the memento id 
+	 * (value <code>"org.eclipse.ui.id"</code>).
+	 *
+	 * @see #getId
+	 */
+	public static final String TAG_ID = "IMemento.internal.id"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new child of this memento with the given type.
+	 * <p>
+	 * The <code>getChild</code> and <code>getChildren</code> methods
+	 * are used to retrieve children of a given type.
+	 * </p>
+	 *
+	 * @param type the type
+	 * @return a new child memento
+	 * @see #getChild
+	 * @see #getChildren
+	 */
+	public IMemento createChild(String type);
+	
+	/**
+	 * Creates a new child of this memento with the given type and id.
+	 * The id is stored in the child memento (using a special reserved
+	 * key, <code>TAG_ID</code>) and can be retrieved using <code>getId</code>.
+	 * <p>
+	 * The <code>getChild</code> and <code>getChildren</code> methods
+	 * are used to retrieve children of a given type.
+	 * </p>
+	 *
+	 * @param type the type
+	 * @param id the child id
+	 * @return a new child memento with the given type and id
+	 * @see #getId
+	 */
+	public IMemento createChild(String type, String id);
+	
+	/**
+	 * Returns the first child with the given type id.
+	 *
+	 * @param type the type id
+	 * @return the first child with the given type
+	 */
+	public IMemento getChild(String type);
+	
+	/**
+	 * Returns all children with the given type id.
+	 *
+	 * @param type the type id
+	 * @return the list of children with the given type
+	 */
+	public IMemento[] getChildren(String type);
+	
+	/**
+	 * Returns the floating point value of the given key.
+	 *
+	 * @param key the key
+	 * @return the value, or <code>null</code> if the key was not found or was found
+	 *   but was not a floating point number
+	 */
+	public Float getFloat(String key);
+	
+	/**
+	 * Returns the id for this memento.
+	 *
+	 * @return the memento id, or <code>null</code> if none
+	 * @see #createChild(java.lang.String,java.lang.String)
+	 */
+	public String getId();
+	
+	/**
+	 * Returns the name for this memento.
+	 *
+	 * @return the memento name, or <code>null</code> if none
+	 * @see #createChild(java.lang.String,java.lang.String)
+	 */
+	public String getName();
+
+	/**
+	 * Returns the integer value of the given key.
+	 *
+	 * @param key the key
+	 * @return the value, or <code>null</code> if the key was not found or was found
+	 *   but was not an integer
+	 */
+	public Integer getInteger(String key);
+
+	/**
+	 * Returns the string value of the given key.
+	 *
+	 * @param key the key
+	 * @return the value, or <code>null</code> if the key was not found or was found
+	 *  but was not an integer
+	 */
+	public String getString(String key);
+
+	/**
+	 * Returns the boolean value of the given key.
+	 *
+	 * @param key the key
+	 * @return the value, or <code>null</code> if the key was not found or was found
+	 *  but was not a boolean
+	 */
+	public Boolean getBoolean(String key);
+	
+	/**
+	 * Return the list of names.
+	 * 
+	 * @return a possibly empty list of names
+	 */
+	public List getNames();
+	
+	/**
+	 * Sets the value of the given key to the given floating point number.
+	 *
+	 * @param key the key
+	 * @param value the value
+	 */
+	public void putFloat(String key, float value);
+	
+	/**
+	 * Sets the value of the given key to the given integer.
+	 *
+	 * @param key the key
+	 * @param value the value
+	 */
+	public void putInteger(String key, int value);
+	
+	/**
+	 * Sets the value of the given key to the given boolean value.
+	 *
+	 * @param key the key
+	 * @param value the value
+	 */
+	public void putBoolean(String key, boolean value);
+
+	/**
+	 * Copy the attributes and children from  <code>memento</code>
+	 * to the receiver.
+	 *
+	 * @param memento the IMemento to be copied.
+	 */
+	public void putMemento(IMemento memento);
+
+	/**
+	 * Sets the value of the given key to the given string.
+	 *
+	 * @param key the key
+	 * @param value the value
+	 */
+	public void putString(String key, String value);
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/Messages.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/Messages.java
new file mode 100644
index 0000000..29b071a
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/Messages.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal;
+
+import org.eclipse.osgi.util.NLS;
+/**
+ * Translated messages.
+ */
+public class Messages extends NLS {
+	public static String errorLocation;
+	public static String errorJRE;
+	public static String classpathContainerDescription;
+	public static String classpathContainer;
+	public static String classpathContainerUnbound;
+
+	public static String copyingTask;
+	public static String deletingTask;
+	public static String errorCopyingFile;
+	public static String errorCreatingZipFile;
+	public static String errorDelete;
+	public static String errorRename;
+	public static String errorReading;
+	public static String updateClasspathContainers;
+	public static String errorNoRuntime;
+	public static String errorFacet;
+	public static String errorDeleting;
+	public static String errorNotADirectory;
+	public static String errorMkdir;
+
+	public static String artifactServlet;
+	public static String artifactEJB;
+	public static String artifactJNDI;
+	public static String artifactCactusTest;
+
+	public static String canModifyModules;
+	public static String errorNoProfiler;
+	public static String errorPublish;
+	public static String httpPort;
+	public static String errorPortInUse;
+
+	static {
+		NLS.initializeMessages(PreviewPlugin.PLUGIN_ID + ".internal.Messages", Messages.class);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/Messages.properties b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/Messages.properties
new file mode 100644
index 0000000..76c6ce4
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/Messages.properties
@@ -0,0 +1,44 @@
+###############################################################################
+# Copyright (c) 2004, 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+classpathContainerDescription=Server Library
+classpathContainer={0} [{1}]
+classpathContainerUnbound={0} [{1}] (unbound)
+
+errorLocation=Invalid location.
+errorJRE=Invalid JRE.
+
+copyingTask=Copying from {0} to {1}
+deletingTask=Deleting {0}
+errorCopyingFile=Error copying file {0}: {1}
+errorCreatingZipFile=Error creating zip file {0}: {1}
+errorDelete=Could not delete previous copy, which may be locked by another process.
+errorRename=Could not replace with temp file {0}.
+errorReading=Error reading file {0}
+errorNoRuntime=Cannot verify facets because there is no runtime associated with the server.
+errorFacet=Project facet {0} version {1} is not supported.
+errorDeleting=Could not delete {0}. May be locked by another process.
+errorNotADirectory=Could not delete {0} since it is not a directory.
+errorMkdir=Could not create directory {0}.
+
+updateClasspathContainers=Updating classpath container for {0}
+
+artifactServlet=Servlet {0}
+artifactEJB=EJB {0}
+artifactJNDI=JNDI {0}
+artifactCactusTest=Cactus test {0}
+
+canModifyModules=Web module can be added to the server.
+errorNoProfiler=Could not launch in profiling mode because no profilers are configured.
+errorPublish=An error occured during publishing.
+httpPort=HTTP Port
+errorPortInUse=Port {0} required by {1} is already in use. The server may already be running in another process, or a system process may be using the port. \
+  To start this server you will need to stop the other process or change the port number(s).
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/PreviewPlugin.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/PreviewPlugin.java
new file mode 100644
index 0000000..d374fa9
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/PreviewPlugin.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal;
+
+import org.eclipse.core.runtime.*;
+/**
+ * The main preview server tools plugin class.
+ */
+public class PreviewPlugin extends Plugin {
+	/**
+	 * Java server plugin id
+	 */
+	public static final String PLUGIN_ID = "org.eclipse.jst.server.preview.adapter";
+
+	// singleton instance of this class
+	private static PreviewPlugin singleton;
+
+	/**
+	 * Create the PreviewPlugin.
+	 */
+	public PreviewPlugin() {
+		super();
+		singleton = this;
+	}
+
+	/**
+	 * Returns the singleton instance of this plugin.
+	 *
+	 * @return a singleton instance
+	 */
+	public static PreviewPlugin getInstance() {
+		return singleton;
+	}
+
+	/**
+	 * Convenience method for logging.
+	 *
+	 * @param status a status
+	 */
+	private static void log(IStatus status) {
+		getInstance().getLog().log(status);
+	}
+
+	public static void logWarning(String msg) {
+		log(new Status(IStatus.WARNING, PLUGIN_ID, IStatus.OK, msg, null));
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/ProgressUtil.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/ProgressUtil.java
new file mode 100644
index 0000000..1dea57b
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/ProgressUtil.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal;
+
+import org.eclipse.core.runtime.*;
+/**
+ * Progress Monitor utility.
+ */
+public class ProgressUtil {
+	/**
+	 * ProgressUtil constructor comment.
+	 */
+	private ProgressUtil() {
+		super();
+	}
+
+	/**
+	 * Return a valid progress monitor.
+	 *
+	 * @param monitor org.eclipse.core.runtime.IProgressMonitor
+	 * @return org.eclipse.core.runtime.IProgressMonitor
+	 */
+	public static IProgressMonitor getMonitorFor(IProgressMonitor monitor) {
+		if (monitor == null)
+			return new NullProgressMonitor();
+		return monitor;
+	}
+
+	/**
+	 * Return a sub-progress monitor with the given amount on the
+	 * current progress monitor.
+	 *
+	 * @param monitor org.eclipse.core.runtime.IProgressMonitor
+	 * @param ticks int
+	 * @return org.eclipse.core.runtime.IProgressMonitor
+	 */
+	public static IProgressMonitor getSubMonitorFor(IProgressMonitor monitor, int ticks) {
+		if (monitor == null)
+			return new NullProgressMonitor();
+		if (monitor instanceof NullProgressMonitor)
+			return monitor;
+		return new SubProgressMonitor(monitor, ticks);
+	}
+
+	/**
+	 * Return a sub-progress monitor with the given amount on the
+	 * current progress monitor.
+	 *
+	 * @param monitor org.eclipse.core.runtime.IProgressMonitor
+	 * @param ticks a number of ticks
+	 * @param style a style
+	 * @return org.eclipse.core.runtime.IProgressMonitor
+	 */
+	public static IProgressMonitor getSubMonitorFor(IProgressMonitor monitor, int ticks, int style) {
+		if (monitor == null)
+			return new NullProgressMonitor();
+		if (monitor instanceof NullProgressMonitor)
+			return monitor;
+		return new SubProgressMonitor(monitor, ticks, style);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/Trace.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/Trace.java
new file mode 100644
index 0000000..96ea9b7
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/Trace.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal;
+/**
+ * Helper class to route trace output.
+ */
+public class Trace {
+	/**
+	 * Config tracing
+	 */
+	public static final byte CONFIG = 0;
+	/**
+	 * Warning tracing
+	 */
+	public static final byte WARNING = 1;
+	/**
+	 * Severe tracing
+	 */
+	public static final byte SEVERE = 2;
+	/**
+	 * Finest tracing
+	 */
+	public static final byte FINEST = 3;
+
+	public static final byte PUBLISHING = 4;
+
+	/**
+	 * Trace constructor comment.
+	 */
+	private Trace() {
+		super();
+	}
+
+	/**
+	 * Trace the given text.
+	 *
+	 * @param level trace level
+	 * @param s String
+	 */
+	public static void trace(byte level, String s) {
+		Trace.trace(level, s, null);
+	}
+
+	/**
+	 * Trace the given message and exception.
+	 *
+	 * @param level trace level
+	 * @param s String
+	 * @param t Throwable
+	 */
+	public static void trace(byte level, String s, Throwable t) {
+		if (!PreviewPlugin.getInstance().isDebugging())
+			return;
+		
+		System.out.println(PreviewPlugin.PLUGIN_ID + " " + s);
+		if (t != null)
+			t.printStackTrace();
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/XMLMemento.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/XMLMemento.java
new file mode 100644
index 0000000..dfbcd59
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/XMLMemento.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal;
+
+import java.io.*;
+import java.util.*;
+
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+/**
+ * A Memento is a class independent container for persistence
+ * info.  It is a reflection of 3 storage requirements.
+ *
+ * 1)   We need the ability to persist an object and restore it.  
+ * 2)   The class for an object may be absent.  If so we would 
+ *      like to skip the object and keep reading. 
+ * 3)   The class for an object may change.  If so the new class 
+ *      should be able to read the old persistence info.
+ *
+ * We could ask the objects to serialize themselves into an 
+ * ObjectOutputStream, DataOutputStream, or Hashtable.  However 
+ * all of these approaches fail to meet the second requirement.
+ *
+ * Memento supports binary persistance with a version ID.
+ */
+public final class XMLMemento implements IMemento {
+	private Document factory;
+	private Element element;
+
+	/**
+	 * Answer a memento for the document and element.  For simplicity
+	 * you should use createReadRoot and createWriteRoot to create the initial
+	 * mementos on a document.
+	 */
+	private XMLMemento(Document doc, Element el) {
+		factory = doc;
+		element = el;
+	}
+
+	/**
+	 * @see IMemento#createChild(String)
+	 */
+	public IMemento createChild(String type) {
+		Element child = factory.createElement(type);
+		element.appendChild(child);
+		return new XMLMemento(factory, child);
+	}
+
+	/**
+	 * @see IMemento#createChild(String, String)
+	 */
+	public IMemento createChild(String type, String id) {
+		Element child = factory.createElement(type);
+		child.setAttribute(TAG_ID, id);
+		element.appendChild(child);
+		return new XMLMemento(factory, child);
+	}
+
+	/**
+	 * Create a Document from a Reader and answer a root memento for reading 
+	 * a document.
+	 */
+	protected static XMLMemento createReadRoot(InputStream in) {
+		Document document = null;
+		try {
+			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+			DocumentBuilder parser = factory.newDocumentBuilder();
+			document = parser.parse(new InputSource(in));
+			Node node = document.getFirstChild();
+			if (node instanceof Element)
+				return new XMLMemento(document, (Element) node);
+		} catch (Exception e) {
+			// ignore
+		} finally {
+			try {
+				in.close();
+			} catch (Exception e) {
+				// ignore
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * Answer a root memento for writing a document.
+	 * 
+	 * @param type a type
+	 * @return a memento
+	 */
+	public static XMLMemento createWriteRoot(String type) {
+		Document document;
+		try {
+			document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+			Element element = document.createElement(type);
+			document.appendChild(element);
+			return new XMLMemento(document, element);            
+		} catch (ParserConfigurationException e) {
+			throw new Error(e);
+		}
+	}
+	
+	/*
+	 * @see IMemento
+	 */
+	public IMemento getChild(String type) {
+		// Get the nodes.
+		NodeList nodes = element.getChildNodes();
+		int size = nodes.getLength();
+		if (size == 0)
+			return null;
+	
+		// Find the first node which is a child of this node.
+		for (int nX = 0; nX < size; nX ++) {
+			Node node = nodes.item(nX);
+			if (node instanceof Element) {
+				Element element2 = (Element)node;
+				if (element2.getNodeName().equals(type))
+					return new XMLMemento(factory, element2);
+			}
+		}
+	
+		// A child was not found.
+		return null;
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public IMemento [] getChildren(String type) {
+		// Get the nodes.
+		NodeList nodes = element.getChildNodes();
+		int size = nodes.getLength();
+		if (size == 0)
+			return new IMemento[0];
+	
+		// Extract each node with given type.
+		ArrayList list = new ArrayList(size);
+		for (int nX = 0; nX < size; nX ++) {
+			Node node = nodes.item(nX);
+			if (node instanceof Element) {
+				Element element2 = (Element)node;
+				if (element2.getNodeName().equals(type))
+					list.add(element2);
+			}
+		}
+	
+		// Create a memento for each node.
+		size = list.size();
+		IMemento [] results = new IMemento[size];
+		for (int x = 0; x < size; x ++) {
+			results[x] = new XMLMemento(factory, (Element)list.get(x));
+		}
+		return results;
+	}
+
+	/**
+	 * Return the contents of this memento as a byte array.
+	 *
+	 * @return byte[]
+	 * @throws IOException if anything goes wrong
+	 */
+	public byte[] getContents() throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		save(out);
+		return out.toByteArray();
+	}
+
+	/**
+	 * Returns an input stream for writing to the disk with a local locale.
+	 *
+	 * @return java.io.InputStream
+	 * @throws IOException if anything goes wrong
+	 */
+	public InputStream getInputStream() throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		save(out);
+		return new ByteArrayInputStream(out.toByteArray());
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public Float getFloat(String key) {
+		Attr attr = element.getAttributeNode(key);
+		if (attr == null)
+			return null; 
+		String strValue = attr.getValue();
+		try {
+			return new Float(strValue);
+		} catch (NumberFormatException e) {
+			return null;
+		}
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public String getId() {
+		return element.getAttribute(TAG_ID);
+	}
+	
+	/*
+	 * @see IMemento
+	 */
+	public String getName() {
+		return element.getNodeName();
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public Integer getInteger(String key) {
+		Attr attr = element.getAttributeNode(key);
+		if (attr == null)
+			return null; 
+		String strValue = attr.getValue();
+		try {
+			return new Integer(strValue);
+		} catch (NumberFormatException e) {
+			return null;
+		}
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public String getString(String key) {
+		Attr attr = element.getAttributeNode(key);
+		if (attr == null)
+			return null; 
+		return attr.getValue();
+	}
+	
+	public List getNames() {
+		NamedNodeMap map = element.getAttributes();
+		int size = map.getLength();
+		List list = new ArrayList();
+		for (int i = 0; i < size; i++) {
+			Node node = map.item(i);
+			String name = node.getNodeName();
+			list.add(name);
+		}
+		return list;
+	}
+
+	/**
+	 * Loads a memento from the given filename.
+	 *
+	 * @param filename java.lang.String
+	 * @exception java.io.IOException
+	 * @return a memento
+	 */
+	public static IMemento loadMemento(String filename) throws IOException {
+		InputStream in = null;
+		try {
+			in = new BufferedInputStream(new FileInputStream(filename));
+			return XMLMemento.createReadRoot(in);
+		} finally {
+			try {
+				if (in != null)
+					in.close();
+			} catch (Exception e) {
+				// ignore
+			}
+		}
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	private void putElement(Element element2) {
+		NamedNodeMap nodeMap = element2.getAttributes();
+		int size = nodeMap.getLength();
+		for (int i = 0; i < size; i++){
+			Attr attr = (Attr)nodeMap.item(i);
+			putString(attr.getName(),attr.getValue());
+		}
+		
+		NodeList nodes = element2.getChildNodes();
+		size = nodes.getLength();
+		for (int i = 0; i < size; i ++) {
+			Node node = nodes.item(i);
+			if (node instanceof Element) {
+				XMLMemento child = (XMLMemento)createChild(node.getNodeName());
+				child.putElement((Element)node);
+			}
+		}
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public void putFloat(String key, float f) {
+		element.setAttribute(key, String.valueOf(f));
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public void putInteger(String key, int n) {
+		element.setAttribute(key, String.valueOf(n));
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public void putMemento(IMemento memento) {
+		XMLMemento xmlMemento = (XMLMemento) memento;
+		putElement(xmlMemento.element);
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public void putString(String key, String value) {
+		if (value == null)
+			return;
+		element.setAttribute(key, value);
+	}
+	
+	/**
+	 * Save this Memento to a Writer.
+	 * 
+	 * @param os an output stream
+	 * @throws IOException if anything goes wrong
+	 */
+	public void save(OutputStream os) throws IOException {
+		Result result = new StreamResult(os);
+		Source source = new DOMSource(factory);
+		try {
+			Transformer transformer = TransformerFactory.newInstance().newTransformer();
+			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+			transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+			transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
+			transformer.transform(source, result);
+		} catch (Exception e) {
+			throw (IOException) (new IOException().initCause(e));
+		}
+	}
+
+	/**
+	 * Saves the memento to the given file.
+	 *
+	 * @param filename java.lang.String
+	 * @exception java.io.IOException
+	 */
+	public void saveToFile(String filename) throws IOException {
+		FileOutputStream w = null;
+		try {
+			w = new FileOutputStream(filename);
+			save(w);
+		} catch (IOException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new IOException(e.getLocalizedMessage());
+		} finally {
+			if (w != null) {
+				try {
+					w.close();
+				} catch (Exception e) {
+					// ignore
+				}
+			}
+		}
+	}
+	
+	/*
+	 * @see IMemento#getBoolean(String)
+	 */
+	public Boolean getBoolean(String key) {
+		Attr attr = element.getAttributeNode(key);
+		if (attr == null)
+			return null;
+		String strValue = attr.getValue();
+		if ("true".equalsIgnoreCase(strValue))
+			return new Boolean(true);
+		return new Boolean(false);
+	}
+
+	/*
+	 * @see IMemento#putBoolean(String, boolean)
+	 */
+	public void putBoolean(String key, boolean value) {
+		element.setAttribute(key, value ? "true" : "false");
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PingThread.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PingThread.java
new file mode 100644
index 0000000..76b719c
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PingThread.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal.core;
+
+import java.io.FileNotFoundException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.eclipse.jst.server.preview.internal.Trace;
+import org.eclipse.wst.server.core.IServer;
+/**
+ * Thread used to ping server to test when it is started.
+ */
+public class PingThread {
+	// delay before pinging starts
+	private static final int PING_DELAY = 2000;
+
+	// delay between pings
+	private static final int PING_INTERVAL = 250;
+
+	// maximum number of pings before giving up
+	private int maxPings = 40;
+
+	private boolean stop = false;
+	private String url;
+	private IServer server;
+	private PreviewServerBehaviour behaviour;
+
+	/**
+	 * Create a new PingThread.
+	 * 
+	 * @param server
+	 * @param url
+	 * @param behaviour
+	 */
+	public PingThread(IServer server, String url, PreviewServerBehaviour behaviour) {
+		super();
+		this.server = server;
+		this.url = url;
+		this.behaviour = behaviour;
+		Thread t = new Thread("Preview Ping Thread") {
+			public void run() {
+				ping();
+			}
+		};
+		t.setDaemon(true);
+		t.start();
+	}
+
+	/**
+	 * Ping the server until it is started. Then set the server
+	 * state to STATE_STARTED.
+	 */
+	protected void ping() {
+		int count = 0;
+		try {
+			Thread.sleep(PING_DELAY);
+		} catch (Exception e) {
+			// ignore
+		}
+		while (!stop) {
+			try {
+				if (count == maxPings) {
+					try {
+						server.stop(false);
+					} catch (Exception e) {
+						Trace.trace(Trace.FINEST, "Ping: could not stop server");
+					}
+					stop = true;
+					break;
+				}
+				count++;
+				
+				Trace.trace(Trace.FINEST, "Ping: pinging " + count);
+				URL pingUrl = new URL(url);
+				URLConnection conn = pingUrl.openConnection();
+				((HttpURLConnection)conn).getResponseCode();
+	
+				// ping worked - server is up
+				if (!stop) {
+					Trace.trace(Trace.FINEST, "Ping: success");
+					Thread.sleep(200);
+					behaviour.setServerStarted();
+				}
+				stop = true;
+			} catch (FileNotFoundException fe) {
+				try {
+					Thread.sleep(200);
+				} catch (Exception e) {
+					// ignore
+				}
+				behaviour.setServerStarted();
+				stop = true;
+			} catch (Exception e) {
+				Trace.trace(Trace.FINEST, "Ping: failed");
+				// pinging failed
+				if (!stop) {
+					try {
+						Thread.sleep(PING_INTERVAL);
+					} catch (InterruptedException e2) {
+						// ignore
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Tell the pinging to stop.
+	 */
+	public void stop() {
+		Trace.trace(Trace.FINEST, "Ping: stopping");
+		stop = true;
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewLaunchConfigurationDelegate.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewLaunchConfigurationDelegate.java
new file mode 100644
index 0000000..583a8d5
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewLaunchConfigurationDelegate.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal.core;
+
+import java.io.File;
+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.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.jdt.launching.*;
+import org.eclipse.jst.server.core.ServerProfilerDelegate;
+import org.eclipse.jst.server.preview.internal.PreviewPlugin;
+import org.eclipse.jst.server.preview.internal.Trace;
+
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.ServerUtil;
+import org.osgi.framework.Bundle;
+/**
+ * 
+ */
+public class PreviewLaunchConfigurationDelegate extends AbstractJavaLaunchConfigurationDelegate {
+	private static final String[] REQUIRED_BUNDLE_IDS = new String[] {
+		"org.eclipse.core.runtime",
+		"org.apache.commons.logging",
+		"javax.servlet",
+		"javax.servlet.jsp",
+		"org.mortbay.jetty",
+		"org.eclipse.wst.server.preview"
+	};
+
+	private static final String MAIN_CLASS = "org.eclipse.wst.server.preview.internal.PreviewStarter";
+
+	public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+		IServer server = ServerUtil.getServer(configuration);
+		if (server == null) {
+			Trace.trace(Trace.FINEST, "Launch configuration could not find server");
+			// throw CoreException();
+			return;
+		}
+		
+		PreviewServerBehaviour previewServer = (PreviewServerBehaviour) server.loadAdapter(PreviewServerBehaviour.class, null);
+		
+		int size = REQUIRED_BUNDLE_IDS.length;
+		String[] jars = new String[size];
+		for (int i = 0; i < size; i++) {
+			Bundle b = Platform.getBundle(REQUIRED_BUNDLE_IDS[i]);
+			IPath path = null;
+			if (b != null)
+				path = PreviewRuntime.getJarredPluginPath(b);
+			if (path == null)
+				throw new CoreException(new Status(IStatus.ERROR, PreviewPlugin.PLUGIN_ID, "Could not find required bundle " + REQUIRED_BUNDLE_IDS[i]));
+			jars[i] = path.toOSString();
+		}
+		
+		if (new File(jars[5] + "bin").exists())
+			jars[5] = jars[5] + "bin";
+		
+		IVMInstall vm = verifyVMInstall(configuration);
+		
+		IVMRunner runner = vm.getVMRunner(mode);
+		if (runner == null)
+			runner = vm.getVMRunner(ILaunchManager.RUN_MODE);
+		
+		File workingDir = verifyWorkingDirectory(configuration);
+		String workingDirName = null;
+		if (workingDir != null)
+			workingDirName = workingDir.getAbsolutePath();
+		
+		// Program & VM args
+		String pgmArgs = previewServer.getTempDirectory().append("preview.xml").toOSString(); 
+			//getProgramArguments(configuration);
+		String vmArgs = getVMArguments(configuration);
+		String[] envp = getEnvironment(configuration);
+		
+		ExecutionArguments execArgs = new ExecutionArguments(vmArgs, pgmArgs);
+		
+		// VM-specific attributes
+		Map vmAttributesMap = getVMSpecificAttributesMap(configuration);
+		
+		// Classpath
+		String[] classpath2 = getClasspath(configuration);
+		String[] classpath = new String[classpath2.length + REQUIRED_BUNDLE_IDS.length];
+		System.arraycopy(jars, 0, classpath, 0, REQUIRED_BUNDLE_IDS.length);
+		System.arraycopy(classpath2, 0, classpath, REQUIRED_BUNDLE_IDS.length, classpath2.length);
+		
+		// Create VM config
+		VMRunnerConfiguration runConfig = new VMRunnerConfiguration(MAIN_CLASS, classpath);
+		runConfig.setProgramArguments(execArgs.getProgramArgumentsArray());
+		runConfig.setVMArguments(execArgs.getVMArgumentsArray());
+		runConfig.setWorkingDirectory(workingDirName);
+		runConfig.setEnvironment(envp);
+		runConfig.setVMSpecificAttributesMap(vmAttributesMap);
+		
+		// Bootpath
+		String[] bootpath = getBootpath(configuration);
+		if (bootpath != null && bootpath.length > 0)
+			runConfig.setBootClassPath(bootpath);
+		
+		setDefaultSourceLocator(launch, configuration);
+		
+		// Launch the configuration
+		previewServer.setupLaunch(launch, mode, monitor);
+		
+		if (ILaunchManager.PROFILE_MODE.equals(mode))
+			ServerProfilerDelegate.configureProfiling(launch, vm, runConfig, monitor);
+		
+		try {
+			runner.run(runConfig, launch, monitor);
+			previewServer.setProcess(launch.getProcesses()[0]);
+		} catch (Exception e) {
+			// ignore - process failed
+		}
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewLaunchableAdapterDelegate.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewLaunchableAdapterDelegate.java
new file mode 100644
index 0000000..6da4b71
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewLaunchableAdapterDelegate.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal.core;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jst.server.preview.internal.Trace;
+import org.eclipse.wst.server.core.IModuleArtifact;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.model.LaunchableAdapterDelegate;
+import org.eclipse.wst.server.core.util.HttpLaunchable;
+import org.eclipse.wst.server.core.util.WebResource;
+
+public class PreviewLaunchableAdapterDelegate extends LaunchableAdapterDelegate {
+	/*
+	 * @see LaunchableAdapterDelegate#getLaunchable(IServer, IModuleArtifact)
+	 */
+	public Object getLaunchable(IServer server, IModuleArtifact moduleArtifact) throws CoreException {
+		if (server == null || moduleArtifact == null)
+			return null;
+		
+		PreviewServer server2 = (PreviewServer) server.loadAdapter(PreviewServer.class, null);
+		if (server2 == null)
+			return null;
+		
+		try {
+			URL url = server2.getModuleRootURL(moduleArtifact.getModule());
+			
+			if (moduleArtifact instanceof WebResource) {
+				WebResource resource = (WebResource) moduleArtifact;
+				String path = resource.getPath().toString();
+				
+				if (path.startsWith("/"))
+					path = path.substring(1);
+				url = new URL(url.toExternalForm() + "/" + path);
+			}
+			return new HttpLaunchable(url);
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error in launchable adapter", e);
+		}
+		
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewRuntime.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewRuntime.java
new file mode 100644
index 0000000..d873ac3
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewRuntime.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal.core;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMInstallType;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jst.server.core.IJavaRuntime;
+import org.eclipse.jst.server.preview.internal.Messages;
+import org.eclipse.jst.server.preview.internal.PreviewPlugin;
+import org.eclipse.wst.server.core.model.RuntimeDelegate;
+import org.osgi.framework.Bundle;
+/**
+ * J2EE preview runtime.
+ */
+public class PreviewRuntime extends RuntimeDelegate implements IJavaRuntime {
+	public static final String ID = "org.eclipse.jst.server.preview.runtime";
+
+	protected static final String PROP_VM_INSTALL_TYPE_ID = "vm-install-type-id";
+	protected static final String PROP_VM_INSTALL_ID = "vm-install-id";
+
+	/**
+	 * Create a new preview runtime.
+	 */
+	public PreviewRuntime() {
+		// do nothing
+	}
+
+	/**
+	 * Returns the path that corresponds to the specified bundle.
+	 * 
+	 * @return a path
+	 */
+	protected static Path getPluginPath(Bundle bundle) {
+		try {
+			URL installURL = bundle.getEntry("/");
+			URL localURL = FileLocator.toFileURL(installURL);
+			return new Path(localURL.getFile());
+		} catch (IOException ioe) {
+			return null;
+		}
+	}
+
+	protected static IPath getJarredPluginPath(Bundle bundle) {
+		Path runtimeLibFullPath = null;
+		String jarPluginLocation = bundle.getLocation().substring(7);
+		
+		// handle case where jars are installed outside of eclipse installation
+		Path jarPluginPath = new Path(jarPluginLocation);
+		if (jarPluginPath.isAbsolute())
+			runtimeLibFullPath = jarPluginPath;
+		// handle normal case where all plugins under eclipse install
+		else {
+			int ind = jarPluginLocation.lastIndexOf(":");
+			if (ind > 0)
+				jarPluginLocation = jarPluginLocation.substring(ind+1);
+			
+			String installPath = Platform.getInstallLocation().getURL().getPath();
+			runtimeLibFullPath = new Path(installPath+"/"+jarPluginLocation);
+		}
+		return runtimeLibFullPath;
+	}
+
+	protected String getVMInstallTypeId() {
+		return getAttribute(PROP_VM_INSTALL_TYPE_ID, (String)null);
+	}
+
+	protected String getVMInstallId() {
+		return getAttribute(PROP_VM_INSTALL_ID, (String)null);
+	}
+
+	/**
+	 * @see RuntimeDelegate#setDefaults(IProgressMonitor)
+	 */
+	public void setDefaults(IProgressMonitor monitor) {
+		getRuntimeWorkingCopy().setLocation(new Path(""));
+	}
+
+	/**
+	 * Returns <code>true</code> if the runtime is using the default JRE.
+	 * 
+	 * @return <code>true</code> if the runtime is using the default JRE,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isUsingDefaultJRE() {
+		return getVMInstallTypeId() == null;
+	}
+
+	public IVMInstall getVMInstall() {
+		if (getVMInstallTypeId() == null)
+			return JavaRuntime.getDefaultVMInstall();
+		try {
+			IVMInstallType vmInstallType = JavaRuntime.getVMInstallType(getVMInstallTypeId());
+			IVMInstall[] vmInstalls = vmInstallType.getVMInstalls();
+			int size = vmInstalls.length;
+			String id = getVMInstallId();
+			for (int i = 0; i < size; i++) {
+				if (id.equals(vmInstalls[i].getId()))
+					return vmInstalls[i];
+			}
+		} catch (Exception e) {
+			// ignore
+		}
+		return null;
+	}
+
+	/**
+	 * @see RuntimeDelegate#validate()
+	 */
+	public IStatus validate() {
+		IStatus status = super.validate();
+		if (!status.isOK())
+			return status;
+		
+		if (getVMInstall() == null)
+			return new Status(IStatus.ERROR, PreviewPlugin.PLUGIN_ID, 0, Messages.errorJRE, null);
+		
+		return Status.OK_STATUS;
+	}
+
+	public void setVMInstall(IVMInstall vmInstall) {
+		if (vmInstall == null) {
+			setVMInstall(null, null);
+		} else
+			setVMInstall(vmInstall.getVMInstallType().getId(), vmInstall.getId());
+	}
+
+	protected void setVMInstall(String typeId, String id) {
+		if (typeId == null)
+			setAttribute(PROP_VM_INSTALL_TYPE_ID, (String)null);
+		else
+			setAttribute(PROP_VM_INSTALL_TYPE_ID, typeId);
+		
+		if (id == null)
+			setAttribute(PROP_VM_INSTALL_ID, (String)null);
+		else
+			setAttribute(PROP_VM_INSTALL_ID, id);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewRuntimeClasspathProvider.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewRuntimeClasspathProvider.java
new file mode 100644
index 0000000..7c3caf1
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewRuntimeClasspathProvider.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jst.server.core.RuntimeClasspathProviderDelegate;
+
+import org.eclipse.wst.server.core.IRuntime;
+import org.osgi.framework.Bundle;
+/**
+ * 
+ */
+public class PreviewRuntimeClasspathProvider extends RuntimeClasspathProviderDelegate {
+	private static final String[] REQUIRED_BUNDLE_IDS = new String[] {
+		"javax.servlet",
+		"javax.servlet.jsp"
+	};
+
+	/** (non-Javadoc)
+	 * @see RuntimeClasspathProviderDelegate#resolveClasspathContainer(IProject, IRuntime)
+	 */
+	public IClasspathEntry[] resolveClasspathContainer(IProject project, IRuntime runtime) {
+		List list = new ArrayList();
+		
+		int size = REQUIRED_BUNDLE_IDS.length;
+		for (int i = 0; i < size; i++) {
+			Bundle b = Platform.getBundle(REQUIRED_BUNDLE_IDS[i]);
+			IPath path = PreviewRuntime.getJarredPluginPath(b);
+			if (path != null)
+				list.add(JavaCore.newLibraryEntry(path, null, null));
+		}
+		
+		return (IClasspathEntry[])list.toArray(new IClasspathEntry[list.size()]);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewServer.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewServer.java
new file mode 100644
index 0000000..1956d5c
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewServer.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal.core;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jst.server.core.IWebModule;
+import org.eclipse.jst.server.preview.internal.Messages;
+import org.eclipse.jst.server.preview.internal.PreviewPlugin;
+import org.eclipse.jst.server.preview.internal.Trace;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.IRuntime;
+import org.eclipse.wst.server.core.IRuntimeType;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.IServerType;
+import org.eclipse.wst.server.core.IServerWorkingCopy;
+import org.eclipse.wst.server.core.ServerCore;
+import org.eclipse.wst.server.core.ServerPort;
+import org.eclipse.wst.server.core.model.IURLProvider;
+import org.eclipse.wst.server.core.model.ServerDelegate;
+import org.eclipse.wst.server.core.util.IStaticWeb;
+/**
+ * J2EE preview server.
+ */
+public class PreviewServer extends ServerDelegate implements IURLProvider {
+	public static final String ID = "org.eclipse.jst.server.preview.server";
+
+	public static final String PROPERTY_PORT = "port";
+
+	/**
+	 * PreviewServer.
+	 */
+	public PreviewServer() {
+		super();
+	}
+
+	protected void initialize() {
+		// do nothing
+	}
+
+	public PreviewRuntime getPreviewRuntime() {
+		if (getServer().getRuntime() == null)
+			return null;
+		
+		return (PreviewRuntime) getServer().getRuntime().loadAdapter(PreviewRuntime.class, null);
+	}
+
+	/**
+	 * Return the root URL of this module.
+	 * 
+	 * @param module a module
+	 * @return java.net.URL
+	 */
+	public URL getModuleRootURL(IModule module) {
+		try {
+			String base = "http://localhost";
+			
+			int port = getPort();
+			URL url = null;
+			if (port == 80)
+				url = new URL(base + "/");
+			else
+				url = new URL(base + ":" + port + "/");
+			
+			String type = module.getModuleType().getId();
+			if ("wst.web".equals(type)) {
+				IStaticWeb staticWeb = (IStaticWeb) module.loadAdapter(IStaticWeb.class, null);
+				return new URL(url, staticWeb.getContextRoot());
+			} else if ("jst.web".equals(type)) {
+				IWebModule webModule = (IWebModule) module.loadAdapter(IWebModule.class, null);
+				return new URL(url, webModule.getContextRoot());
+			}
+			return url;
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Could not get root URL", e);
+			return null;
+		}
+	}
+
+	/*
+	 * Returns the child module(s) of this module.
+	 */
+	public IModule[] getChildModules(IModule[] module) {
+		return new IModule[0];
+	}
+
+	/*
+	 * Returns the root module(s) of this module.
+	 */
+	public IModule[] getRootModules(IModule module) throws CoreException {
+		return new IModule[] { module };
+	}
+
+	/**
+	 * Returns true if the given project is supported by this server, and false
+	 * otherwise.
+	 * 
+	 * @param add modules
+	 * @param remove modules
+	 * @return the status
+	 */
+	public IStatus canModifyModules(IModule[] add, IModule[] remove) {
+		return new Status(IStatus.OK, PreviewPlugin.PLUGIN_ID, 0, Messages.canModifyModules, null);
+	}
+
+	public ServerPort[] getServerPorts() {
+		int port = getPort();
+		ServerPort[] ports = { new ServerPort("http", Messages.httpPort, port, "http") };
+		return ports;
+	}
+
+	public int getPort() {
+		return getAttribute(PreviewServer.PROPERTY_PORT, 8080);
+	}
+
+	public void setPort(int port) {
+		setAttribute(PreviewServer.PROPERTY_PORT, port);
+	}
+
+	public static IServer createPreviewServer(String serverName) {
+		try {
+			NullProgressMonitor monitor = new NullProgressMonitor();
+			IRuntimeType runtimeType = ServerCore.findRuntimeType(PreviewRuntime.ID);
+			IRuntimeWorkingCopy runtimeCopy = runtimeType.createRuntime(PreviewRuntime.ID, monitor);
+			IRuntime runtime = runtimeCopy.save(true, monitor);
+			
+			IServerType serverType = ServerCore.findServerType(ID);
+			IServerWorkingCopy workingCopy = serverType.createServer(ID, null, runtime, monitor);
+			workingCopy.setName(serverName);
+			workingCopy.setHost("localhost");
+			return workingCopy.save(true, monitor);
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error creating server", e);
+		}
+		
+		return null;
+	}
+
+	public static IServer findPreviewServer(String id) {
+		IServer[] servers = ServerCore.getServers();
+		for (int i = 0; i < servers.length; i++) {
+			if (servers[i].getId().equals(id)) {
+				return servers[i];
+			}
+		}
+		return null;
+	}
+
+	public void modifyModules(IModule[] add, IModule[] remove, IProgressMonitor monitor) throws CoreException {
+		// do nothing
+	}
+
+	/**
+	 * Return a string representation of this object.
+	 * 
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return "PreviewServer";
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewServerBehaviour.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewServerBehaviour.java
new file mode 100644
index 0000000..7d1248e
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewServerBehaviour.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal.core;
+
+import java.io.IOException;
+
+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.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IDebugEventSetListener;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.jst.server.core.IWebModule;
+import org.eclipse.jst.server.preview.internal.IMemento;
+import org.eclipse.jst.server.preview.internal.Messages;
+import org.eclipse.jst.server.preview.internal.PreviewPlugin;
+import org.eclipse.jst.server.preview.internal.ProgressUtil;
+import org.eclipse.jst.server.preview.internal.Trace;
+import org.eclipse.jst.server.preview.internal.XMLMemento;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.ServerPort;
+import org.eclipse.wst.server.core.model.IModuleResource;
+import org.eclipse.wst.server.core.model.IModuleResourceDelta;
+import org.eclipse.wst.server.core.model.ServerBehaviourDelegate;
+import org.eclipse.wst.server.core.util.IStaticWeb;
+import org.eclipse.wst.server.core.util.PublishUtil;
+import org.eclipse.wst.server.core.util.SocketUtil;
+/**
+ * Generic Http server.
+ */
+public class PreviewServerBehaviour extends ServerBehaviourDelegate {
+	// the thread used to ping the server to check for startup
+	protected transient PingThread ping = null;
+	protected transient IProcess process;
+	protected transient IDebugEventSetListener processListener;
+
+	/**
+	 * PreviewServer.
+	 */
+	public PreviewServerBehaviour() {
+		super();
+	}
+
+	public void initialize(IProgressMonitor monitor) {
+		// do nothing
+	}
+
+	public PreviewRuntime getPreviewRuntime() {
+		if (getServer().getRuntime() == null)
+			return null;
+
+		return (PreviewRuntime) getServer().getRuntime().loadAdapter(PreviewRuntime.class, null);
+	}
+
+	public PreviewServer getPreviewServer() {
+		return (PreviewServer) getServer().getAdapter(PreviewServer.class);
+	}
+
+	/**
+	 * Returns the runtime base path for relative paths in the server
+	 * configuration.
+	 * 
+	 * @return the base path
+	 */
+	public IPath getRuntimeBaseDirectory() {
+		return getServer().getRuntime().getLocation();
+	}
+
+	/**
+	 * Setup for starting the server.
+	 * 
+	 * @param launch ILaunch
+	 * @param launchMode String
+	 * @param monitor IProgressMonitor
+	 * @throws CoreException if anything goes wrong
+	 */
+	protected void setupLaunch(ILaunch launch, String launchMode, IProgressMonitor monitor) throws CoreException {
+		// check that ports are free
+		ServerPort[] ports = getPreviewServer().getServerPorts();
+		int port = ports[0].getPort();
+		
+		if (SocketUtil.isPortInUse(port, 5))
+			throw new CoreException(new Status(IStatus.ERROR, PreviewPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorPortInUse, new String[] {port + "", getServer().getName()}), null));
+		
+		// generate preview config file
+		XMLMemento memento = XMLMemento.createWriteRoot("server");
+		memento.putInteger("port", port);
+		
+		IModule[] modules = getServer().getModules();
+		int size = modules.length;
+		for (int i = 0; i < size; i++) {
+			IMemento mod = memento.createChild("module");
+			mod.putString("name", modules[i].getName());
+			String type = modules[i].getModuleType().getId();
+			if ("wst.web".equals(type)) {
+				IStaticWeb staticWeb = (IStaticWeb) modules[i].loadAdapter(IStaticWeb.class, null);
+				mod.putString("context", staticWeb.getContextRoot());
+				mod.putString("type", "static");
+			} else if ("jst.web".equals(type)) {
+				IWebModule webModule = (IWebModule) modules[i].loadAdapter(IWebModule.class, null);
+				mod.putString("context", webModule.getContextRoot());
+				mod.putString("type", "j2ee");
+			}
+			mod.putString("path", getModulePublishDirectory(modules[i]).toPortableString());
+		}
+		try {
+			memento.saveToFile(getTempDirectory().append("preview.xml").toOSString());
+		} catch (IOException e) {
+			Trace.trace(Trace.SEVERE, "Could not write preview config", e);
+			throw new CoreException(new Status(IStatus.ERROR, PreviewPlugin.PLUGIN_ID, 0, "Could not write preview configuration", null));
+		}
+		
+		setServerRestartState(false);
+		setServerState(IServer.STATE_STARTING);
+		setMode(launchMode);
+		
+		// ping server to check for startup
+		try {
+			String url = "http://localhost";
+			if (port != 80)
+				url += ":" + port;
+			ping = new PingThread(getServer(), url, this);
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Can't ping for Tomcat startup.");
+		}
+	}
+
+	protected void setProcess(final IProcess newProcess) {
+		if (process != null)
+			return;
+		
+		process = newProcess;
+		if (processListener != null)
+			DebugPlugin.getDefault().removeDebugEventListener(processListener);
+		if (newProcess == null)
+			return;
+		
+		processListener = new IDebugEventSetListener() {
+			public void handleDebugEvents(DebugEvent[] events) {
+				if (events != null) {
+					int size = events.length;
+					for (int i = 0; i < size; i++) {
+						Object obj = events[i].getSource();
+						
+						if (!(obj instanceof IDebugTarget))
+							continue;
+						
+						IDebugTarget target = (IDebugTarget) obj;
+						IProcess targetProcess = target.getProcess();
+						
+						if (process != null && process.equals(targetProcess)
+								&& events[i].getKind() == DebugEvent.TERMINATE) {
+							DebugPlugin.getDefault().removeDebugEventListener(this);
+							stopImpl();
+						}
+					}
+				}
+			}
+		};
+		DebugPlugin.getDefault().addDebugEventListener(processListener);
+	}
+
+	protected void setServerStarted() {
+		setServerState(IServer.STATE_STARTED);
+	}
+
+	protected void stopImpl() {
+		if (ping != null) {
+			ping.stop();
+			ping = null;
+		}
+		if (process != null) {
+			process = null;
+			DebugPlugin.getDefault().removeDebugEventListener(processListener);
+			processListener = null;
+		}
+		setServerState(IServer.STATE_STOPPED);
+	}
+
+	protected void publishServer(int kind, IProgressMonitor monitor) throws CoreException {
+		monitor = ProgressUtil.getMonitorFor(monitor);
+		monitor.done();
+
+		setServerPublishState(IServer.PUBLISH_STATE_NONE);
+	}
+
+	/*
+	 * Publishes the given module to the server.
+	 */
+	protected void publishModule(int kind, int deltaKind, IModule[] moduleTree, IProgressMonitor monitor) throws CoreException {
+		IModule module = moduleTree[moduleTree.length - 1]; 
+		IPath to = getModulePublishDirectory(module);
+		
+		if (kind == IServer.PUBLISH_CLEAN || deltaKind == ServerBehaviourDelegate.REMOVED) {
+			IStatus[] status = PublishUtil.deleteDirectory(to.toFile(), monitor);
+			throwException(status);
+		}
+		
+		IModuleResource[] res = getResources(moduleTree);
+		IStatus[] status = PublishUtil.publishSmart(res, to, monitor);
+		throwException(status);
+		
+		setModulePublishState(moduleTree, IServer.PUBLISH_STATE_NONE);
+	}
+
+	/**
+	 * Utility method to throw a CoreException based on the contents of a list of
+	 * error and warning status.
+	 * 
+	 * @param status a List containing error and warning IStatus
+	 * @throws CoreException
+	 */
+	private static void throwException(IStatus[] status) throws CoreException {
+		if (status == null || status.length == 0)
+			return;
+		
+		if (status.length == 1)
+			throw new CoreException(status[0]);
+		
+		String message = Messages.errorPublish;
+		MultiStatus status2 = new MultiStatus(PreviewPlugin.PLUGIN_ID, 0, status, message, null);
+		throw new CoreException(status2);
+	}
+
+	public void restart(String launchMode) throws CoreException {
+		setServerState(IServer.STATE_STOPPED);
+		setServerState(IServer.STATE_STARTED);
+	}
+
+	/**
+	 * Cleanly shuts down and terminates the server.
+	 * 
+	 * @param force <code>true</code> to kill the server
+	 */
+	public void stop(boolean force) {
+		if (force) {
+			terminate();
+			return;
+		}
+		int state = getServer().getServerState();
+		if (state == IServer.STATE_STOPPED)
+			return;
+		else if (state == IServer.STATE_STARTING || state == IServer.STATE_STOPPING) {
+			terminate();
+			return;
+		}
+		
+		// should really try to stop normally
+		terminate();
+	}
+
+	/**
+	 * Terminates the server.
+	 */
+	protected void terminate() {
+		if (getServer().getServerState() == IServer.STATE_STOPPED)
+			return;
+		
+		try {
+			setServerState(IServer.STATE_STOPPING);
+			Trace.trace(Trace.FINEST, "Killing the HTTP process");
+			if (process != null && !process.isTerminated())
+				process.terminate();
+			
+			stopImpl();
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error killing the process", e);
+		}
+	}
+
+	protected IPath getTempDirectory() {
+		return super.getTempDirectory();
+	}
+
+	/**
+	 * Returns the module's publish path.
+	 * 
+	 * @param module a module
+	 * @return the publish directory for the module
+	 */
+	protected IPath getModulePublishDirectory(IModule module) {
+		return getTempDirectory().append(module.getName());
+	}
+
+	/**
+	 * Return a string representation of this object.
+	 * 
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return "PreviewServer";
+	}
+
+	protected IModuleResourceDelta[] getPublishedResourceDelta(IModule[] module) {
+		return super.getPublishedResourceDelta(module);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewSourcePathComputerDelegate.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewSourcePathComputerDelegate.java
new file mode 100644
index 0000000..09c8c44
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewSourcePathComputerDelegate.java
@@ -0,0 +1,90 @@
+/**********************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    IBM Corporation - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.jst.server.preview.internal.core;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.sourcelookup.ISourceContainer;
+import org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate;
+import org.eclipse.debug.core.sourcelookup.containers.FolderSourceContainer;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.ServerUtil;
+/**
+ *
+ */
+public class PreviewSourcePathComputerDelegate implements ISourcePathComputerDelegate {
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate#computeSourceContainers(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public ISourceContainer[] computeSourceContainers(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {
+		List classpaths = new ArrayList();
+		classpaths.addAll(Arrays.asList(JavaRuntime.computeUnresolvedSourceLookupPath(configuration)));
+		List sourcefolderList = new ArrayList();
+		
+		IServer server = ServerUtil.getServer(configuration);
+		if (server != null) {
+			List list = new ArrayList();
+			IModule[] modules = server.getModules();
+			for (int i = 0; i < modules.length; i++) {
+				IProject project = modules[i].getProject();
+				if (project != null) {
+					IFolder moduleFolder = project.getFolder(modules[i].getName());
+					if (moduleFolder.exists()) {
+						sourcefolderList.add(new FolderSourceContainer(moduleFolder, true));
+					}
+					
+					try {
+						if (project.hasNature(JavaCore.NATURE_ID)) {
+							IJavaProject javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
+							if (!list.contains(javaProject))
+								list.add(javaProject);
+						}
+					} catch (Exception e) {
+						// ignore
+					}
+				}
+			}
+			int size = list.size();
+			IJavaProject[] projects = new IJavaProject[size];
+			list.toArray(projects);
+			
+			for (int i = 0; i < size; i++)
+				classpaths.addAll(Arrays.asList(JavaRuntime.computeUnresolvedRuntimeClasspath(projects[i])));
+		}
+
+		IRuntimeClasspathEntry[] entries = new IRuntimeClasspathEntry[classpaths.size()];
+		classpaths.toArray(entries);
+
+		IRuntimeClasspathEntry[] resolved = JavaRuntime.resolveSourceLookupPath(entries, configuration);
+		ISourceContainer[] sourceContainers = JavaRuntime.getSourceContainers(resolved);
+		
+		if (!sourcefolderList.isEmpty()) {
+			ISourceContainer[] combinedSourceContainers = new ISourceContainer[sourceContainers.length + sourcefolderList.size()];
+			sourcefolderList.toArray(combinedSourceContainers);
+			System.arraycopy(sourceContainers, 0, combinedSourceContainers, sourcefolderList.size(), sourceContainers.length);
+			sourceContainers = combinedSourceContainers;
+		}
+
+		return sourceContainers;
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewStartup.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewStartup.java
new file mode 100644
index 0000000..9860f9f
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/core/PreviewStartup.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal.core;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jst.server.preview.internal.Trace;
+import org.eclipse.wst.server.core.IRuntime;
+import org.eclipse.wst.server.core.IRuntimeType;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.IServerType;
+import org.eclipse.wst.server.core.IServerWorkingCopy;
+import org.eclipse.wst.server.core.ServerCore;
+import org.eclipse.wst.server.core.internal.IStartup;
+
+public class PreviewStartup implements IStartup {
+	private static final String ID = "xyz"; 
+
+	public void startup() {
+		// create runtime
+		IRuntime[] runtimes = ServerCore.getRuntimes();
+		IRuntime runtime = null;
+		
+		int size = runtimes.length;
+		for (int i = 0; i < size; i++) {
+			if (runtimes[i].getRuntimeType() != null && PreviewRuntime.ID.equals(runtimes[i].getRuntimeType().getId())) {
+				if (ID.equals(runtimes[i].getId()))
+					runtime = runtimes[i];
+			}
+		}
+		
+		if (runtime == null) {
+			try {
+				IRuntimeType runtimeType = ServerCore.findRuntimeType(PreviewRuntime.ID);
+				IRuntimeWorkingCopy wc = runtimeType.createRuntime(ID, null);
+				wc.setName("My Preview");
+				wc.setReadOnly(true);
+				runtime = wc.save(true, null);
+			} catch (CoreException ce) {
+				Trace.trace(Trace.WARNING, "Could not create default preview runtime");
+			}
+		}
+		
+		// create server
+		IServer[] servers = ServerCore.getServers();
+		
+		boolean found = false;
+		size = servers.length;
+		for (int i = 0; i < size; i++) {
+			if (servers[i].getServerType() != null && PreviewServer.ID.equals(servers[i].getServerType().getId())) {
+				if (ID.equals(servers[i].getId()))
+					found = true;
+			}
+		}
+		
+		if (!found) {
+			try {
+				IServerType serverType = ServerCore.findServerType(PreviewServer.ID);
+				IServerWorkingCopy wc = serverType.createServer(ID, null, runtime, null);
+				wc.setName("My preview");
+				wc.setHost("localhost");
+				wc.setReadOnly(true);
+				wc.save(true, null);
+			} catch (CoreException ce) {
+				Trace.trace(Trace.WARNING, "Could not create default preview server");
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/ui/PreviewLaunchConfigurationTabGroup.java b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/ui/PreviewLaunchConfigurationTabGroup.java
new file mode 100644
index 0000000..bf1ca4e
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.preview.adapter/src/org/eclipse/jst/server/preview/internal/ui/PreviewLaunchConfigurationTabGroup.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.preview.internal.ui;
+
+import org.eclipse.debug.ui.*;
+import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaArgumentsTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab;
+
+import org.eclipse.wst.server.ui.ServerLaunchConfigurationTab;
+/**
+ * A debug tab group for launching Tomcat. 
+ */
+public class PreviewLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup {
+	/*
+	 * @see ILaunchConfigurationTabGroup#createTabs(ILaunchConfigurationDialog, String)
+	 */
+	public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[6];
+		tabs[0] = new ServerLaunchConfigurationTab(new String[] { "org.eclipse.jst.server.preview" });
+		tabs[0].setLaunchConfigurationDialog(dialog);
+		tabs[1] = new JavaArgumentsTab();
+		tabs[1].setLaunchConfigurationDialog(dialog);
+		tabs[2] = new JavaClasspathTab();
+		tabs[2].setLaunchConfigurationDialog(dialog);
+		tabs[3] = new SourceLookupTab();
+		tabs[3].setLaunchConfigurationDialog(dialog);
+		tabs[4] = new EnvironmentTab();
+		tabs[4].setLaunchConfigurationDialog(dialog);
+		tabs[5] = new CommonTab();
+		tabs[5].setLaunchConfigurationDialog(dialog);
+		setTabs(tabs);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/.classpath b/plugins/org.eclipse.wst.server.preview.adapter/.classpath
new file mode 100644
index 0000000..52165ec
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/.cvsignore b/plugins/org.eclipse.wst.server.preview.adapter/.cvsignore
new file mode 100644
index 0000000..33dd7de
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/.cvsignore
@@ -0,0 +1,6 @@
+bin
+temp.folder
+build.xml
+@dot
+src.zip
+javaCompiler...args
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/.project b/plugins/org.eclipse.wst.server.preview.adapter/.project
new file mode 100644
index 0000000..32a9232
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.wst.server.preview.adapter</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..c8be432
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Fri Nov 10 17:11:35 HST 2006
+eclipse.preferences.version=1
+encoding/<project>=ISO-8859-1
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..403949d
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,74 @@
+#Wed Apr 04 18:12:13 EDT 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=error
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,*.testsuite,*.deploy,*.location,*.execution,*.datapool,*.artifact,*.html,*.svg
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=disabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=1000
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=error
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.4
+org.eclipse.jdt.core.incompatibleJDKLevel=warning
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..a7cc1d0
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,3 @@
+#Fri Feb 23 21:11:52 EST 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?>\n<templates/>
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.pde.prefs b/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..08a60e5
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,14 @@
+#Sat Apr 22 18:36:14 EDT 2006
+compilers.incompatible-environment=0
+compilers.p.build=0
+compilers.p.deprecated=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.server.preview.adapter/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..381cd3d
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.wst.server.adapter.preview;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.server.preview.internal.core.PreviewPlugin
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.wst.server.core;bundle-version="[1.0.204,2.0.0)",
+ org.eclipse.debug.core;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.wst.server.ui;bundle-version="[1.0.103,1.1.0)",
+ org.eclipse.debug.ui;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.wst.common.project.facet.ui;bundle-version="[1.2.0,2.0.0)"
+Eclipse-LazyStart: true
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/about.html b/plugins/org.eclipse.wst.server.preview.adapter/about.html
new file mode 100644
index 0000000..4ec5989
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/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>May 2, 2006</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/plugins/org.eclipse.wst.server.preview.adapter/build.properties b/plugins/org.eclipse.wst.server.preview.adapter/build.properties
new file mode 100644
index 0000000..af949f3
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/build.properties
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = META-INF/,\
+               plugin.properties,\
+               .,\
+               plugin.xml,\
+               about.html
+bin.excludes = bin/**,\
+               @dot/**,\
+               temp.folder/**
+source.. = src/
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/icons/obj16/preview.gif b/plugins/org.eclipse.wst.server.preview.adapter/icons/obj16/preview.gif
new file mode 100644
index 0000000..b51ae39
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/icons/obj16/preview.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/plugin.properties b/plugins/org.eclipse.wst.server.preview.adapter/plugin.properties
new file mode 100644
index 0000000..7779d81
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/plugin.properties
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+pluginName=HTTP Preview Support
+providerName=Eclipse.org
+
+previewRuntimeTypeName=HTTP Preview
+previewRuntimeTypeDescription=A runtime to build static Web modules.
+
+previewServerTypeName=HTTP Preview
+previewServerTypeDescription=A server to preview static Web modules.
+
+previewLaunchConfigurationType=HTTP Preview
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/plugin.xml b/plugins/org.eclipse.wst.server.preview.adapter/plugin.xml
new file mode 100644
index 0000000..e07a3c0
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/plugin.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+  <extension point="org.eclipse.wst.server.core.runtimeTypes">
+    <runtimeType
+       id="org.eclipse.wst.server.preview.runtime"
+       name="%previewRuntimeTypeName"
+       description="%previewRuntimeTypeDescription"
+       facetRuntimeComponent="org.eclipse.wst.server.preview.runtime"
+	    facetRuntimeVersion="1.0"
+       class="org.eclipse.wst.server.preview.internal.core.PreviewRuntime">
+       <moduleType
+         types="wst.web"
+         versions="1.0"/>
+    </runtimeType>
+  </extension>
+
+  <extension point="org.eclipse.wst.server.core.serverTypes">
+     <serverType
+       id="org.eclipse.wst.server.preview.server"
+       name="%previewServerTypeName"
+       description="%previewServerTypeDescription"
+       supportsRemoteHosts="false"
+       runtime="true"
+       initialState="stopped"
+       hasConfiguration="false"
+       launchModes="run,debug,profile"
+       launchConfigId="org.eclipse.wst.server.preview.launchConfigurationType"
+       runtimeTypeId="org.eclipse.wst.server.preview.runtime"
+       class="org.eclipse.wst.server.preview.internal.core.PreviewServer"
+       behaviourClass="org.eclipse.wst.server.preview.internal.core.PreviewServerBehaviour"/>
+  </extension>
+
+  <extension point="org.eclipse.wst.common.project.facet.core.runtimes">
+    <runtime-component-type
+       id="org.eclipse.wst.server.preview.runtime"/>
+
+    <runtime-component-version
+       type="org.eclipse.wst.server.preview.runtime"
+       version="1.0"/>
+
+    <supported>
+      <runtime-component
+         id="org.eclipse.wst.server.preview.runtime"
+         version="1.0"/>
+      <facet
+         id="wst.web"
+         version="1.0"/>
+    </supported>
+  </extension>
+
+  <extension point="org.eclipse.debug.core.launchConfigurationTypes">
+     <launchConfigurationType
+        id="org.eclipse.wst.server.preview.launchConfigurationType"
+        name="%previewLaunchConfigurationType"
+        delegate="org.eclipse.wst.server.preview.internal.core.PreviewLaunchConfigurationDelegate"
+        modes="run,debug,profile"/>
+  </extension>
+
+  <extension point="org.eclipse.wst.server.core.launchableAdapters">
+    <launchableAdapter
+      id="org.eclipse.wst.server.preview"
+      class="org.eclipse.wst.server.preview.internal.core.PreviewLaunchableAdapterDelegate"/>
+  </extension>
+
+
+  <extension point="org.eclipse.wst.server.ui.serverImages">
+    <image
+      id="org.eclipse.wst.server.preview.ui"
+      typeIds="org.eclipse.wst.server.preview.runtime,org.eclipse.wst.server.preview.server"
+      icon="icons/obj16/preview.gif"/>
+  </extension>
+
+  <extension point="org.eclipse.wst.common.project.facet.ui.images">
+    <image runtime-component-type="org.eclipse.wst.server.preview.runtime"
+       path="icons/obj16/preview.gif"/>
+  </extension>
+
+  <extension point="org.eclipse.wst.common.project.facet.core.runtimes">
+    <adapter>
+      <runtime-component id="org.eclipse.wst.server.preview.runtime"/>
+      <factory class="org.eclipse.wst.server.ui.internal.facets.RuntimeLabelProvider$Factory"/>
+      <type class="org.eclipse.wst.common.project.facet.ui.IRuntimeComponentLabelProvider"/>
+    </adapter>
+  </extension>
+
+  <extension point="org.eclipse.debug.ui.launchConfigurationTypeImages">
+    <launchConfigurationTypeImage
+      id="org.eclipse.wst.server.preview.launchConfigurationTypeImage"
+      configTypeID="org.eclipse.wst.server.preview.launchConfigurationType"
+      icon="icons/obj16/preview.gif">
+    </launchConfigurationTypeImage>
+  </extension>
+
+  <extension point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+    <launchConfigurationTabGroup
+      id="org.eclipse.wst.server.preview.launchConfigurationTabGroup"
+      type="org.eclipse.wst.server.core.preview.launchConfigurationType"
+      class="org.eclipse.wst.server.preview.internal.ui.PreviewLaunchConfigurationTabGroup">
+    </launchConfigurationTabGroup>
+  </extension>
+</plugin>
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/IMemento.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/IMemento.java
new file mode 100644
index 0000000..4049dac
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/IMemento.java
@@ -0,0 +1,194 @@
+/**********************************************************************
+ * Copyright (c) 2003, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import java.util.List;
+/**
+ * Interface to a memento used for saving the important state of an object
+ * in a form that can be persisted in the file system.
+ * <p>
+ * Mementos were designed with the following requirements in mind:
+ * <ol>
+ *  <li>Certain objects need to be saved and restored across platform sessions.
+ *    </li>
+ *  <li>When an object is restored, an appropriate class for an object might not
+ *    be available. It must be possible to skip an object in this case.</li>
+ *  <li>When an object is restored, the appropriate class for the object may be
+ *    different from the one when the object was originally saved. If so, the
+ *    new class should still be able to read the old form of the data.</li>
+ * </ol>
+ * </p>
+ * <p>
+ * Mementos meet these requirements by providing support for storing a
+ * mapping of arbitrary string keys to primitive values, and by allowing
+ * mementos to have other mementos as children (arranged into a tree).
+ * A robust external storage format based on XML is used.
+ * </p><p>
+ * The key for an attribute may be any alpha numeric value.  However, the
+ * value of <code>TAG_ID</code> is reserved for internal use.
+ * </p><p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IMemento {
+	/**
+	 * Special reserved key used to store the memento id 
+	 * (value <code>"org.eclipse.ui.id"</code>).
+	 *
+	 * @see #getId
+	 */
+	public static final String TAG_ID = "IMemento.internal.id"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new child of this memento with the given type.
+	 * <p>
+	 * The <code>getChild</code> and <code>getChildren</code> methods
+	 * are used to retrieve children of a given type.
+	 * </p>
+	 *
+	 * @param type the type
+	 * @return a new child memento
+	 * @see #getChild
+	 * @see #getChildren
+	 */
+	public IMemento createChild(String type);
+	
+	/**
+	 * Creates a new child of this memento with the given type and id.
+	 * The id is stored in the child memento (using a special reserved
+	 * key, <code>TAG_ID</code>) and can be retrieved using <code>getId</code>.
+	 * <p>
+	 * The <code>getChild</code> and <code>getChildren</code> methods
+	 * are used to retrieve children of a given type.
+	 * </p>
+	 *
+	 * @param type the type
+	 * @param id the child id
+	 * @return a new child memento with the given type and id
+	 * @see #getId
+	 */
+	public IMemento createChild(String type, String id);
+	
+	/**
+	 * Returns the first child with the given type id.
+	 *
+	 * @param type the type id
+	 * @return the first child with the given type
+	 */
+	public IMemento getChild(String type);
+	
+	/**
+	 * Returns all children with the given type id.
+	 *
+	 * @param type the type id
+	 * @return the list of children with the given type
+	 */
+	public IMemento[] getChildren(String type);
+	
+	/**
+	 * Returns the floating point value of the given key.
+	 *
+	 * @param key the key
+	 * @return the value, or <code>null</code> if the key was not found or was found
+	 *   but was not a floating point number
+	 */
+	public Float getFloat(String key);
+	
+	/**
+	 * Returns the id for this memento.
+	 *
+	 * @return the memento id, or <code>null</code> if none
+	 * @see #createChild(java.lang.String,java.lang.String)
+	 */
+	public String getId();
+	
+	/**
+	 * Returns the name for this memento.
+	 *
+	 * @return the memento name, or <code>null</code> if none
+	 * @see #createChild(java.lang.String,java.lang.String)
+	 */
+	public String getName();
+
+	/**
+	 * Returns the integer value of the given key.
+	 *
+	 * @param key the key
+	 * @return the value, or <code>null</code> if the key was not found or was found
+	 *   but was not an integer
+	 */
+	public Integer getInteger(String key);
+
+	/**
+	 * Returns the string value of the given key.
+	 *
+	 * @param key the key
+	 * @return the value, or <code>null</code> if the key was not found or was found
+	 *  but was not an integer
+	 */
+	public String getString(String key);
+
+	/**
+	 * Returns the boolean value of the given key.
+	 *
+	 * @param key the key
+	 * @return the value, or <code>null</code> if the key was not found or was found
+	 *  but was not a boolean
+	 */
+	public Boolean getBoolean(String key);
+	
+	/**
+	 * Return the list of names.
+	 * 
+	 * @return a possibly empty list of names
+	 */
+	public List getNames();
+	
+	/**
+	 * Sets the value of the given key to the given floating point number.
+	 *
+	 * @param key the key
+	 * @param value the value
+	 */
+	public void putFloat(String key, float value);
+	
+	/**
+	 * Sets the value of the given key to the given integer.
+	 *
+	 * @param key the key
+	 * @param value the value
+	 */
+	public void putInteger(String key, int value);
+	
+	/**
+	 * Sets the value of the given key to the given boolean value.
+	 *
+	 * @param key the key
+	 * @param value the value
+	 */
+	public void putBoolean(String key, boolean value);
+
+	/**
+	 * Copy the attributes and children from  <code>memento</code>
+	 * to the receiver.
+	 *
+	 * @param memento the IMemento to be copied.
+	 */
+	public void putMemento(IMemento memento);
+
+	/**
+	 * Sets the value of the given key to the given string.
+	 *
+	 * @param key the key
+	 * @param value the value
+	 */
+	public void putString(String key, String value);
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/Messages.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/Messages.java
new file mode 100644
index 0000000..cc068bd
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/Messages.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import org.eclipse.osgi.util.NLS;
+/**
+ * Translated messages.
+ */
+public class Messages extends NLS {
+	public static String canModifyModules;
+	public static String httpPort;
+
+	public static String errorPortInUse;
+	public static String errorPublish;
+
+	static {
+		NLS.initializeMessages(PreviewPlugin.PLUGIN_ID + ".internal.Messages", Messages.class);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/Messages.properties b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/Messages.properties
new file mode 100644
index 0000000..e42ed17
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/Messages.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+httpPort=HTTP Port
+canModifyModules=Web modules can be modified.
+
+errorPublish=Error during publish
+errorPortInUse=Port {0} required by {1} is already in use. The server may already be running in another process, or a system process may be using the port. \
+  To start this server you will need to stop the other process or change the port number(s).
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PingThread.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PingThread.java
new file mode 100644
index 0000000..fec3693
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PingThread.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import java.io.FileNotFoundException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.eclipse.wst.server.core.IServer;
+/**
+ * Thread used to ping server to test when it is started.
+ */
+public class PingThread {
+	// delay before pinging starts
+	private static final int PING_DELAY = 2000;
+
+	// delay between pings
+	private static final int PING_INTERVAL = 250;
+
+	// maximum number of pings before giving up
+	private int maxPings = 40;
+
+	private boolean stop = false;
+	private String url;
+	private IServer server;
+	private PreviewServerBehaviour behaviour;
+
+	/**
+	 * Create a new PingThread.
+	 * 
+	 * @param server
+	 * @param url
+	 * @param behaviour
+	 */
+	public PingThread(IServer server, String url, PreviewServerBehaviour behaviour) {
+		super();
+		this.server = server;
+		this.url = url;
+		this.behaviour = behaviour;
+		Thread t = new Thread("Preview Ping Thread") {
+			public void run() {
+				ping();
+			}
+		};
+		t.setDaemon(true);
+		t.start();
+	}
+
+	/**
+	 * Ping the server until it is started. Then set the server
+	 * state to STATE_STARTED.
+	 */
+	protected void ping() {
+		int count = 0;
+		try {
+			Thread.sleep(PING_DELAY);
+		} catch (Exception e) {
+			// ignore
+		}
+		while (!stop) {
+			try {
+				if (count == maxPings) {
+					try {
+						server.stop(false);
+					} catch (Exception e) {
+						Trace.trace(Trace.FINEST, "Ping: could not stop server");
+					}
+					stop = true;
+					break;
+				}
+				count++;
+				
+				Trace.trace(Trace.FINEST, "Ping: pinging " + count);
+				URL pingUrl = new URL(url);
+				URLConnection conn = pingUrl.openConnection();
+				((HttpURLConnection)conn).getResponseCode();
+	
+				// ping worked - server is up
+				if (!stop) {
+					Trace.trace(Trace.FINEST, "Ping: success");
+					Thread.sleep(200);
+					behaviour.setServerStarted();
+				}
+				stop = true;
+			} catch (FileNotFoundException fe) {
+				try {
+					Thread.sleep(200);
+				} catch (Exception e) {
+					// ignore
+				}
+				behaviour.setServerStarted();
+				stop = true;
+			} catch (Exception e) {
+				Trace.trace(Trace.FINEST, "Ping: failed");
+				// pinging failed
+				if (!stop) {
+					try {
+						Thread.sleep(PING_INTERVAL);
+					} catch (InterruptedException e2) {
+						// ignore
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Tell the pinging to stop.
+	 */
+	public void stop() {
+		Trace.trace(Trace.FINEST, "Ping: stopping");
+		stop = true;
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewLaunchConfigurationDelegate.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewLaunchConfigurationDelegate.java
new file mode 100644
index 0000000..b56c41d
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewLaunchConfigurationDelegate.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+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.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
+import org.eclipse.osgi.service.environment.Constants;
+
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.ServerUtil;
+import org.osgi.framework.Bundle;
+/**
+ * 
+ */
+public class PreviewLaunchConfigurationDelegate extends LaunchConfigurationDelegate {
+	private static final String[] REQUIRED_BUNDLE_IDS = new String[] {
+		"org.eclipse.core.runtime",
+		"org.apache.commons.logging",
+		"javax.servlet",
+		"javax.servlet.jsp",
+		"org.mortbay.jetty",
+		"org.eclipse.wst.server.preview"
+	};
+
+	private static final String[] fgCandidateJavaFiles = {"javaw", "javaw.exe", "java",
+		"java.exe", "j9w", "j9w.exe", "j9", "j9.exe"};
+	private static final String[] fgCandidateJavaLocations = {"bin" + File.separatorChar,
+		"jre" + File.separatorChar + "bin" + File.separatorChar};
+
+	private static final String MAIN_CLASS = "org.eclipse.wst.server.preview.internal.PreviewStarter";
+
+	public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+		IServer server = ServerUtil.getServer(configuration);
+		if (server == null) {
+			Trace.trace(Trace.FINEST, "Launch configuration could not find server");
+			// throw CoreException();
+			return;
+		}
+		
+		PreviewServerBehaviour previewServer = (PreviewServerBehaviour) server.loadAdapter(PreviewServerBehaviour.class, null);
+		
+		int size = REQUIRED_BUNDLE_IDS.length;
+		//String[] jars = new String[size];
+		StringBuffer cp = new StringBuffer();
+		for (int i = 0; i < size; i++) {
+			Bundle b = Platform.getBundle(REQUIRED_BUNDLE_IDS[i]);
+			IPath path = null;
+			if (b != null)
+				path = PreviewRuntime.getJarredPluginPath(b);
+			if (path == null)
+				throw new CoreException(new Status(IStatus.ERROR, PreviewPlugin.PLUGIN_ID, "Could not find required bundle " + REQUIRED_BUNDLE_IDS[i]));
+			
+			if (i == 5 && path.append("bin").toFile().exists())
+				path = path.append("bin");
+			
+			if (i > 0)
+				cp.append(File.pathSeparator);
+			cp.append(path.toOSString());
+		}
+		
+		List cmds = new ArrayList();
+		
+		// jre
+		File java = getJavaExecutable();
+		if (java == null)
+			throw new CoreException(new Status(IStatus.ERROR, PreviewPlugin.PLUGIN_ID, "Could not find JRE executable"));
+		
+		cmds.add(java.getAbsolutePath());
+		
+		cmds.add("-classpath");
+		cmds.add(cp.toString());
+		
+		cmds.add(MAIN_CLASS);
+		
+		cmds.add(previewServer.getTempDirectory().append("preview.xml").toOSString());
+		
+		//setDefaultSourceLocator(launch, configuration);
+		
+		// launch the configuration
+		previewServer.setupLaunch(launch, mode, monitor);
+		
+		try {
+			String[] cmdLine = new String[cmds.size()];
+			cmds.toArray(cmdLine);
+			Process p = DebugPlugin.exec(cmdLine, null);
+			if (p != null) {
+				IProcess pr = DebugPlugin.newProcess(launch, p, "Preview!");
+				if (pr != null)
+					launch.addProcess(pr);
+			}
+			previewServer.setProcess(launch.getProcesses()[0]);
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Problem creating preview process");
+		}
+	}
+
+	protected static File getJavaExecutable() {
+		// do not detect on the Mac OS
+		if (Platform.getOS().equals(Constants.OS_MACOSX))
+			return null;
+		
+		// Retrieve the 'java.home' system property.  If that directory doesn't exist, 
+		// return null.
+		File javaHome; 
+		try {
+			javaHome = new File(System.getProperty("java.home")).getCanonicalFile();
+		} catch (IOException e) {
+			return null;
+		}
+		if (!javaHome.exists())
+			return null;
+		
+		// Find the 'java' executable file under the java home directory.  If it can't be
+		// found, return null.
+		return findJavaExecutable(javaHome);
+	}
+
+	protected static File findJavaExecutable(File vmInstallLocation) {
+		// Try each candidate in order.  The first one found wins.  Thus, the order
+		// of fgCandidateJavaLocations and fgCandidateJavaFiles is significant.
+		for (int i = 0; i < fgCandidateJavaFiles.length; i++) {
+			for (int j = 0; j < fgCandidateJavaLocations.length; j++) {
+				File javaFile = new File(vmInstallLocation, fgCandidateJavaLocations[j] + fgCandidateJavaFiles[i]);
+				if (javaFile.isFile()) {
+					return javaFile;
+				}				
+			}
+		}		
+		return null;							
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewLaunchableAdapterDelegate.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewLaunchableAdapterDelegate.java
new file mode 100644
index 0000000..be5980b
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewLaunchableAdapterDelegate.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.server.core.IModuleArtifact;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.model.LaunchableAdapterDelegate;
+import org.eclipse.wst.server.core.util.HttpLaunchable;
+import org.eclipse.wst.server.core.util.WebResource;
+
+public class PreviewLaunchableAdapterDelegate extends LaunchableAdapterDelegate {
+	/*
+	 * @see LaunchableAdapterDelegate#getLaunchable(IServer, IModuleArtifact)
+	 */
+	public Object getLaunchable(IServer server, IModuleArtifact moduleArtifact) throws CoreException {
+		if (server == null || moduleArtifact == null)
+			return null;
+		
+		PreviewServer server2 = (PreviewServer) server.loadAdapter(PreviewServer.class, null);
+		if (server2 == null)
+			return null;
+		
+		try {
+			URL url = server2.getModuleRootURL(moduleArtifact.getModule());
+			
+			if (moduleArtifact instanceof WebResource) {
+				WebResource resource = (WebResource) moduleArtifact;
+				String path = resource.getPath().toString();
+				
+				if (path.startsWith("/"))
+					path = path.substring(1);
+				url = new URL(url.toExternalForm() + "/" + path);
+			}
+			return new HttpLaunchable(url);
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error in launchable adapter", e);
+		}
+		
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewPlugin.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewPlugin.java
new file mode 100644
index 0000000..d0a3915
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewPlugin.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+/**
+ * The HTTP server core plugin.
+ */
+public class PreviewPlugin extends Plugin {
+	public static final String PLUGIN_ID = "org.eclipse.wst.server.preview.adapter";
+
+	private static PreviewPlugin plugin;
+
+	/**
+	 * The constructor
+	 */
+	public PreviewPlugin() {
+		plugin = this;
+	}
+
+	/**
+	 * Returns the singleton instance of this plugin.
+	 * 
+	 * @return an instance
+	 */
+	public static PreviewPlugin getInstance() {
+		return plugin;
+	}
+
+	/**
+	 * Return the install location preference.
+	 * 
+	 * @param id a runtime type id
+	 * @return the install location
+	 */
+	public static String getPreference(String id) {
+		return getInstance().getPluginPreferences().getString(id);
+	}
+
+	/**
+	 * Set the install location preference.
+	 * 
+	 * @param id the runtimt type id
+	 * @param value the location
+	 */
+	public static void setPreference(String id, String value) {
+		getInstance().getPluginPreferences().setValue(id, value);
+		getInstance().savePluginPreferences();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewRuntime.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewRuntime.java
new file mode 100644
index 0000000..ab2c90b
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewRuntime.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.wst.server.core.model.RuntimeDelegate;
+import org.osgi.framework.Bundle;
+/**
+ * HTTP preview runtime.
+ */
+public class PreviewRuntime extends RuntimeDelegate {
+	public static final String ID = "org.eclipse.wst.server.preview.runtime";
+
+	/**
+	 * Create a new preview runtime.
+	 */
+	public PreviewRuntime() {
+		// do nothing
+	}
+
+	/**
+	 * Returns the path that corresponds to the specified bundle.
+	 * 
+	 * @return a path
+	 */
+	protected static Path getPluginPath(Bundle bundle) {
+		try {
+			URL installURL = bundle.getEntry("/");
+			URL localURL = FileLocator.toFileURL(installURL);
+			return new Path(localURL.getFile());
+		} catch (IOException ioe) {
+			return null;
+		}
+	}
+
+	protected static IPath getJarredPluginPath(Bundle bundle) {
+		Path runtimeLibFullPath = null;
+		String jarPluginLocation = bundle.getLocation().substring(7);
+		
+		// handle case where jars are installed outside of eclipse installation
+		Path jarPluginPath = new Path(jarPluginLocation);
+		if (jarPluginPath.isAbsolute())
+			runtimeLibFullPath = jarPluginPath;
+		// handle normal case where all plugins under eclipse install
+		else {
+			int ind = jarPluginLocation.lastIndexOf(":");
+			if (ind > 0)
+				jarPluginLocation = jarPluginLocation.substring(ind+1);
+			
+			String installPath = Platform.getInstallLocation().getURL().getPath();
+			runtimeLibFullPath = new Path(installPath+"/"+jarPluginLocation);
+		}
+		return runtimeLibFullPath;
+	}
+
+	/**
+	 * @see RuntimeDelegate#setDefaults(IProgressMonitor)
+	 */
+	public void setDefaults(IProgressMonitor monitor) {
+		getRuntimeWorkingCopy().setLocation(new Path(""));
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewServer.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewServer.java
new file mode 100644
index 0000000..7d613bd
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewServer.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.IRuntime;
+import org.eclipse.wst.server.core.IRuntimeType;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.IServerType;
+import org.eclipse.wst.server.core.IServerWorkingCopy;
+import org.eclipse.wst.server.core.ServerCore;
+import org.eclipse.wst.server.core.ServerPort;
+import org.eclipse.wst.server.core.model.IURLProvider;
+import org.eclipse.wst.server.core.model.ServerDelegate;
+import org.eclipse.wst.server.core.util.IStaticWeb;
+/**
+ * HTTP preview server.
+ */
+public class PreviewServer extends ServerDelegate implements IURLProvider {
+	public static final String ID = "org.eclipse.wst.server.preview.server";
+
+	public static final String PROPERTY_PORT = "port";
+
+	/**
+	 * PreviewServer.
+	 */
+	public PreviewServer() {
+		super();
+	}
+
+	protected void initialize() {
+		// do nothing
+	}
+
+	public PreviewRuntime getPreviewRuntime() {
+		if (getServer().getRuntime() == null)
+			return null;
+		
+		return (PreviewRuntime) getServer().getRuntime().loadAdapter(PreviewRuntime.class, null);
+	}
+
+	/**
+	 * Return the root URL of this module.
+	 * 
+	 * @param module a module
+	 * @return java.net.URL
+	 */
+	public URL getModuleRootURL(IModule module) {
+		try {
+			String base = "http://localhost";
+			
+			int port = getPort();
+			URL url = null;
+			if (port == 80)
+				url = new URL(base + "/");
+			else
+				url = new URL(base + ":" + port + "/");
+			
+			String type = module.getModuleType().getId();
+			if ("wst.web".equals(type)) {
+				IStaticWeb staticWeb = (IStaticWeb) module.loadAdapter(IStaticWeb.class, null);
+				return new URL(url, staticWeb.getContextRoot());
+			}
+			return url;
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Could not get root URL", e);
+			return null;
+		}
+	}
+
+	/*
+	 * Returns the child module(s) of this module.
+	 */
+	public IModule[] getChildModules(IModule[] module) {
+		return new IModule[0];
+	}
+
+	/*
+	 * Returns the root module(s) of this module.
+	 */
+	public IModule[] getRootModules(IModule module) throws CoreException {
+		return new IModule[] { module };
+	}
+
+	/**
+	 * Returns true if the given project is supported by this server, and false
+	 * otherwise.
+	 * 
+	 * @param add modules
+	 * @param remove modules
+	 * @return the status
+	 */
+	public IStatus canModifyModules(IModule[] add, IModule[] remove) {
+		return new Status(IStatus.OK, PreviewPlugin.PLUGIN_ID, 0, Messages.canModifyModules, null);
+	}
+
+	public ServerPort[] getServerPorts() {
+		int port = getPort();
+		ServerPort[] ports = { new ServerPort("http", Messages.httpPort, port, "http") };
+		return ports;
+	}
+
+	public int getPort() {
+		return getAttribute(PreviewServer.PROPERTY_PORT, 8080);
+	}
+
+	public void setPort(int port) {
+		setAttribute(PreviewServer.PROPERTY_PORT, port);
+	}
+
+	public static IServer createPreviewServer(String serverName) {
+		try {
+			NullProgressMonitor monitor = new NullProgressMonitor();
+			IRuntimeType runtimeType = ServerCore.findRuntimeType(PreviewRuntime.ID);
+			IRuntimeWorkingCopy runtimeCopy = runtimeType.createRuntime(PreviewRuntime.ID, monitor);
+			IRuntime runtime = runtimeCopy.save(true, monitor);
+			
+			IServerType serverType = ServerCore.findServerType(ID);
+			IServerWorkingCopy workingCopy = serverType.createServer(ID, null, runtime, monitor);
+			workingCopy.setName(serverName);
+			workingCopy.setHost("localhost");
+			return workingCopy.save(true, monitor);
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error creating server", e);
+		}
+		
+		return null;
+	}
+
+	public static IServer findPreviewServer(String id) {
+		IServer[] servers = ServerCore.getServers();
+		for (int i = 0; i < servers.length; i++) {
+			if (servers[i].getId().equals(id)) {
+				return servers[i];
+			}
+		}
+		return null;
+	}
+
+	public void modifyModules(IModule[] add, IModule[] remove, IProgressMonitor monitor) throws CoreException {
+		// do nothing
+	}
+
+	/**
+	 * Return a string representation of this object.
+	 * 
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return "PreviewServer";
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewServerBehaviour.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewServerBehaviour.java
new file mode 100644
index 0000000..7d87bb3
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewServerBehaviour.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import java.io.IOException;
+
+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.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IDebugEventSetListener;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.ServerPort;
+import org.eclipse.wst.server.core.model.IModuleResource;
+import org.eclipse.wst.server.core.model.IModuleResourceDelta;
+import org.eclipse.wst.server.core.model.ServerBehaviourDelegate;
+import org.eclipse.wst.server.core.util.IStaticWeb;
+import org.eclipse.wst.server.core.util.PublishUtil;
+import org.eclipse.wst.server.core.util.SocketUtil;
+/**
+ * Generic Http server.
+ */
+public class PreviewServerBehaviour extends ServerBehaviourDelegate {
+	// the thread used to ping the server to check for startup
+	protected transient PingThread ping = null;
+	protected transient IProcess process;
+	protected transient IDebugEventSetListener processListener;
+
+	/**
+	 * PreviewServer.
+	 */
+	public PreviewServerBehaviour() {
+		super();
+	}
+
+	public void initialize(IProgressMonitor monitor) {
+		// do nothing
+	}
+
+	public PreviewRuntime getPreviewRuntime() {
+		if (getServer().getRuntime() == null)
+			return null;
+
+		return (PreviewRuntime) getServer().getRuntime().loadAdapter(PreviewRuntime.class, null);
+	}
+
+	public PreviewServer getPreviewServer() {
+		return (PreviewServer) getServer().getAdapter(PreviewServer.class);
+	}
+
+	/**
+	 * Returns the runtime base path for relative paths in the server
+	 * configuration.
+	 * 
+	 * @return the base path
+	 */
+	public IPath getRuntimeBaseDirectory() {
+		return getServer().getRuntime().getLocation();
+	}
+
+	/**
+	 * Setup for starting the server.
+	 * 
+	 * @param launch ILaunch
+	 * @param launchMode String
+	 * @param monitor IProgressMonitor
+	 * @throws CoreException if anything goes wrong
+	 */
+	protected void setupLaunch(ILaunch launch, String launchMode, IProgressMonitor monitor) throws CoreException {
+		// check that ports are free
+		ServerPort[] ports = getPreviewServer().getServerPorts();
+		int port = ports[0].getPort();
+		
+		if (SocketUtil.isPortInUse(port, 5))
+			throw new CoreException(new Status(IStatus.ERROR, PreviewPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorPortInUse, new String[] {port + "", getServer().getName()}), null));
+		
+		// generate preview config file
+		XMLMemento memento = XMLMemento.createWriteRoot("server");
+		memento.putInteger("port", port);
+		
+		IModule[] modules = getServer().getModules();
+		int size = modules.length;
+		for (int i = 0; i < size; i++) {
+			IMemento mod = memento.createChild("module");
+			mod.putString("name", modules[i].getName());
+			String type = modules[i].getModuleType().getId();
+			if ("wst.web".equals(type)) {
+				IStaticWeb staticWeb = (IStaticWeb) modules[i].loadAdapter(IStaticWeb.class, null);
+				mod.putString("context", staticWeb.getContextRoot());
+				mod.putString("type", "static");
+			}
+			mod.putString("path", getModulePublishDirectory(modules[i]).toPortableString());
+		}
+		try {
+			memento.saveToFile(getTempDirectory().append("preview.xml").toOSString());
+		} catch (IOException e) {
+			Trace.trace(Trace.SEVERE, "Could not write preview config", e);
+			throw new CoreException(new Status(IStatus.ERROR, PreviewPlugin.PLUGIN_ID, 0, "Could not write preview configuration", null));
+		}
+		
+		setServerRestartState(false);
+		setServerState(IServer.STATE_STARTING);
+		setMode(launchMode);
+		
+		// ping server to check for startup
+		try {
+			String url = "http://localhost";
+			if (port != 80)
+				url += ":" + port;
+			ping = new PingThread(getServer(), url, this);
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Can't ping for Tomcat startup.");
+		}
+	}
+
+	protected void setProcess(final IProcess newProcess) {
+		if (process != null)
+			return;
+		
+		process = newProcess;
+		if (processListener != null)
+			DebugPlugin.getDefault().removeDebugEventListener(processListener);
+		if (newProcess == null)
+			return;
+		
+		processListener = new IDebugEventSetListener() {
+			public void handleDebugEvents(DebugEvent[] events) {
+				if (events != null) {
+					int size = events.length;
+					for (int i = 0; i < size; i++) {
+						Object obj = events[i].getSource();
+						
+						if (!(obj instanceof IDebugTarget))
+							continue;
+						
+						IDebugTarget target = (IDebugTarget) obj;
+						IProcess targetProcess = target.getProcess();
+						
+						if (process != null && process.equals(targetProcess)
+								&& events[i].getKind() == DebugEvent.TERMINATE) {
+							DebugPlugin.getDefault().removeDebugEventListener(this);
+							stopImpl();
+						}
+					}
+				}
+			}
+		};
+		DebugPlugin.getDefault().addDebugEventListener(processListener);
+	}
+
+	protected void setServerStarted() {
+		setServerState(IServer.STATE_STARTED);
+	}
+
+	protected void stopImpl() {
+		if (ping != null) {
+			ping.stop();
+			ping = null;
+		}
+		if (process != null) {
+			process = null;
+			DebugPlugin.getDefault().removeDebugEventListener(processListener);
+			processListener = null;
+		}
+		setServerState(IServer.STATE_STOPPED);
+	}
+
+	protected void publishServer(int kind, IProgressMonitor monitor) throws CoreException {
+		monitor = ProgressUtil.getMonitorFor(monitor);
+		monitor.done();
+
+		setServerPublishState(IServer.PUBLISH_STATE_NONE);
+	}
+
+	/*
+	 * Publishes the given module to the server.
+	 */
+	protected void publishModule(int kind, int deltaKind, IModule[] moduleTree, IProgressMonitor monitor) throws CoreException {
+		IModule module = moduleTree[moduleTree.length - 1]; 
+		IPath to = getModulePublishDirectory(module);
+		
+		if (kind == IServer.PUBLISH_CLEAN || deltaKind == ServerBehaviourDelegate.REMOVED) {
+			IStatus[] status = PublishUtil.deleteDirectory(to.toFile(), monitor);
+			throwException(status);
+		}
+		
+		IModuleResource[] res = getResources(moduleTree);
+		IStatus[] status = PublishUtil.publishSmart(res, to, monitor);
+		throwException(status);
+		
+		setModulePublishState(moduleTree, IServer.PUBLISH_STATE_NONE);
+	}
+
+	/**
+	 * Utility method to throw a CoreException based on the contents of a list of
+	 * error and warning status.
+	 * 
+	 * @param status a List containing error and warning IStatus
+	 * @throws CoreException
+	 */
+	private static void throwException(IStatus[] status) throws CoreException {
+		if (status == null || status.length == 0)
+			return;
+		
+		if (status.length == 1)
+			throw new CoreException(status[0]);
+		
+		String message = Messages.errorPublish;
+		MultiStatus status2 = new MultiStatus(PreviewPlugin.PLUGIN_ID, 0, status, message, null);
+		throw new CoreException(status2);
+	}
+
+	public void restart(String launchMode) throws CoreException {
+		setServerState(IServer.STATE_STOPPED);
+		setServerState(IServer.STATE_STARTED);
+	}
+
+	/**
+	 * Cleanly shuts down and terminates the server.
+	 * 
+	 * @param force <code>true</code> to kill the server
+	 */
+	public void stop(boolean force) {
+		if (force) {
+			terminate();
+			return;
+		}
+		int state = getServer().getServerState();
+		if (state == IServer.STATE_STOPPED)
+			return;
+		else if (state == IServer.STATE_STARTING || state == IServer.STATE_STOPPING) {
+			terminate();
+			return;
+		}
+		
+		// should really try to stop normally
+		terminate();
+	}
+
+	/**
+	 * Terminates the server.
+	 */
+	protected void terminate() {
+		if (getServer().getServerState() == IServer.STATE_STOPPED)
+			return;
+		
+		try {
+			setServerState(IServer.STATE_STOPPING);
+			Trace.trace(Trace.FINEST, "Killing the HTTP process");
+			if (process != null && !process.isTerminated())
+				process.terminate();
+			
+			stopImpl();
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error killing the process", e);
+		}
+	}
+
+	protected IPath getTempDirectory() {
+		return super.getTempDirectory();
+	}
+
+	/**
+	 * Returns the module's publish path.
+	 * 
+	 * @param module a module
+	 * @return the publish directory for the module
+	 */
+	protected IPath getModulePublishDirectory(IModule module) {
+		return getTempDirectory().append(module.getName());
+	}
+
+	/**
+	 * Return a string representation of this object.
+	 * 
+	 * @return java.lang.String
+	 */
+	public String toString() {
+		return "PreviewServer";
+	}
+
+	protected IModuleResourceDelta[] getPublishedResourceDelta(IModule[] module) {
+		return super.getPublishedResourceDelta(module);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewStartup.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewStartup.java
new file mode 100644
index 0000000..f200c69
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/PreviewStartup.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.wst.server.core.IRuntime;
+import org.eclipse.wst.server.core.IRuntimeType;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.IServerType;
+import org.eclipse.wst.server.core.IServerWorkingCopy;
+import org.eclipse.wst.server.core.ServerCore;
+import org.eclipse.wst.server.core.internal.IStartup;
+
+public class PreviewStartup implements IStartup {
+	private static final String ID = "xyz"; 
+
+	public void startup() {
+		// create runtime
+		IRuntime[] runtimes = ServerCore.getRuntimes();
+		IRuntime runtime = null;
+		
+		int size = runtimes.length;
+		for (int i = 0; i < size; i++) {
+			if (runtimes[i].getRuntimeType() != null && PreviewRuntime.ID.equals(runtimes[i].getRuntimeType().getId())) {
+				if (ID.equals(runtimes[i].getId()))
+					runtime = runtimes[i];
+			}
+		}
+		
+		if (runtime == null) {
+			try {
+				IRuntimeType runtimeType = ServerCore.findRuntimeType(PreviewRuntime.ID);
+				IRuntimeWorkingCopy wc = runtimeType.createRuntime(ID, null);
+				wc.setName("My Preview");
+				wc.setReadOnly(true);
+				runtime = wc.save(true, null);
+			} catch (CoreException ce) {
+				Trace.trace(Trace.WARNING, "Could not create default preview runtime");
+			}
+		}
+		
+		// create server
+		IServer[] servers = ServerCore.getServers();
+		
+		boolean found = false;
+		size = servers.length;
+		for (int i = 0; i < size; i++) {
+			if (servers[i].getServerType() != null && PreviewServer.ID.equals(servers[i].getServerType().getId())) {
+				if (ID.equals(servers[i].getId()))
+					found = true;
+			}
+		}
+		
+		if (!found) {
+			try {
+				IServerType serverType = ServerCore.findServerType(PreviewServer.ID);
+				IServerWorkingCopy wc = serverType.createServer(ID, null, runtime, null);
+				wc.setName("My preview");
+				wc.setHost("localhost");
+				wc.setReadOnly(true);
+				wc.save(true, null);
+			} catch (CoreException ce) {
+				Trace.trace(Trace.WARNING, "Could not create default preview server");
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/ProgressUtil.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/ProgressUtil.java
new file mode 100644
index 0000000..fc12e36
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/ProgressUtil.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import org.eclipse.core.runtime.*;
+/**
+ * Progress Monitor utility.
+ */
+public class ProgressUtil {
+	/**
+	 * ProgressUtil constructor comment.
+	 */
+	private ProgressUtil() {
+		super();
+	}
+
+	/**
+	 * Return a valid progress monitor.
+	 *
+	 * @param monitor org.eclipse.core.runtime.IProgressMonitor
+	 * @return org.eclipse.core.runtime.IProgressMonitor
+	 */
+	public static IProgressMonitor getMonitorFor(IProgressMonitor monitor) {
+		if (monitor == null)
+			return new NullProgressMonitor();
+		return monitor;
+	}
+
+	/**
+	 * Return a sub-progress monitor with the given amount on the
+	 * current progress monitor.
+	 *
+	 * @param monitor org.eclipse.core.runtime.IProgressMonitor
+	 * @param ticks int
+	 * @return org.eclipse.core.runtime.IProgressMonitor
+	 */
+	public static IProgressMonitor getSubMonitorFor(IProgressMonitor monitor, int ticks) {
+		if (monitor == null)
+			return new NullProgressMonitor();
+		if (monitor instanceof NullProgressMonitor)
+			return monitor;
+		return new SubProgressMonitor(monitor, ticks);
+	}
+
+	/**
+	 * Return a sub-progress monitor with the given amount on the
+	 * current progress monitor.
+	 *
+	 * @param monitor org.eclipse.core.runtime.IProgressMonitor
+	 * @param ticks a number of ticks
+	 * @param style a style
+	 * @return org.eclipse.core.runtime.IProgressMonitor
+	 */
+	public static IProgressMonitor getSubMonitorFor(IProgressMonitor monitor, int ticks, int style) {
+		if (monitor == null)
+			return new NullProgressMonitor();
+		if (monitor instanceof NullProgressMonitor)
+			return monitor;
+		return new SubProgressMonitor(monitor, ticks, style);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/Trace.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/Trace.java
new file mode 100644
index 0000000..c1672cd
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/Trace.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Helper class to route trace output.
+ */
+public class Trace {
+	public static byte CONFIG = 0;
+	public static byte WARNING = 1;
+	public static byte SEVERE = 2;
+	public static byte FINEST = 3;
+	public static byte FINER = 4;
+	
+	private static final String[] levelNames = new String[] { "CONFIG   ", "WARNING  ",
+		"SEVERE   ", "FINER    ", "FINEST   " };
+
+	private static final String spacer = "                                   ";
+
+	private static final SimpleDateFormat sdf = new SimpleDateFormat(
+			"dd/MM/yy HH:mm.ss.SSS");
+
+	protected static int pluginLength = -1;
+
+	/**
+	 * Trace constructor comment.
+	 */
+	private Trace() {
+		super();
+	}
+
+	/**
+	 * Trace the given text.
+	 * 
+	 * @param level the trace level
+	 * @param s a message
+	 */
+	public static void trace(byte level, String s) {
+		Trace.trace(level, s, null);
+	}
+
+	/**
+	 * Trace the given message and exception.
+	 * 
+	 * @param level the trace level
+	 * @param s a message
+	 * @param t a throwable
+	 */
+	public static void trace(byte level, String s, Throwable t) {
+		if (!PreviewPlugin.getInstance().isDebugging())
+			return;
+
+		/*
+		 * System.out.println(ApachePlugin.PLUGIN_ID + " " + s); if (t != null)
+		 * t.printStackTrace();
+		 */
+		trace(PreviewPlugin.PLUGIN_ID, level, s, t);
+	}
+
+	/**
+	 * Trace the given message and exception.
+	 * 
+	 * @param level a trace level
+	 * @param s a message
+	 * @param t a throwable
+	 */
+	private static void trace(String pluginId, int level, String s, Throwable t) {
+		if (pluginId == null || s == null)
+			return;
+
+		if (!PreviewPlugin.getInstance().isDebugging())
+			return;
+
+		StringBuffer sb = new StringBuffer(pluginId);
+		if (pluginId.length() > pluginLength)
+			pluginLength = pluginId.length();
+		else if (pluginId.length() < pluginLength)
+			sb.append(spacer.substring(0, pluginLength - pluginId.length()));
+		sb.append(" ");
+		sb.append(levelNames[level]);
+		sb.append(" ");
+		sb.append(sdf.format(new Date()));
+		sb.append(" ");
+		sb.append(s);
+		// Platform.getDebugOption(ServerCore.PLUGIN_ID + "/" + "resources");
+
+		System.out.println(sb.toString());
+		if (t != null)
+			t.printStackTrace();
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/XMLMemento.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/XMLMemento.java
new file mode 100644
index 0000000..08a14ea
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/core/XMLMemento.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.core;
+
+import java.io.*;
+import java.util.*;
+
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+/**
+ * A Memento is a class independent container for persistence
+ * info.  It is a reflection of 3 storage requirements.
+ *
+ * 1)   We need the ability to persist an object and restore it.  
+ * 2)   The class for an object may be absent.  If so we would 
+ *      like to skip the object and keep reading. 
+ * 3)   The class for an object may change.  If so the new class 
+ *      should be able to read the old persistence info.
+ *
+ * We could ask the objects to serialize themselves into an 
+ * ObjectOutputStream, DataOutputStream, or Hashtable.  However 
+ * all of these approaches fail to meet the second requirement.
+ *
+ * Memento supports binary persistance with a version ID.
+ */
+public final class XMLMemento implements IMemento {
+	private Document factory;
+	private Element element;
+
+	/**
+	 * Answer a memento for the document and element.  For simplicity
+	 * you should use createReadRoot and createWriteRoot to create the initial
+	 * mementos on a document.
+	 */
+	private XMLMemento(Document doc, Element el) {
+		factory = doc;
+		element = el;
+	}
+
+	/**
+	 * @see IMemento#createChild(String)
+	 */
+	public IMemento createChild(String type) {
+		Element child = factory.createElement(type);
+		element.appendChild(child);
+		return new XMLMemento(factory, child);
+	}
+
+	/**
+	 * @see IMemento#createChild(String, String)
+	 */
+	public IMemento createChild(String type, String id) {
+		Element child = factory.createElement(type);
+		child.setAttribute(TAG_ID, id);
+		element.appendChild(child);
+		return new XMLMemento(factory, child);
+	}
+
+	/**
+	 * Create a Document from a Reader and answer a root memento for reading 
+	 * a document.
+	 */
+	protected static XMLMemento createReadRoot(InputStream in) {
+		Document document = null;
+		try {
+			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+			DocumentBuilder parser = factory.newDocumentBuilder();
+			document = parser.parse(new InputSource(in));
+			Node node = document.getFirstChild();
+			if (node instanceof Element)
+				return new XMLMemento(document, (Element) node);
+		} catch (Exception e) {
+			// ignore
+		} finally {
+			try {
+				in.close();
+			} catch (Exception e) {
+				// ignore
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * Answer a root memento for writing a document.
+	 * 
+	 * @param type a type
+	 * @return a memento
+	 */
+	public static XMLMemento createWriteRoot(String type) {
+		Document document;
+		try {
+			document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+			Element element = document.createElement(type);
+			document.appendChild(element);
+			return new XMLMemento(document, element);            
+		} catch (ParserConfigurationException e) {
+			throw new Error(e);
+		}
+	}
+	
+	/*
+	 * @see IMemento
+	 */
+	public IMemento getChild(String type) {
+		// Get the nodes.
+		NodeList nodes = element.getChildNodes();
+		int size = nodes.getLength();
+		if (size == 0)
+			return null;
+	
+		// Find the first node which is a child of this node.
+		for (int nX = 0; nX < size; nX ++) {
+			Node node = nodes.item(nX);
+			if (node instanceof Element) {
+				Element element2 = (Element)node;
+				if (element2.getNodeName().equals(type))
+					return new XMLMemento(factory, element2);
+			}
+		}
+	
+		// A child was not found.
+		return null;
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public IMemento [] getChildren(String type) {
+		// Get the nodes.
+		NodeList nodes = element.getChildNodes();
+		int size = nodes.getLength();
+		if (size == 0)
+			return new IMemento[0];
+	
+		// Extract each node with given type.
+		ArrayList list = new ArrayList(size);
+		for (int nX = 0; nX < size; nX ++) {
+			Node node = nodes.item(nX);
+			if (node instanceof Element) {
+				Element element2 = (Element)node;
+				if (element2.getNodeName().equals(type))
+					list.add(element2);
+			}
+		}
+	
+		// Create a memento for each node.
+		size = list.size();
+		IMemento [] results = new IMemento[size];
+		for (int x = 0; x < size; x ++) {
+			results[x] = new XMLMemento(factory, (Element)list.get(x));
+		}
+		return results;
+	}
+
+	/**
+	 * Return the contents of this memento as a byte array.
+	 *
+	 * @return byte[]
+	 * @throws IOException if anything goes wrong
+	 */
+	public byte[] getContents() throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		save(out);
+		return out.toByteArray();
+	}
+
+	/**
+	 * Returns an input stream for writing to the disk with a local locale.
+	 *
+	 * @return java.io.InputStream
+	 * @throws IOException if anything goes wrong
+	 */
+	public InputStream getInputStream() throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		save(out);
+		return new ByteArrayInputStream(out.toByteArray());
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public Float getFloat(String key) {
+		Attr attr = element.getAttributeNode(key);
+		if (attr == null)
+			return null; 
+		String strValue = attr.getValue();
+		try {
+			return new Float(strValue);
+		} catch (NumberFormatException e) {
+			return null;
+		}
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public String getId() {
+		return element.getAttribute(TAG_ID);
+	}
+	
+	/*
+	 * @see IMemento
+	 */
+	public String getName() {
+		return element.getNodeName();
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public Integer getInteger(String key) {
+		Attr attr = element.getAttributeNode(key);
+		if (attr == null)
+			return null; 
+		String strValue = attr.getValue();
+		try {
+			return new Integer(strValue);
+		} catch (NumberFormatException e) {
+			return null;
+		}
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public String getString(String key) {
+		Attr attr = element.getAttributeNode(key);
+		if (attr == null)
+			return null; 
+		return attr.getValue();
+	}
+	
+	public List getNames() {
+		NamedNodeMap map = element.getAttributes();
+		int size = map.getLength();
+		List list = new ArrayList();
+		for (int i = 0; i < size; i++) {
+			Node node = map.item(i);
+			String name = node.getNodeName();
+			list.add(name);
+		}
+		return list;
+	}
+
+	/**
+	 * Loads a memento from the given filename.
+	 *
+	 * @param filename java.lang.String
+	 * @exception java.io.IOException
+	 * @return a memento
+	 */
+	public static IMemento loadMemento(String filename) throws IOException {
+		InputStream in = null;
+		try {
+			in = new BufferedInputStream(new FileInputStream(filename));
+			return XMLMemento.createReadRoot(in);
+		} finally {
+			try {
+				if (in != null)
+					in.close();
+			} catch (Exception e) {
+				// ignore
+			}
+		}
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	private void putElement(Element element2) {
+		NamedNodeMap nodeMap = element2.getAttributes();
+		int size = nodeMap.getLength();
+		for (int i = 0; i < size; i++){
+			Attr attr = (Attr)nodeMap.item(i);
+			putString(attr.getName(),attr.getValue());
+		}
+		
+		NodeList nodes = element2.getChildNodes();
+		size = nodes.getLength();
+		for (int i = 0; i < size; i ++) {
+			Node node = nodes.item(i);
+			if (node instanceof Element) {
+				XMLMemento child = (XMLMemento)createChild(node.getNodeName());
+				child.putElement((Element)node);
+			}
+		}
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public void putFloat(String key, float f) {
+		element.setAttribute(key, String.valueOf(f));
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public void putInteger(String key, int n) {
+		element.setAttribute(key, String.valueOf(n));
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public void putMemento(IMemento memento) {
+		XMLMemento xmlMemento = (XMLMemento) memento;
+		putElement(xmlMemento.element);
+	}
+
+	/*
+	 * @see IMemento
+	 */
+	public void putString(String key, String value) {
+		if (value == null)
+			return;
+		element.setAttribute(key, value);
+	}
+	
+	/**
+	 * Save this Memento to a Writer.
+	 * 
+	 * @param os an output stream
+	 * @throws IOException if anything goes wrong
+	 */
+	public void save(OutputStream os) throws IOException {
+		Result result = new StreamResult(os);
+		Source source = new DOMSource(factory);
+		try {
+			Transformer transformer = TransformerFactory.newInstance().newTransformer();
+			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+			transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+			transformer.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2");
+			transformer.transform(source, result);
+		} catch (Exception e) {
+			throw (IOException) (new IOException().initCause(e));
+		}
+	}
+
+	/**
+	 * Saves the memento to the given file.
+	 *
+	 * @param filename java.lang.String
+	 * @exception java.io.IOException
+	 */
+	public void saveToFile(String filename) throws IOException {
+		FileOutputStream w = null;
+		try {
+			w = new FileOutputStream(filename);
+			save(w);
+		} catch (IOException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new IOException(e.getLocalizedMessage());
+		} finally {
+			if (w != null) {
+				try {
+					w.close();
+				} catch (Exception e) {
+					// ignore
+				}
+			}
+		}
+	}
+	
+	/*
+	 * @see IMemento#getBoolean(String)
+	 */
+	public Boolean getBoolean(String key) {
+		Attr attr = element.getAttributeNode(key);
+		if (attr == null)
+			return null;
+		String strValue = attr.getValue();
+		if ("true".equalsIgnoreCase(strValue))
+			return new Boolean(true);
+		return new Boolean(false);
+	}
+
+	/*
+	 * @see IMemento#putBoolean(String, boolean)
+	 */
+	public void putBoolean(String key, boolean value) {
+		element.setAttribute(key, value ? "true" : "false");
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/ui/PreviewLaunchConfigurationTabGroup.java b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/ui/PreviewLaunchConfigurationTabGroup.java
new file mode 100644
index 0000000..b411ce0
--- /dev/null
+++ b/plugins/org.eclipse.wst.server.preview.adapter/src/org/eclipse/wst/server/preview/internal/ui/PreviewLaunchConfigurationTabGroup.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.server.preview.internal.ui;
+
+import org.eclipse.debug.ui.*;
+
+import org.eclipse.wst.server.ui.ServerLaunchConfigurationTab;
+/**
+ * A debug tab group for launching Tomcat. 
+ */
+public class PreviewLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup {
+	/*
+	 * @see ILaunchConfigurationTabGroup#createTabs(ILaunchConfigurationDialog, String)
+	 */
+	public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[2];
+		tabs[0] = new ServerLaunchConfigurationTab(new String[] { "org.eclipse.wst.server.preview" });
+		tabs[0].setLaunchConfigurationDialog(dialog);
+		/*tabs[1] = new SourceLookupTab();
+		tabs[1].setLaunchConfigurationDialog(dialog);
+		tabs[2] = new EnvironmentTab();
+		tabs[2].setLaunchConfigurationDialog(dialog);*/
+		tabs[1] = new CommonTab();
+		tabs[1].setLaunchConfigurationDialog(dialog);
+		setTabs(tabs);
+	}
+}
\ No newline at end of file