Initial work to support an ISDKManager implementation that only understands SBSv2 (meaning, no devices.xml support).
authorEd Swartz <ed.swartz@nokia.com>
Wed, 02 Dec 2009 14:39:17 -0600
changeset 608 d2a651a847a5
parent 607 5d59ce9f9035
child 609 bf7dbec89c47
Initial work to support an ISDKManager implementation that only understands SBSv2 (meaning, no devices.xml support). This abstracts the common behavior of both SDKManagers into AbstractSDKManager but does not change API. SBSv2Utils is extended to encapsulate some repeated patterns to find sbs.bat.
builder/com.nokia.carbide.cdt.builder/src/com/nokia/carbide/cdt/internal/builder/CarbideSBSv2Builder.java
core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/api/sdk/SBSv2Utils.java
core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/api/sdk/SDKManagerInternalAPI.java
core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/sdk/core/model/AbstractSDKManager.java
core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/sdk/core/model/SDKManager.java
core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/sdk/core/model/SDKManagerRaptorOnly.java
core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/sdk/core/SDKCorePlugin.java
core/com.nokia.carbide.cpp.sdk.ui/src/com/nokia/carbide/cpp/internal/sdk/ui/SDKPreferencePage.java
--- a/builder/com.nokia.carbide.cdt.builder/src/com/nokia/carbide/cdt/internal/builder/CarbideSBSv2Builder.java	Wed Dec 02 14:34:30 2009 -0600
+++ b/builder/com.nokia.carbide.cdt.builder/src/com/nokia/carbide/cdt/internal/builder/CarbideSBSv2Builder.java	Wed Dec 02 14:39:17 2009 -0600
@@ -33,11 +33,10 @@
 import com.nokia.carbide.cdt.builder.project.ICarbideBuildConfiguration;
 import com.nokia.carbide.cdt.builder.project.ICarbideProjectInfo;
 import com.nokia.carbide.cpp.internal.api.sdk.SBSv2Utils;
+import com.nokia.carbide.cpp.sdk.core.SDKCorePlugin;
 
 public class CarbideSBSv2Builder implements ICarbideBuilder {
 
-    private static final IPath SBS = new Path("sbs.bat"); //$NON-NLS-1$
-
     private static final String CLEAN_CMD = "CLEAN"; //$NON-NLS-1$
     private static final String FREEZE_CMD = "FREEZE"; //$NON-NLS-1$
     private static final String REALLYCLEAN_CMD = "REALLYCLEAN"; //$NON-NLS-1$
@@ -45,9 +44,6 @@
     private static final String COMPONENT_ARG = "-p"; //$NON-NLS-1$
     private static final String COMPILE_ARG = "-c"; //$NON-NLS-1$
     
-    private static final IPath SBS_BAT = new Path("sbs.bat"); //$NON-NLS-1$
-    
-    
     public boolean buildAllComponents(ICarbideBuildConfiguration buildConfig, List<IPath> normalMakMakePaths, List<IPath> testMakMakePaths, CarbideCommandLauncher launcher, IProgressMonitor monitor) {
 		
 		SubMonitor progress = SubMonitor.convert(monitor, 3);
@@ -543,7 +539,8 @@
 
 		launcher.writeToConsole("\n***Invoking sbs command\n");
 		
-		int retVal = launcher.executeCommand(SBS, args.toArray(new String[args.size()]), getResolvedEnvVars(buildConfig), cpi.getINFWorkingDirectory());
+		int retVal = launcher.executeCommand(SBSv2Utils.getSBSPath(), 
+				args.toArray(new String[args.size()]), getResolvedEnvVars(buildConfig), cpi.getINFWorkingDirectory());
 		if (retVal != 0) {
 			launcher.writeToConsole("\n=== SBS command failed with error code " + retVal + " ===");
 			launcher.writeToConsole("\n***Stopping. Check the Problems view or Console output for errors.\n");
@@ -582,7 +579,9 @@
 		String[] sbsArgs = new String[] {"--source-target=" + file.toOSString(), COMPILE_ARG, buildTarget, COMPONENT_ARG, fullMMPPath.toFile().getName()};
 		launcher.setErrorParserManager(buildConfig.getCarbideProject().getINFWorkingDirectory(), buildConfig.getErrorParserList());
 		
-		int retVal = launcher.executeCommand(SBS_BAT, sbsArgs, getResolvedEnvVars(buildConfig), workingDirectory);
+		int retVal = launcher.executeCommand(
+				SBSv2Utils.getSBSPath(),
+				sbsArgs, getResolvedEnvVars(buildConfig), workingDirectory);
 		if (retVal != 0) {
 			launcher.writeToConsole("\n=== make failed with error code " + retVal + " ===");
 			launcher.writeToConsole("\n***Stopping. Check the Problems view or Console output for errors.\n");
--- a/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/api/sdk/SBSv2Utils.java	Wed Dec 02 14:34:30 2009 -0600
+++ b/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/api/sdk/SBSv2Utils.java	Wed Dec 02 14:39:17 2009 -0600
@@ -29,6 +29,7 @@
 
 import com.nokia.carbide.cpp.sdk.core.*;
 import com.nokia.cpp.internal.api.utils.core.FileUtils;
+import com.nokia.cpp.internal.api.utils.core.HostOS;
 import com.nokia.cpp.internal.api.utils.core.Logging;
 
 /**
@@ -42,6 +43,12 @@
 
 	private static List<String> unfilteredSBSv2ConfigNames;
 
+	protected static final String SBS_HOME = "SBS_HOME";
+	protected static String sbsHome;
+	protected static IPath sbsPath;
+
+	private static boolean scannedSbsState = false;
+	private static final String sbsScriptName = HostOS.IS_WIN32 ? "sbs.bat" : "sbs"; 
 	
 	/**
      * Get the path to the SBSv2 bin directory.  This is based on the SBS_HOME environment variable
@@ -220,6 +227,20 @@
 	}
 
 	/**
+	 * Whether or not to display SBSv1 builder UI
+	 * @return true if SBSv1 is available, false otherwise
+	 */
+	public static boolean enableSBSv1Support() {
+		if (!enableSBSv2Support())
+			return true;
+		
+		// TODO LINUX: more accurate check
+		if (HostOS.IS_WIN32)
+			return true;
+		return false;
+	}
+	
+	/**
 	 * Whether or not to display SBSv2 builder UI
 	 * @return true if SBSv2 is installed, false otherwise
 	 */
@@ -276,4 +297,35 @@
 			}
 		}
     }
+
+	/**
+	 * (Re-)scan the SBSv2 / Raptor configuration
+	 * @return message if error, else null
+	 */
+	public static String scanSBSv2() {
+		// do some basic checks
+		sbsHome = System.getenv(SBS_HOME);
+		if (sbsHome == null) {
+			return "Please define the SBS_HOME environment (e.g. /path/to/raptor) and add $SBS_HOME/bin to your PATH before running Carbide.";
+		}
+		
+		sbsPath = HostOS.findProgramOnPath(sbsScriptName, null);
+		if (sbsPath == null) {
+			return "Please add $SBS_HOME/bin to your PATH before running Carbide.";
+		}
+
+		return null;
+	}
+
+    /**
+     * Get the path to SBSv2 (sbs.bat or sbs)
+     */
+	public static IPath getSBSPath() {
+		if (!scannedSbsState) {
+			scanSBSv2();
+			scannedSbsState = true;
+		}
+		return sbsPath != null ? sbsPath : new Path(sbsScriptName);  // dummy
+	}
+
 }
--- a/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/api/sdk/SDKManagerInternalAPI.java	Wed Dec 02 14:34:30 2009 -0600
+++ b/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/api/sdk/SDKManagerInternalAPI.java	Wed Dec 02 14:39:17 2009 -0600
@@ -14,37 +14,37 @@
 
 import java.util.List;
 
-import com.nokia.carbide.cpp.internal.sdk.core.model.SDKManager;
+import com.nokia.carbide.cpp.internal.sdk.core.model.AbstractSDKManager;
 import com.nokia.carbide.cpp.sdk.core.*;
 
 public class SDKManagerInternalAPI {
 	    
     public static ISymbianSDK addMissingSdk(String uid) {
-    	return ((SDKManager)SDKCorePlugin.getSDKManager()).addMissingSdk(uid);
+    	return ((AbstractSDKManager)SDKCorePlugin.getSDKManager()).addMissingSdk(uid);
     }
     
     public static void removeMissingSdk(String uid) {
-    	((SDKManager)SDKCorePlugin.getSDKManager()).removeMissingSdk(uid);
+    	((AbstractSDKManager)SDKCorePlugin.getSDKManager()).removeMissingSdk(uid);
     }
     
     public static ISymbianSDK getMissingSdk(String uid) {
-    	return ((SDKManager)SDKCorePlugin.getSDKManager()).getMissingSdk(uid);
+    	return ((AbstractSDKManager)SDKCorePlugin.getSDKManager()).getMissingSdk(uid);
     }
     
 	public static List<ISymbianSDK> getMissingSDKList() {
-		return ((SDKManager)SDKCorePlugin.getSDKManager()).getMissingSDKList();			
+		return ((AbstractSDKManager)SDKCorePlugin.getSDKManager()).getMissingSDKList();			
 	}
 
 	public static void addInstalledSdkChangeListener(ICarbideInstalledSDKChangeListener listener) {
-		((SDKManager)SDKCorePlugin.getSDKManager()).addInstalledSdkChangeListener(listener);
+		((AbstractSDKManager)SDKCorePlugin.getSDKManager()).addInstalledSdkChangeListener(listener);
 	}
 	
 	public static void removeInstalledSdkChangeListener(ICarbideInstalledSDKChangeListener listener) {
-		((SDKManager)SDKCorePlugin.getSDKManager()).removeInstalledSdkChangeListener(listener);
+		((AbstractSDKManager)SDKCorePlugin.getSDKManager()).removeInstalledSdkChangeListener(listener);
 	}
 	
 	public static void fireInstalledSdkChanged(ICarbideInstalledSDKChangeListener.SDKChangeEventType eventType) {
-		((SDKManager)SDKCorePlugin.getSDKManager()).fireInstalledSdkChanged(eventType);
+		((AbstractSDKManager)SDKCorePlugin.getSDKManager()).fireInstalledSdkChanged(eventType);
 	}
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/sdk/core/model/AbstractSDKManager.java	Wed Dec 02 14:39:17 2009 -0600
@@ -0,0 +1,691 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+*/
+package com.nokia.carbide.cpp.internal.sdk.core.model;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.osgi.framework.Version;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeIterator;
+import org.xml.sax.SAXException;
+
+import com.nokia.carbide.cpp.internal.api.sdk.BuildPlat;
+import com.nokia.carbide.cpp.internal.api.sdk.ICarbideDevicesXMLChangeListener;
+import com.nokia.carbide.cpp.internal.api.sdk.ISDKManagerInternal;
+import com.nokia.carbide.cpp.internal.api.sdk.SBSv2Utils;
+import com.nokia.carbide.cpp.internal.api.sdk.SDKManagerInternalAPI;
+import com.nokia.carbide.cpp.internal.api.sdk.SymbianMacroStore;
+import com.nokia.carbide.cpp.sdk.core.ICarbideInstalledSDKChangeListener;
+import com.nokia.carbide.cpp.sdk.core.IRVCTToolChainInfo;
+import com.nokia.carbide.cpp.sdk.core.ISDKManager;
+import com.nokia.carbide.cpp.sdk.core.ISymbianSDK;
+import com.nokia.carbide.cpp.sdk.core.SDKCorePlugin;
+import com.nokia.carbide.cpp.sdk.core.ICarbideInstalledSDKChangeListener.SDKChangeEventType;
+import com.nokia.cpp.internal.api.utils.core.FileUtils;
+import com.nokia.cpp.internal.api.utils.core.HostOS;
+import com.nokia.cpp.internal.api.utils.core.ListenerList;
+import com.nokia.cpp.internal.api.utils.core.Logging;
+import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;
+import com.sun.org.apache.xpath.internal.XPathAPI;
+
+public abstract class AbstractSDKManager implements ISDKManager, ISDKManagerInternal {
+	
+	protected static List<ISymbianSDK> sdkList = new ArrayList<ISymbianSDK>();
+	protected HashMap<String,ISymbianSDK> missingSdkMap = new HashMap<String,ISymbianSDK>();
+
+	protected static final String CARBIDE_SDK_CACHE_FILE_NAME = "carbideSDKCache.xml";
+	protected static final String SDK_CACHE_ID_ATTRIB = "id";
+	protected static final String SDK_CACHE_ENABLED_ATTRIB = "isEnabled";
+	protected static final String SDK_CACHE_OS_VERSION_ATTRIB = "osVersion";
+	protected static final String SDK_CACHE_OS_BRANCH_ATTRIB = "osBranch";
+	protected static final String SDK_CACHE_SDK_VERSION_ATTRIB = "sdkVersion";
+	protected static final String SDK_SCANNED_FOR_PLUGINS = "sdkScanned";
+
+	protected static final String SDK_CACHE_EPOCROOT_ATTRIB = "epocroot";
+
+	protected static final String EMPTY_STRING = "";
+	protected static boolean enableBSFScanner;
+	protected static List<BuildPlat> platList = new ArrayList<BuildPlat>();
+	protected static SymbianMacroStore macroStore;
+	
+	protected static final String[] knownRVCTVersions = {"3.1", "3.0", "2.2", "2.1"};
+	protected Version sbsV2Version;
+	
+	/**
+	 * Minimum SBSv2 version supported with Carbide
+	 */
+	public static final Version MINIMUM_RAPTOR_VERSION = new Version(2, 8, 6);
+
+	static boolean hasScannedSDKs = false; // make sure we only scan SDKs when needed
+	
+	protected static List<IRVCTToolChainInfo> rvctInfoList = null;
+	
+	/**
+	 * Implement listener so other class that use this can listen to SDK 
+	 * change event (e.g. validate project config description)
+	 */
+	protected static ListenerList<ICarbideInstalledSDKChangeListener> listeners = new ListenerList<ICarbideInstalledSDKChangeListener>();
+	
+	/*
+	 * Implement listener so other class that use this can listen for when a change to the devices.xml
+	 * has been modified outside of Carbide
+	 */
+	protected static ListenerList<ICarbideDevicesXMLChangeListener> devicesXMLListeners = new ListenerList<ICarbideDevicesXMLChangeListener>();
+	
+	
+	public AbstractSDKManager() {
+		macroStore = SymbianMacroStore.getInstance();
+	}
+	
+	public SymbianMacroStore getSymbianMacroStore(){
+		return macroStore;
+	}
+	
+	public void scanSDKs() {
+		synchronized (sdkList)
+		{
+			ArrayList<ISymbianSDK> oldSDkList = new ArrayList<ISymbianSDK>(sdkList);
+			
+			getSBSv2Version(true);
+			
+			if (sdkList != null){
+				sdkList.clear();
+			}
+		
+			if (!doScanSDKs())
+				return;
+			
+			// now these SDK's are newly added, remove from internal list
+			for (ISymbianSDK sdk : sdkList) {
+				if (SDKManagerInternalAPI.getMissingSdk(sdk.getUniqueId()) != null) {
+					SDKManagerInternalAPI.removeMissingSdk(sdk
+							.getUniqueId());
+				}
+			}
+
+			// now these SDK's are removed from the old list, add to
+			// internal list
+			for (ISymbianSDK oldSdk : oldSDkList) {
+				boolean found = false;
+				for (ISymbianSDK sdk : sdkList) {
+					if (sdk.getUniqueId().equals(oldSdk.getUniqueId())) {
+						found = true;
+						break;
+					}
+				}
+				if (found == false) {
+					SDKManagerInternalAPI.addMissingSdk(oldSdk
+							.getUniqueId());
+				}
+			}
+
+
+		}
+
+		// make sure we don't rescan over and over again
+		hasScannedSDKs = true;
+		
+		// tell others about it
+		fireInstalledSdkChanged(SDKChangeEventType.eSDKScanned);
+		scanCarbideSDKCache();
+	}
+
+	/**
+	 * Actually scan the SDKs available and populate sdkList.   
+	 * @param oldSDkList old list of SDKs available for reference, e.g., detecting
+	 * when SDKs are newly missing
+	 * @return
+	 */
+	abstract protected boolean doScanSDKs();
+	
+
+	protected void ensureScannedSDKs() {
+		if (!hasScannedSDKs) {
+			scanSDKs();
+		}
+	}
+	
+	public List<ISymbianSDK> getSDKList() {
+		
+		synchronized(sdkList)
+		{
+			if (sdkList.size() < 1) {
+				ensureScannedSDKs();
+			}
+			List<ISymbianSDK> listCopy = new ArrayList<ISymbianSDK>(sdkList);
+			return listCopy;			
+		}
+	}
+
+	public ISymbianSDK getSDK(String sdkId, boolean scanIfNecessary) {
+		if (scanIfNecessary) {
+			getSDKList();
+		}
+		synchronized(sdkList)
+		{
+			for (Iterator iter = sdkList.iterator(); iter.hasNext();) {
+				ISymbianSDK sdk = (ISymbianSDK)iter.next();
+				if (sdk.getUniqueId().compareTo(sdkId) == 0) {
+					return sdk;
+				}
+			}
+		}
+		return null;
+	}
+
+	
+	public void addSDK(ISymbianSDK sdk) {
+		synchronized(sdkList)
+		{
+			try {
+				updateSDK(sdk);
+				sdkList.add(sdk);
+				SDKManagerInternalAPI.removeMissingSdk(sdk.getUniqueId());
+				// tell others about it
+				fireInstalledSdkChanged(SDKChangeEventType.eSDKAdded);
+			}
+			catch (Exception e) {
+				logError("Could not add SDK", e);
+				String message = "Could not add this SDK. Your devices.xml file may be corrupt. If you remove the file from its current location and then rescan SDKs, Carbide will offer to create a new one.";
+				Logging.showErrorDialog(WorkbenchUtils.getSafeShell(), null, message, Logging.newSimpleStatus(1, e));
+			}
+		}
+	}
+	
+	public boolean removeSDK(String sdkId) {
+		synchronized (sdkList)
+		{
+			if (sdkList != null){
+				for (ISymbianSDK currSDK : sdkList){
+					if (currSDK.getUniqueId().equals(sdkId)){
+						sdkList.remove(currSDK);
+						
+						SDKManagerInternalAPI.addMissingSdk(currSDK.getUniqueId());
+						
+						// tell others about it
+						fireInstalledSdkChanged(SDKChangeEventType.eSDKRemoved);
+						
+						doRemoveSDK(sdkId);
+						
+						break;
+					}
+				}
+				
+				updateCarbideSDKCache();
+				
+			} else {
+				return false;
+			}			
+		}
+		return true;
+	}
+
+	abstract protected boolean doRemoveSDK(String sdkId);
+
+	protected void scanCarbideSDKCache(){
+		
+		DocumentBuilder docBuilder = null;
+		try {
+			docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+		} catch (ParserConfigurationException e) {
+			ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
+			throw new RuntimeException(e);
+		}
+		
+		// NOTE: If debugging runtime workbench and you clear your configuraiton at each launch
+		// the data in the configuration location will be lost
+		Location configurationLocation = Platform.getConfigurationLocation();
+		try {
+			URL url = new URL(configurationLocation.getURL(), SDKCorePlugin.PLUGIN_ID);
+			File configFolder = new File(url.getFile());
+			if (!configFolder.exists()) {
+				configFolder.mkdirs();
+			}
+
+		    File carbideSDKCacheFile = new File(configFolder, CARBIDE_SDK_CACHE_FILE_NAME);
+		    if (!carbideSDKCacheFile.exists()){
+		    	try {
+		    	FileUtils.writeFileContents(carbideSDKCacheFile, EMPTY_STRING.toCharArray(), null);
+		    	} catch (CoreException e){
+		    		e.printStackTrace();
+		    	}
+		    }else if (carbideSDKCacheFile.length() > 0) {
+			Document lastKnownDoc = docBuilder.parse(carbideSDKCacheFile);
+			
+			NodeIterator ni = XPathAPI.selectNodeIterator(lastKnownDoc, "/sdks/sdk");
+			for (Node n = ni.nextNode(); n != null; n = ni.nextNode()) {
+				
+				// get the unique ID
+				NamedNodeMap attribs = n.getAttributes();
+				String id = attribs.getNamedItem(SDK_CACHE_ID_ATTRIB).getNodeValue();
+				
+				// get whether or not the SDK is enabled
+				String sdkEnabled = "true";
+				Node sdkEnabledItem = attribs.getNamedItem(SDK_CACHE_ENABLED_ATTRIB);
+				if (sdkEnabledItem != null)
+					sdkEnabled = sdkEnabledItem.getNodeValue();
+				
+				// get the os version
+				String osVersion = "";
+				Node osVersionItem = attribs.getNamedItem(SDK_CACHE_OS_VERSION_ATTRIB);
+				if (osVersionItem != null)
+					osVersion = osVersionItem.getNodeValue();
+				
+				// get the os branch
+				String osBranch = "";
+				Node osBranchItem = attribs.getNamedItem(SDK_CACHE_OS_BRANCH_ATTRIB);
+				if (osBranchItem != null)
+					osBranch = osBranchItem.getNodeValue();
+				
+				// get the sdk version
+				String sdkVersion = "";
+				Node sdkVersionItem = attribs.getNamedItem(SDK_CACHE_SDK_VERSION_ATTRIB);
+				if (sdkVersionItem != null)
+					sdkVersion = sdkVersionItem.getNodeValue();
+				
+				// get the custom EPOCROOT, if allowed
+				String customEpocroot = null;
+				if (!isEPOCRootFixed()) {
+					Node epocrootItem = attribs.getNamedItem(SDK_CACHE_EPOCROOT_ATTRIB);
+					if (epocrootItem != null)
+						customEpocroot = epocrootItem.getNodeValue();
+				}
+				
+				// get whether or not this SDK has been scanned
+				String wasScanned = "false";
+				Node sdkScannedItem = attribs.getNamedItem(SDK_SCANNED_FOR_PLUGINS);
+				if (sdkScannedItem != null)
+					wasScanned = sdkScannedItem.getNodeValue();
+				
+				ISymbianSDK sdk = getSDK(id, false);
+				if (sdk != null){
+					
+					if (wasScanned.equalsIgnoreCase("true")){
+						sdk.setPreviouslyScanned(true);
+					} else {
+						sdk.setPreviouslyScanned(false);
+					}
+					
+					if (sdkEnabled.equalsIgnoreCase("true")){
+						sdk.setEnabled(true);
+					} else {
+						sdk.setEnabled(false);
+					}
+					
+					if (!osVersion.equals("")){
+						if (Version.parseVersion(osVersion).getMajor() != 0){
+							sdk.setOSVersion(Version.parseVersion(osVersion));
+						}
+					}
+					
+					if (!osBranch.equals("")){
+						sdk.setOSSDKBranch(osBranch);
+					}
+					
+					if (!sdkVersion.equals("")){
+						if (Version.parseVersion(sdkVersion).getMajor() != 0){
+							sdk.setSDKVersion(Version.parseVersion(sdkVersion));
+						}
+					}
+					
+					if (customEpocroot != null) {
+						sdk.setEPOCROOT(customEpocroot);
+					}
+					
+				}
+				
+			} // for
+		} 
+	} catch (TransformerException e) {
+	} catch (SAXException e) {
+	} catch (IOException e) {
+	}
+	}
+	
+	public void updateCarbideSDKCache() {
+		if (!Platform.isRunning())
+			return;
+			
+		DocumentBuilder docBuilder = null;
+		try {
+			docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+		} catch (ParserConfigurationException e) {
+			ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
+			return;
+		}
+		
+		Location configurationLocation = Platform.getConfigurationLocation();
+		try {
+					
+			URL url = new URL(configurationLocation.getURL(), SDKCorePlugin.PLUGIN_ID);
+			File configFolder = new File(url.getFile());
+			if (!configFolder.exists()) {
+				configFolder.mkdirs();
+			}
+			
+			File carbideSDKCacheFile = new File(configFolder, CARBIDE_SDK_CACHE_FILE_NAME);
+		    if (!carbideSDKCacheFile.exists()){
+		    	try {
+		    	FileUtils.writeFileContents(carbideSDKCacheFile, EMPTY_STRING.toCharArray(), null);
+		    	} catch (CoreException e){
+		    		e.printStackTrace();
+		    	}
+		    }
+		    
+			Document d = docBuilder.newDocument();
+			Node sdks = d.appendChild(d.createElement("sdks"));
+				
+			synchronized(sdkList)
+			{
+				for (ISymbianSDK currSDK: sdkList) {
+					Node sdk = sdks.appendChild(d.createElement("sdk"));
+					NamedNodeMap attribs = sdk.getAttributes();
+					Node idNode = d.createAttribute(SDK_CACHE_ID_ATTRIB);
+					idNode.setNodeValue(currSDK.getUniqueId());
+					attribs.setNamedItem(idNode);
+						
+					// Hide the build config from view in the build config list?
+					Node enabledNode = d.createAttribute(SDK_CACHE_ENABLED_ATTRIB);
+					if (true == currSDK.isEnabled()) {
+						enabledNode.setNodeValue("true");
+					} else {
+						enabledNode.setNodeValue("false");
+					}
+					attribs.setNamedItem(enabledNode);
+					
+					Node wasScannedNode = d.createAttribute(SDK_SCANNED_FOR_PLUGINS);
+					if (true == currSDK.isPreviouslyScanned()) {
+						wasScannedNode.setNodeValue("true");
+					} else {
+						wasScannedNode.setNodeValue("false");
+					}
+					attribs.setNamedItem(wasScannedNode);
+					
+					Node osVerNode = d.createAttribute(SDK_CACHE_OS_VERSION_ATTRIB);
+					osVerNode.setNodeValue(currSDK.getOSVersion().toString());
+					attribs.setNamedItem(osVerNode);
+					
+					Node osBranchNode = d.createAttribute(SDK_CACHE_OS_BRANCH_ATTRIB);
+					osBranchNode.setNodeValue(currSDK.getSDKOSBranch());
+					attribs.setNamedItem(osBranchNode);
+					
+					Node sdkVerNode = d.createAttribute(SDK_CACHE_SDK_VERSION_ATTRIB);
+					sdkVerNode.setNodeValue(currSDK.getSDKVersion().toString());
+					attribs.setNamedItem(sdkVerNode);
+					
+					if (!isEPOCRootFixed()) {
+						Node sdkEpocRootNode = d.createAttribute(SDK_CACHE_EPOCROOT_ATTRIB);
+						sdkEpocRootNode.setNodeValue(currSDK.getEPOCROOT());
+						attribs.setNamedItem(sdkEpocRootNode);
+					}
+				}
+			}
+			DOMSource domSource = new DOMSource(d);
+			TransformerFactory transFactory = TransformerFactory.newInstance();
+			Result fileResult = new StreamResult(carbideSDKCacheFile);
+			try {
+				transFactory.newTransformer().transform(domSource, fileResult);
+			} catch (TransformerConfigurationException e) {
+				ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
+			} catch (TransformerException e) {
+				ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
+			} 
+		} catch (MalformedURLException e){
+			
+		}
+	}
+
+	/**
+	 * Tell whether EPOCROOT can be changed for a given ISymbianSDK
+	 * @return flag
+	 */
+	abstract protected boolean isEPOCRootFixed();
+
+	public boolean getBSFScannerEnabled(){
+		return enableBSFScanner;
+	}
+	
+	public void enableBSFScanner(boolean enabled){
+		enableBSFScanner = enabled;
+	}
+	
+	public void setPlatformList(List<BuildPlat> inPlatList){
+		platList = inPlatList;
+	}
+	
+	public List<BuildPlat> getPlatformList(){
+		return platList;
+	}
+
+	public synchronized IRVCTToolChainInfo[] getInstalledRVCTTools() {
+		// the path wn't change inside one invocation so cache the results
+		if (rvctInfoList == null) {
+			rvctInfoList = scanForInstalledRVCTCompilers();
+		}
+		return (IRVCTToolChainInfo[]) rvctInfoList.toArray(new IRVCTToolChainInfo[rvctInfoList.size()]);
+	}
+	
+	/**
+	 * Get a list of IRVCTToolChainInfo objects for all RVCT installations detected on the PATH env var.
+	 */
+	protected static List<IRVCTToolChainInfo> scanForInstalledRVCTCompilers() {
+		
+		Runtime rt=Runtime.getRuntime();
+		List<IRVCTToolChainInfo> rvctToolList = new ArrayList<IRVCTToolChainInfo>();
+		
+		IPath[] pathEntries = HostOS.getPathEntries(null);
+		
+		for(IPath path : pathEntries) {
+			try {
+				String command = path.append("armcc").toOSString() + " --vsn";
+				
+				Process p = rt.exec(command);
+				
+				BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+				
+				String overallOutput = null;
+				String stdErrLine = null;
+
+				// RVCT waits for like 4 minutes trying to find a license when the computer is
+				// not connected to the network.  in such cases, the call to br.readline doesn't
+				// return for 4 minutes which is unacceptable here.  Instead we'll poll at 1/2 second
+				// intervals for 40 seconds and see if we get a response. On the first response we break out
+				// of the loop and read the output. So in most normal circumstances it will take 1/2 to 1 seconds.
+				int maxTries = 80;
+				int numTries = 0;
+				while (numTries < maxTries) {
+					try {
+						Thread.sleep(500);
+					} catch (InterruptedException e) {
+						// ignore
+					}
+					if (br.ready()) {
+						while ((stdErrLine = br.readLine()) != null) {
+							overallOutput += stdErrLine;
+						}
+						break;
+					}
+					numTries++;
+				}
+				
+				p.destroy();
+				
+				if (overallOutput != null && overallOutput.length() > 0){
+					for (String currVersion : knownRVCTVersions) {
+						
+						if(overallOutput.contains(currVersion)) {
+							RVCTToolChainInfo rvctInfo = new RVCTToolChainInfo();
+							rvctInfo.setRvctToolBinariesDirectory(path.toOSString());
+							rvctInfo.setRvctToolsVersion(new Version(currVersion));
+							rvctToolList.add(rvctInfo);
+							break; // tool successfully added
+						}
+					}
+				}
+			}
+			catch (IOException e) {
+				// armcc isn't in this directory, ignore....
+			}
+		}
+				
+		return rvctToolList;
+	}
+	
+    public ISymbianSDK addMissingSdk(String uid) {
+		ISymbianSDK sdk = getMissingSdk(uid);
+		if (sdk == null) {
+			sdk = SymbianMissingSDKFactory.createInstance(uid);
+			missingSdkMap.put(uid, sdk);
+		}
+    	return sdk;
+    }
+    
+    public void removeMissingSdk(String uid) {
+    	missingSdkMap.remove(uid);
+    }
+    
+    public ISymbianSDK getMissingSdk(String uid) {
+    	return missingSdkMap.get(uid);
+    }
+    
+	public List<ISymbianSDK> getMissingSDKList() {
+		List<ISymbianSDK> listCopy = new ArrayList<ISymbianSDK>();
+		synchronized(missingSdkMap) {
+			for (ISymbianSDK sdk : missingSdkMap.values()) {
+				listCopy.add(sdk);
+			}
+		}
+		return listCopy;			
+	}
+	
+	public void addInstalledSdkChangeListener(ICarbideInstalledSDKChangeListener listener) {
+		listeners.add(listener);
+	}
+	
+	public void removeInstalledSdkChangeListener(ICarbideInstalledSDKChangeListener listener) {
+		listeners.remove(listener);
+	}
+	
+	public void fireInstalledSdkChanged(SDKChangeEventType eventType) {
+		for (ICarbideInstalledSDKChangeListener l : listeners) {
+			l.installedSdkChanged(eventType);
+		}
+	}
+	
+	public void addDevicesXMLChangeListener(ICarbideDevicesXMLChangeListener listener) {
+		devicesXMLListeners.add(listener);
+	}
+	
+	public void removeDevicesXMLChangeListener(ICarbideDevicesXMLChangeListener listener) {
+		devicesXMLListeners.remove(listener);
+	}
+	
+	public void fireDevicesXMLChanged() {
+		for (ICarbideDevicesXMLChangeListener l : devicesXMLListeners) {
+			l.devicesXMLOutOfSync();
+		}
+	}
+	
+	protected void logError(String message, Throwable t) {
+		SDKCorePlugin.getDefault().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.getPluginId(), message, t));		
+	}
+
+	public Version getSBSv2Version(boolean forceScan) {
+		if (sbsV2Version == null || forceScan){
+			sbsV2Version = new Version(0, 0, 0);
+			
+			Runtime rt=Runtime.getRuntime();
+			try {
+				IPath sbsPath = SBSv2Utils.getSBSPath();
+				Process p = rt.exec(new String[] { sbsPath.toOSString(), "-v" });
+				
+				BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
+				String overallOutput = null;
+				String stdErrLine = null;
+				while ((stdErrLine = br.readLine()) != null) {
+					overallOutput += stdErrLine;
+				}
+				
+				if (overallOutput != null) {
+				{
+					String[] tokens = overallOutput.split(" ");
+					if (tokens.length >= 3) {
+						if (tokens[2].split("\\.").length == 3) {
+							sbsV2Version = Version.parseVersion(tokens[2]);
+						}
+					}
+						if (sbsV2Version.compareTo(MINIMUM_RAPTOR_VERSION) < 0 && sbsV2Version.getMajor() > 0) {
+
+							String incorrectRaptorVersionStr = "SBSv2 version detected: "
+									+ sbsV2Version.toString()
+									+ ". The minimum version suggested for Carbide is: "
+									+ MINIMUM_RAPTOR_VERSION.getMajor()
+									+ "."
+									+ MINIMUM_RAPTOR_VERSION.getMinor()
+									+ "."
+									+ MINIMUM_RAPTOR_VERSION.getMicro();
+
+							ResourcesPlugin.getPlugin().getLog().log(
+									new Status(IStatus.WARNING,
+											SDKCorePlugin.PLUGIN_ID,
+											IStatus.WARNING,
+											incorrectRaptorVersionStr, null));
+						}
+					
+					p.destroy();
+				}
+			}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			
+			
+			
+		}
+		return sbsV2Version;
+	}
+
+	public Version getMinimumSupportedSBSv2Version() {
+		return MINIMUM_RAPTOR_VERSION;
+	}
+	
+	
+}
--- a/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/sdk/core/model/SDKManager.java	Wed Dec 02 14:34:30 2009 -0600
+++ b/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/sdk/core/model/SDKManager.java	Wed Dec 02 14:39:17 2009 -0600
@@ -19,71 +19,33 @@
 import java.io.InputStreamReader;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
-import java.net.URL;
 import java.text.MessageFormat;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Result;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
 import org.eclipse.cdt.utils.WindowsRegistry;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.osgi.service.datalocation.Location;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PlatformUI;
-import org.osgi.framework.Version;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.traversal.NodeIterator;
-import org.xml.sax.SAXException;
 
-import com.nokia.carbide.cpp.internal.api.sdk.BuildPlat;
-import com.nokia.carbide.cpp.internal.api.sdk.ICarbideDevicesXMLChangeListener;
-import com.nokia.carbide.cpp.internal.api.sdk.ISDKManagerInternal;
-import com.nokia.carbide.cpp.internal.api.sdk.SDKManagerInternalAPI;
-import com.nokia.carbide.cpp.internal.api.sdk.SymbianMacroStore;
 import com.nokia.carbide.cpp.internal.sdk.core.gen.Devices.DeviceType;
 import com.nokia.carbide.cpp.internal.sdk.core.gen.Devices.DevicesType;
 import com.nokia.carbide.cpp.internal.sdk.core.xml.DevicesLoader;
-import com.nokia.carbide.cpp.sdk.core.ICarbideInstalledSDKChangeListener;
-import com.nokia.carbide.cpp.sdk.core.IRVCTToolChainInfo;
-import com.nokia.carbide.cpp.sdk.core.ISDKManager;
 import com.nokia.carbide.cpp.sdk.core.ISymbianSDK;
 import com.nokia.carbide.cpp.sdk.core.SDKCorePlugin;
 import com.nokia.carbide.cpp.sdk.core.SDKEnvInfoFailureException;
-import com.nokia.carbide.cpp.sdk.core.ICarbideInstalledSDKChangeListener.SDKChangeEventType;
-import com.nokia.cpp.internal.api.utils.core.FileUtils;
-import com.nokia.cpp.internal.api.utils.core.ListenerList;
-import com.nokia.cpp.internal.api.utils.core.Logging;
 import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;
-import com.sun.org.apache.xpath.internal.XPathAPI;
-import com.sun.org.apache.xpath.internal.operations.Minus;
 
-public class SDKManager implements ISDKManager, ISDKManagerInternal {
+public class SDKManager extends AbstractSDKManager {
 	
-	private static List<ISymbianSDK> sdkList = new ArrayList<ISymbianSDK>();
-	private HashMap<String,ISymbianSDK> missingSdkMap = new HashMap<String,ISymbianSDK>();
-
 	private static final String SYMBIAN_COMMON_REG_PATH = "SOFTWARE\\Symbian\\EPOC SDKs\\";
 	private static final String SYMBIAN_COMMON_PATH = "CommonPath";
 	
@@ -92,35 +54,9 @@
 
 	private static final String EMPTY_DEVICES_XML_CONTENT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><devices version=\"1.0\"></devices>";
 	
-	private static final String CARBIDE_SDK_CACHE_FILE_NAME = "carbideSDKCache.xml";
-	private static final String SDK_CACHE_ID_ATTRIB = "id";
-	private static final String SDK_CACHE_ENABLED_ATTRIB = "isEnabled";
-	private static final String SDK_CACHE_OS_VERSION_ATTRIB = "osVersion";
-	private static final String SDK_CACHE_OS_BRANCH_ATTRIB = "osBranch";
-	private static final String SDK_CACHE_SDK_VERSION_ATTRIB = "sdkVersion";
-	private static final String SDK_SCANNED_FOR_PLUGINS = "sdkScanned";
-	
-	private static final String EMPTY_STRING = "";
-	private static boolean enableBSFScanner;
-	private static List<BuildPlat> platList = new ArrayList<BuildPlat>();
-	private static SymbianMacroStore macroStore;
-	
-	private static final String[] knownRVCTVersions = {"3.1", "3.0", "2.2", "2.1"};
-	private Version sbsV2Version;
-	
-	/**
-	 * Minimum SBSv2 version supported with Carbide
-	 */
-	public static final Version MINIMUM_RAPTOR_VERSION = new Version(2, 8, 6);
-
-	
-	
 	static boolean hasPromptedForDevicesXML = false; // make sure we only ask once at startup if devices.xml does not exist
-	static boolean hasScannedSDKs = false; // make sure we only scan SDKs when needed
 	long devicesXLMLastModified;
 	
-	private static List<IRVCTToolChainInfo> rvctInfoList = null;
-	
 	/**
 	 * Registry key location for checking CSL (GCCE) Arm Toolchain installation directory. 
 	 */
@@ -131,138 +67,44 @@
 	 */
 	private static final String CSL_ARM_TOOLCHAIN_REG_KEY="InstallLocation";
 	
-	/**
-	 * Implement listener so other class that use this can listen to SDK 
-	 * change event (e.g. validate project config description)
-	 */
-	private static ListenerList<ICarbideInstalledSDKChangeListener> listeners = new ListenerList<ICarbideInstalledSDKChangeListener>();
-	
-	/*
-	 * Implement listener so other class that use this can listen for when a change to the devices.xml
-	 * has been modified outside of Carbide
-	 */
-	private static ListenerList<ICarbideDevicesXMLChangeListener> devicesXMLListeners = new ListenerList<ICarbideDevicesXMLChangeListener>();
-	
-	
 	public SDKManager() {
-		macroStore = SymbianMacroStore.getInstance();
-		
+		super();
 		checkPerlInstallation();
 		
 	}
 	
-	public SymbianMacroStore getSymbianMacroStore(){
-		return macroStore;
-	}
-	
-	public void scanSDKs() {
-		synchronized (sdkList)
-		{
-			ArrayList<ISymbianSDK> oldSDkList = new ArrayList<ISymbianSDK>(sdkList);
-			
-			getSBSv2Version(true);
-			
-			if (sdkList != null){
-				sdkList.clear();
-			}
-			DevicesType devicesType;
-			try {
-				File devicesFile = getDevicesXMLFile();
-
-				if (devicesFile == null || !devicesFile.exists()) {
-					// There is no devices.xml. Ask the user if he/she wants to
-					// add it
-					if (hasPromptedForDevicesXML == false) {
-						hasPromptedForDevicesXML = true;
-						doAsynchPromptCreateDevicesXML();
-					}
-					return; // no devices.xml file..
-				}
-
-				devicesXLMLastModified = devicesFile.lastModified();
-				devicesType = DevicesLoader.loadDevices(devicesFile.toURL());
-				EList devices = devicesType.getDevice();
-				for (Iterator iter = devices.iterator(); iter.hasNext();) {
-					SymbianSDK sdk = new SymbianSDK((DeviceType) iter.next());
-					sdkList.add(sdk);
-				}
-
-				// now these SDK's are newly added, remove from internal list
-				for (ISymbianSDK sdk : sdkList) {
-					if (SDKManagerInternalAPI.getMissingSdk(sdk.getUniqueId()) != null) {
-						SDKManagerInternalAPI.removeMissingSdk(sdk
-								.getUniqueId());
-					}
-				}
+	protected boolean doScanSDKs() {
+		
+		DevicesType devicesType;
+		try {
+			File devicesFile = getDevicesXMLFile();
 
-				// now these SDK's are removed from the old list, add to
-				// internal list
-				for (ISymbianSDK oldSdk : oldSDkList) {
-					boolean found = false;
-					for (ISymbianSDK sdk : sdkList) {
-						if (sdk.getUniqueId().equals(oldSdk.getUniqueId())) {
-							found = true;
-							break;
-						}
-					}
-					if (found == false) {
-						SDKManagerInternalAPI.addMissingSdk(oldSdk
-								.getUniqueId());
-					}
+			if (devicesFile == null || !devicesFile.exists()) {
+				// There is no devices.xml. Ask the user if he/she wants to
+				// add it
+				if (hasPromptedForDevicesXML == false) {
+					hasPromptedForDevicesXML = true;
+					doAsynchPromptCreateDevicesXML();
 				}
-
-			} catch (MalformedURLException e) {
-				e.printStackTrace();
-			} catch (URISyntaxException e) {
-				e.printStackTrace();
-			} catch (IOException e) {
-				e.printStackTrace();
+				return false; // no devices.xml file..
 			}
-		}
-
-		// make sure we don't rescan over and over again
-		hasScannedSDKs = true;
-		
-		// tell others about it
-		fireInstalledSdkChanged(SDKChangeEventType.eSDKScanned);
-		scanCarbideSDKCache();
-	}
 
-	private void ensureScannedSDKs() {
-		if (!hasScannedSDKs) {
-			scanSDKs();
-		}
-	}
-	
-	public List<ISymbianSDK> getSDKList() {
-		
-		synchronized(sdkList)
-		{
-			if (sdkList.size() < 1) {
-				ensureScannedSDKs();
+			devicesXLMLastModified = devicesFile.lastModified();
+			devicesType = DevicesLoader.loadDevices(devicesFile.toURL());
+			EList devices = devicesType.getDevice();
+			for (Iterator iter = devices.iterator(); iter.hasNext();) {
+				SymbianSDK sdk = new SymbianSDK((DeviceType) iter.next());
+				sdkList.add(sdk);
 			}
-			List<ISymbianSDK> listCopy = new ArrayList<ISymbianSDK>(sdkList);
-			return listCopy;			
+
+			return true;
+		} catch (Exception e) {
+			logError("Failed to scan SDKs", e);
+			return false;
 		}
 	}
 
-	public ISymbianSDK getSDK(String sdkId, boolean scanIfNecessary) {
-		if (scanIfNecessary) {
-			getSDKList();
-		}
-		synchronized(sdkList)
-		{
-			for (Iterator iter = sdkList.iterator(); iter.hasNext();) {
-				ISymbianSDK sdk = (ISymbianSDK)iter.next();
-				if (sdk.getUniqueId().compareTo(sdkId) == 0) {
-					return sdk;
-				}
-			}
-		}
-		return null;
-	}
 
-	
 	public void updateSDK(ISymbianSDK sdk) {
 		try {
 			File devicesFile = getDevicesXMLFile();
@@ -278,24 +120,6 @@
 		}
 	}
 	
-	public void addSDK(ISymbianSDK sdk) {
-		synchronized(sdkList)
-		{
-			try {
-				updateSDK(sdk);
-				sdkList.add(sdk);
-				SDKManagerInternalAPI.removeMissingSdk(sdk.getUniqueId());
-				// tell others about it
-				fireInstalledSdkChanged(SDKChangeEventType.eSDKAdded);
-			}
-			catch (Exception e) {
-				logError("Could not add SDK", e);
-				String message = "Could not add this SDK. Your devices.xml file may be corrupt. If you remove the file from its current location and then rescan SDKs, Carbide will offer to create a new one.";
-				Logging.showErrorDialog(WorkbenchUtils.getSafeShell(), null, message, Logging.newSimpleStatus(1, e));
-			}
-		}
-	}
-	
 	public void setDefaultSDK(ISymbianSDK sdk){
 		try {
 			File devicesFile = getDevicesXMLFile();
@@ -322,56 +146,31 @@
 	}
 
 	
-	public boolean removeSDK(String sdkId) {
-		synchronized (sdkList)
-		{
-			if (sdkList != null){
-				for (ISymbianSDK currSDK : sdkList){
-					if (currSDK.getUniqueId().equals(sdkId)){
-						sdkList.remove(currSDK);
-						
-						SDKManagerInternalAPI.addMissingSdk(currSDK.getUniqueId());
-						
-						// tell others about it
-						fireInstalledSdkChanged(SDKChangeEventType.eSDKRemoved);
-						
-						// Now actually remove it from the file...
-						DevicesType devicesType;
-						try {
-							File devicesFile = getDevicesXMLFile();
-							 
-							// if file does not exist, let exception cath it...
-							devicesType = DevicesLoader.loadDevices(devicesFile.toURL());
-							EList devices = devicesType.getDevice();
-							for (Iterator iter = devices.iterator(); iter.hasNext();) {
-								DeviceType device = (DeviceType)iter.next();
-								if (device.getId().equals(sdkId)){
-									if (!DevicesLoader.deleteDeviceEntry(device, devicesFile.toURL())){
-										return false; // write failed
-									}
-									break;
-								}
-							}
-						} catch (MalformedURLException e) {
-							e.printStackTrace();
-						} catch (URISyntaxException e) {
-							e.printStackTrace();
-						} catch (IOException e) {
-							e.printStackTrace();
-						}
-						
-						
-						break;
+	protected boolean doRemoveSDK(String sdkId) {
+		// Now actually remove it from the file...
+		DevicesType devicesType;
+		try {
+			File devicesFile = getDevicesXMLFile();
+			 
+			// if file does not exist, let exception cath it...
+			devicesType = DevicesLoader.loadDevices(devicesFile.toURL());
+			EList devices = devicesType.getDevice();
+			for (Iterator iter = devices.iterator(); iter.hasNext();) {
+				DeviceType device = (DeviceType)iter.next();
+				if (device.getId().equals(sdkId)){
+					if (!DevicesLoader.deleteDeviceEntry(device, devicesFile.toURL())){
+						return false; // write failed
 					}
+					break;
 				}
-				
-				updateCarbideSDKCache();
-				
-			} else {
-				return false;
-			}			
+			}
+			
+			return true;
+		} catch (Exception e) {
+			logError("Failed to remove SDK", e);
 		}
-		return true;
+		return false;
+		
 	}
 
 	// Read the devices.xml locaiton from the local machine registry.
@@ -400,217 +199,6 @@
 		return regPath;
 	}
 	
-	private void scanCarbideSDKCache(){
-		
-		DocumentBuilder docBuilder = null;
-		try {
-			docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-		} catch (ParserConfigurationException e) {
-			ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
-			throw new RuntimeException(e);
-		}
-		
-		// NOTE: If debugging runtime workbench and you clear your configuraiton at each launch
-		// the data in the configuration location will be lost
-		Location configurationLocation = Platform.getConfigurationLocation();
-		try {
-			URL url = new URL(configurationLocation.getURL(), SDKCorePlugin.PLUGIN_ID);
-			File configFolder = new File(url.getFile());
-			if (!configFolder.exists()) {
-				configFolder.mkdirs();
-			}
-
-		    File carbideSDKCacheFile = new File(configFolder, CARBIDE_SDK_CACHE_FILE_NAME);
-		    if (!carbideSDKCacheFile.exists()){
-		    	try {
-		    	FileUtils.writeFileContents(carbideSDKCacheFile, EMPTY_STRING.toCharArray(), null);
-		    	} catch (CoreException e){
-		    		e.printStackTrace();
-		    	}
-		    }else if (carbideSDKCacheFile.length() > 0) {
-			Document lastKnownDoc = docBuilder.parse(carbideSDKCacheFile);
-			
-			NodeIterator ni = XPathAPI.selectNodeIterator(lastKnownDoc, "/sdks/sdk");
-			for (Node n = ni.nextNode(); n != null; n = ni.nextNode()) {
-				
-				// get the unique ID
-				NamedNodeMap attribs = n.getAttributes();
-				String id = attribs.getNamedItem(SDK_CACHE_ID_ATTRIB).getNodeValue();
-				
-				// get whether or not the SDK is enabled
-				String sdkEnabled = "true";
-				Node sdkEnabledItem = attribs.getNamedItem(SDK_CACHE_ENABLED_ATTRIB);
-				if (sdkEnabledItem != null)
-					sdkEnabled = sdkEnabledItem.getNodeValue();
-				
-				// get the os version
-				String osVersion = "";
-				Node osVersionItem = attribs.getNamedItem(SDK_CACHE_OS_VERSION_ATTRIB);
-				if (osVersionItem != null)
-					osVersion = osVersionItem.getNodeValue();
-				
-				// get the os branch
-				String osBranch = "";
-				Node osBranchItem = attribs.getNamedItem(SDK_CACHE_OS_BRANCH_ATTRIB);
-				if (osBranchItem != null)
-					osBranch = osBranchItem.getNodeValue();
-				
-				// get the sdk version
-				String sdkVersion = "";
-				Node sdkVersionItem = attribs.getNamedItem(SDK_CACHE_SDK_VERSION_ATTRIB);
-				if (sdkVersionItem != null)
-					sdkVersion = sdkVersionItem.getNodeValue();
-				
-				// get whether or not this SDK has been scanned
-				String wasScanned = "false";
-				Node sdkScannedItem = attribs.getNamedItem(SDK_SCANNED_FOR_PLUGINS);
-				if (sdkScannedItem != null)
-					wasScanned = sdkScannedItem.getNodeValue();
-				
-				ISymbianSDK sdk = getSDK(id, false);
-				if (sdk != null){
-					
-					if (wasScanned.equalsIgnoreCase("true")){
-						sdk.setPreviouslyScanned(true);
-					} else {
-						sdk.setPreviouslyScanned(false);
-					}
-					
-					if (sdkEnabled.equalsIgnoreCase("true")){
-						sdk.setEnabled(true);
-					} else {
-						sdk.setEnabled(false);
-					}
-					
-					if (!osVersion.equals("")){
-						if (Version.parseVersion(osVersion).getMajor() != 0){
-							sdk.setOSVersion(Version.parseVersion(osVersion));
-						}
-					}
-					
-					if (!osBranch.equals("")){
-						sdk.setOSSDKBranch(osBranch);
-					}
-					
-					if (!sdkVersion.equals("")){
-						if (Version.parseVersion(sdkVersion).getMajor() != 0){
-							sdk.setSDKVersion(Version.parseVersion(sdkVersion));
-						}
-					}
-					
-				}
-				
-			} // for
-		} 
-	} catch (TransformerException e) {
-	} catch (SAXException e) {
-	} catch (IOException e) {
-	}
-	}
-	
-	public void updateCarbideSDKCache() {
-		if (!Platform.isRunning())
-			return;
-			
-		DocumentBuilder docBuilder = null;
-		try {
-			docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-		} catch (ParserConfigurationException e) {
-			ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
-			return;
-		}
-		
-		Location configurationLocation = Platform.getConfigurationLocation();
-		try {
-					
-			URL url = new URL(configurationLocation.getURL(), SDKCorePlugin.PLUGIN_ID);
-			File configFolder = new File(url.getFile());
-			if (!configFolder.exists()) {
-				configFolder.mkdirs();
-			}
-			
-			File carbideSDKCacheFile = new File(configFolder, CARBIDE_SDK_CACHE_FILE_NAME);
-		    if (!carbideSDKCacheFile.exists()){
-		    	try {
-		    	FileUtils.writeFileContents(carbideSDKCacheFile, EMPTY_STRING.toCharArray(), null);
-		    	} catch (CoreException e){
-		    		e.printStackTrace();
-		    	}
-		    }
-		    
-			Document d = docBuilder.newDocument();
-			Node sdks = d.appendChild(d.createElement("sdks"));
-				
-			synchronized(sdkList)
-			{
-				for (ISymbianSDK currSDK: sdkList) {
-					Node sdk = sdks.appendChild(d.createElement("sdk"));
-					NamedNodeMap attribs = sdk.getAttributes();
-					Node idNode = d.createAttribute(SDK_CACHE_ID_ATTRIB);
-					idNode.setNodeValue(currSDK.getUniqueId());
-					attribs.setNamedItem(idNode);
-						
-					// Hide the build config from view in the build config list?
-					Node enabledNode = d.createAttribute(SDK_CACHE_ENABLED_ATTRIB);
-					if (true == currSDK.isEnabled()) {
-						enabledNode.setNodeValue("true");
-					} else {
-						enabledNode.setNodeValue("false");
-					}
-					attribs.setNamedItem(enabledNode);
-					
-					Node wasScannedNode = d.createAttribute(SDK_SCANNED_FOR_PLUGINS);
-					if (true == currSDK.isPreviouslyScanned()) {
-						wasScannedNode.setNodeValue("true");
-					} else {
-						wasScannedNode.setNodeValue("false");
-					}
-					attribs.setNamedItem(wasScannedNode);
-					
-					Node osVerNode = d.createAttribute(SDK_CACHE_OS_VERSION_ATTRIB);
-					osVerNode.setNodeValue(currSDK.getOSVersion().toString());
-					attribs.setNamedItem(osVerNode);
-					
-					Node osBranchNode = d.createAttribute(SDK_CACHE_OS_BRANCH_ATTRIB);
-					osBranchNode.setNodeValue(currSDK.getSDKOSBranch());
-					attribs.setNamedItem(osBranchNode);
-					
-					Node sdkVerNode = d.createAttribute(SDK_CACHE_SDK_VERSION_ATTRIB);
-					sdkVerNode.setNodeValue(currSDK.getSDKVersion().toString());
-					attribs.setNamedItem(sdkVerNode);
-				}
-			}
-				DOMSource domSource = new DOMSource(d);
-				TransformerFactory transFactory = TransformerFactory.newInstance();
-				Result fileResult = new StreamResult(carbideSDKCacheFile);
-				try {
-					transFactory.newTransformer().transform(domSource, fileResult);
-				} catch (TransformerConfigurationException e) {
-					ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
-				} catch (TransformerException e) {
-					ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
-				} 
-		} catch (MalformedURLException e){
-			
-		}
-	}
-	
-	public boolean getBSFScannerEnabled(){
-		return enableBSFScanner;
-	}
-	
-	public void enableBSFScanner(boolean enabled){
-		enableBSFScanner = enabled;
-	}
-	
-	public void setPlatformList(List<BuildPlat> inPlatList){
-		platList = inPlatList;
-	}
-	
-	public List<BuildPlat> getPlatformList(){
-		return platList;
-	}
-
 	public File getDevicesXMLFile() {
 		IPath devicesPath = getDevicesXMLFromRegistry();
 		
@@ -673,83 +261,6 @@
 		return gcceToolDir;
 	}
 	
-	public synchronized IRVCTToolChainInfo[] getInstalledRVCTTools() {
-		// the path wn't change inside one invocation so cache the results
-		if (rvctInfoList == null) {
-			rvctInfoList = scanForInstalledRVCTCompilers();
-		}
-		return (IRVCTToolChainInfo[]) rvctInfoList.toArray(new IRVCTToolChainInfo[rvctInfoList.size()]);
-	}
-	
-	/**
-	 * Get a list of IRVCTToolChainInfo objects for all RVCT installations detected on the PATH env var.
-	 */
-	private static List<IRVCTToolChainInfo> scanForInstalledRVCTCompilers() {
-		
-		Runtime rt=Runtime.getRuntime();
-		List<IRVCTToolChainInfo> rvctToolList = new ArrayList<IRVCTToolChainInfo>();
-		String pathStr = System.getenv("PATH");
-		String[] pathTokens = pathStr.split(";");
-		
-		for(String currTok : pathTokens) {
-			try {
-				String command = currTok;
-				command += (currTok.endsWith("\\") || currTok.endsWith("/")) ? "" : File.separator;
-				command += "armcc.exe --vsn";
-				
-				Process p = rt.exec(command);
-				
-				BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
-				
-				String overallOutput = null;
-				String stdErrLine = null;
-
-				// RVCT waits for like 4 minutes trying to find a license when the computer is
-				// not connected to the network.  in such cases, the call to br.readline doesn't
-				// return for 4 minutes which is unacceptable here.  Instead we'll poll at 1/2 second
-				// intervals for 40 seconds and see if we get a response. On the first response we break out
-				// of the loop and read the output. So in most normal circumstances it will take 1/2 to 1 seconds.
-				int maxTries = 80;
-				int numTries = 0;
-				while (numTries < maxTries) {
-					try {
-						Thread.sleep(500);
-					} catch (InterruptedException e) {
-						// ignore
-					}
-					if (br.ready()) {
-						while ((stdErrLine = br.readLine()) != null) {
-							overallOutput += stdErrLine;
-						}
-						break;
-					}
-					numTries++;
-				}
-				
-				p.destroy();
-				
-				if (overallOutput != null && overallOutput.length() > 0){
-					for (String currVersion : knownRVCTVersions) {
-						
-						if(overallOutput.contains(currVersion)) {
-							RVCTToolChainInfo rvctInfo = new RVCTToolChainInfo();
-							rvctInfo.setRvctToolBinariesDirectory(currTok);
-							rvctInfo.setRvctToolsVersion(new Version(currVersion));
-							rvctToolList.add(rvctInfo);
-							break; // tool successfully added
-						}
-					}
-				}
-			}
-			catch (IOException e) {
-				// armcc isn't in this directory, ignore....
-			}
-		}
-				
-		return rvctToolList;
-	}
-	
-
 	public void doAsynchPromptCreateDevicesXML() {
 		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
 			public void run() {
@@ -829,61 +340,6 @@
 		}
 	}
 	
-    public ISymbianSDK addMissingSdk(String uid) {
-		ISymbianSDK sdk = getMissingSdk(uid);
-		if (sdk == null) {
-			sdk = SymbianMissingSDKFactory.createInstance(uid);
-			missingSdkMap.put(uid, sdk);
-		}
-    	return sdk;
-    }
-    
-    public void removeMissingSdk(String uid) {
-    	missingSdkMap.remove(uid);
-    }
-    
-    public ISymbianSDK getMissingSdk(String uid) {
-    	return missingSdkMap.get(uid);
-    }
-    
-	public List<ISymbianSDK> getMissingSDKList() {
-		List<ISymbianSDK> listCopy = new ArrayList<ISymbianSDK>();
-		synchronized(missingSdkMap) {
-			for (ISymbianSDK sdk : missingSdkMap.values()) {
-				listCopy.add(sdk);
-			}
-		}
-		return listCopy;			
-	}
-	
-	public void addInstalledSdkChangeListener(ICarbideInstalledSDKChangeListener listener) {
-		listeners.add(listener);
-	}
-	
-	public void removeInstalledSdkChangeListener(ICarbideInstalledSDKChangeListener listener) {
-		listeners.remove(listener);
-	}
-	
-	public void fireInstalledSdkChanged(SDKChangeEventType eventType) {
-		for (ICarbideInstalledSDKChangeListener l : listeners) {
-			l.installedSdkChanged(eventType);
-		}
-	}
-	
-	public void addDevicesXMLChangeListener(ICarbideDevicesXMLChangeListener listener) {
-		devicesXMLListeners.add(listener);
-	}
-	
-	public void removeDevicesXMLChangeListener(ICarbideDevicesXMLChangeListener listener) {
-		devicesXMLListeners.remove(listener);
-	}
-	
-	public void fireDevicesXMLChanged() {
-		for (ICarbideDevicesXMLChangeListener l : devicesXMLListeners) {
-			l.devicesXMLOutOfSync();
-		}
-	}
-	
 	public boolean checkDevicesXMLSynchronized(){
 		if (devicesXLMLastModified == 0){
 			return true; // no devices.xml file
@@ -954,68 +410,9 @@
 			return true;
 		}
 	}
-	
-	private void logError(String message, Throwable t) {
-		SDKCorePlugin.getDefault().getLog().log(new Status(IStatus.ERROR, SDKCorePlugin.getPluginId(), message, t));		
+
+	@Override
+	protected boolean isEPOCRootFixed() {
+		return true;
 	}
-
-	public Version getSBSv2Version(boolean forceScan) {
-		if (sbsV2Version == null || forceScan){
-			sbsV2Version = new Version(0, 0, 0);
-			
-			Runtime rt=Runtime.getRuntime();
-			try {
-				Process p = rt.exec("sbs.bat -v");
-				
-				BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
-				String overallOutput = null;
-				String stdErrLine = null;
-				while ((stdErrLine = br.readLine()) != null) {
-					overallOutput += stdErrLine;
-				}
-				
-				if (overallOutput != null) {
-				{
-					String[] tokens = overallOutput.split(" ");
-					if (tokens.length >= 3) {
-						if (tokens[2].split("\\.").length == 3) {
-							sbsV2Version = Version.parseVersion(tokens[2]);
-						}
-					}
-						if (sbsV2Version.compareTo(MINIMUM_RAPTOR_VERSION) < 0 && sbsV2Version.getMajor() > 0) {
-
-							String incorrectRaptorVersionStr = "SBSv2 version detected: "
-									+ sbsV2Version.toString()
-									+ ". The minimum version suggested for Carbide is: "
-									+ MINIMUM_RAPTOR_VERSION.getMajor()
-									+ "."
-									+ MINIMUM_RAPTOR_VERSION.getMinor()
-									+ "."
-									+ MINIMUM_RAPTOR_VERSION.getMicro();
-
-							ResourcesPlugin.getPlugin().getLog().log(
-									new Status(IStatus.WARNING,
-											SDKCorePlugin.PLUGIN_ID,
-											IStatus.WARNING,
-											incorrectRaptorVersionStr, null));
-						}
-					
-					p.destroy();
-				}
-			}
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
-			
-			
-			
-		}
-		return sbsV2Version;
-	}
-
-	public Version getMinimumSupportedSBSv2Version() {
-		return MINIMUM_RAPTOR_VERSION;
-	}
-	
-	
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/internal/sdk/core/model/SDKManagerRaptorOnly.java	Wed Dec 02 14:39:17 2009 -0600
@@ -0,0 +1,142 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+package com.nokia.carbide.cpp.internal.sdk.core.model;
+
+import java.io.File;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.carbide.cpp.internal.api.sdk.SBSv2Utils;
+import com.nokia.carbide.cpp.internal.sdk.core.gen.Devices.DefaultType;
+import com.nokia.carbide.cpp.internal.sdk.core.gen.Devices.DeviceType;
+import com.nokia.carbide.cpp.internal.sdk.core.gen.Devices.DevicesFactory;
+import com.nokia.carbide.cpp.sdk.core.ISymbianSDK;
+import com.nokia.carbide.cpp.sdk.core.SDKEnvInfoFailureException;
+import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;
+
+/**
+ * This SDK manager only expects Raptor (SBSv2) to exist.
+ */
+public class SDKManagerRaptorOnly extends AbstractSDKManager {
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.sdk.core.model.AbstractSDKManager#doScanSDKs()
+	 */
+	@Override
+	protected boolean doScanSDKs() {
+		
+		String message = SBSv2Utils.scanSBSv2();
+		if (message != null) {
+			reportError(message);
+			return false;
+		}
+		
+		// TODO LINUX: real configuration
+		String epocrootStr = System.getenv("EPOCROOT");
+		if (epocrootStr == null)
+			epocrootStr = System.getProperty("user.home") + "/epocroot";
+		
+		File epocroot = new File(epocrootStr);
+		
+		if (epocroot.isDirectory()) {
+			addSymbianSDK(epocroot);
+		}
+		
+		return true;
+	}
+
+	protected void addSymbianSDK(File epocroot) {
+		// TODO LINUX: see if Raptor has a database for this stuff
+		DeviceType deviceType = DevicesFactory.eINSTANCE.createDeviceType();
+		deviceType.setDefault(DefaultType.YES_LITERAL);
+		deviceType.setEpocroot(epocroot.getAbsolutePath());
+		deviceType.setId("raptor");
+		deviceType.setName("com.nokia.s60");
+		deviceType.setAlias("Default Raptor target");
+		deviceType.setToolsroot(new File(epocroot, "epoc32/tools").getAbsolutePath());
+		deviceType.setUserdeletable("false");
+		
+		SymbianSDK sdk = new SymbianSDK(deviceType);
+		sdkList.add(sdk);
+	}
+
+	protected void reportError(final String string) {
+		if (WorkbenchUtils.isJUnitRunning())
+			return;
+		Display.getDefault().syncExec(new Runnable() {
+			public void run() {
+				MessageDialog.openWarning(WorkbenchUtils.getActiveShell(), "SBSv2 Setup Failed", string);
+			}
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.internal.sdk.core.model.AbstractSDKManager#doRemoveSDK(java.lang.String)
+	 */
+	@Override
+	protected boolean doRemoveSDK(String sdkId) {
+		reportError("Cannot delete Raptor targets");
+		return false;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.sdk.core.ISDKManager#checkDevicesXMLSynchronized()
+	 */
+	public boolean checkDevicesXMLSynchronized() {
+		// TODO LINUX: investigate
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.sdk.core.ISDKManager#getCSLArmToolchainInstallPathAndCheckReqTools()
+	 */
+	public String getCSLArmToolchainInstallPathAndCheckReqTools()
+			throws SDKEnvInfoFailureException {
+		throw new SDKEnvInfoFailureException("CSL ARM Tools detection not yet implemented");
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.sdk.core.ISDKManager#getDevicesXMLFile()
+	 */
+	public File getDevicesXMLFile() {
+		// This is a placeholder, since this file is not used in Linux
+		return new File(System.getProperty("user.home"), "devices.xml");
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.sdk.core.ISDKManager#setDefaultSDK(com.nokia.carbide.cpp.sdk.core.ISymbianSDK)
+	 */
+	public void setDefaultSDK(ISymbianSDK sdk) {
+		// ignore
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.carbide.cpp.sdk.core.ISDKManager#updateSDK(com.nokia.carbide.cpp.sdk.core.ISymbianSDK)
+	 */
+	public void updateSDK(ISymbianSDK sdkId) {
+		updateCarbideSDKCache();
+	}
+	
+	@Override
+	protected boolean isEPOCRootFixed() {
+		return false;
+	}
+
+}
--- a/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/sdk/core/SDKCorePlugin.java	Wed Dec 02 14:34:30 2009 -0600
+++ b/core/com.nokia.carbide.cpp.sdk.core/src/com/nokia/carbide/cpp/sdk/core/SDKCorePlugin.java	Wed Dec 02 14:39:17 2009 -0600
@@ -16,6 +16,8 @@
 import org.osgi.framework.BundleContext;
 
 import com.nokia.carbide.cpp.internal.sdk.core.model.SDKManager;
+import com.nokia.carbide.cpp.internal.sdk.core.model.SDKManagerRaptorOnly;
+import com.nokia.cpp.internal.api.utils.core.HostOS;
 
 
 /**
@@ -31,7 +33,7 @@
 	// The shared instance
 	private static SDKCorePlugin plugin;
 	
-	private static SDKManager sdkManager;
+	private static ISDKManager sdkManager;
 	
 	/**
 	 * The constructor
@@ -76,7 +78,10 @@
 	 */
 	public static ISDKManager getSDKManager() {
 		if (sdkManager == null) {
-			sdkManager = new SDKManager();
+			if (HostOS.IS_WIN32)
+				sdkManager = new SDKManager();
+			else
+				sdkManager = new SDKManagerRaptorOnly();
 		}
 		return sdkManager;
 	}
--- a/core/com.nokia.carbide.cpp.sdk.ui/src/com/nokia/carbide/cpp/internal/sdk/ui/SDKPreferencePage.java	Wed Dec 02 14:34:30 2009 -0600
+++ b/core/com.nokia.carbide.cpp.sdk.ui/src/com/nokia/carbide/cpp/internal/sdk/ui/SDKPreferencePage.java	Wed Dec 02 14:39:17 2009 -0600
@@ -101,7 +101,8 @@
 		GRAY = shell.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
 		
 		// check that devices.xml actually exists
-		((SDKManager) sdkMgr).checkDevicesXMLExistAndCreate();
+		if (sdkMgr instanceof SDKManager)
+			((SDKManager) sdkMgr).checkDevicesXMLExistAndCreate();
 		
 		Composite content = new Composite(parent, SWT.NONE);
 		setControl(content);