[308916] Add Tomcat 7 support
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/build.properties b/plugins/org.eclipse.jst.server.tomcat.core/build.properties
index c90ba0b..378c1d5 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/build.properties
+++ b/plugins/org.eclipse.jst.server.tomcat.core/build.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2004, 2007 IBM Corporation and others.
+# Copyright (c) 2004, 2010 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -17,11 +17,13 @@
                about.html,\
                org.eclipse.jst.server.tomcat.runtime.50.loader.jar,\
                org.eclipse.jst.server.tomcat.runtime.55.loader.jar,\
-               org.eclipse.jst.server.tomcat.runtime.60.loader.jar
+               org.eclipse.jst.server.tomcat.runtime.60.loader.jar,\
+               org.eclipse.jst.server.tomcat.runtime.70.loader.jar
 bin.excludes = bin/**,\
                @dot/**,\
                temp.folder/**
 source.. = tomcatcore/
 src.includes = org.eclipse.jst.server.tomcat.runtime.50.loader-src.zip,\
                org.eclipse.jst.server.tomcat.runtime.55.loader-src.zip,\
-               org.eclipse.jst.server.tomcat.runtime.60.loader-src.zip
+               org.eclipse.jst.server.tomcat.runtime.60.loader-src.zip,\
+               org.eclipse.jst.server.tomcat.runtime.70.loader-src.zip
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/org.eclipse.jst.server.tomcat.runtime.70.loader-src.zip b/plugins/org.eclipse.jst.server.tomcat.core/org.eclipse.jst.server.tomcat.runtime.70.loader-src.zip
new file mode 100644
index 0000000..0701da9
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.tomcat.core/org.eclipse.jst.server.tomcat.runtime.70.loader-src.zip
Binary files differ
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/org.eclipse.jst.server.tomcat.runtime.70.loader.jar b/plugins/org.eclipse.jst.server.tomcat.core/org.eclipse.jst.server.tomcat.runtime.70.loader.jar
new file mode 100644
index 0000000..f1bd450
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.tomcat.core/org.eclipse.jst.server.tomcat.runtime.70.loader.jar
Binary files differ
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/plugin.properties b/plugins/org.eclipse.jst.server.tomcat.core/plugin.properties
index e560850..4e53496 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/plugin.properties
+++ b/plugins/org.eclipse.jst.server.tomcat.core/plugin.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2004, 2007 IBM Corporation and others.
+# Copyright (c) 2004, 2010 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -24,7 +24,9 @@
 runtimeTypeTomcat55Label=Apache Tomcat v5.5
 runtimeTypeTomcat55Description=Apache Tomcat v5.5 supports J2EE 1.2, 1.3, and 1.4 Web modules.
 runtimeTypeTomcat60Label=Apache Tomcat v6.0
-runtimeTypeTomcat60Description=Apache Tomcat v6.0 supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules.
+runtimeTypeTomcat60Description=Apache Tomcat v6.0 supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules.
+runtimeTypeTomcat70Label=Apache Tomcat v7.0
+runtimeTypeTomcat70Description=Apache Tomcat v7.0 supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules.
 
 # --------------- Servers ---------------
 tomcat32ServerType=Tomcat v3.2 Server
@@ -45,6 +47,9 @@
 tomcat60ServerType=Tomcat v6.0 Server
 tomcat60ServerDescription=Publishes and runs J2EE and Java EE Web projects and server configurations to a local Tomcat server.
 
+tomcat70ServerType=Tomcat v7.0 Server
+tomcat70ServerDescription=Publishes and runs J2EE and Java EE Web projects and server configurations to a local Tomcat server.
+
 tomcatLaunchConfigurationType=Apache Tomcat
 
 # --------------- General ---------------
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/plugin.xml b/plugins/org.eclipse.jst.server.tomcat.core/plugin.xml
index 41f4b20..0e00b14 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/plugin.xml
+++ b/plugins/org.eclipse.jst.server.tomcat.core/plugin.xml
@@ -92,6 +92,21 @@
          types="jst.utility"
          versions="1.0"/>
     </runtimeType>
+
+    <runtimeType
+       id="org.eclipse.jst.server.tomcat.runtime.70"
+       name="%runtimeTypeTomcat70Label"
+       description="%runtimeTypeTomcat70Description"
+       vendor="%apache"
+       version="7.0"
+       class="org.eclipse.jst.server.tomcat.core.internal.TomcatRuntime">
+       <moduleType
+         types="jst.web"
+         versions="2.2, 2.3, 2.4, 2.5, 3.0"/>
+       <moduleType
+         types="jst.utility"
+         versions="1.0"/>
+    </runtimeType>
   </extension>
 
   <extension point="org.eclipse.wst.server.core.runtimeLocators">
@@ -199,6 +214,21 @@
        class="org.eclipse.jst.server.tomcat.core.internal.TomcatServer"
        behaviourClass="org.eclipse.jst.server.tomcat.core.internal.TomcatServerBehaviour">
      </serverType>
+     <serverType
+       id="org.eclipse.jst.server.tomcat.70"
+       name="%tomcat70ServerType"
+       description="%tomcat70ServerDescription"
+       supportsRemoteHosts="false"
+       runtime="true"
+       startTimeout="45000"
+       stopTimeout="15000"
+       initialState="stopped"
+       hasConfiguration="true"
+       launchConfigId="org.eclipse.jst.server.tomcat.core.launchConfigurationType"
+       runtimeTypeId="org.eclipse.jst.server.tomcat.runtime.70"
+       class="org.eclipse.jst.server.tomcat.core.internal.TomcatServer"
+       behaviourClass="org.eclipse.jst.server.tomcat.core.internal.TomcatServerBehaviour">
+     </serverType>
   </extension>
 
   <extension point="org.eclipse.wst.server.core.serverLocators">
@@ -266,6 +296,10 @@
        type="org.eclipse.jst.server.tomcat"
        version="6.0"/>
 
+    <runtime-component-version
+       type="org.eclipse.jst.server.tomcat"
+       version="7.0"/>
+
     <adapter>
       <runtime-component
          id="org.eclipse.jst.server.tomcat"/>
@@ -346,6 +380,21 @@
          id="jst.utility"
          version="1.0"/>
     </supported>
+
+    <supported>
+      <runtime-component
+         id="org.eclipse.jst.server.tomcat"
+         version="7.0"/>
+      <facet
+         id="jst.web"
+         version="2.2,2.3,2.4,2.5,3.0"/>
+      <facet
+         id="jst.webfragment"
+         version="3.0"/>
+      <facet
+         id="jst.utility"
+         version="1.0"/>
+    </supported>
   </extension>
   
   <extension point="org.eclipse.wst.common.project.facet.core.defaultFacets">
@@ -380,6 +429,10 @@
       runtimeTypeId="org.eclipse.jst.server.tomcat.runtime.60"
       runtime-component="org.eclipse.jst.server.tomcat"
       version="6.0"/>
+    <runtimeFacetMapping
+      runtimeTypeId="org.eclipse.jst.server.tomcat.runtime.70"
+      runtime-component="org.eclipse.jst.server.tomcat"
+      version="7.0"/>
   </extension>
 
   <extension point="org.eclipse.wst.server.core.installableRuntimes">
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ITomcatRuntime.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ITomcatRuntime.java
index d10c027..884151c 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ITomcatRuntime.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ITomcatRuntime.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -12,6 +12,7 @@
 
 import java.util.List;
 
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.jst.server.core.IJavaRuntime;
 /**
  * 
@@ -22,5 +23,5 @@
 	 * 
 	 * @return the runtime classpath
 	 */
-	public List getRuntimeClasspath();
+	public List getRuntimeClasspath(IPath configPath);
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ITomcatVersionHandler.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ITomcatVersionHandler.java
index 066c4cc..319848f 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ITomcatVersionHandler.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/ITomcatVersionHandler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -44,7 +44,7 @@
 	 * @return list of classpath entries required to
 	 * start the Tomcat server.
 	 */
-	public List getRuntimeClasspath(IPath installPath);
+	public List getRuntimeClasspath(IPath installPath, IPath configPath);
 	
 	/**
 	 * Return the program's runtime arguments.
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.java
index 43cb2b1..b4937f2 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * Copyright (c) 2005, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -22,6 +22,7 @@
 	public static String errorUnknownVersion;
 	public static String errorInstallDirEmpty;
 	public static String errorInstallDirWrongVersion;
+	public static String errorInstallDirWrongVersion2;
 	public static String errorInstallDirDoesNotExist;
 	public static String errorInstallDirMissingFile;
 	public static String errorInstallDirMissingFile2;
@@ -29,6 +30,7 @@
 	public static String errorInstallDirTrailingSlash;
 	public static String errorJRE;
 	public static String errorJRETomcat60;
+	public static String errorJRETomcat70;
 	public static String warningJRE;
 	public static String warningCantReadConfig;
 	public static String target32runtime;
@@ -50,6 +52,7 @@
 	public static String errorSpec50;
 	public static String errorSpec55;
 	public static String errorSpec60;
+	public static String errorSpec70;
 	public static String portServer;
 	public static String runtimeDirPrepared;
 	public static String publishConfigurationTask;
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.properties b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.properties
index a8b865c..17afafd 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.properties
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Messages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2004, 2008 IBM Corporation and others.
+# Copyright (c) 2004, 2010 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -60,6 +60,7 @@
 errorUnknownVersion=Unknown version of Tomcat was specified.
 errorInstallDirEmpty=The Tomcat installation directory may not be empty.
 errorInstallDirWrongVersion=The name of the Tomcat installation directory indicates it is for different version of Tomcat.
+errorInstallDirWrongVersion2=The Apache Tomcat installation at this directory is version {0}.  A Tomcat {1} installation is expected.
 errorInstallDirDoesNotExist=The specified Tomcat installation directory does not exist.
 errorInstallDirMissingFile=The Tomcat installation directory is not valid. It is missing expected file or folder {0}.
 errorInstallDirMissingFile2=The Tomcat installation directory is not valid. It is missing expected file or folder {0} (alternate name {1}).
@@ -67,6 +68,7 @@
 errorInstallDirTrailingSlash=The Tomcat installation directory should not have a trailing slash.
 errorJRE=The JRE could not be found. Edit the server and change the JRE location.
 errorJRETomcat60=Tomcat version 6.0 requires J2SE 5.0 or later.  Change the JRE to one that meets this requirement.
+errorJRETomcat70=Tomcat version 7.0 requires Java SE 6 or later.  Change the JRE to one that meets this requirement.
 errorPortInvalid=The server cannot be started because one or more of the ports are invalid. Open the server editor and correct the invalid ports.
 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).
@@ -89,6 +91,7 @@
 errorSpec50=Tomcat version 5.0 only supports J2EE 1.2, 1.3, and 1.4 Web modules
 errorSpec55=Tomcat version 5.5 only supports J2EE 1.2, 1.3, and 1.4 Web modules
 errorSpec60=Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules
+errorSpec70=Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules
 errorDuplicateContextRoot=Two or more Web modules defined in the configuration have the same context root ({0}). \
   To start this server you will need to remove the duplicate(s).
 errorCouldNotLoadContextXml=Could not load the context configuration for the {0} context due to a syntax error or other exception.
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat32Handler.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat32Handler.java
index f6f749d..b7e698f 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat32Handler.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat32Handler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -38,9 +38,9 @@
 	}
 
 	/**
-	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath)
+	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath, IPath)
 	 */
-	public List getRuntimeClasspath(IPath installPath) {
+	public List getRuntimeClasspath(IPath installPath, IPath configPath) {
 		List cp = new ArrayList();
 		// add all jars from the Tomcat lib directory
 		File libDir = installPath.append("lib").toFile();
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat40Handler.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat40Handler.java
index b0ab813..60f3fb2 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat40Handler.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat40Handler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -37,9 +37,9 @@
 	}
 	
 	/**
-	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath)
+	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath, IPath)
 	 */
-	public List getRuntimeClasspath(IPath installPath) {
+	public List getRuntimeClasspath(IPath installPath, IPath configPath) {
 		List cp = new ArrayList();
 		
 		// 4.0 - add bootstrap.jar from the Tomcat bin directory
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat41Handler.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat41Handler.java
index 64a3dbd..8648b1c 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat41Handler.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat41Handler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -26,7 +26,12 @@
 	 * @see ITomcatVersionHandler#verifyInstallPath(IPath)
 	 */
 	public IStatus verifyInstallPath(IPath installPath) {
-		return TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_41);
+		IStatus result = TomcatVersionHelper.checkCatalinaVersion(installPath, TomcatPlugin.TOMCAT_41);
+		// If check was canceled, use folder check
+		if (result.getSeverity() == IStatus.CANCEL) {
+			result = TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_41);
+		}
+		return result;
 	}
 	
 	/**
@@ -37,9 +42,9 @@
 	}
 	
 	/**
-	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath)
+	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath, IPath)
 	 */
-	public List getRuntimeClasspath(IPath installPath) {
+	public List getRuntimeClasspath(IPath installPath, IPath configPath) {
 		List cp = new ArrayList();
 		
 		// 4.1 - add bootstrap.jar from the Tomcat bin directory
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat50Handler.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat50Handler.java
index c7984f0..192679e 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat50Handler.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat50Handler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -26,7 +26,12 @@
 	 * @see ITomcatVersionHandler#verifyInstallPath(IPath)
 	 */
 	public IStatus verifyInstallPath(IPath installPath) {
-		return TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_50);
+		IStatus result = TomcatVersionHelper.checkCatalinaVersion(installPath, TomcatPlugin.TOMCAT_50);
+		// If check was canceled, use folder check
+		if (result.getSeverity() == IStatus.CANCEL) {
+			result = TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_50);
+		}
+		return result;
 	}
 	
 	/**
@@ -37,9 +42,9 @@
 	}
 	
 	/**
-	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath)
+	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath, IPath)
 	 */
-	public List getRuntimeClasspath(IPath installPath) {
+	public List getRuntimeClasspath(IPath installPath, IPath configPath) {
 		List cp = new ArrayList();
 		
 		// 5.0 - add bootstrap.jar from the Tomcat bin directory
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat55Handler.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat55Handler.java
index 012273a..3f4bc04 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat55Handler.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat55Handler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -22,7 +22,12 @@
 	 * @see ITomcatVersionHandler#verifyInstallPath(IPath)
 	 */
 	public IStatus verifyInstallPath(IPath installPath) {
-		return TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_55);
+		IStatus result = TomcatVersionHelper.checkCatalinaVersion(installPath, TomcatPlugin.TOMCAT_55);
+		// If check was canceled, use folder check
+		if (result.getSeverity() == IStatus.CANCEL) {
+			result = TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_55);
+		}
+		return result;
 	}
 	
 	/**
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat60Handler.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat60Handler.java
index f8c14c7..c141d5e 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat60Handler.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat60Handler.java
@@ -1,5 +1,5 @@
 /**********************************************************************
- * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * Copyright (c) 2007, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -26,7 +26,12 @@
 	 * @see ITomcatVersionHandler#verifyInstallPath(IPath)
 	 */
 	public IStatus verifyInstallPath(IPath installPath) {
-		return TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_60);
+		IStatus result = TomcatVersionHelper.checkCatalinaVersion(installPath, TomcatPlugin.TOMCAT_60);
+		// If check was canceled, use folder check
+		if (result.getSeverity() == IStatus.CANCEL) {
+			result = TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_60);
+		}
+		return result;
 	}
 	
 	/**
@@ -37,9 +42,9 @@
 	}
 	
 	/**
-	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath)
+	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath, IPath)
 	 */
-	public List getRuntimeClasspath(IPath installPath) {
+	public List getRuntimeClasspath(IPath installPath, IPath configPath) {
 		List cp = new ArrayList();
 		
 		// 6.0 - add bootstrap.jar from the Tomcat bin directory
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat70Configuration.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat70Configuration.java
new file mode 100644
index 0000000..e84d73e
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat70Configuration.java
@@ -0,0 +1,710 @@
+/**********************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    IBM Corporation - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.jst.server.tomcat.core.internal;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+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.Status;
+import org.eclipse.jst.server.tomcat.core.internal.xml.Factory;
+import org.eclipse.jst.server.tomcat.core.internal.xml.XMLUtil;
+import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Connector;
+import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Context;
+import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Listener;
+import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Server;
+import org.eclipse.jst.server.tomcat.core.internal.xml.server40.ServerInstance;
+import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Service;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.server.core.ServerPort;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+/**
+ * Tomcat v7.0 server configuration.
+ */
+public class Tomcat70Configuration extends TomcatConfiguration {
+	protected static final String DEFAULT_SERVICE = "Catalina";
+	protected static final String EOL = System.getProperty("line.separator");
+	protected Server server;
+	protected ServerInstance serverInstance;
+	protected Factory serverFactory;
+	protected boolean isServerDirty;
+
+	protected WebAppDocument webAppDocument;
+
+	protected Document contextDocument;
+
+	protected Document tomcatUsersDocument;
+
+	protected String policyFile;
+
+	protected String propertiesFile;
+	
+	protected static final Map protocolHandlerMap = new HashMap();
+	static {
+		protocolHandlerMap.put("org.apache.coyote.http11.Http11Protocol", "HTTP/1.1");
+		protocolHandlerMap.put("org.apache.coyote.http11.Http11NioProtocol", "HTTP/1.1");
+		protocolHandlerMap.put("org.apache.coyote.http11.Http11AprProtocol", "HTTP/1.1");
+		protocolHandlerMap.put("org.apache.coyote.ajp.AjpAprProtocol", "AJP/1.3");
+		protocolHandlerMap.put("org.apache.jk.server.JkCoyoteHandler", "AJP/1.3");
+	}
+	
+	/**
+	 * Tomcat60Configuration constructor.
+	 * 
+	 * @param path a path
+	 */
+	public Tomcat70Configuration(IFolder path) {
+		super(path);
+	}
+
+	/**
+	 * Return the port number.
+	 * @return int
+	 */
+	public ServerPort getMainPort() {
+		Iterator iterator = getServerPorts().iterator();
+		while (iterator.hasNext()) {
+			ServerPort port = (ServerPort) iterator.next();
+			// Return only an HTTP port from the selected Service
+			if (port.getProtocol().toLowerCase().equals("http") && port.getId().indexOf('/') < 0)
+				return port;
+		}
+		return null;
+	}
+	
+	/**
+	 * Returns the mime mappings.
+	 * @return java.util.List
+	 */
+	public List getMimeMappings() {
+		return webAppDocument.getMimeMappings();
+	}
+
+	/**
+	 * Returns a list of ServerPorts that this configuration uses.
+	 *
+	 * @return java.util.List
+	 */
+	public List getServerPorts() {
+		List ports = new ArrayList();
+	
+		// first add server port
+		try {
+			int port = Integer.parseInt(server.getPort());
+			ports.add(new ServerPort("server", Messages.portServer, port, "TCPIP"));
+		} catch (Exception e) {
+			// ignore
+		}
+	
+		// add connectors
+		try {
+			String instanceServiceName = serverInstance.getService().getName();
+			int size = server.getServiceCount();
+			for (int i = 0; i < size; i++) {
+				Service service = server.getService(i);
+				int size2 = service.getConnectorCount();
+				for (int j = 0; j < size2; j++) {
+					Connector connector = service.getConnector(j);
+					String name = "HTTP/1.1";
+					String protocol2 = "HTTP";
+					boolean advanced = true;
+					String[] contentTypes = null;
+					int port = -1;
+					try {
+						port = Integer.parseInt(connector.getPort());
+					} catch (Exception e) {
+						// ignore
+					}
+					String protocol = connector.getProtocol();
+					if (protocol != null && protocol.length() > 0) {
+						if (protocol.startsWith("HTTP")) {
+							name = protocol;
+						}
+						else if (protocol.startsWith("AJP")) {
+							name = protocol;
+							protocol2 = "AJP"; 
+						}
+						else {
+							// Get Tomcat equivalent name if protocol handler class specified
+							name = (String)protocolHandlerMap.get(protocol);
+							if (name != null) {
+								// Prepare simple protocol string for ServerPort protocol
+								int index = name.indexOf('/');
+								if (index > 0)
+									protocol2 = name.substring(0, index);
+								else
+									protocol2 = name;
+							}
+							// Specified protocol is unknown, just use as is
+							else {
+								name = protocol;
+								protocol2 = protocol;
+							}
+						}
+					}
+					if (protocol2.toLowerCase().equals("http"))
+						contentTypes = new String[] { "web", "webservices" };
+					String secure = connector.getSecure();
+					if (secure != null && secure.length() > 0) {
+						name = "SSL";
+						protocol2 = "SSL";
+					} else
+						advanced = false;
+					String portId;
+					if (instanceServiceName != null && instanceServiceName.equals(service.getName()))
+						portId = Integer.toString(j);
+					else
+						portId = i +"/" + j;
+					ports.add(new ServerPort(portId, name, port, protocol2, contentTypes, advanced));
+				}
+			}
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error getting server ports", e);
+		}
+		return ports;
+	}
+	
+	/**
+	 * Return a list of the web modules in this server.
+	 * @return java.util.List
+	 */
+	public List getWebModules() {
+		List list = new ArrayList();
+	
+		try {
+			Context [] contexts = serverInstance.getContexts();
+			if (contexts != null) {
+				for (int i = 0; i < contexts.length; i++) {
+					Context context = contexts[i];
+					String reload = context.getReloadable();
+					if (reload == null)
+						reload = "false";
+					WebModule module = new WebModule(context.getPath(), 
+						context.getDocBase(), context.getSource(),
+						reload.equalsIgnoreCase("true") ? true : false);
+					list.add(module);
+				}
+			}
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error getting project refs", e);
+		}
+		return list;
+	}
+	
+	/**
+	 * @see TomcatConfiguration#getServerWorkDirectory(IPath)
+	 */
+	public IPath getServerWorkDirectory(IPath basePath) {
+		return serverInstance.getHostWorkDirectory(basePath);
+	}
+
+	/**
+	 * @see TomcatConfiguration#getContextWorkDirectory(IPath, ITomcatWebModule)
+	 */
+	public IPath getContextWorkDirectory(IPath basePath, ITomcatWebModule module) {
+		Context context = serverInstance.getContext(module.getPath());
+		if (context != null)
+			return serverInstance.getContextWorkDirectory(basePath, context);
+		
+		return null;
+	}
+
+	/**
+	 * @see TomcatConfiguration#load(IPath, IProgressMonitor)
+	 */
+	public void load(IPath path, IProgressMonitor monitor) throws CoreException {
+		try {
+			monitor = ProgressUtil.getMonitorFor(monitor);
+			monitor.beginTask(Messages.loadingTask, 7);
+			
+			// check for catalina.policy to verify that this is a v5.5 config
+			InputStream in = new FileInputStream(path.append("catalina.policy").toFile());
+			in.read();
+			in.close();
+			monitor.worked(1);
+
+			serverFactory = new Factory();
+			serverFactory.setPackageName("org.eclipse.jst.server.tomcat.core.internal.xml.server40");
+			server = (Server) serverFactory.loadDocument(new FileInputStream(path.append("server.xml").toFile()));
+			serverInstance = new ServerInstance(server, null, null);
+			monitor.worked(1);
+
+			webAppDocument = new WebAppDocument(path.append("web.xml"));
+			monitor.worked(1);
+			
+			File file = path.append("context.xml").toFile();
+			if (file.exists())
+				contextDocument = XMLUtil.getDocumentBuilder().parse(new InputSource(new FileInputStream(file)));
+			monitor.worked(1);
+			
+			tomcatUsersDocument = XMLUtil.getDocumentBuilder().parse(new InputSource(new FileInputStream(path.append("tomcat-users.xml").toFile())));
+			monitor.worked(1);
+			
+			// load policy file
+			policyFile = TomcatVersionHelper.getFileContents(new FileInputStream(path.append("catalina.policy").toFile()));
+			monitor.worked(1);
+
+			// load properties file
+			file = path.append("catalina.properties").toFile();
+			if (file.exists())
+				propertiesFile = TomcatVersionHelper.getFileContents(new FileInputStream(file));
+			else
+				propertiesFile = null;
+			monitor.worked(1);
+			
+			if (monitor.isCanceled())
+				return;
+			monitor.done();
+		} catch (Exception e) {
+			Trace.trace(Trace.WARNING, "Could not load Tomcat v5.5 configuration from " + path.toOSString() + ": " + e.getMessage());
+			throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotLoadConfiguration, path.toOSString()), e));
+		}
+	}
+
+	/**
+	 * @see TomcatConfiguration#importFromPath(IPath, boolean, IProgressMonitor)
+	 */
+	public void importFromPath(IPath path, boolean isTestEnv, IProgressMonitor monitor) throws CoreException {
+		load(path, monitor);
+		
+		// for test environment, remove existing contexts since a separate
+		// catalina.base will be used
+		if (isTestEnv) {
+			while (serverInstance.removeContext(0)) {
+				// no-op
+			}
+		}
+	}
+
+	/**
+	 * @see TomcatConfiguration#load(IFolder, IProgressMonitor)
+	 */
+	public void load(IFolder folder, IProgressMonitor monitor) throws CoreException {
+		try {
+			monitor = ProgressUtil.getMonitorFor(monitor);
+			monitor.beginTask(Messages.loadingTask, 1200);
+	
+			// check for catalina.policy to verify that this is a v4.0 config
+			IFile file = folder.getFile("catalina.policy");
+			if (!file.exists())
+				throw new CoreException(new Status(IStatus.WARNING, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotLoadConfiguration, folder.getFullPath().toOSString()), null));
+	
+			// load server.xml
+			file = folder.getFile("server.xml");
+			InputStream in = file.getContents();
+			serverFactory = new Factory();
+			serverFactory.setPackageName("org.eclipse.jst.server.tomcat.core.internal.xml.server40");
+			server = (Server) serverFactory.loadDocument(in);
+			serverInstance = new ServerInstance(server, null, null);
+			monitor.worked(200);
+	
+			// load web.xml
+			file = folder.getFile("web.xml");
+			webAppDocument = new WebAppDocument(file);
+			monitor.worked(200);
+	
+			// load context.xml
+			file = folder.getFile("context.xml");
+			if (file.exists()) {
+				in = file.getContents();
+				contextDocument = XMLUtil.getDocumentBuilder().parse(new InputSource(in));
+			}
+			else
+				contextDocument = null;
+			monitor.worked(200);
+		
+			// load tomcat-users.xml
+			file = folder.getFile("tomcat-users.xml");
+			in = file.getContents();
+			
+			tomcatUsersDocument = XMLUtil.getDocumentBuilder().parse(new InputSource(in));
+			monitor.worked(200);
+		
+			// load catalina.policy
+			file = folder.getFile("catalina.policy");
+			in = file.getContents();
+			policyFile = TomcatVersionHelper.getFileContents(in);
+			monitor.worked(200);
+	
+			// load catalina.properties
+			file = folder.getFile("catalina.properties");
+			if (file.exists()) {
+				in = file.getContents();
+				propertiesFile = TomcatVersionHelper.getFileContents(in);
+			}
+			else
+				propertiesFile = null;
+			monitor.worked(200);
+			
+			if (monitor.isCanceled())
+				throw new Exception("Cancelled");
+			monitor.done();
+		} catch (Exception e) {
+			Trace.trace(Trace.WARNING, "Could not reload Tomcat v5.5 configuration from: " + folder.getFullPath() + ": " + e.getMessage());
+			throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotLoadConfiguration, folder.getFullPath().toOSString()), e));
+		}
+	}
+
+	/**
+	 * Save to the given directory.
+	 * @param path a path
+	 * @param forceDirty boolean
+	 * @param monitor a progress monitor
+	 * @exception CoreException
+	 */
+	protected void save(IPath path, boolean forceDirty, IProgressMonitor monitor) throws CoreException {
+		try {
+			monitor = ProgressUtil.getMonitorFor(monitor);
+			monitor.beginTask(Messages.savingTask, 5);
+			
+			// make sure directory exists
+			if (!path.toFile().exists()) {
+				forceDirty = true;
+				path.toFile().mkdir();
+			}
+			monitor.worked(1);
+			
+			// save files
+			if (forceDirty || isServerDirty) {
+				serverFactory.save(path.append("server.xml").toOSString());
+				isServerDirty = false;
+			}
+			monitor.worked(1);
+			
+			webAppDocument.save(path.append("web.xml").toOSString(), forceDirty);
+			monitor.worked(1);
+			
+			if (forceDirty && contextDocument != null)
+				XMLUtil.save(path.append("context.xml").toOSString(), contextDocument);
+			monitor.worked(1);
+			
+			if (forceDirty)
+				XMLUtil.save(path.append("tomcat-users.xml").toOSString(), tomcatUsersDocument);
+			monitor.worked(1);
+			
+			if (forceDirty) {
+				BufferedWriter bw = new BufferedWriter(new FileWriter(path.append("catalina.policy").toFile()));
+				bw.write(policyFile);
+				bw.close();
+			}
+			monitor.worked(1);
+			if (propertiesFile != null && forceDirty) {
+				BufferedWriter bw = new BufferedWriter(new FileWriter(path.append("catalina.properties").toFile()));
+				bw.write(propertiesFile);
+				bw.close();
+			}
+			monitor.worked(1);
+			
+			if (monitor.isCanceled())
+				return;
+			monitor.done();
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Could not save Tomcat v5.5 configuration to " + path, e);
+			throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotSaveConfiguration, new String[] {e.getLocalizedMessage()}), e));
+		}
+	}
+
+	/**
+	 * Save to the given directory.  All configuration files
+	 * are forced to be saved.
+	 * 
+	 * @param path Desination path for the configuration files.
+	 * @param monitor A progress monitor
+	 * @exception CoreException
+	 */
+	public void save(IPath path, IProgressMonitor monitor) throws CoreException {
+		save(path, true, monitor);
+	}
+
+	/**
+	 * Save the information held by this object to the given directory.
+	 *
+	 * @param folder a folder
+	 * @param monitor a progress monitor
+	 * @throws CoreException
+	 */
+	public void save(IFolder folder, IProgressMonitor monitor) throws CoreException {
+		try {
+			monitor = ProgressUtil.getMonitorFor(monitor);
+			monitor.beginTask(Messages.savingTask, 1200);
+	
+			// save server.xml
+			byte[] data = serverFactory.getContents();
+			InputStream in = new ByteArrayInputStream(data);
+			IFile file = folder.getFile("server.xml");
+			if (file.exists()) {
+				if (isServerDirty)
+					file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+				else
+					monitor.worked(200);
+			} else
+				file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+			isServerDirty = false;
+			
+			// save web.xml
+			webAppDocument.save(folder.getFile("web.xml"), ProgressUtil.getSubMonitorFor(monitor, 200));
+			
+			// save context.xml
+			if (contextDocument != null) {
+				data = XMLUtil.getContents(contextDocument);
+				in = new ByteArrayInputStream(data);
+				file = folder.getFile("context.xml");
+				if (file.exists())
+					monitor.worked(200);
+					//file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+				else
+					file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+			}
+			
+			// save tomcat-users.xml
+			data = XMLUtil.getContents(tomcatUsersDocument);
+			in = new ByteArrayInputStream(data);
+			file = folder.getFile("tomcat-users.xml");
+			if (file.exists())
+				monitor.worked(200);
+				//file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+			else
+				file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+			
+			// save catalina.policy
+			in = new ByteArrayInputStream(policyFile.getBytes());
+			file = folder.getFile("catalina.policy");
+			if (file.exists())
+				monitor.worked(200);
+				//file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+			else
+				file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+			
+			// save catalina.properties
+			if (propertiesFile != null) {
+				in = new ByteArrayInputStream(propertiesFile.getBytes());
+				file = folder.getFile("catalina.properties");
+				if (file.exists())
+					monitor.worked(200);
+					//file.setContents(in, true, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+				else
+					file.create(in, true, ProgressUtil.getSubMonitorFor(monitor, 200));
+			} else
+				monitor.worked(200);
+			
+			if (monitor.isCanceled())
+				return;
+			monitor.done();
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Could not save Tomcat v5.5 configuration to " + folder.toString(), e);
+			throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, NLS.bind(Messages.errorCouldNotSaveConfiguration, new String[] {e.getLocalizedMessage()}), e));
+		}
+	}
+
+	protected static boolean hasMDBListener(Server server) {
+		if (server == null)
+			return false;
+		
+		int count = server.getListenerCount();
+		if (count == 0)
+			return false;
+			
+		for (int i = 0; i < count; i++) {
+			Listener listener = server.getListener(i);
+			if (listener != null && listener.getClassName() != null && listener.getClassName().indexOf("mbean") >= 0)
+				return true;
+		}
+		return false;
+	}
+	
+	/**
+	 * @see ITomcatConfigurationWorkingCopy#addMimeMapping(int, IMimeMapping)
+	 */
+	public void addMimeMapping(int index, IMimeMapping map) {
+		webAppDocument.addMimeMapping(index, map);
+		firePropertyChangeEvent(ADD_MAPPING_PROPERTY, new Integer(index), map);
+	}
+
+	/**
+	 * @see ITomcatConfigurationWorkingCopy#addWebModule(int, ITomcatWebModule)
+	 */
+	public void addWebModule(int index, ITomcatWebModule module) {
+		try {
+			Context context = serverInstance.createContext(index);
+			if (context != null) {
+				context.setDocBase(module.getDocumentBase());
+				context.setPath(module.getPath());
+				context.setReloadable(module.isReloadable() ? "true" : "false");
+				if (module.getMemento() != null && module.getMemento().length() > 0)
+					context.setSource(module.getMemento());
+				isServerDirty = true;
+				firePropertyChangeEvent(ADD_WEB_MODULE_PROPERTY, null, module);
+			}
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error adding web module " + module.getPath(), e);
+		}
+	}
+
+	/**
+	 * Change the extension of a mime mapping.
+	 * 
+	 * @param index
+	 * @param map
+	 */
+	public void modifyMimeMapping(int index, IMimeMapping map) {
+		webAppDocument.modifyMimeMapping(index, map);
+		firePropertyChangeEvent(MODIFY_MAPPING_PROPERTY, new Integer(index), map);
+	}
+
+	/**
+	 * Modify the port with the given id.
+	 *
+	 * @param id java.lang.String
+	 * @param port int
+	 */
+	public void modifyServerPort(String id, int port) {
+		try {
+			if ("server".equals(id)) {
+				server.setPort(port + "");
+				isServerDirty = true;
+				firePropertyChangeEvent(MODIFY_PORT_PROPERTY, id, new Integer(port));
+				return;
+			}
+	
+			int i = id.indexOf("/");
+			// If a connector in the instance Service
+			if (i < 0) {
+				int connNum = Integer.parseInt(id);
+				Connector connector = serverInstance.getConnector(connNum);
+				if (connector != null) {
+					connector.setPort(port + "");
+					isServerDirty = true;
+					firePropertyChangeEvent(MODIFY_PORT_PROPERTY, id, new Integer(port));
+				}
+			}
+			// Else a connector in another Service
+			else {
+				int servNum = Integer.parseInt(id.substring(0, i));
+				int connNum = Integer.parseInt(id.substring(i + 1));
+				
+				Service service = server.getService(servNum);
+				Connector connector = service.getConnector(connNum);
+				connector.setPort(port + "");
+				isServerDirty = true;
+				firePropertyChangeEvent(MODIFY_PORT_PROPERTY, id, new Integer(port));
+			}
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error modifying server port " + id, e);
+		}
+	}
+	/**
+	 * Change a web module.
+	 * @param index int
+	 * @param docBase java.lang.String
+	 * @param path java.lang.String
+	 * @param reloadable boolean
+	 */
+	public void modifyWebModule(int index, String docBase, String path, boolean reloadable) {
+		try {
+			Context context = serverInstance.getContext(index);
+			if (context != null) {
+				context.setPath(path);
+				context.setDocBase(docBase);
+				context.setReloadable(reloadable ? "true" : "false");
+				isServerDirty = true;
+				WebModule module = new WebModule(path, docBase, null, reloadable);
+				firePropertyChangeEvent(MODIFY_WEB_MODULE_PROPERTY, new Integer(index), module);
+			}
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error modifying web module " + index, e);
+		}
+	}
+
+	/**
+	 * Removes a mime mapping.
+	 * @param index int
+	 */
+	public void removeMimeMapping(int index) {
+		webAppDocument.removeMimeMapping(index);
+		firePropertyChangeEvent(REMOVE_MAPPING_PROPERTY, null, new Integer(index));
+	}
+
+	/**
+	 * Removes a web module.
+	 * @param index int
+	 */
+	public void removeWebModule(int index) {
+		try {
+			serverInstance.removeContext(index);
+			isServerDirty = true;
+			firePropertyChangeEvent(REMOVE_WEB_MODULE_PROPERTY, null, new Integer(index));
+		} catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error removing module ref " + index, e);
+		}
+	}
+
+	/**
+	 * Add context configuration found in META-INF/context.xml files
+	 * present in projects to published server.xml.
+	 * 
+	 * @param baseDir path to catalina instance directory
+	 * @param deployDir path to deployment directory
+	 * @param monitor a progress monitor or null
+	 * @return result of operation
+	 */
+	protected IStatus publishContextConfig(IPath baseDir, IPath deployDir, IProgressMonitor monitor) {
+		return TomcatVersionHelper.publishCatalinaContextConfig(baseDir, deployDir, monitor);
+	}
+	
+	/**
+	 * Update contexts in server.xml to serve projects directly without
+	 * publishing.
+	 * 
+	 * @param baseDir path to catalina instance directory
+	 * @param monitor a progress monitor or null
+	 * @return result of operation
+	 */
+	protected IStatus updateContextsToServeDirectly(IPath baseDir, String loader, IProgressMonitor monitor) {
+		return TomcatVersionHelper.updateContextsToServeDirectly(baseDir, loader, monitor);
+	}
+
+	/**
+	 * Cleanup the server instance.  This consists of deleting the work
+	 * directory associated with Contexts that are going away in the
+	 * up coming publish.
+	 * 
+	 * @param baseDir path to server instance directory, i.e. catalina.base
+	 * @param installDir path to server installation directory (not currently used)
+	 * @param monitor a progress monitor or null
+	 * @return MultiStatus containing results of the cleanup operation
+	 */
+	protected IStatus cleanupServer(IPath baseDir, IPath installDir, boolean removeKeptContextFiles, IProgressMonitor monitor) {
+		List modules = getWebModules();
+		return TomcatVersionHelper.cleanupCatalinaServer(baseDir, installDir, removeKeptContextFiles, modules, monitor);
+	}
+
+	/**
+	 * @see TomcatConfiguration#localizeConfiguration(IPath, IPath, TomcatServer, IProgressMonitor)
+	 */
+	public IStatus localizeConfiguration(IPath baseDir, IPath deployDir, TomcatServer tomcatServer, IProgressMonitor monitor) {
+		return TomcatVersionHelper.localizeConfiguration(baseDir, deployDir, tomcatServer, monitor);
+	}
+}
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat70Handler.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat70Handler.java
new file mode 100644
index 0000000..2a02f8c
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/Tomcat70Handler.java
@@ -0,0 +1,206 @@
+/**********************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *    IBM Corporation - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.jst.server.tomcat.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.wst.server.core.IModule;
+/**
+ * Tomcat 70 handler.
+ */
+public class Tomcat70Handler implements ITomcatVersionHandler {
+	/**
+	 * @see ITomcatVersionHandler#verifyInstallPath(IPath)
+	 */
+	public IStatus verifyInstallPath(IPath installPath) {
+		IStatus result = TomcatVersionHelper.checkCatalinaVersion(installPath, TomcatPlugin.TOMCAT_70);
+		// If check was canceled, use folder check
+		if (result.getSeverity() == IStatus.CANCEL) {
+			result = TomcatPlugin.verifyInstallPathWithFolderCheck(installPath, TomcatPlugin.TOMCAT_70);
+		}
+		return result;
+	}
+	
+	/**
+	 * @see ITomcatVersionHandler#getRuntimeClass()
+	 */
+	public String getRuntimeClass() {
+		return "org.apache.catalina.startup.Bootstrap";
+	}
+	
+	/**
+	 * @see ITomcatVersionHandler#getRuntimeClasspath(IPath, IPath)
+	 */
+	public List getRuntimeClasspath(IPath installPath, IPath configPath) {
+		List cp = new ArrayList();
+		
+		// 7.0 - add bootstrap.jar and tomcat-juli.jar from the Tomcat bin directory
+		IPath binPath = installPath.append("bin");
+		if (binPath.toFile().exists()) {
+			IPath path = binPath.append("bootstrap.jar");
+			cp.add(JavaRuntime.newArchiveRuntimeClasspathEntry(path));
+			// Add tomcat-juli.jar if it exists
+			path = binPath.append("tomcat-juli.jar");
+			if (path.toFile().exists()) {
+				cp.add(JavaRuntime.newArchiveRuntimeClasspathEntry(path));
+			}
+			// If tomcat-juli.jar is not found in the install, check the config directory
+			else if (configPath != null){
+				path = configPath.append("bin/tomcat-juli.jar");
+				if (path.toFile().exists()) {
+					cp.add(JavaRuntime.newArchiveRuntimeClasspathEntry(path));
+				}
+			}
+		}
+		
+		return cp;
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#getRuntimeProgramArguments(IPath, boolean, boolean)
+	 */
+	public String[] getRuntimeProgramArguments(IPath configPath, boolean debug, boolean starting) {
+		List list = new ArrayList();
+
+		if (starting)
+			list.add("start");
+		else
+			list.add("stop");
+		
+		String[] temp = new String[list.size()];
+		list.toArray(temp);
+		return temp;
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#getExcludedRuntimeProgramArguments(boolean, boolean)
+	 */
+	public String[] getExcludedRuntimeProgramArguments(boolean debug, boolean starting) {
+		return null;
+	}
+	
+	/**
+	 * @see ITomcatVersionHandler#getRuntimeVMArguments(IPath, IPath, IPath, boolean)
+	 */
+	public String[] getRuntimeVMArguments(IPath installPath, IPath configPath, IPath deployPath, boolean isTestEnv) {
+		return TomcatVersionHelper.getCatalinaVMArguments(installPath, configPath, deployPath, getEndorsedDirectories(installPath), isTestEnv);
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#getRuntimePolicyFile(IPath)
+	 */
+	public String getRuntimePolicyFile(IPath configPath) {
+		return configPath.append("conf").append("catalina.policy").toOSString();
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#canAddModule(IModule)
+	 */
+	public IStatus canAddModule(IModule module) {
+		String version = module.getModuleType().getVersion();
+		if ("2.2".equals(version) || "2.3".equals(version) || "2.4".equals(version) || "2.5".equals(version)
+				|| "3.0".equals(version))
+			return Status.OK_STATUS;
+		
+		return new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorSpec70, null);
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#getRuntimeBaseDirectory(TomcatServer)
+	 */
+	public IPath getRuntimeBaseDirectory(TomcatServer server) {
+		return TomcatVersionHelper.getStandardBaseDirectory(server);
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#prepareRuntimeDirectory(IPath)
+	 */
+	public IStatus prepareRuntimeDirectory(IPath baseDir) {
+		return TomcatVersionHelper.createCatalinaInstanceDirectory(baseDir);
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#prepareDeployDirectory(IPath)
+	 */
+	public IStatus prepareDeployDirectory(IPath deployPath) {
+		return TomcatVersionHelper.createDeploymentDirectory(deployPath,
+				TomcatVersionHelper.DEFAULT_WEBXML_SERVLET25);
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#prepareForServingDirectly(IPath, TomcatServer)
+	 */
+	public IStatus prepareForServingDirectly(IPath baseDir, TomcatServer server) {
+		IStatus status;
+		// If serving modules without publishing, loader jar is needed
+		// TODO Need to examine catalina.properties to ensure loader jar and catalina.properties are handled appropriately
+		if (server.isServeModulesWithoutPublish()) {
+			status = TomcatVersionHelper.copyLoaderJar(
+					getRuntimeBaseDirectory(server).append("lib"),
+					server.getServer().getRuntime().getRuntimeType().getId());
+			// If copy successful and running a separate server instance, modify catalina.properties
+			if (status.isOK() && server.isTestEnvironment()) {
+				status = TomcatVersionHelper.updatePropertiesToServeDirectly(baseDir, "lib", "common");
+			}
+		}
+		// Else ensure jar is removed
+		else {
+			TomcatVersionHelper.removeLoaderJar(
+					getRuntimeBaseDirectory(server).append("lib"),
+					server.getServer().getRuntime().getRuntimeType().getId());
+			// TODO Decide what to do with removal warning, maybe nothing
+			status = Status.OK_STATUS;
+		}
+		return status;
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#getSharedLoader(IPath)
+	 */
+	public String getSharedLoader(IPath baseDir) {
+		return "common";
+	}
+	
+	/**
+	 * Returns true since Tomcat 6.x supports this feature.
+	 * 
+	 * @return true since feature is supported
+	 */
+	public boolean supportsServeModulesWithoutPublish() {
+		return true;
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#supportsDebugArgument()
+	 */
+	public boolean supportsDebugArgument() {
+		return false;
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#supportsSeparateContextFiles()
+	 */
+	public boolean supportsSeparateContextFiles() {
+		return true;
+	}
+
+	/**
+	 * @see ITomcatVersionHandler#getEndorsedDirectories(IPath)
+	 */
+	public String getEndorsedDirectories(IPath installPath) {
+		return installPath.append("endorsed").toOSString();
+	}	
+}
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java
index a5ea341..b10d1ff 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatPlugin.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2007 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -37,6 +37,7 @@
 	public static final String TOMCAT_50 = "org.eclipse.jst.server.tomcat.50";
 	public static final String TOMCAT_55 = "org.eclipse.jst.server.tomcat.55";
 	public static final String TOMCAT_60 = "org.eclipse.jst.server.tomcat.60";
+	public static final String TOMCAT_70 = "org.eclipse.jst.server.tomcat.70";
 
 	protected static final String VERIFY_INSTALL_FILE = "verifyInstall.properties";
 	protected static VerifyResourceSpec[] verify32;
@@ -45,6 +46,7 @@
 	protected static VerifyResourceSpec[] verify50;
 	protected static VerifyResourceSpec[] verify55;
 	protected static VerifyResourceSpec[] verify60;
+	protected static VerifyResourceSpec[] verify70;
 	
 	protected static final IStatus emptyInstallDirStatus = new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorInstallDirEmpty, null);
 	protected static final IStatus wrongDirVersionStatus = new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorInstallDirWrongVersion, null);
@@ -130,6 +132,8 @@
 			return new Tomcat55Handler();
 		else if (TOMCAT_60.equals(id))
 			return new Tomcat60Handler();
+		else if (TOMCAT_70.equals(id))
+			return new Tomcat70Handler();
 		else
 			return null;
 	}
@@ -148,6 +152,7 @@
 		verify50 = new VerifyResourceSpec[0];
 		verify55 = new VerifyResourceSpec[0];
 		verify60 = new VerifyResourceSpec[0];
+		verify70 = new VerifyResourceSpec[0];
 		
 		try {
 			URL url = getInstance().getBundle().getEntry(VERIFY_INSTALL_FILE);
@@ -249,6 +254,22 @@
 			Trace.trace(Trace.FINEST, "Verify60: " + list.toString());
 			verify60 = new VerifyResourceSpec[list.size()];
 			list.toArray(verify60);
+
+			// v7.0
+			// Check backdoor system property, use internal spec if not found
+			verify = System.getProperty(PLUGIN_ID + ".verify70install");
+			if (verify == null) {
+				verify = p.getProperty("verify70install");
+			}
+			verify.replace('/', File.separatorChar);
+
+			st = new StringTokenizer(verify, ",");
+			list = new ArrayList();
+			while (st.hasMoreTokens())
+				list.add(new VerifyResourceSpec(st.nextToken()));
+			Trace.trace(Trace.FINEST, "Verify70: " + list.toString());
+			verify70 = new VerifyResourceSpec[list.size()];
+			list.toArray(verify70);
 		} catch (Exception e) {
 			Trace.trace(Trace.SEVERE, "Could not load installation verification properties", e);
 		}
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntime.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntime.java
index ce0c7b7..8690654 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntime.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntime.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -16,6 +16,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -79,7 +80,7 @@
 		return null;
 	}
 
-	public List getRuntimeClasspath() {
+	public List getRuntimeClasspath(IPath configPath) {
 		IPath installPath = getRuntime().getLocation();
 		// If installPath is relative, convert to canonical path and hope for the best
 		if (!installPath.isAbsolute()) {
@@ -90,7 +91,7 @@
 				// Ignore if there is a problem
 			}
 		}
-		return getVersionHandler().getRuntimeClasspath(installPath);
+		return getVersionHandler().getRuntimeClasspath(installPath, configPath);
 	}
 
 	/**
@@ -164,12 +165,22 @@
 			IVMInstall vmInstall = getVMInstall();
 			if (vmInstall instanceof IVMInstall2) {
 				String javaVersion = ((IVMInstall2)vmInstall).getJavaVersion();
-				if (javaVersion != null && javaVersion.compareTo("1.5") < 0) {
+				if (javaVersion != null && !isVMMinimumVersion(javaVersion, 105)) {
 					return new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorJRETomcat60, null);
 				}
 			}
 		}
-		
+		// Else for Tomcat 7.0, ensure we have J2SE 6.0
+		else if (id != null && id.indexOf("70") > 0) {
+			IVMInstall vmInstall = getVMInstall();
+			if (vmInstall instanceof IVMInstall2) {
+				String javaVersion = ((IVMInstall2)vmInstall).getJavaVersion();
+				if (javaVersion != null && !isVMMinimumVersion(javaVersion, 106)) {
+					return new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0, Messages.errorJRETomcat70, null);
+				}
+			}
+		}
+
 		return Status.OK_STATUS;
 	}
 
@@ -270,4 +281,33 @@
 		TomcatPlugin.log(MessageFormat.format("Failed compiler check for {0}", new String[] { javaHome.getAbsolutePath() }));
 		return false;
 	}
+
+	private static Map javaVersionMap = new ConcurrentHashMap();
+
+	private boolean isVMMinimumVersion(String javaVersion, int minimumVersion) {
+		Integer version = (Integer)javaVersionMap.get(javaVersion);
+		if (version == null) {
+			int index = javaVersion.indexOf('.');
+			if (index > 0) {
+				try {
+					int major = Integer.parseInt(javaVersion.substring(0, index)) * 100;
+					index++;
+					int index2 = javaVersion.indexOf('.', index);
+					if (index2 > 0) {
+						int minor = Integer.parseInt(javaVersion.substring(index, index2));
+						version = new Integer(major + minor);
+						javaVersionMap.put(javaVersion, version);
+					}
+				}
+				catch (NumberFormatException e) {
+					// Ignore
+				}
+			}
+		}
+		// If we have a version, and it's less than the minimum, fail the check
+		if (version != null && version.intValue() < minimumVersion) {
+			return false;
+		}
+		return true;
+	}
 }
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntimeClasspathProvider.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntimeClasspathProvider.java
index c96649d..6983d64 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntimeClasspathProvider.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatRuntimeClasspathProvider.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2007 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -37,7 +37,7 @@
 		if (runtimeId.indexOf("32") > 0) {
 			IPath path = installPath.append("lib");
 			addLibraryEntries(list, path.toFile(), true);
-		} else if (runtimeId.indexOf("60") > 0) {
+		} else if (runtimeId.indexOf("60") > 0 || runtimeId.indexOf("70") > 0) {
 			// TODO May need some flexibility in case the installation has been configured differently
 			// This lib "simplification" may cause issues for some.
 			// Not known yet whether packaged Linux installs will go along.
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServer.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServer.java
index fefeabf..9f163cf 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServer.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -99,6 +99,8 @@
 				configuration = new Tomcat55Configuration(folder);
 			else if (id.indexOf("60") > 0)
 				configuration = new Tomcat60Configuration(folder);
+			else if (id.indexOf("70") > 0)
+				configuration = new Tomcat70Configuration(folder);
 			try {
 				configuration.load(folder, null);
 			} catch (CoreException ce) {
@@ -131,6 +133,8 @@
 			configuration = new Tomcat55Configuration(folder);
 		else if (id.indexOf("60") > 0)
 			configuration = new Tomcat60Configuration(folder);
+		else if (id.indexOf("70") > 0)
+			configuration = new Tomcat70Configuration(folder);
 		try {
 			configuration.importFromPath(path, isTestEnvironment(), monitor);
 		} catch (CoreException ce) {
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServerBehaviour.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServerBehaviour.java
index 85e8ab7..4323ea1 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServerBehaviour.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatServerBehaviour.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2009 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -835,7 +835,7 @@
 		for (int i = 0; i < size; i++)
 			oldCp.add(originalClasspath[i]);
 		
-		List cp2 = runtime.getRuntimeClasspath();
+		List cp2 = runtime.getRuntimeClasspath(getRuntimeBaseDirectory());
 		Iterator iterator = cp2.iterator();
 		while (iterator.hasNext()) {
 			IRuntimeClasspathEntry entry = (IRuntimeClasspathEntry) iterator.next();
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatVersionHelper.java b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatVersionHelper.java
index 97cdd78..46807a7 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatVersionHelper.java
+++ b/plugins/org.eclipse.jst.server.tomcat.core/tomcatcore/org/eclipse/jst/server/tomcat/core/internal/TomcatVersionHelper.java
@@ -1,5 +1,5 @@
 /**********************************************************************
- * Copyright (c) 2007, 2008 SAS Institute, Inc and others.
+ * Copyright (c) 2007, 2010 SAS Institute, Inc and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -19,13 +19,17 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.xml.parsers.DocumentBuilder;
 
@@ -92,6 +96,19 @@
 		"</web-app>";
 
 	/**
+	 * Map of server type ID to expected version string fragment for version checking.
+	 */
+	private static final Map versionStringMap = new HashMap();
+	
+	static {
+		versionStringMap.put(TomcatPlugin.TOMCAT_41, "4.1.");
+		versionStringMap.put(TomcatPlugin.TOMCAT_50, "5.0.");
+		versionStringMap.put(TomcatPlugin.TOMCAT_55, "5.5.");
+		versionStringMap.put(TomcatPlugin.TOMCAT_60, "6.0.");
+		versionStringMap.put(TomcatPlugin.TOMCAT_70, "7.0.");
+	}
+
+	/**
 	 * Reads the from the specified InputStream and returns
 	 * the result as a String. Each line is terminated by
 	 * &quot;\n&quot;.  Returns whatever is read regardless
@@ -1001,4 +1018,122 @@
 		}
 		return context;
 	}
+
+	private static Map catalinaJarVersion = new ConcurrentHashMap();
+	private static Map catalinaJarLastModified = new HashMap();
+	private static volatile long lastCheck = 0;
+
+	/**
+	 * Checks if the version of Tomcat installed at the specified location matches
+	 * the specified server type.  The return status indicates if the version matches
+	 * or not, or can't be determined.
+	 * 
+	 * Because this can get called repeatedly for certain operations, some caching
+	 * is provided.  The first check for an installPath in the current Eclipse
+	 * session will query the catalina.jar for its version.  Any additional
+	 * checks will compare the catalina.jar's time stamp and will use the previously
+	 * cached version if it didn't change.  Additional checks that occur within
+	 * 2 seconds of the last check, regardless of Tomcat version, don't bother with
+	 * checking the jar time stamp and just use the cached values.
+	 * 
+	 * @param installPath Path to Tomcat installation
+	 * @param serverType The server type ID for the desired version of Tomcat
+	 * @return Returns Status.OK_Status if check succeeds, or an error status
+	 * if the check fails.  If the check can't determine if the version matches,
+	 * Status.CANCEL_STATUS is returned.
+	 */
+	public static IStatus checkCatalinaVersion(IPath installPath, String serverType) {
+		String versionSubString = null;
+		IPath catalinaJarPath = null;
+		File jarFile = null;
+		
+		if (TomcatPlugin.TOMCAT_60.equals(serverType) || TomcatPlugin.TOMCAT_70.equals(serverType)) {
+			catalinaJarPath = installPath.append("lib").append("catalina.jar");
+			jarFile = catalinaJarPath.toFile();
+			// If jar is not at expected location, try alternate location
+			if (!jarFile.exists()) {
+				catalinaJarPath = installPath.append("server/lib").append("catalina.jar");
+				jarFile = catalinaJarPath.toFile();
+				// If not here either, discard path
+				if (!jarFile.exists()) {
+					catalinaJarPath = null;
+				}
+			}
+		}
+		else if (TomcatPlugin.TOMCAT_50.equals(serverType) || TomcatPlugin.TOMCAT_55.equals(serverType)
+				 || TomcatPlugin.TOMCAT_41.equals(serverType)) {
+			catalinaJarPath = installPath.append("server/lib").append("catalina.jar");
+			jarFile = catalinaJarPath.toFile();
+			// If jar is not at expected location, try alternate location
+			if (!jarFile.exists()) {
+				catalinaJarPath = installPath.append("lib").append("catalina.jar");
+				jarFile = catalinaJarPath.toFile();
+				// If not here either, discard path
+				if (!jarFile.exists()) {
+					catalinaJarPath = null;
+				}
+			}
+		}
+		if (catalinaJarPath != null) {
+			versionSubString = (String)catalinaJarVersion.get(catalinaJarPath);
+			long checkTime = System.currentTimeMillis();
+			// Use some logic to try to determine if a cached value is stale
+			// If last check was more than a couple of seconds ago, check the jar time stamp 
+			if (versionSubString != null && (checkTime - lastCheck > 2000)) {
+				long curLastModified = jarFile.lastModified();
+				Long oldLastModified = (Long)catalinaJarLastModified.get(catalinaJarPath);
+				// If jar time stamps differ, discard the cached version string
+				if (oldLastModified == null || curLastModified != oldLastModified.longValue()) {
+					versionSubString = null;
+				}
+			}
+			lastCheck = checkTime;
+			// If a version string needs to be acquired
+			if (versionSubString == null) {
+				try {
+					// Read version string from catalina.jar
+					URL catalinaJarURL = jarFile.toURI().toURL();
+					URLClassLoader cl = new URLClassLoader(new URL [] { catalinaJarURL }, null);
+					InputStream is = cl.getResourceAsStream("org/apache/catalina/util/ServerInfo.properties");
+					if (is != null) {
+						Properties props = new Properties();
+						props.load(is);
+						String serverVersion = props.getProperty("server.info");
+						if (serverVersion != null) {
+							int index = serverVersion.indexOf("/");
+							if (index > 0) {
+								versionSubString = serverVersion.substring(index + 1);
+								catalinaJarVersion.put(catalinaJarPath, versionSubString);
+								catalinaJarLastModified.put(catalinaJarPath, new Long(jarFile.lastModified()));
+							}
+							else {
+								return Status.CANCEL_STATUS;
+							}
+						}
+					}
+					else {
+						return Status.CANCEL_STATUS;
+					}
+				} catch (MalformedURLException e) {
+					return Status.CANCEL_STATUS;
+				} catch (IOException e) {
+					return Status.CANCEL_STATUS;
+				}
+			}
+			if (versionSubString != null) {
+				String versionTest = (String)versionStringMap.get(serverType);
+				if (versionTest != null && !versionSubString.startsWith(versionTest)) {
+					return new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID,
+							NLS.bind(Messages.errorInstallDirWrongVersion2,
+									versionSubString, versionTest.substring(0, versionTest.length() -1)));
+				}
+			}
+		}
+		// Else server type is not supported or jar doesn't exist
+		else {
+			return Status.CANCEL_STATUS;
+		}
+		
+		return Status.OK_STATUS;
+	}
 }
diff --git a/plugins/org.eclipse.jst.server.tomcat.core/verifyInstall.properties b/plugins/org.eclipse.jst.server.tomcat.core/verifyInstall.properties
index b23c16c..252f4ea 100644
--- a/plugins/org.eclipse.jst.server.tomcat.core/verifyInstall.properties
+++ b/plugins/org.eclipse.jst.server.tomcat.core/verifyInstall.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2003, 2007 IBM Corporation and others.
+# Copyright (c) 2003, 2010 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -17,3 +17,4 @@
 verify50install=common/lib/servlet-api.jar|[servletapi5].jar,common/lib/naming-common.jar,bin/bootstrap.jar,conf,webapps
 verify55install=common/i18n,bin/bootstrap.jar,conf,webapps
 verify60install=lib/jasper-el.jar,lib/servlet-api.jar|[servletapi6].jar,bin/bootstrap.jar,conf,webapps
+verify70install=lib/jasper-el.jar,lib/servlet-api.jar|[servletapi6].jar,bin/bootstrap.jar,conf,webapps
diff --git a/plugins/org.eclipse.jst.server.tomcat.ui/plugin.xml b/plugins/org.eclipse.jst.server.tomcat.ui/plugin.xml
index 93aeffc..db7503b 100644
--- a/plugins/org.eclipse.jst.server.tomcat.ui/plugin.xml
+++ b/plugins/org.eclipse.jst.server.tomcat.ui/plugin.xml
@@ -27,6 +27,10 @@
          id="org.eclipse.jst.server.tomcat.60"
          icon="icons/obj16/tomcat.gif"
          typeIds="org.eclipse.jst.server.tomcat.runtime.60"/>
+      <image
+         id="org.eclipse.jst.server.tomcat.70"
+         icon="icons/obj16/tomcat.gif"
+         typeIds="org.eclipse.jst.server.tomcat.runtime.70"/>
 
       <image
          id="org.eclipse.jst.server.tomcat.32"
@@ -52,6 +56,10 @@
          id="org.eclipse.jst.server.tomcat.60"
          icon="icons/obj16/tomcat.gif"
          typeIds="org.eclipse.jst.server.tomcat.60"/>
+      <image
+         id="org.eclipse.jst.server.tomcat.70"
+         icon="icons/obj16/tomcat.gif"
+         typeIds="org.eclipse.jst.server.tomcat.70"/>
    </extension>
    
    <extension point="org.eclipse.core.expressions.propertyTesters">
@@ -137,6 +145,10 @@
          id="org.eclipse.jst.server.tomcat.runtime.60"
          typeIds="org.eclipse.jst.server.tomcat.runtime.60"
          class="org.eclipse.jst.server.tomcat.ui.internal.TomcatRuntimeWizardFragment"/>
+      <fragment
+         id="org.eclipse.jst.server.tomcat.runtime.70"
+         typeIds="org.eclipse.jst.server.tomcat.runtime.70"
+         class="org.eclipse.jst.server.tomcat.ui.internal.TomcatRuntimeWizardFragment"/>
    </extension>
 
   <extension point="org.eclipse.debug.ui.launchConfigurationTypeImages">