Fix Eclipse sample tests.
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectCreationPage.java
similarity index 71%
rename from tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectCreationPage.java
rename to tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectCreationPage.java
index 75b6d9b..0ed9ed4 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectCreationPage.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectCreationPage.java
@@ -21,28 +21,31 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
 
-import java.io.File;
-
 /**
- * Stub class for project creation page Returns canned responses for creating a
- * sample project
+ * Stub class for project creation page.
+ * <p/>
+ * Returns canned responses for creating a sample project.
  */
-public class StubSampleProjectCreationPage extends NewProjectCreationPage {
+public class StubProjectCreationPage extends NewProjectCreationPage {
 
-    private String mSampleProjectName;
-    private String mOsSdkLocation;
+    private final String mProjectName;
+    private final String mLocation;
+    private final IAndroidTarget mTarget;
 
-    public StubSampleProjectCreationPage(String sampleProjectName, String osSdkLocation) {
+    public StubProjectCreationPage(String projectName, String projectLocation, IAndroidTarget target) {
         super();
-        this.mSampleProjectName = sampleProjectName;
-        this.mOsSdkLocation = osSdkLocation;
+        this.mProjectName = projectName;
+        this.mLocation = projectLocation;
+        this.mTarget = target;
+        // don't set test project info
+        setTestInfo(null);
     }
 
     @Override
     public IMainInfo getMainInfo() {
         return new IMainInfo() {
             public String getProjectName() {
-                return mSampleProjectName;
+                return mProjectName;
             }
 
             public String getPackageName() {
@@ -50,11 +53,11 @@
             }
 
             public String getActivityName() {
-                return mSampleProjectName;
+                return mProjectName;
             }
 
             public String getApplicationName() {
-                return mSampleProjectName;
+                return mProjectName;
             }
 
             public boolean isNewProject() {
@@ -66,9 +69,7 @@
             }
 
             public IPath getLocationPath() {
-                return new Path(mOsSdkLocation + File.separator +
-                        "samples" + File.separator +
-                        mSampleProjectName);
+                return new Path(mLocation);
             }
 
             public String getMinSdkVersion() {
@@ -76,7 +77,7 @@
             }
 
             public IAndroidTarget getSdkTarget() {
-                return null;
+                return mTarget;
             }
 
             public boolean isCreateActivity() {
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectWizard.java
similarity index 71%
rename from tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectWizard.java
rename to tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectWizard.java
index 28c2c7e..18a29cc 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectWizard.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubProjectWizard.java
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * 
+ *
  * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
  * may not use this file except in compliance with the License. You may obtain a
  * copy of the License at
- * 
+ *
  *      http://www.eclipse.org/org/documents/epl-v10.php
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -17,6 +17,8 @@
 
 import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectCreationPage;
 import com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard;
+import com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectCreationPage;
+import com.android.sdklib.IAndroidTarget;
 
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jface.operation.IRunnableWithProgress;
@@ -27,24 +29,27 @@
 import java.lang.reflect.InvocationTargetException;
 
 /**
- * Stub class for project creation wizard Created so project creation logic can
- * be run without UI creation/manipulation Returns canned responses for creating
- * a sample project
+ * Stub class for project creation wizard.
+ * <p/>
+ * Created so project creation logic can be run without UI creation/manipulation.
  */
-public class StubSampleProjectWizard extends NewProjectWizard {
+public class StubProjectWizard extends NewProjectWizard {
 
-    private final String mSampleProjectName;
-    private final String mOsSdkLocation;
+    private final String mProjectName;
+    private final String mProjectLocation;
+    private final IAndroidTarget mTarget;
 
     /**
      * Constructor
-     * 
-     * @param sampleProjectName
-     * @param osSdkLocation
+     *
+     * @param projectName
+     * @param projectLocation
+     * @parama target
      */
-    public StubSampleProjectWizard(String sampleProjectName, String osSdkLocation) {
-        this.mSampleProjectName = sampleProjectName;
-        this.mOsSdkLocation = osSdkLocation;
+    public StubProjectWizard(String projectName, String projectLocation, IAndroidTarget target) {
+        this.mProjectName = projectName;
+        this.mProjectLocation = projectLocation;
+        this.mTarget = target;
     }
 
     /**
@@ -52,7 +57,15 @@
      */
     @Override
     protected NewProjectCreationPage createMainPage() {
-        return new StubSampleProjectCreationPage(mSampleProjectName, mOsSdkLocation);
+        return new StubProjectCreationPage(mProjectName, mProjectLocation, mTarget);
+    }
+
+    /**
+     * Override parent to return null page
+     */
+    @Override
+    protected NewTestProjectCreationPage createTestPage() {
+        return null;
     }
 
     /**
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java
index 4322727..344f9ee 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java
@@ -15,40 +15,70 @@
  */
 package com.android.ide.eclipse.tests;
 
+import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetParser;
+import com.android.ide.eclipse.adt.internal.sdk.Sdk;
+import com.android.sdklib.IAndroidTarget;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
 import junit.framework.TestCase;
 
 /**
- * Generic superclass for Eclipse Android functional test cases, that provides
- * common facilities
+ * Generic superclass for Eclipse Android functional test cases, that provides common facilities.
  */
 public class FuncTestCase extends TestCase {
 
     private String mOsSdkLocation;
+    protected Sdk mSdk;
 
     /**
-     * Constructor
-     *
-     * @throws IllegalArgumentException if environment variable "sdk_home" is
-     *         not set
+     * Initializes test SDK
+     * <p/>
+     * Fails test if environment variable "sdk_home" is not set.
      */
-    protected FuncTestCase() {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
         mOsSdkLocation = System.getProperty("sdk_home");
         if (mOsSdkLocation == null) {
             mOsSdkLocation = System.getenv("sdk_home");
         }
         if (mOsSdkLocation == null || mOsSdkLocation.length() < 1) {
-            throw new IllegalArgumentException(
-                    "Environment variable sdk_home is not set");
+            fail("Environment variable sdk_home is not set");
         }
+
+        loadSdk(mOsSdkLocation);
     }
 
     /**
-     * Returns the absolute file system path of the Android SDK location to use
-     * for this test
+     * Returns the absolute file system path of the Android SDK location to use for this test.
      */
     protected String getOsSdkLocation() {
         return mOsSdkLocation;
     }
 
+    /**
+     * Returns the {@link Sdk} under test.
+     */
+    protected Sdk getSdk() {
+        return mSdk;
+    }
 
+    /**
+     * Loads the {@link Sdk}.
+     */
+    private void loadSdk(String sdkLocation) {
+        mSdk = Sdk.loadSdk(sdkLocation);
+
+        int n = mSdk.getTargets().length;
+        if (n > 0) {
+            for (IAndroidTarget target : mSdk.getTargets()) {
+                IStatus status = new AndroidTargetParser(target).run(new NullProgressMonitor());
+                if (status.getCode() != IStatus.OK) {
+                    fail("Failed to parse targets data");
+                }
+            }
+        }
+    }
 }
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
index 2b9aca3..f4dafc8 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
@@ -37,9 +37,7 @@
 import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
 import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
 import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetParser;
 import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.internal.sdk.Sdk;
 import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
 import com.android.ide.eclipse.tests.FuncTestCase;
 import com.android.layoutlib.api.ILayoutResult;
@@ -49,8 +47,6 @@
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.SdkConstants;
 
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
 import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -120,30 +116,10 @@
 
     }
 
-    private Sdk mSdk;
-
     public void testApiDemos() throws IOException, XmlPullParserException {
-        loadSdk();
         findApiDemos();
     }
 
-    /**
-     * Loads the {@link Sdk}.
-     */
-    private void loadSdk() {
-        mSdk = Sdk.loadSdk(this.getOsSdkLocation());
-
-        int n = mSdk.getTargets().length;
-        if (n > 0) {
-            for (IAndroidTarget target : mSdk.getTargets()) {
-                IStatus status = new AndroidTargetParser(target).run(new NullProgressMonitor());
-                if (status.getCode() != IStatus.OK) {
-                    fail("Failed to parse targets data");
-                }
-            }
-        }
-    }
-
     private void findApiDemos() throws IOException, XmlPullParserException {
         IAndroidTarget[] targets = mSdk.getTargets();
 
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java
new file mode 100644
index 0000000..495c3be
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/AndroidManifestWriter.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.ide.eclipse.tests.functests.sampleProjects;
+
+import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
+import com.android.sdklib.SdkConstants;
+import com.android.sdklib.xml.AndroidManifest;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+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;
+
+/**
+ * Helper class for modifying an AndroidManifest.
+ * <p/>
+ * TODO: consider merging this with AndroidManifestParser.
+ */
+class AndroidManifestWriter {
+
+    private static final Logger sLogger = Logger.getLogger(AndroidManifestWriter.class.getName());
+
+    private final Document mDoc;
+    private final String mOsManifestFilePath;
+
+    private AndroidManifestWriter(Document doc, String osManifestFilePath) {
+        mDoc = doc;
+        mOsManifestFilePath = osManifestFilePath;
+    }
+
+    /**
+     * Sets the minimum SDK version for this manifest
+     * @param minSdkVersion - the minimim sdk version to use
+     * @returns <code>true</code> on success, false otherwise
+     */
+    public boolean setMinSdkVersion(String minSdkVersion) {
+        Element usesSdkElement = null;
+        NodeList nodeList = mDoc.getElementsByTagName(AndroidManifest.NODE_USES_SDK);
+        if (nodeList.getLength() > 0) {
+            usesSdkElement = (Element) nodeList.item(0);
+        } else {
+            usesSdkElement = mDoc.createElement(AndroidManifest.NODE_USES_SDK);
+            mDoc.getDocumentElement().appendChild(usesSdkElement);
+        }
+        Attr minSdkAttr = mDoc.createAttributeNS(SdkConstants.NS_RESOURCES,
+                AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
+        String prefix = mDoc.lookupPrefix(SdkConstants.NS_RESOURCES);
+        minSdkAttr.setPrefix(prefix);
+        minSdkAttr.setValue(minSdkVersion);
+        usesSdkElement.setAttributeNodeNS(minSdkAttr);
+        return saveXmlToFile();
+    }
+
+    private boolean saveXmlToFile() {
+        try {
+            // Prepare the DOM document for writing
+            Source source = new DOMSource(mDoc);
+
+            // Prepare the output file
+            File file = new File(mOsManifestFilePath);
+            Result result = new StreamResult(file);
+
+            // Write the DOM document to the file
+            Transformer xformer = TransformerFactory.newInstance().newTransformer();
+            xformer.transform(source, result);
+        } catch (TransformerConfigurationException e) {
+            sLogger.log(Level.SEVERE, "Failed to write xml file", e);
+            return false;
+        } catch (TransformerException e) {
+            sLogger.log(Level.SEVERE, "Failed to write xml file", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Parses the manifest file, and collects data.
+     *
+     * @param osManifestFilePath The OS path of the manifest file to parse.
+     * @return an {@link AndroidManifestParser} or null if parsing failed
+     */
+    public static AndroidManifestWriter parse(String osManifestFilePath) {
+        try {
+            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+            docFactory.setNamespaceAware(true);
+            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+            Document doc = docBuilder.parse(osManifestFilePath);
+            return new AndroidManifestWriter(doc, osManifestFilePath);
+        } catch (ParserConfigurationException e) {
+            sLogger.log(Level.SEVERE, "Error parsing file", e);
+            return null;
+        } catch (SAXException e) {
+            sLogger.log(Level.SEVERE, "Error parsing file", e);
+            return null;
+        } catch (IOException e) {
+            sLogger.log(Level.SEVERE, "Error parsing file", e);
+            return null;
+        }
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java
index 54fcb99..4b7d014 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * 
+ *
  * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
  * may not use this file except in compliance with the License. You may obtain a
  * copy of the License at
- * 
+ *
  *      http://www.eclipse.org/org/documents/epl-v10.php
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -15,9 +15,11 @@
  */
 package com.android.ide.eclipse.tests.functests.sampleProjects;
 
+import com.android.ide.eclipse.adt.AndroidConstants;
 import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
-import com.android.ide.eclipse.adt.wizards.newproject.StubSampleProjectWizard;
+import com.android.ide.eclipse.adt.wizards.newproject.StubProjectWizard;
 import com.android.ide.eclipse.tests.FuncTestCase;
+import com.android.sdklib.IAndroidTarget;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResourceChangeEvent;
@@ -26,74 +28,112 @@
 import org.eclipse.core.resources.IResourceDeltaVisitor;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.swt.widgets.Display;
 
+import java.io.File;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
- * Test case that verifies all SDK sample projects can be imported, built in
- * Eclipse
- * 
+ * Test case that verifies all SDK sample projects can be imported, and built in
+ * Eclipse.
+ * <p/>
  * TODO: add support for deploying apps onto emulator and verifying successful
  * execution there
- * 
+ *
  */
 public class SampleProjectTest extends FuncTestCase {
-    
+
     private static final Logger sLogger = Logger.getLogger(SampleProjectTest.class.getName());
 
     /**
-     * Tests the sample project with the given name
-     * 
-     * @param name - name of sample project to test
+     * Finds all samples projects in set SDK and verify they can be built in Eclipse.
+     * <p/>
+     * TODO: add install and run on emulator test
+     * @throws CoreException
      */
-    protected void doTestSampleProject(String name) {
-        try {
-
-            StubSampleProjectWizard newProjCreator = new StubSampleProjectWizard(
-                    name, getOsSdkLocation());
-            newProjCreator.init(null, null);
-            newProjCreator.performFinish();
-
-            IProject iproject = validateProjectExists(name);
-
-            validateNoProblems(iproject);
-
-        } 
-        catch (CoreException e) {
-            fail("Unexpected exception when creating sample project: " + e.toString());
+    public void testSamples() throws CoreException {
+        // TODO: For reporting purposes, it would be better if a separate test success or failure
+        // could be reported for each sample
+        IAndroidTarget[] targets = mSdk.getTargets();
+        for (IAndroidTarget target : targets) {
+            doTestSamplesForTarget(target);
         }
     }
 
-    public void testApiDemos() {
-        doTestSampleProject("ApiDemos");
+    private void doTestSamplesForTarget(IAndroidTarget target) throws CoreException {
+        String path = target.getPath(IAndroidTarget.SAMPLES);
+        File samples = new File(path);
+        if (samples.isDirectory()) {
+            File[] files = samples.listFiles();
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    doTestSampleProject(file.getName(), file.getAbsolutePath(), target);
+                }
+            }
+        }
     }
 
-    public void testHelloActivity() {
-        doTestSampleProject("HelloActivity");
+    /**
+     * Tests the sample project with the given name
+     *
+     * @param target - SDK target of project
+     * @param name - name of sample project to test
+     * @param path - absolute file system path
+     * @throws CoreException
+     */
+    private void doTestSampleProject(String name, String path, IAndroidTarget target)
+             throws CoreException {
+        IProject iproject = null;
+        try {
+            sLogger.log(Level.INFO, String.format("Testing sample %s for target %s", name,
+                    target.getName()));
+
+            prepareProject(path, target);
+
+            final StubProjectWizard newProjCreator = new StubProjectWizard(
+                    name, path, target);
+            newProjCreator.init(null, null);
+            // need to run finish on ui thread since it invokes a perspective switch
+            Display.getDefault().syncExec(new Runnable() {
+                public void run() {
+                    newProjCreator.performFinish();
+                }
+            });
+
+            iproject = validateProjectExists(name);
+            validateNoProblems(iproject);
+        }
+        catch (CoreException e) {
+            sLogger.log(Level.SEVERE,
+                    String.format("Unexpected exception when creating sample project %s " +
+                            "for target %s", name, target.getName()));
+            throw e;
+        } finally {
+            if (iproject != null) {
+                iproject.delete(false, true, new NullProgressMonitor());
+            }
+        }
     }
 
-    public void testLunarLander() {
-        doTestSampleProject("LunarLander");
-    }
-
-    public void testNotePad() {
-        doTestSampleProject("NotePad");
-    }
-
-    public void testSkeletonApp() {
-        doTestSampleProject("SkeletonApp");
-    }
-
-    public void testSnake() {
-        doTestSampleProject("Snake");
+    private void prepareProject(String path, IAndroidTarget target) {
+        if (target.getVersion().isPreview()) {
+            // need to explicitly set preview's version in manifest for project to compile
+            final String manifestPath = path + File.separatorChar +
+                    AndroidConstants.FN_ANDROID_MANIFEST;
+            AndroidManifestWriter manifestWriter =
+                AndroidManifestWriter.parse(manifestPath);
+            assertNotNull(String.format("could not read manifest %s", manifestPath),
+                    manifestWriter);
+            assertTrue(manifestWriter.setMinSdkVersion(target.getVersion().getApiString()));
+        }
     }
 
     private IProject validateProjectExists(String name) {
         IProject iproject = getIProject(name);
-        assertTrue(iproject.exists());
-        assertTrue(iproject.isOpen());
+        assertTrue(String.format("%s project not created", name), iproject.exists());
+        assertTrue(String.format("%s project not opened", name), iproject.isOpen());
         return iproject;
     }
 
@@ -105,17 +145,17 @@
 
     private void validateNoProblems(IProject iproject) throws CoreException {
         waitForBuild(iproject);
-        assertFalse(ProjectHelper.hasError(iproject, true));
+        assertFalse(String.format("%s project has compile errors", iproject.getName()),
+                ProjectHelper.hasError(iproject, true));
     }
 
-
     /**
      * Waits for build to complete.
-     * 
+     *
      * @param iproject
      */
     private void waitForBuild(final IProject iproject) {
-       
+
         final BuiltProjectDeltaVisitor deltaVisitor = new BuiltProjectDeltaVisitor(iproject);
         IResourceChangeListener newBuildListener = new IResourceChangeListener() {
 
@@ -127,9 +167,9 @@
                     fail();
                 }
             }
-            
+
         };
-        iproject.getWorkspace().addResourceChangeListener(newBuildListener, 
+        iproject.getWorkspace().addResourceChangeListener(newBuildListener,
           IResourceChangeEvent.POST_BUILD);
 
         // poll build listener to determine when build is done
@@ -143,32 +183,31 @@
                 Thread.sleep(50);
             }
             catch (InterruptedException e) {
-                
+                // ignore
             }
            if (Display.getCurrent() != null) {
                Display.getCurrent().readAndDispatch();
            }
         }
-        
-        sLogger.log(Level.SEVERE, "expected build event never happened?");
-        fail("expected build event never happened for " + iproject.getName());
 
+        sLogger.log(Level.SEVERE, "expected build event never happened?");
+        fail(String.format("Expected build event never happened for %s", iproject.getName()));
     }
-    
+
     /**
      * Scans a given IResourceDelta looking for a "build event" change for given IProject
-     * 
+     *
      */
     private class BuiltProjectDeltaVisitor implements IResourceDeltaVisitor {
 
         private IProject mIProject;
         private boolean  mIsBuilt;
-        
+
         public BuiltProjectDeltaVisitor(IProject iproject) {
             mIProject = iproject;
             mIsBuilt = false;
         }
-        
+
         public boolean visit(IResourceDelta delta) {
             if (mIProject.equals(delta.getResource())) {
                 setBuilt(true);
@@ -176,7 +215,7 @@
             }
             return true;
         }
-        
+
         private synchronized void setBuilt(boolean b) {
             mIsBuilt = b;
         }
@@ -184,6 +223,5 @@
         public synchronized boolean isProjectBuilt() {
             return mIsBuilt;
         }
-        
     }
 }