diff --git a/asterix-app/src/test/java/edu/uci/ics/asterix/test/metadata/MetadataTest.java b/asterix-app/src/test/java/edu/uci/ics/asterix/test/metadata/MetadataTest.java
index 6339c07..dfbd305 100644
--- a/asterix-app/src/test/java/edu/uci/ics/asterix/test/metadata/MetadataTest.java
+++ b/asterix-app/src/test/java/edu/uci/ics/asterix/test/metadata/MetadataTest.java
@@ -15,12 +15,16 @@
 package edu.uci.ics.asterix.test.metadata;
 
 import java.io.File;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
 
 import org.apache.commons.io.FileUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 import edu.uci.ics.asterix.api.common.AsterixHyracksIntegrationUtil;
 import edu.uci.ics.asterix.common.config.GlobalConfig;
@@ -30,13 +34,15 @@
 /**
  * Executes the Metadata tests.
  */
+@RunWith(Parameterized.class)
 public class MetadataTest {
 
+    private TestCaseContext tcCtx;
+
     private static final String PATH_ACTUAL = "mdtest/";
     private static final String PATH_BASE = "src/test/resources/metadata/";
     private static final String TEST_CONFIG_FILE_NAME = "asterix-build-configuration.xml";
     private static final String WEB_SERVER_PORT = "19002";
-    private static List<TestCaseContext> testCaseCollection;
 
     @BeforeClass
     public static void setUp() throws Exception {
@@ -51,8 +57,7 @@
         }
 
         AsterixHyracksIntegrationUtil.init();
-        TestCaseContext.Builder b = new TestCaseContext.Builder();
-        testCaseCollection = b.build(new File(PATH_BASE));
+
     }
 
     @AfterClass
@@ -75,11 +80,23 @@
         }
     }
 
-    @Test
-    public void test() throws Exception {
-        for (TestCaseContext testCaseCtx : testCaseCollection) {
-            TestsUtils.executeTest(PATH_ACTUAL, testCaseCtx);
+    @Parameters
+    public static Collection<Object[]> tests() throws Exception {
+        Collection<Object[]> testArgs = new ArrayList<Object[]>();
+        TestCaseContext.Builder b = new TestCaseContext.Builder();
+        for (TestCaseContext ctx : b.build(new File(PATH_BASE))) {
+            testArgs.add(new Object[] { ctx });
         }
+        return testArgs;
     }
 
-}
+    public MetadataTest(TestCaseContext tcCtx) {
+        this.tcCtx = tcCtx;
+    }
+
+    @Test
+    public void test() throws Exception {
+        TestsUtils.executeTest(PATH_ACTUAL, tcCtx);
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-app/src/test/java/edu/uci/ics/asterix/test/optimizer/OptimizerTest.java b/asterix-app/src/test/java/edu/uci/ics/asterix/test/optimizer/OptimizerTest.java
index bb66d0d..0f1f8b5 100644
--- a/asterix-app/src/test/java/edu/uci/ics/asterix/test/optimizer/OptimizerTest.java
+++ b/asterix-app/src/test/java/edu/uci/ics/asterix/test/optimizer/OptimizerTest.java
@@ -58,12 +58,12 @@
         System.setProperty(GlobalConfig.WEB_SERVER_PORT_PROPERTY, "19002");
         File outdir = new File(PATH_ACTUAL);
         outdir.mkdirs();
-        
+
         File log = new File("asterix_logs");
         if (log.exists()) {
-            FileUtils.deleteDirectory(log); 
+            FileUtils.deleteDirectory(log);
         }
-        
+
         AsterixHyracksIntegrationUtil.init();
         // Set the node resolver to be the identity resolver that expects node names 
         // to be node controller ids; a valid assumption in test environment. 
@@ -79,10 +79,10 @@
         if (files == null || files.length == 0) {
             outdir.delete();
         }
-        
+
         File log = new File("asterix_logs");
         if (log.exists()) {
-            FileUtils.deleteDirectory(log); 
+            FileUtils.deleteDirectory(log);
         }
     }
 
@@ -138,7 +138,7 @@
             }
             Assume.assumeTrue(!skipped);
 
-            LOGGER.severe("RUN TEST: \"" + queryFile.getPath() + "\"");
+            LOGGER.info("RUN TEST: \"" + queryFile.getPath() + "\"");
             Reader query = new BufferedReader(new InputStreamReader(new FileInputStream(queryFile), "UTF-8"));
             PrintWriter plan = new PrintWriter(actualFile);
             AsterixJavaClient asterix = new AsterixJavaClient(
@@ -180,7 +180,7 @@
                     throw new Exception("Result for " + queryFile + " changed at line " + num + ":\n< \n> "
                             + lineActual);
                 }
-                LOGGER.severe("Test \"" + queryFile.getPath() + "\" PASSED!");
+                LOGGER.info("Test \"" + queryFile.getPath() + "\" PASSED!");
                 actualFile.delete();
             } finally {
                 readerExpected.close();
diff --git a/asterix-app/src/test/java/edu/uci/ics/asterix/test/runtime/ExecutionTest.java b/asterix-app/src/test/java/edu/uci/ics/asterix/test/runtime/ExecutionTest.java
index 6478d0a..5ca397b 100644
--- a/asterix-app/src/test/java/edu/uci/ics/asterix/test/runtime/ExecutionTest.java
+++ b/asterix-app/src/test/java/edu/uci/ics/asterix/test/runtime/ExecutionTest.java
@@ -1,7 +1,8 @@
 package edu.uci.ics.asterix.test.runtime;
 
 import java.io.File;
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
 
 import org.apache.commons.io.FileUtils;
 import org.junit.AfterClass;
@@ -9,6 +10,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 import edu.uci.ics.asterix.api.common.AsterixHyracksIntegrationUtil;
 import edu.uci.ics.asterix.common.config.GlobalConfig;
@@ -20,71 +22,76 @@
 /**
  * Runs the runtime test cases under 'asterix-app/src/test/resources/runtimets'.
  */
-//@RunWith(Parameterized.class)
+@RunWith(Parameterized.class)
 public class ExecutionTest {
-	private static final String PATH_ACTUAL = "rttest/";
-	private static final String PATH_BASE = "src/test/resources/runtimets/";
+    private static final String PATH_ACTUAL = "rttest/";
+    private static final String PATH_BASE = "src/test/resources/runtimets/";
 
-	private static final String TEST_CONFIG_FILE_NAME = "asterix-build-configuration.xml";
-	private static final String[] ASTERIX_DATA_DIRS = new String[] { "nc1data",
-			"nc2data" };
+    private static final String TEST_CONFIG_FILE_NAME = "asterix-build-configuration.xml";
+    private static final String[] ASTERIX_DATA_DIRS = new String[] { "nc1data", "nc2data" };
 
-	private static List<TestCaseContext> testCaseCollection;
+    @BeforeClass
+    public static void setUp() throws Exception {
+        System.setProperty(GlobalConfig.CONFIG_FILE_PROPERTY, TEST_CONFIG_FILE_NAME);
+        System.setProperty(GlobalConfig.WEB_SERVER_PORT_PROPERTY, "19002");
+        File outdir = new File(PATH_ACTUAL);
+        outdir.mkdirs();
 
-	@BeforeClass
-	public static void setUp() throws Exception {
-		System.setProperty(GlobalConfig.CONFIG_FILE_PROPERTY,
-				TEST_CONFIG_FILE_NAME);
-		System.setProperty(GlobalConfig.WEB_SERVER_PORT_PROPERTY, "19002");
-		File outdir = new File(PATH_ACTUAL);
-		outdir.mkdirs();
+        File log = new File("asterix_logs");
+        if (log.exists()) {
+            FileUtils.deleteDirectory(log);
+        }
 
-		File log = new File("asterix_logs");
-		if (log.exists()) {
-			FileUtils.deleteDirectory(log);
-		}
+        AsterixHyracksIntegrationUtil.init();
 
-		AsterixHyracksIntegrationUtil.init();
+        // TODO: Uncomment when hadoop version is upgraded and adapters are
+        // ported. 
+        HDFSCluster.getInstance().setup();
 
-		// TODO: Uncomment when hadoop version is upgraded and adapters are
-		// ported.
-		HDFSCluster.getInstance().setup();
+        // Set the node resolver to be the identity resolver that expects node names 
+        // to be node controller ids; a valid assumption in test environment. 
+        System.setProperty(FileSystemBasedAdapter.NODE_RESOLVER_FACTORY_PROPERTY,
+                IdentitiyResolverFactory.class.getName());
+    }
 
-		// Set the node resolver to be the identity resolver that expects node
-		// names
-		// to be node controller ids; a valid assumption in test environment.
-		System.setProperty(
-				FileSystemBasedAdapter.NODE_RESOLVER_FACTORY_PROPERTY,
-				IdentitiyResolverFactory.class.getName());
-		TestCaseContext.Builder b = new TestCaseContext.Builder();
-		testCaseCollection = b.build(new File(PATH_BASE));
-	}
+    @AfterClass
+    public static void tearDown() throws Exception {
+        AsterixHyracksIntegrationUtil.deinit();
+        File outdir = new File(PATH_ACTUAL);
+        File[] files = outdir.listFiles();
+        if (files == null || files.length == 0) {
+            outdir.delete();
+        }
+        // clean up the files written by the ASTERIX storage manager
+        for (String d : ASTERIX_DATA_DIRS) {
+            TestsUtils.deleteRec(new File(d));
+        }
 
-	@AfterClass
-	public static void tearDown() throws Exception {
-		AsterixHyracksIntegrationUtil.deinit();
-		File outdir = new File(PATH_ACTUAL);
-		File[] files = outdir.listFiles();
-		if (files == null || files.length == 0) {
-			outdir.delete();
-		}
-		// clean up the files written by the ASTERIX storage manager
-		for (String d : ASTERIX_DATA_DIRS) {
-			TestsUtils.deleteRec(new File(d));
-		}
+        File log = new File("asterix_logs");
+        if (log.exists()) {
+            FileUtils.deleteDirectory(log);
+        }
+        HDFSCluster.getInstance().cleanup();
+    }
 
-		File log = new File("asterix_logs");
-		if (log.exists()) {
-			FileUtils.deleteDirectory(log);
-		}
-		HDFSCluster.getInstance().cleanup();
-	}
+    @Parameters
+    public static Collection<Object[]> tests() throws Exception {
+        Collection<Object[]> testArgs = new ArrayList<Object[]>();
+        TestCaseContext.Builder b = new TestCaseContext.Builder();
+        for (TestCaseContext ctx : b.build(new File(PATH_BASE))) {
+            testArgs.add(new Object[] { ctx });
+        }
+        return testArgs;
+    }
 
-	@Test
-	public void test() throws Exception {
-		for (TestCaseContext testCaseCtx : testCaseCollection) {
-			TestsUtils.executeTest(PATH_ACTUAL, testCaseCtx);
-		}
+    private TestCaseContext tcCtx;
 
-	}
-}
+    public ExecutionTest(TestCaseContext tcCtx) {
+        this.tcCtx = tcCtx;
+    }
+
+    @Test
+    public void test() throws Exception {
+        TestsUtils.executeTest(PATH_ACTUAL, tcCtx);
+    }
+}
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/logging.properties b/asterix-app/src/test/resources/logging.properties
index deb88307..6f8cd00 100644
--- a/asterix-app/src/test/resources/logging.properties
+++ b/asterix-app/src/test/resources/logging.properties
@@ -60,6 +60,7 @@
 # For example, set the com.xyz.foo logger to only log SEVERE
 # messages:
 
+edu.uci.ics.asterix.test.level = INFO
 #edu.uci.ics.asterix.level = FINE
 #edu.uci.ics.algebricks.level = FINE
 #edu.uci.ics.hyracks.level = INFO
diff --git a/asterix-common/src/main/java/edu/uci/ics/asterix/common/config/AsterixProperties.java b/asterix-common/src/main/java/edu/uci/ics/asterix/common/config/AsterixProperties.java
index 20a0d11..04e974d 100644
--- a/asterix-common/src/main/java/edu/uci/ics/asterix/common/config/AsterixProperties.java
+++ b/asterix-common/src/main/java/edu/uci/ics/asterix/common/config/AsterixProperties.java
@@ -247,6 +247,6 @@
             default:
                 level = Level.ALL;
         }
-        Logger.getLogger("edu.uci.ics").setLevel(level);
+        Logger.getLogger(".").setLevel(level);
     }
 }
diff --git a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
index 7e9b08f..8449971 100644
--- a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
+++ b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
@@ -31,398 +31,369 @@
 import edu.uci.ics.asterix.testframework.context.TestCaseContext;
 import edu.uci.ics.asterix.testframework.context.TestFileContext;
 import edu.uci.ics.asterix.testframework.xml.TestCase.CompilationUnit;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
 
 public class TestsUtils {
 
-	private static final String EXTENSION_AQL_RESULT = "adm";
-	private static final Logger LOGGER = Logger.getLogger(TestsUtils.class
-			.getName());
-	private static Method managixExecuteMethod = null;
+    private static final String EXTENSION_AQL_RESULT = "adm";
+    private static final Logger LOGGER = Logger.getLogger(TestsUtils.class.getName());
+    private static Method managixExecuteMethod = null;
 
-	/**
-	 * Probably does not work well with symlinks.
-	 */
-	public static boolean deleteRec(File path) {
-		if (path.isDirectory()) {
-			for (File f : path.listFiles()) {
-				if (!deleteRec(f)) {
-					return false;
-				}
-			}
-		}
-		return path.delete();
-	}
+    /**
+     * Probably does not work well with symlinks.
+     */
+    public static boolean deleteRec(File path) {
+        if (path.isDirectory()) {
+            for (File f : path.listFiles()) {
+                if (!deleteRec(f)) {
+                    return false;
+                }
+            }
+        }
+        return path.delete();
+    }
 
-	public static void runScriptAndCompareWithResult(File scriptFile,
-			PrintWriter print, File expectedFile, File actualFile)
-			throws Exception {
-		BufferedReader readerExpected = new BufferedReader(
-				new InputStreamReader(new FileInputStream(expectedFile),
-						"UTF-8"));
-		BufferedReader readerActual = new BufferedReader(new InputStreamReader(
-				new FileInputStream(actualFile), "UTF-8"));
-		String lineExpected, lineActual;
-		int num = 1;
-		try {
-			while ((lineExpected = readerExpected.readLine()) != null) {
-				lineActual = readerActual.readLine();
-				// Assert.assertEquals(lineExpected, lineActual);
-				if (lineActual == null) {
-					if (lineExpected.isEmpty()) {
-						continue;
-					}
-					throw new Exception("Result for " + scriptFile
-							+ " changed at line " + num + ":\n< "
-							+ lineExpected + "\n> ");
-				}
+    public static void runScriptAndCompareWithResult(File scriptFile, PrintWriter print, File expectedFile,
+            File actualFile) throws Exception {
+        BufferedReader readerExpected = new BufferedReader(new InputStreamReader(new FileInputStream(expectedFile),
+                "UTF-8"));
+        BufferedReader readerActual = new BufferedReader(
+                new InputStreamReader(new FileInputStream(actualFile), "UTF-8"));
+        String lineExpected, lineActual;
+        int num = 1;
+        try {
+            while ((lineExpected = readerExpected.readLine()) != null) {
+                lineActual = readerActual.readLine();
+                // Assert.assertEquals(lineExpected, lineActual);
+                if (lineActual == null) {
+                    if (lineExpected.isEmpty()) {
+                        continue;
+                    }
+                    throw new Exception("Result for " + scriptFile + " changed at line " + num + ":\n< " + lineExpected
+                            + "\n> ");
+                }
 
-				if (!equalStrings(lineExpected.split("Timestamp")[0],
-						lineActual.split("Timestamp")[0])) {
-					fail("Result for " + scriptFile + " changed at line " + num
-							+ ":\n< " + lineExpected + "\n> " + lineActual);
-				}
+                if (!equalStrings(lineExpected.split("Timestamp")[0], lineActual.split("Timestamp")[0])) {
+                    fail("Result for " + scriptFile + " changed at line " + num + ":\n< " + lineExpected + "\n> "
+                            + lineActual);
+                }
 
-				++num;
-			}
-			lineActual = readerActual.readLine();
-			// Assert.assertEquals(null, lineActual);
-			if (lineActual != null) {
-				throw new Exception("Result for " + scriptFile
-						+ " changed at line " + num + ":\n< \n> " + lineActual);
-			}
-			// actualFile.delete();
-		} finally {
-			readerExpected.close();
-			readerActual.close();
-		}
+                ++num;
+            }
+            lineActual = readerActual.readLine();
+            // Assert.assertEquals(null, lineActual);
+            if (lineActual != null) {
+                throw new Exception("Result for " + scriptFile + " changed at line " + num + ":\n< \n> " + lineActual);
+            }
+            // actualFile.delete();
+        } finally {
+            readerExpected.close();
+            readerActual.close();
+        }
 
-	}
+    }
 
-	private static boolean equalStrings(String s1, String s2) {
-		String[] rowsOne = s1.split("\n");
-		String[] rowsTwo = s2.split("\n");
+    private static boolean equalStrings(String s1, String s2) {
+        String[] rowsOne = s1.split("\n");
+        String[] rowsTwo = s2.split("\n");
 
-		for (int i = 0; i < rowsOne.length; i++) {
-			String row1 = rowsOne[i];
-			String row2 = rowsTwo[i];
+        for (int i = 0; i < rowsOne.length; i++) {
+            String row1 = rowsOne[i];
+            String row2 = rowsTwo[i];
 
-			if (row1.equals(row2))
-				continue;
+            if (row1.equals(row2))
+                continue;
 
-			String[] fields1 = row1.split(" ");
-			String[] fields2 = row2.split(" ");
+            String[] fields1 = row1.split(" ");
+            String[] fields2 = row2.split(" ");
 
-			for (int j = 0; j < fields1.length; j++) {
-				if (fields1[j].equals(fields2[j])) {
-					continue;
-				} else if (fields1[j].indexOf('.') < 0) {
-					return false;
-				} else {
-					fields1[j] = fields1[j].split(",")[0];
-					fields2[j] = fields2[j].split(",")[0];
-					Double double1 = Double.parseDouble(fields1[j]);
-					Double double2 = Double.parseDouble(fields2[j]);
-					float float1 = (float) double1.doubleValue();
-					float float2 = (float) double2.doubleValue();
+            for (int j = 0; j < fields1.length; j++) {
+                if (fields1[j].equals(fields2[j])) {
+                    continue;
+                } else if (fields1[j].indexOf('.') < 0) {
+                    return false;
+                } else {
+                    fields1[j] = fields1[j].split(",")[0];
+                    fields2[j] = fields2[j].split(",")[0];
+                    Double double1 = Double.parseDouble(fields1[j]);
+                    Double double2 = Double.parseDouble(fields2[j]);
+                    float float1 = (float) double1.doubleValue();
+                    float float2 = (float) double2.doubleValue();
 
-					if (Math.abs(float1 - float2) == 0)
-						continue;
-					else {
-						return false;
-					}
-				}
-			}
-		}
-		return true;
-	}
+                    if (Math.abs(float1 - float2) == 0)
+                        continue;
+                    else {
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
 
-	public static String aqlExtToResExt(String fname) {
-		int dot = fname.lastIndexOf('.');
-		return fname.substring(0, dot + 1) + EXTENSION_AQL_RESULT;
-	}
+    public static String aqlExtToResExt(String fname) {
+        int dot = fname.lastIndexOf('.');
+        return fname.substring(0, dot + 1) + EXTENSION_AQL_RESULT;
+    }
 
-	public static void writeResultsToFile(File actualFile, JSONObject result)
-			throws IOException, JSONException {
-		BufferedWriter writer = new BufferedWriter(new FileWriter(actualFile));
-		Results res = new Results(result);
-		for (String line : res) {
-			writer.write(line);
-			writer.newLine();
-		}
-		writer.close();
-	}
+    public static void writeResultsToFile(File actualFile, JSONObject result) throws IOException, JSONException {
+        BufferedWriter writer = new BufferedWriter(new FileWriter(actualFile));
+        Results res = new Results(result);
+        for (String line : res) {
+            writer.write(line);
+            writer.newLine();
+        }
+        writer.close();
+    }
 
-	public static class Results implements Iterable<String> {
-		private final JSONArray chunks;
+    public static class Results implements Iterable<String> {
+        private final JSONArray chunks;
 
-		public Results(JSONObject result) throws JSONException {
-			chunks = result.getJSONArray("results");
-		}
+        public Results(JSONObject result) throws JSONException {
+            chunks = result.getJSONArray("results");
+        }
 
-		public Iterator<String> iterator() {
-			return new ResultIterator(chunks);
-		}
-	}
+        public Iterator<String> iterator() {
+            return new ResultIterator(chunks);
+        }
+    }
 
-	public static class ResultIterator implements Iterator<String> {
-		private final JSONArray chunks;
+    public static class ResultIterator implements Iterator<String> {
+        private final JSONArray chunks;
 
-		private int chunkCounter = 0;
-		private int recordCounter = 0;
+        private int chunkCounter = 0;
+        private int recordCounter = 0;
 
-		public ResultIterator(JSONArray chunks) {
-			this.chunks = chunks;
-		}
+        public ResultIterator(JSONArray chunks) {
+            this.chunks = chunks;
+        }
 
-		@Override
-		public boolean hasNext() {
-			JSONArray resultArray;
-			try {
-				resultArray = chunks.getJSONArray(chunkCounter);
-				if (resultArray.getString(recordCounter) != null) {
-					return true;
-				}
-			} catch (JSONException e) {
-				return false;
-			}
-			return false;
-		}
+        @Override
+        public boolean hasNext() {
+            JSONArray resultArray;
+            try {
+                resultArray = chunks.getJSONArray(chunkCounter);
+                if (resultArray.getString(recordCounter) != null) {
+                    return true;
+                }
+            } catch (JSONException e) {
+                return false;
+            }
+            return false;
+        }
 
-		@Override
-		public String next() throws NoSuchElementException {
-			JSONArray resultArray;
-			String item = "";
+        @Override
+        public String next() throws NoSuchElementException {
+            JSONArray resultArray;
+            String item = "";
 
-			try {
-				resultArray = chunks.getJSONArray(chunkCounter);
-				item = resultArray.getString(recordCounter);
-				if (item == null) {
-					throw new NoSuchElementException();
-				}
-				item = item.trim();
+            try {
+                resultArray = chunks.getJSONArray(chunkCounter);
+                item = resultArray.getString(recordCounter);
+                if (item == null) {
+                    throw new NoSuchElementException();
+                }
+                item = item.trim();
 
-				recordCounter++;
-				if (recordCounter >= resultArray.length()) {
-					chunkCounter++;
-					recordCounter = 0;
-				}
-			} catch (JSONException e) {
-				throw new NoSuchElementException(e.getMessage());
-			}
-			return item;
-		}
+                recordCounter++;
+                if (recordCounter >= resultArray.length()) {
+                    chunkCounter++;
+                    recordCounter = 0;
+                }
+            } catch (JSONException e) {
+                throw new NoSuchElementException(e.getMessage());
+            }
+            return item;
+        }
 
-		@Override
-		public void remove() {
-			throw new NotImplementedException();
-		}
-	}
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
 
-	// Executes Query and returns results as JSONArray
-	public static JSONObject executeQuery(String str) throws Exception {
+    // Executes Query and returns results as JSONArray
+    public static JSONObject executeQuery(String str) throws Exception {
 
-		final String url = "http://localhost:19101/query";
+        final String url = "http://localhost:19101/query";
 
-		// Create an instance of HttpClient.
-		HttpClient client = new HttpClient();
+        // Create an instance of HttpClient.
+        HttpClient client = new HttpClient();
 
-		// Create a method instance.
-		GetMethod method = new GetMethod(url);
+        // Create a method instance.
+        GetMethod method = new GetMethod(url);
 
-		method.setQueryString(new NameValuePair[] { new NameValuePair("query",
-				str) });
+        method.setQueryString(new NameValuePair[] { new NameValuePair("query", str) });
 
-		// Provide custom retry handler is necessary
-		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
-				new DefaultHttpMethodRetryHandler(3, false));
+        // Provide custom retry handler is necessary
+        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
 
-		JSONObject result = null;
+        JSONObject result = null;
 
-		try {
-			// Execute the method.
-			int statusCode = client.executeMethod(method);
+        try {
+            // Execute the method.
+            int statusCode = client.executeMethod(method);
 
-			// Check if the method was executed successfully.
-			if (statusCode != HttpStatus.SC_OK) {
-				System.err.println("Method failed: " + method.getStatusLine());
-			}
+            // Check if the method was executed successfully.
+            if (statusCode != HttpStatus.SC_OK) {
+                System.err.println("Method failed: " + method.getStatusLine());
+            }
 
-			// Read the response body as String.
-			String responseBody = method.getResponseBodyAsString();
+            // Read the response body as String.
+            String responseBody = method.getResponseBodyAsString();
 
-			result = new JSONObject(responseBody);
-		} catch (Exception e) {
-			System.out.println(e.getMessage());
-			e.printStackTrace();
-		}
-		return result;
-	}
+            result = new JSONObject(responseBody);
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+        }
+        return result;
+    }
 
-	// To execute Update statements
-	// Insert and Delete statements are executed here
-	public static void executeUpdate(String str) throws Exception {
-		final String url = "http://localhost:19101/update";
+    // To execute Update statements
+    // Insert and Delete statements are executed here
+    public static void executeUpdate(String str) throws Exception {
+        final String url = "http://localhost:19101/update";
 
-		// Create an instance of HttpClient.
-		HttpClient client = new HttpClient();
+        // Create an instance of HttpClient.
+        HttpClient client = new HttpClient();
 
-		// Create a method instance.
-		GetMethod method = new GetMethod(url);
+        // Create a method instance.
+        GetMethod method = new GetMethod(url);
 
-		method.setQueryString(new NameValuePair[] { new NameValuePair(
-				"statements", str) });
+        method.setQueryString(new NameValuePair[] { new NameValuePair("statements", str) });
 
-		// Provide custom retry handler is necessary
-		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
-				new DefaultHttpMethodRetryHandler(3, false));
+        // Provide custom retry handler is necessary
+        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
 
-		// Execute the method.
-		int statusCode = client.executeMethod(method);
+        // Execute the method.
+        int statusCode = client.executeMethod(method);
 
-		// Check if the method was executed successfully.
-		if (statusCode != HttpStatus.SC_OK) {
-			System.err.println("Method failed: " + method.getStatusLine());
-		}
-	}
+        // Check if the method was executed successfully.
+        if (statusCode != HttpStatus.SC_OK) {
+            System.err.println("Method failed: " + method.getStatusLine());
+        }
+    }
 
-	// To execute DDL and Update statements
-	// create type statement
-	// create dataset statement
-	// create index statement
-	// create dataverse statement
-	// create function statement
-	public static void executeDDL(String str) throws Exception {
-		final String url = "http://localhost:19101/ddl";
+    // To execute DDL and Update statements
+    // create type statement
+    // create dataset statement
+    // create index statement
+    // create dataverse statement
+    // create function statement
+    public static void executeDDL(String str) throws Exception {
+        final String url = "http://localhost:19101/ddl";
 
-		// Create an instance of HttpClient.
-		HttpClient client = new HttpClient();
+        // Create an instance of HttpClient.
+        HttpClient client = new HttpClient();
 
-		// Create a method instance.
-		GetMethod method = new GetMethod(url);
+        // Create a method instance.
+        GetMethod method = new GetMethod(url);
 
-		method.setQueryString(new NameValuePair[] { new NameValuePair("ddl",
-				str) });
+        method.setQueryString(new NameValuePair[] { new NameValuePair("ddl", str) });
 
-		// Provide custom retry handler is necessary
-		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
-				new DefaultHttpMethodRetryHandler(3, false));
+        // Provide custom retry handler is necessary
+        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
 
-		// Execute the method.
-		int statusCode = client.executeMethod(method);
+        // Execute the method.
+        int statusCode = client.executeMethod(method);
 
-		// Check if the method was executed successfully.
-		if (statusCode != HttpStatus.SC_OK) {
-			System.err.println("Method failed: " + method.getStatusLine());
-		}
-	}
+        // Check if the method was executed successfully.
+        if (statusCode != HttpStatus.SC_OK) {
+            System.err.println("Method failed: " + method.getStatusLine());
+        }
+    }
 
-	// Method that reads a DDL/Update/Query File
-	// and returns the contents as a string
-	// This string is later passed to REST API for execution.
-	public static String readTestFile(File testFile) throws Exception {
-		BufferedReader reader = new BufferedReader(new FileReader(testFile));
-		String line = null;
-		StringBuilder stringBuilder = new StringBuilder();
-		String ls = System.getProperty("line.separator");
+    // Method that reads a DDL/Update/Query File
+    // and returns the contents as a string
+    // This string is later passed to REST API for execution.
+    public static String readTestFile(File testFile) throws Exception {
+        BufferedReader reader = new BufferedReader(new FileReader(testFile));
+        String line = null;
+        StringBuilder stringBuilder = new StringBuilder();
+        String ls = System.getProperty("line.separator");
 
-		while ((line = reader.readLine()) != null) {
-			stringBuilder.append(line);
-			stringBuilder.append(ls);
-		}
+        while ((line = reader.readLine()) != null) {
+            stringBuilder.append(line);
+            stringBuilder.append(ls);
+        }
 
-		return stringBuilder.toString();
-	}
+        return stringBuilder.toString();
+    }
 
-	public static void executeManagixCommand(String command)
-			throws ClassNotFoundException, NoSuchMethodException,
-			SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-		if (managixExecuteMethod == null) {
-			Class clazz = Class
-					.forName("edu.uci.ics.asterix.installer.test.AsterixInstallerIntegrationUtil");
-			managixExecuteMethod = clazz.getMethod("executeCommand",
-					String.class);
-		}
-		managixExecuteMethod.invoke(null, command);
-	}
+    public static void executeManagixCommand(String command) throws ClassNotFoundException, NoSuchMethodException,
+            SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+        if (managixExecuteMethod == null) {
+            Class clazz = Class.forName("edu.uci.ics.asterix.installer.test.AsterixInstallerIntegrationUtil");
+            managixExecuteMethod = clazz.getMethod("executeCommand", String.class);
+        }
+        managixExecuteMethod.invoke(null, command);
+    }
 
-	public static void executeTest(String actualPath,
-			TestCaseContext testCaseCtx) throws Exception {
+    public static void executeTest(String actualPath, TestCaseContext testCaseCtx) throws Exception {
 
-		File testFile;
-		File expectedResultFile;
-		String statement;
-		List<TestFileContext> expectedResultFileCtxs;
-		List<TestFileContext> testFileCtxs;
+        File testFile;
+        File expectedResultFile;
+        String statement;
+        List<TestFileContext> expectedResultFileCtxs;
+        List<TestFileContext> testFileCtxs;
 
-		int queryCount = 0;
-		JSONObject result;
+        int queryCount = 0;
+        JSONObject result;
 
-		List<CompilationUnit> cUnits = testCaseCtx.getTestCase()
-				.getCompilationUnit();
-		for (CompilationUnit cUnit : cUnits) {
-			LOGGER.info("[TEST]: " + testCaseCtx.getTestCase().getFilePath()
-					+ "/" + cUnit.getName());
+        List<CompilationUnit> cUnits = testCaseCtx.getTestCase().getCompilationUnit();
+        for (CompilationUnit cUnit : cUnits) {
+            LOGGER.info("[TEST]: " + testCaseCtx.getTestCase().getFilePath() + "/" + cUnit.getName());
 
-			testFileCtxs = testCaseCtx.getTestFiles(cUnit);
-			expectedResultFileCtxs = testCaseCtx.getExpectedResultFiles(cUnit);
+            testFileCtxs = testCaseCtx.getTestFiles(cUnit);
+            expectedResultFileCtxs = testCaseCtx.getExpectedResultFiles(cUnit);
 
-			for (TestFileContext ctx : testFileCtxs) {
-				testFile = ctx.getFile();
-				statement = TestsUtils.readTestFile(testFile);
-				try {
-					switch (ctx.getType()) {
-					case "ddl":
-						TestsUtils.executeDDL(statement);
-						break;
-					case "update":
-						TestsUtils.executeUpdate(statement);
-						break;
-					case "query":
-						result = TestsUtils.executeQuery(statement);
-						if (!cUnit.getExpectedError().isEmpty()) {
-							if (!result.has("error")) {
-								throw new Exception("Test \"" + testFile
-										+ "\" FAILED!");
-							}
-						} else {
-							expectedResultFile = expectedResultFileCtxs.get(
-									queryCount).getFile();
+            for (TestFileContext ctx : testFileCtxs) {
+                testFile = ctx.getFile();
+                statement = TestsUtils.readTestFile(testFile);
+                try {
+                    switch (ctx.getType()) {
+                        case "ddl":
+                            TestsUtils.executeDDL(statement);
+                            break;
+                        case "update":
+                            TestsUtils.executeUpdate(statement);
+                            break;
+                        case "query":
+                            result = TestsUtils.executeQuery(statement);
+                            if (!cUnit.getExpectedError().isEmpty()) {
+                                if (!result.has("error")) {
+                                    throw new Exception("Test \"" + testFile + "\" FAILED!");
+                                }
+                            } else {
+                                expectedResultFile = expectedResultFileCtxs.get(queryCount).getFile();
 
-							File actualFile = new File(actualPath
-									+ File.separator
-									+ testCaseCtx.getTestCase().getFilePath()
-											.replace(File.separator, "_") + "_"
-									+ cUnit.getName() + ".adm");
+                                File actualFile = new File(actualPath + File.separator
+                                        + testCaseCtx.getTestCase().getFilePath().replace(File.separator, "_") + "_"
+                                        + cUnit.getName() + ".adm");
 
-							File actualResultFile = testCaseCtx
-									.getActualResultFile(cUnit, new File(
-											actualPath));
-							actualResultFile.getParentFile().mkdirs();
+                                File actualResultFile = testCaseCtx.getActualResultFile(cUnit, new File(actualPath));
+                                actualResultFile.getParentFile().mkdirs();
 
-							TestsUtils.writeResultsToFile(actualFile, result);
+                                TestsUtils.writeResultsToFile(actualFile, result);
 
-							TestsUtils.runScriptAndCompareWithResult(testFile,
-									new PrintWriter(System.err),
-									expectedResultFile, actualFile);
-						}
-						queryCount++;
-						break;
-					case "mgx":
-						executeManagixCommand(statement);
-						break;
-					default:
-						throw new IllegalArgumentException(
-								"No statements of type " + ctx.getType());
-					}
-				} catch (Exception e) {
-					if (cUnit.getExpectedError().isEmpty()) {
-						throw new Exception(
-								"Test \"" + testFile + "\" FAILED!", e);
-					}
-				}
-			}
-		}
+                                TestsUtils.runScriptAndCompareWithResult(testFile, new PrintWriter(System.err),
+                                        expectedResultFile, actualFile);
+                            }
+                            queryCount++;
+                            break;
+                        case "mgx":
+                            executeManagixCommand(statement);
+                            break;
+                        default:
+                            throw new IllegalArgumentException("No statements of type " + ctx.getType());
+                    }
+                } catch (Exception e) {
+                    if (cUnit.getExpectedError().isEmpty()) {
+                        throw new Exception("Test \"" + testFile + "\" FAILED!", e);
+                    }
+                }
+            }
+        }
 
-	}
+    }
 }
