jh: refactor RichText Editor to be its own feature
diff --git a/org.eclipse.epf.common.service/.classpath b/org.eclipse.epf.common.service/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/org.eclipse.epf.common.service/.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"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.epf.common.service/.project b/org.eclipse.epf.common.service/.project
new file mode 100644
index 0000000..62bfa73
--- /dev/null
+++ b/org.eclipse.epf.common.service/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.epf.common.service</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.epf.common.service/META-INF/MANIFEST.MF b/org.eclipse.epf.common.service/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..4053200
--- /dev/null
+++ b/org.eclipse.epf.common.service/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.epf.common.service;singleton:=true
+Bundle-Version: 1.2.0.qualifier
+Bundle-Activator: org.eclipse.epf.common.service.ServicePlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.epf.common;visibility:=reexport
+Eclipse-LazyStart: true
+Bundle-Vendor: %providerName
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.epf.common.service.utils,
+ org.eclipse.epf.common.service.versioning
diff --git a/org.eclipse.epf.common.service/build.properties b/org.eclipse.epf.common.service/build.properties
new file mode 100644
index 0000000..d67426f
--- /dev/null
+++ b/org.eclipse.epf.common.service/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               schema/,\
+               plugin.properties
diff --git a/org.eclipse.epf.common.service/plugin.properties b/org.eclipse.epf.common.service/plugin.properties
new file mode 100644
index 0000000..f212da5
--- /dev/null
+++ b/org.eclipse.epf.common.service/plugin.properties
@@ -0,0 +1,15 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2000, 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial implementation.
+#-------------------------------------------------------------------------------
+# NLS_MESSAGEFORMAT_VAR
+
+# Plug-in
+pluginName=EPF Common Service
+providerName=Eclipse.org
diff --git a/org.eclipse.epf.common.service/plugin.xml b/org.eclipse.epf.common.service/plugin.xml
new file mode 100644
index 0000000..b08b78d
--- /dev/null
+++ b/org.eclipse.epf.common.service/plugin.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension-point id="version" name="Version" schema="schema/org.eclipse.epf.common.version.exsd"/>
+   <extension-point id="commandLineRunners" name="CommandLineRunners" schema="schema/commandLineRunners.exsd"/>
+   <extension
+         id="epf"
+         point="org.eclipse.epf.common.service.version">
+         <versions
+         	class="org.eclipse.epf.common.service.versioning.EPFVersions"/>
+   </extension>
+
+</plugin>
diff --git a/org.eclipse.epf.common.service/schema/commandLineRunners.exsd b/org.eclipse.epf.common.service/schema/commandLineRunners.exsd
new file mode 100644
index 0000000..26fc73a
--- /dev/null
+++ b/org.eclipse.epf.common.service/schema/commandLineRunners.exsd
@@ -0,0 +1,119 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.epf.common">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.epf.common" id="commandLineRunners" name="CommandLineRunners"/>
+      </appInfo>
+      <documentation>
+         ICommandLineRunner object that can be accessed and run from RunUtil, provided with runnerId
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="commandLineRunner" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="commandLineRunner">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="runnerId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         1.2
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         org.eclipse.epf.common.utils.ICommandLineRunner
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         //------------------------------------------------------------------------------
+// Copyright (c) 2005, 2007 IBM Corporation and others.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Contributors:
+// IBM Corporation - initial implementation
+//------------------------------------------------------------------------------
+
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.epf.common.service/schema/org.eclipse.epf.common.version.exsd b/org.eclipse.epf.common.service/schema/org.eclipse.epf.common.version.exsd
new file mode 100644
index 0000000..a5e25a9
--- /dev/null
+++ b/org.eclipse.epf.common.service/schema/org.eclipse.epf.common.version.exsd
@@ -0,0 +1,135 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.epf.common">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.epf.common" id="org.eclipse.epf.common.version" name="Version"/>
+      </appInfo>
+      <documentation>
+         Define schema/tool versions
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="versions" minOccurs="0" maxOccurs="1"/>
+            <element ref="libraryExtensionVersionCheck" minOccurs="0" maxOccurs="1"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="versions">
+      <complexType>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.epf.common.serviceability.Versions"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="libraryExtensionVersionCheck">
+      <complexType>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.epf.common.serviceability.ILibraryExtensionVersionCheck"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/ServicePlugin.java b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/ServicePlugin.java
new file mode 100644
index 0000000..f9eb497
--- /dev/null
+++ b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/ServicePlugin.java
@@ -0,0 +1,46 @@
+package org.eclipse.epf.common.service;
+
+import org.eclipse.epf.common.plugin.AbstractPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class ServicePlugin extends AbstractPlugin {
+
+	// The shared plug-in instance.
+	private static ServicePlugin plugin;
+
+	/**
+	 * Creates a new instance.
+	 */
+	public ServicePlugin() {
+		super();
+		plugin = this;
+	}
+
+	/**
+	 * @see org.eclipse.epf.common.plugin.AbstractPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+	}
+
+	/**
+	 * @see org.eclipse.epf.common.plugin.AbstractPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		super.stop(context);
+		plugin = null;
+	}
+
+	/**
+	 * Gets the shared instance.
+	 * 
+	 * @return the shared plug-in instance
+	 */
+	public static ServicePlugin getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/utils/CommandLineRunUtil.java b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/utils/CommandLineRunUtil.java
new file mode 100644
index 0000000..76ecabc
--- /dev/null
+++ b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/utils/CommandLineRunUtil.java
@@ -0,0 +1,109 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 2007 IBM Corporation and others.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Contributors:
+// IBM Corporation - initial implementation
+//------------------------------------------------------------------------------
+package org.eclipse.epf.common.service.utils;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.osgi.framework.Bundle;
+
+/**
+ * Utility class for excuting a ICommandLineRunner object's execute method
+ * 
+ * @author Weiping Lu
+ * @since 1.2
+ */
+public class CommandLineRunUtil {
+	
+	private static CommandLineRunUtil instance = new CommandLineRunUtil();
+	private boolean needToRun = false;
+	
+	public static CommandLineRunUtil getInstance() {
+		return instance;
+	}
+	
+	public CommandLineRunUtil() {		
+	}	
+	
+	public boolean execute(String[] args) {
+		//For general case, args should be parsed here to call on right runnerId.
+		//for now, just hard code it with "commandLinePluginImporter"
+		executeCommandRunner(args, "commandLinePluginImporter");	//$NON-NLS-1$ 
+		return false;
+	}
+	
+	protected boolean executeCommandRunner(String[] args, String runnerId) {
+		ICommandLineRunner runner = getRunner(runnerId);
+		if (runner != null) {
+			return runner.execute(args);
+		}
+		return false;
+	}
+	
+	private static final ICommandLineRunner getRunner(String id) {
+		IExtensionRegistry extensionRegistry = Platform
+				.getExtensionRegistry();
+		IExtensionPoint extensionPoint = extensionRegistry
+				.getExtensionPoint(
+						"org.eclipse.epf.common", "commandLineRunners"); //$NON-NLS-1$ //$NON-NLS-2$			
+		if (extensionPoint == null) {
+			return null;
+		}
+		
+		IExtension[] extensions = extensionPoint.getExtensions();
+		for (int i = 0; i < extensions.length; i++) {
+			IExtension extension = extensions[i];
+			String pluginId = extension.getNamespaceIdentifier();
+			Bundle bundle = Platform.getBundle(pluginId);
+			IConfigurationElement[] configElements = extension
+					.getConfigurationElements();
+			for (int j = 0; j < configElements.length; j++) {
+				IConfigurationElement configElement = configElements[j];
+				String runnerId = configElement.getAttribute("runnerId"); //$NON-NLS-1$
+				if (runnerId == null) {
+					continue;
+				}
+				runnerId = runnerId.trim();
+				if (! runnerId.equals(id)) {
+					continue;
+				}
+				String className = configElement.getAttribute("class"); //$NON-NLS-1$
+				if (className == null) {
+					continue;
+				}
+				className = className.trim();
+				try {
+					ICommandLineRunner runner = (ICommandLineRunner) bundle.loadClass(className).newInstance();
+					return runner;
+				} catch (Exception e) {					
+				}
+			}
+		}	
+
+		return null;
+	}
+
+	public boolean isNeedToRun() {
+		return needToRun;
+	}
+
+	public void setNeedToRun(boolean needToRun) {
+		this.needToRun = needToRun;
+	}
+
+	public static void setInstance(CommandLineRunUtil instance) {
+		CommandLineRunUtil.instance = instance;
+	}
+
+	
+}
diff --git a/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/utils/CommandLineRunner.java b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/utils/CommandLineRunner.java
new file mode 100644
index 0000000..505fb7e
--- /dev/null
+++ b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/utils/CommandLineRunner.java
@@ -0,0 +1,56 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 2007 IBM Corporation and others.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Contributors:
+// IBM Corporation - initial implementation
+//------------------------------------------------------------------------------
+package org.eclipse.epf.common.service.utils;
+
+import java.io.File;
+
+/**
+ * Base implementation for ICommandLineRunner
+ * 
+ * @author Weiping Lu
+ * @since 1.2
+ */
+public class CommandLineRunner implements ICommandLineRunner {
+	protected static boolean localDebug = true;
+	
+	private File inputFile;
+	
+	public boolean execute(String[] args) {
+		if (localDebug) {
+			System.out.println("LD> CommandLinePluginImporter.execute, args: "); //$NON-NLS-1$
+			for (int i = 0; i < args.length; i++) {
+				System.out.println("LD> args[" + i + "]: " + args[i]); //$NON-NLS-1$//$NON-NLS-2$
+			}
+		}
+		
+		for (int i = 0; i < args.length; i++) {
+			if (args[i].equalsIgnoreCase("-batch")) { //$NON-NLS-1$
+				if (i + 1 < args.length) {
+					String path = args[i + 1];
+					inputFile = new File(path);
+					if (!inputFile.exists()) {
+						String msg = "Cannot fine the file: " + path; //$NON-NLS-1$
+						System.out.println("Error> " + msg); //$NON-NLS-1$
+						return false;
+					}
+					break;
+				}
+			}
+		}
+						
+		return true;
+	}
+	
+	protected File getInputFile() {
+		return inputFile;
+	}
+	
+}
diff --git a/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/utils/ICommandLineRunner.java b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/utils/ICommandLineRunner.java
new file mode 100644
index 0000000..7b6f7f7
--- /dev/null
+++ b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/utils/ICommandLineRunner.java
@@ -0,0 +1,21 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 2007 IBM Corporation and others.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Contributors:
+// IBM Corporation - initial implementation
+//------------------------------------------------------------------------------
+package org.eclipse.epf.common.service.utils;
+
+/**
+ * Interface for excuting a command line
+ * 
+ * @author Weiping Lu
+ * @since 1.2
+ */
+public interface ICommandLineRunner {
+	boolean execute(String[] args);
+}
diff --git a/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/EPFVersion.java b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/EPFVersion.java
new file mode 100644
index 0000000..9694436
--- /dev/null
+++ b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/EPFVersion.java
@@ -0,0 +1,148 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 2006 IBM Corporation and others.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Contributors:
+// IBM Corporation - initial implementation
+//------------------------------------------------------------------------------
+package org.eclipse.epf.common.service.versioning;
+
+import org.osgi.framework.Version;
+
+/**
+ * This class represents a single version of EPF Composer.
+ * It contains all the versions of the sub-components of EPF.
+ * 
+ * @author Jeff Hardy
+ * @sicne 1.0
+ */
+public class EPFVersion {
+
+	// the tool version
+	protected Version toolVersion;
+	
+	// the library version
+	protected Version libraryVersion;
+	
+	// the schema version
+	protected Version xmlSchemaVersion;
+	
+	
+	public EPFVersion() {
+		this.toolVersion = Version.emptyVersion;
+		this.libraryVersion = Version.emptyVersion;
+		this.xmlSchemaVersion = Version.emptyVersion;
+	};
+	
+	public EPFVersion(String toolVersion, String libraryVersion, String xmlSchemaVersion) {
+		this.toolVersion = new Version(toolVersion);
+		this.libraryVersion = new Version(libraryVersion);
+		this.xmlSchemaVersion = new Version(xmlSchemaVersion);
+	}
+
+	/**
+	 * @return the tool version
+	 */
+	public Version getToolVersion() {
+		return toolVersion;
+	}
+
+	/**
+	 * @return the library version
+	 */
+	public Version getLibraryVersion() {
+		return libraryVersion;
+	}
+
+	/**
+	 * @return the XML schema version
+	 */
+	public Version getXMLSchemaVersion() {
+		return xmlSchemaVersion;
+	}
+	
+	/**
+	 * Compares the given tool version to this one
+	 * 
+	 * @see org.osgi.framework.Version#compareTo()
+	 * 
+	 * @param schemaVersion The schema version to be compared.
+	 * @return A negative integer if this tool version is less than the given one<br />
+	 * Zero if the this tool version is the same as the given one<br />
+	 * A positive integer if this tool version is greater than the given one<br />
+	 * 
+	 */
+	public int compareToolVersionTo(Version toolVersion) {
+		if (!VersionUtil.isVersionCheckingDisabled())
+			return getToolVersion().compareTo(toolVersion);
+		else 
+			return 0;
+	}
+	
+	/**
+	 * Compares the given library version to this one
+	 * 
+	 * @see org.osgi.framework.Version#compareTo()
+	 * 
+	 * @param schemaVersion The schema version to be compared.
+	 * @return A negative integer if this library version is less than the given one<br />
+	 * Zero if the this library version is the same as the given one<br />
+	 * A positive integer if this library version is greater than the given one<br />
+	 * 
+	 */
+	public int compareLibraryVersionTo(Version libraryVersion) {
+		if (!VersionUtil.isVersionCheckingDisabled())
+			return getLibraryVersion().compareTo(libraryVersion);
+		else 
+			return 0;
+	}
+
+	/**
+	 * Compares the given XML Schema version to this one
+	 * 
+	 * @see org.osgi.framework.Version#compareTo()
+	 * 
+	 * @param schemaVersion The schema version to be compared.
+	 * @return A negative integer if this XML Schema version is less than the given one<br />
+	 * Zero if the this XML Schema version is the same as the given one<br />
+	 * A positive integer if this XML Schema version is greater than the given one<br />
+	 * 
+	 */
+	public int compareXMLSchemaVersionTo(Version XMLSchemaVersion) {
+		if (!VersionUtil.isVersionCheckingDisabled())
+			return getXMLSchemaVersion().compareTo(XMLSchemaVersion);
+		else 
+			return 0;
+	}
+	
+	public String toString() {
+		return getToolVersion().toString() + "," + //$NON-NLS-1$
+		getLibraryVersion().toString() + "," + //$NON-NLS-1$
+		getXMLSchemaVersion().toString();
+	}
+	
+	public boolean equals(Object object) {
+		if (object == this) { // quicktest
+			return true;
+		}
+
+		if (!(object instanceof EPFVersion)) {
+			return false;
+		}
+
+		EPFVersion other = (EPFVersion) object;
+		return (getToolVersion().equals(other.getToolVersion())) && (getLibraryVersion().equals(other.getLibraryVersion()))
+				&& (getXMLSchemaVersion().equals(other.getXMLSchemaVersion()));
+	}
+	
+	@Override
+	public int hashCode() {
+		int result = toolVersion.hashCode();
+		result ^= libraryVersion.hashCode();
+		result ^= xmlSchemaVersion.hashCode();
+		return result;
+	}
+}
diff --git a/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/EPFVersions.java b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/EPFVersions.java
new file mode 100644
index 0000000..bbdd958
--- /dev/null
+++ b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/EPFVersions.java
@@ -0,0 +1,132 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 2007 IBM Corporation and others.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Contributors:
+// IBM Corporation - initial implementation
+//------------------------------------------------------------------------------
+package org.eclipse.epf.common.service.versioning;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.osgi.framework.Version;
+
+/**
+ * This class stores all of the version information for the known EPF versions.
+ * 
+ * @author Jeff Hardy
+ * @since 1.0
+ */
+public class EPFVersions {
+
+	public static final String TOOL_ID = "epf"; //$NON-NLS-1$
+
+	// the name space URI string for the TOOL_ID
+	private static String nsUri = "http://www.eclipse.org/epf"; //$NON-NLS-1$
+
+	// EPF 1.0
+	private static EPFVersion EPF_10 = new EPFVersion("1.0", //$NON-NLS-1$  tool version
+			"1.0.3.0", //$NON-NLS-1$  library version
+			"1.0.0"); //$NON-NLS-1$  xml schema version
+
+	// EPF 1.1 - This is EPF 1.2 Iteration 1
+	private static EPFVersion EPF_11 = new EPFVersion("1.1", //$NON-NLS-1$  tool version
+			"1.0.4.0", //$NON-NLS-1$  library version
+			"1.0.0"); //$NON-NLS-1$  xml schema version
+
+	// EPF 1.2 release
+	private static EPFVersion EPF_12 = new EPFVersion("1.2", //$NON-NLS-1$  tool version
+			"1.0.4.1", //$NON-NLS-1$  library version
+			"1.0.1"); //$NON-NLS-1$  xml schema version
+
+	private static EPFVersion currentVersion = EPF_12;
+
+	public EPFVersion getCurrentVersion() {
+		return currentVersion;
+	}
+
+	public EPFVersion getVersion(String toolVersion) {
+		if (toolVersion != null) {
+			for (Iterator iter = getAllVersions().iterator(); iter.hasNext();) {
+				EPFVersion ver = (EPFVersion) iter.next();
+				if (ver.getToolVersion().equals(new Version(toolVersion))) {
+					return ver;
+				}
+			}
+		}
+		return null;
+	}
+
+	public Collection getAllVersions() {
+		List<EPFVersion> versions = new ArrayList<EPFVersion>();
+		versions.add(EPF_10);
+		versions.add(EPF_11);
+		versions.add(EPF_12);
+		return versions;
+	}
+
+	/**
+	 * 
+	 * @param libraryVersion
+	 * @return the minimum tool version that uses the specified library version
+	 */
+	public EPFVersion getMinToolVersionForLibraryVersion(Version libraryVersion) {
+		for (Iterator iter = getAllVersions().iterator(); iter.hasNext();) {
+			EPFVersion versionInfo = (EPFVersion) iter.next();
+			if (versionInfo.getLibraryVersion().compareTo(libraryVersion) == 0) {
+				return versionInfo;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * 
+	 * @return the minimum tool version that uses the current library version
+	 */
+	public EPFVersion getMinToolVersionForCurrentLibraryVersion() {
+		Version libraryVersion = getCurrentVersion().getLibraryVersion();
+		return getMinToolVersionForLibraryVersion(libraryVersion);
+	}
+
+	/**
+	 * 
+	 * @param xmlSchemaVersion
+	 * @return the minimum tool version that uses the specified XML Schema
+	 *         version
+	 */
+	public EPFVersion getMinToolVersionForXMLSchemaVersion(
+			Version xmlSchemaVersion) {
+		for (Iterator iter = getAllVersions().iterator(); iter.hasNext();) {
+			EPFVersion versionInfo = (EPFVersion) iter.next();
+			if (versionInfo.getXMLSchemaVersion().compareTo(xmlSchemaVersion) == 0) {
+				return versionInfo;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * 
+	 * @return the minimum tool version that uses the current XML Schema version
+	 */
+	public EPFVersion getMinToolVersionForCurrentXMLSchemaVersion() {
+		Version xmlSchemaVersion = getCurrentVersion().getXMLSchemaVersion();
+		return getMinToolVersionForXMLSchemaVersion(xmlSchemaVersion);
+	}
+
+	/**
+	 * 
+	 * @return the name space URI string for the TOOL_ID
+	 */
+	public String getNsURI() {
+		return nsUri;
+	}
+
+}
diff --git a/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/ILibraryExtensionVersionCheck.java b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/ILibraryExtensionVersionCheck.java
new file mode 100644
index 0000000..3ca9bab
--- /dev/null
+++ b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/ILibraryExtensionVersionCheck.java
@@ -0,0 +1,37 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 2006 IBM Corporation and others.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Contributors:
+// IBM Corporation - initial implementation
+//------------------------------------------------------------------------------
+package org.eclipse.epf.common.service.versioning;
+
+import java.io.File;
+
+import org.eclipse.epf.common.service.versioning.VersionUtil.VersionCheckInfo;
+
+/**
+ * The interface for performing method library version check.
+ * 
+ * @author Jeff Hardy
+ * @since 1.0
+ */
+public interface ILibraryExtensionVersionCheck {
+
+	/**
+	 * Checks and returns the version information associated with a method
+	 * library.
+	 * 
+	 * @param file
+	 *            a method library XMI file
+	 * @return <code>null</code> if the library XMI file does not contain the
+	 *         version information of the tool that created it; or
+	 *         <code>VersionCheckInfo</code> object
+	 */
+	public VersionCheckInfo checkLibraryVersion(File libPath);
+
+}
diff --git a/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/VersionMismatchException.java b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/VersionMismatchException.java
new file mode 100644
index 0000000..2a22329
--- /dev/null
+++ b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/VersionMismatchException.java
@@ -0,0 +1,47 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 2006 IBM Corporation and others.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Contributors:
+// IBM Corporation - initial implementation
+//------------------------------------------------------------------------------
+package org.eclipse.epf.common.service.versioning;
+
+import org.osgi.framework.Version;
+
+/**
+ * Signals that the current version of the tool is not compatible with the
+ * method library it is trying to open.
+ * 
+ * @author Jeff Hardy
+ * @since 1.0
+ */
+public class VersionMismatchException extends RuntimeException {
+
+	private static final long serialVersionUID = 1L;
+
+	private Version expected;
+
+	private Version actual;
+
+	public VersionMismatchException(Version expected, String actual) {
+		super();
+		this.expected = expected;
+		if (actual == null) {
+			this.actual = Version.emptyVersion;
+		} else {
+			this.actual = new Version(actual);
+		}
+	}
+
+	public Version getActual() {
+		return actual;
+	}
+
+	public Version getExpected() {
+		return expected;
+	}
+}
diff --git a/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/VersionUtil.java b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/VersionUtil.java
new file mode 100644
index 0000000..4db9295
--- /dev/null
+++ b/org.eclipse.epf.common.service/src/org/eclipse/epf/common/service/versioning/VersionUtil.java
@@ -0,0 +1,473 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 2007 IBM Corporation and others.
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Contributors:
+// IBM Corporation - initial implementation
+//------------------------------------------------------------------------------
+package org.eclipse.epf.common.service.versioning;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.epf.common.CommonPlugin;
+import org.eclipse.epf.common.utils.FileUtil;
+import org.eclipse.epf.common.utils.StrUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+/**
+ * Provides utilities to query a method library schema and the version of the
+ * tool that created it.
+ * 
+ * @author Jeff Hardy
+ * @since 1.0
+ */
+public class VersionUtil {
+
+	public static class VersionCheckInfo {
+		public VersionCheckInfo(String id, String toolVersion,
+				String currentMinToolVersion, int result) {
+			this.toolID = id;
+			this.toolVersion = toolVersion;
+			this.currentMinToolVersion = currentMinToolVersion;
+			this.result = result;
+		}
+
+		public String toolID;
+
+		public String toolVersion;
+
+		public String currentMinToolVersion;
+
+		/**
+		 * < 0: fileToolVersion is older than currentMinToolVersion <br/> == 0:
+		 * match <br/> > 0 : fileToolVersion is newer than currentMinToolVersion
+		 * <br/>
+		 */
+		public int result;
+	}
+
+	/**
+	 * The extension point namespace.
+	 */
+	public static final String EXTENSION_POINT_NAMESPACE = CommonPlugin.class
+			.getPackage().getName();
+
+	/**
+	 * The extension point name.
+	 */
+	public static final String EXTENSION_POINT_NAME = "version"; //$NON-NLS-1$
+
+	public static final String EXTENSION_VERSIONS_INFO = "versions"; //$NON-NLS-1$
+
+	public static final String EXTENSION_LIB_EXTENSION_CHECK = "libraryExtensionVersionCheck"; //$NON-NLS-1$
+
+	private static final String DISABLE_VERSION_CHECKING_PREF = "disable_version_checking"; //$NON-NLS-1$
+
+	public static Map<String, EPFVersions> versions = new LinkedHashMap<String, EPFVersions>();
+
+	public static Map<String, ILibraryExtensionVersionCheck> libExtCheckers = new LinkedHashMap<String, ILibraryExtensionVersionCheck>();
+
+	protected static boolean versionCheckingDisabled = false;
+
+	/**
+	 * List of toolIDs to check, in order
+	 */
+	private static List<String> toolIDsCheckList = new ArrayList<String>();
+
+	static {
+		toolIDsCheckList.add(EPFVersions.TOOL_ID);
+
+		// read properties file
+		try {
+			String valueStr = CommonPlugin.getDefault().getPreferenceStore()
+					.getString(DISABLE_VERSION_CHECKING_PREF);
+			versionCheckingDisabled = Boolean.valueOf(valueStr).booleanValue();
+		} catch (MissingResourceException e) {
+			versionCheckingDisabled = false;
+		}
+
+		// Process the "org.eclipse.epf.common.version" extension point
+		// contributors.
+		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(
+				EXTENSION_POINT_NAMESPACE, EXTENSION_POINT_NAME);
+		if (extensionPoint != null) {
+			IExtension[] extensions = extensionPoint.getExtensions();
+			for (int i = 0; i < extensions.length; i++) {
+				IExtension extension = extensions[i];
+				initExtension(extension);
+			}
+		}
+
+	}
+
+	protected static void initExtension(IExtension extension) {
+		String extensionID = extension.getSimpleIdentifier();
+		String pluginId = extension.getNamespaceIdentifier();
+		Bundle bundle = Platform.getBundle(pluginId);
+		IConfigurationElement[] configElements = extension
+				.getConfigurationElements();
+		for (int j = 0; j < configElements.length; j++) {
+			IConfigurationElement configElement = configElements[j];
+			try {
+				if (EXTENSION_VERSIONS_INFO.equals(configElement.getName())) {
+					String className = configElement.getAttribute("class"); //$NON-NLS-1$
+					if (className != null) {
+						versions.put(extensionID, (EPFVersions) bundle
+								.loadClass(className).newInstance());
+						break;
+					}
+				}
+				if (EXTENSION_LIB_EXTENSION_CHECK.equals(configElement
+						.getName())) {
+					String className = configElement.getAttribute("class"); //$NON-NLS-1$
+					if (className != null) {
+						libExtCheckers.put(extensionID,
+								(ILibraryExtensionVersionCheck) bundle
+										.loadClass(className).newInstance());
+						break;
+					}
+				}
+			} catch (Exception e) {
+				CommonPlugin.getDefault().getLogger().logError(e);
+			}
+		}
+	}
+
+	/**
+	 * 
+	 * @return the map of Tool IDs-to-Versions class
+	 */
+	public static Map getVersionsMap() {
+		return Collections.unmodifiableMap(versions);
+	}
+
+	/**
+	 * 
+	 * @return a Set of all known Tool IDs
+	 */
+	public static Set<String> getAllToolIDs() {
+		return Collections.unmodifiableSet(versions.keySet());
+	}
+
+	/**
+	 * 
+	 * @param toolID
+	 * @return The Versions class for the given Tool ID
+	 */
+	public static EPFVersions getVersions(String toolID) {
+		return (EPFVersions) versions.get(toolID);
+	}
+
+	/**
+	 * 
+	 * @return true iff version checking is disabled
+	 */
+	public static boolean isVersionCheckingDisabled() {
+		return versionCheckingDisabled;
+	}
+
+	public static final Pattern p_XMIVersionPattern = Pattern.compile(
+			"(\\w+?):version=\"(.+?)\"", Pattern.DOTALL); //$NON-NLS-1$
+
+	public static final Pattern p_XMLVersionAttributePattern = Pattern.compile(
+			"tool=\"(.*?)\"", Pattern.DOTALL); //$NON-NLS-1$
+
+	public static final Pattern p_XMI_ELEMENT_START_TAG = Pattern
+			.compile("<?xml version=\".+?\" encoding=\".+?\"?>"); //$NON-NLS-1$
+
+	public static final String XML_ELEMENT_END_TAG = ">"; //$NON-NLS-1$
+
+	public static final String XMI_ATTRIBUTE_TAG = "xmi"; //$NON-NLS-1$
+
+	public static final String XML_ELEMENT_START_TAG = "<uma:MethodLibrary"; //$NON-NLS-1$
+
+	public static final String XML_VERSIONS_SEPARATOR = ";"; //$NON-NLS-1$
+
+	public static final String XML_TOOL_VERSION_SEPARATOR = "="; //$NON-NLS-1$
+
+	/**
+	 * Given an XML file, will read the tool="foo=a.b.c.d;bar=w.x.y.z"
+	 * attributes and return a map of the id-to-versions.
+	 * 
+	 * @param xmlFile
+	 *            file to process
+	 * @return null if no versions found; a map of the id-to-versions otherwise
+	 */
+	protected static Map readVersionsFromXMLFile(File xmlFile) {
+		Map<String, String> versions = new LinkedHashMap<String, String>();
+		StringBuffer buf = null;
+		try {
+			buf = FileUtil.readFile(xmlFile, FileUtil.ENCODING_UTF_8);
+		} catch (Exception ex) {
+			CommonPlugin.getDefault().getLogger().logError(ex);
+		}
+		if (buf != null) {
+			int xmiElementStartIdx = buf.indexOf(XML_ELEMENT_START_TAG);
+			if (xmiElementStartIdx != -1) {
+				int xmiElementEndIdx = buf.indexOf(XML_ELEMENT_END_TAG,
+						xmiElementStartIdx + XML_ELEMENT_START_TAG.length());
+				if (xmiElementEndIdx != -1) {
+					String rootElement = buf.substring(xmiElementStartIdx,
+							xmiElementEndIdx);
+					Matcher mAttribute = p_XMLVersionAttributePattern
+							.matcher(rootElement);
+					if (mAttribute.find()) {
+						String toolsAttribute = mAttribute.group(1);
+						if (toolsAttribute != null
+								&& toolsAttribute.length() > 0) {
+							String[] versionsArray = StrUtil.split(
+									toolsAttribute, XML_VERSIONS_SEPARATOR);
+							for (int i = 0; i < versionsArray.length; i++) {
+								if (versionsArray[i] != null
+										&& versionsArray[i].length() > 0) {
+									String[] versionInfoArray = StrUtil.split(
+											versionsArray[i],
+											XML_TOOL_VERSION_SEPARATOR);
+									if (versionInfoArray.length != 2)
+										continue;
+									String toolID = versionInfoArray[0];
+									String toolVersion = versionInfoArray[1];
+									if (toolID != null
+											&& toolID.trim().length() > 0
+											&& toolVersion != null
+											&& toolVersion.trim().length() > 0)
+										versions.put(toolID, toolVersion);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		if (versions.size() == 0) {
+			return null;
+		} else {
+			return versions;
+		}
+	}
+
+	/**
+	 * Given an XMI file, will read the foo:version="x.x.x" attributes and
+	 * return a map of the id-to-versions.
+	 * 
+	 * @param xmlFile
+	 *            file to process
+	 * @return null if no versions found; a map of the id-to-versions otherwise
+	 */
+	protected static Map readVersionsFromXMIFile(File xmiFile) {
+		Map<String, String> versions = new LinkedHashMap<String, String>();
+		StringBuffer buf = null;
+		try {
+			buf = FileUtil.readFile(xmiFile, FileUtil.ENCODING_UTF_8);
+		} catch (Exception ex) {
+			CommonPlugin.getDefault().getLogger().logError(ex);
+		}
+		if (buf != null) {
+			Matcher docStartMatcher = p_XMI_ELEMENT_START_TAG.matcher(buf);
+			if (docStartMatcher.find()) {
+				int docHeaderEndIdx = docStartMatcher.end();
+				int xmiElementEndIdx = buf.indexOf(XML_ELEMENT_END_TAG,
+						docHeaderEndIdx);
+				if (xmiElementEndIdx != -1) {
+					String rootElement = buf.substring(docHeaderEndIdx,
+							xmiElementEndIdx + 1);
+					Matcher m = p_XMIVersionPattern.matcher(rootElement);
+					while (m.find()) {
+						String toolID = m.group(1);
+						if (toolID.equals(XMI_ATTRIBUTE_TAG))
+							continue;
+						String toolVersion = m.group(2);
+						if (toolID != null && toolID.trim().length() > 0
+								&& toolVersion != null
+								&& toolVersion.trim().length() > 0)
+							versions.put(toolID, toolVersion);
+					}
+				}
+			}
+		}
+		if (versions.size() == 0) {
+			return null;
+		} else {
+			return versions;
+		}
+	}
+
+	/**
+	 * Given a file, will read version information and return a map of the
+	 * id-to-versions.
+	 * 
+	 * @param file
+	 *            file to process
+	 * @return null if no versions found; a map of the id-to-versions otherwise
+	 */
+	public static Map readVersionsFromFile(File file) {
+		if (file.getName().toUpperCase().endsWith("XMI")) { //$NON-NLS-1$
+			return readVersionsFromXMIFile(file);
+		} else if (file.getName().toUpperCase().endsWith("XML")) { //$NON-NLS-1$
+			return readVersionsFromXMLFile(file);
+		} else {
+			Map versions = readVersionsFromXMIFile(file);
+			if (versions != null)
+				return versions;
+			versions = readVersionsFromXMLFile(file);
+			if (versions != null)
+				return versions;
+		}
+		return null;
+	}
+
+	/**
+	 * Given a file, will compare with current XML Schema version.
+	 * 
+	 * @param file
+	 * @return null if file tool version can not be found; a VersionCheckInfo
+	 *         object otherwise
+	 */
+	public static VersionCheckInfo checkXMLVersion(File file) {
+		Map versionMap = VersionUtil.readVersionsFromFile(file);
+		if (versionMap == null) {
+			return null;
+		} else {
+			VersionCheckInfo vci = null;
+			for (Iterator iter = toolIDsCheckList.iterator(); iter.hasNext();) {
+				String toolID = (String) iter.next();
+				if (versionMap.get(toolID) != null) {
+					String toolVersion = (String) versionMap.get(toolID);
+					vci = _checkXMLVersion(toolID, toolVersion);
+					if (vci != null)
+						return vci;
+				}
+			}
+		}
+		return null;
+	}
+
+	private static VersionCheckInfo _checkXMLVersion(String toolID,
+			String toolVersion) {
+		// get the class that stores all the version info for this tool ID
+		EPFVersions versions = getVersions(toolID);
+		if (versions != null) {
+			EPFVersion minCurrVersion = versions
+					.getMinToolVersionForCurrentXMLSchemaVersion();
+			int result = minCurrVersion.compareToolVersionTo(new Version(
+					toolVersion));
+			String currentMinToolVersion = minCurrVersion.getToolVersion()
+					.toString();
+			return new VersionCheckInfo(toolID, toolVersion,
+					currentMinToolVersion, -result);
+		}
+		return null;
+	}
+
+	/**
+	 * Given a file, compares with current library schema version
+	 * 
+	 * @param file
+	 * @return null if file tool version can not be found; a VersionCheckInfo
+	 *         object otherwise
+	 */
+	public static VersionCheckInfo checkLibraryVersion(File file) {
+		if (file.getName().equals("library.xmi")) { //$NON-NLS-1$
+			// check library extensions first
+			for (Iterator iter = toolIDsCheckList.iterator(); iter.hasNext();) {
+				String toolID = (String) iter.next();
+				if (libExtCheckers.get(toolID) != null) {
+					VersionCheckInfo vci = null;
+					ILibraryExtensionVersionCheck extCheck = (ILibraryExtensionVersionCheck) libExtCheckers
+							.get(toolID);
+					vci = extCheck.checkLibraryVersion(file.getParentFile());
+					if (vci != null)
+						return vci;
+				}
+			}
+		}
+		Map versionMap = VersionUtil.readVersionsFromFile(file);
+		if (versionMap == null) {
+			return null;
+		} else {
+			VersionCheckInfo vci = null;
+			for (Iterator iter = toolIDsCheckList.iterator(); iter.hasNext();) {
+				String toolID = (String) iter.next();
+				if (versionMap.get(toolID) != null) {
+					String toolVersion = (String) versionMap.get(toolID);
+					vci = _checkLibVersion(toolID, toolVersion);
+					if (vci != null)
+						return vci;
+				}
+			}
+		}
+		return null;
+	}
+
+	private static VersionCheckInfo _checkLibVersion(String toolID,
+			String toolVersion) {
+		// get the class that stores all the version info for this tool ID
+		EPFVersions versions = getVersions(toolID);
+		if (versions != null) {
+			EPFVersion minCurrVersion = versions
+					.getMinToolVersionForCurrentLibraryVersion();
+			int result = minCurrVersion.compareToolVersionTo(new Version(
+					toolVersion));
+			String currentMinToolVersion = minCurrVersion.getToolVersion()
+					.toString();
+			return new VersionCheckInfo(toolID, toolVersion,
+					currentMinToolVersion, -result);
+		}
+		return null;
+	}
+
+	/**
+	 * 
+	 * @return the first toolID that is checked. In most cases, the ID of the
+	 *         currently running application
+	 */
+	public static String getPrimaryToolID() {
+		return (String) toolIDsCheckList.get(0);
+	}
+
+	/**
+	 * Adds a tool ID to the order of tools to check.
+	 * 
+	 * @param toolID
+	 *            toolID to add
+	 * @param toolIDfollowing
+	 *            if null, adds toolID to front of list. otherwise, adds toolID
+	 *            before the specified ID
+	 * @return false iff toolIDfollowing is not null and could not be found in
+	 *         list; true otherwise
+	 */
+	public static boolean addToolID(String toolID, String toolIDfollowing) {
+		if (toolIDfollowing != null) {
+			int idx = toolIDsCheckList.indexOf(toolIDfollowing);
+			if (idx != -1) {
+				toolIDsCheckList.add(idx, toolID);
+				return true;
+			} else {
+				return false;
+			}
+		}
+		toolIDsCheckList.add(0, toolID);
+		return true;
+	}
+
+}