Merged asterix_lsm_stabilization upto r1547

git-svn-id: https://asterixdb.googlecode.com/svn/trunk/asterix@1622 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-installer/src/main/assembly/binary-assembly.xml b/asterix-installer/src/main/assembly/binary-assembly.xml
new file mode 100644
index 0000000..6a0c130
--- /dev/null
+++ b/asterix-installer/src/main/assembly/binary-assembly.xml
@@ -0,0 +1,108 @@
+<assembly>
+  <id>binary-assembly</id>
+  <formats>
+    <format>zip</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <fileSets>
+    <fileSet>
+      <directory>src/main/resources/conf</directory>
+      <outputDirectory>conf</outputDirectory>
+    </fileSet>
+    <fileSet>
+      <directory>src/main/resources/clusters</directory>
+      <outputDirectory>clusters</outputDirectory>
+    </fileSet>
+    <fileSet>
+      <directory>src/main/resources/zookeeper</directory>
+      <fileMode>0755</fileMode>
+      <outputDirectory>.installer/zookeeper/bin</outputDirectory>
+    </fileSet>
+    <fileSet>
+      <directory>src/main/resources/scripts</directory>
+      <fileMode>0755</fileMode>
+      <includes>
+        <include>managix</include>
+      </includes>
+      <outputDirectory>bin</outputDirectory>
+    </fileSet>
+    <fileSet>
+      <directory>src/main/resources/scripts</directory>
+      <fileMode>0755</fileMode>
+      <excludes>
+        <exclude>managix</exclude>
+      </excludes>
+      <outputDirectory>.installer/scripts</outputDirectory>
+    </fileSet>
+    <fileSet>
+      <directory>src/main/resources/hadoop-0.20.2</directory>
+      <outputDirectory>.installer/hadoop-0.20.2</outputDirectory>
+      <fileMode>0755</fileMode>
+    </fileSet>
+    <fileSet>
+      <directory>target</directory>
+      <outputDirectory>lib</outputDirectory>
+      <includes>
+        <include>*.jar</include>
+      </includes>
+    </fileSet>
+    <fileSet>
+      <directory>../asterix-events/src/main/resources/events</directory>
+      <outputDirectory>.installer/eventrix/events</outputDirectory>
+      <fileMode>0755</fileMode>
+    </fileSet>
+    <fileSet>
+      <directory>../asterix-events/src/main/resources/scripts</directory>
+      <outputDirectory>.installer/eventrix/scripts</outputDirectory>
+    </fileSet>
+  </fileSets>
+  <dependencySets>
+    <dependencySet>
+      <includes>
+         <include>log4j:log4j</include>
+         <include>edu.uci.ics.asterix:asterix-events</include>
+         <include>org.apache.zookeeper:zookeeper</include>
+         <include>args4j:args4j</include>
+         <include>log4j:log4j</include>
+         <include>commons-io:commons-io</include>
+         <include>org.slf4j:slf4j-api</include>
+         <include>org.slf4j:slf4j-log4j12</include>
+       </includes>
+       <unpack>false</unpack>
+       <outputDirectory>lib</outputDirectory>
+    </dependencySet>
+    <dependencySet>
+      <includes>
+        <include>org.apache.hadoop:hadoop-core</include>
+        <include>commons-cli:commons-cli</include>
+        <include>commons-logging:commons-logging</include>
+      </includes>
+      <unpack>false</unpack>
+      <outputDirectory>.installer/hadoop-0.20.2/lib</outputDirectory>
+    </dependencySet>
+    <dependencySet>
+      <includes>
+        <include>org.apache.zookeeper:zookeeper</include>
+        <include>log4j:log4j</include>
+        <include>org.slf4j:slf4j-api</include>
+      </includes>
+      <unpack>false</unpack>
+      <outputDirectory>.installer/zookeeper/lib</outputDirectory>
+    </dependencySet>
+    <dependencySet>
+      <outputDirectory>asterix</outputDirectory>
+      <includes>
+        <include>asterix-server*</include>
+      </includes>
+      <useTransitiveDependencies>false</useTransitiveDependencies>
+    </dependencySet>
+    <dependencySet>
+      <outputDirectory>.installer/eventrix</outputDirectory>
+      <includes>
+        <include>asterix-events*</include>
+      </includes>
+      <unpack>false</unpack>
+      <useTransitiveDependencies>false</useTransitiveDependencies>
+    </dependencySet>
+  </dependencySets>
+</assembly>
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AbstractCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AbstractCommand.java
new file mode 100644
index 0000000..66a0697
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AbstractCommand.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import org.apache.log4j.Logger;
+import org.kohsuke.args4j.CmdLineParser;
+
+public abstract class AbstractCommand implements ICommand {
+
+    protected static final Logger LOGGER = Logger.getLogger(AbstractCommand.class.getName());
+
+    protected CommandConfig config;
+
+    protected String usageDescription;
+
+    public void execute(String[] args) throws Exception {
+        String[] cmdArgs = new String[args.length - 1];
+        System.arraycopy(args, 1, cmdArgs, 0, cmdArgs.length);
+        config = getCommandConfig();
+        CmdLineParser parser = new CmdLineParser(config);
+        parser.parseArgument(cmdArgs);
+        execCommand();
+    }
+
+    abstract protected void execCommand() throws Exception;
+
+    abstract protected String getUsageDescription();
+
+    abstract protected CommandConfig getCommandConfig();
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AlterCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AlterCommand.java
new file mode 100644
index 0000000..5ef7449
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AlterCommand.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import java.util.Date;
+import java.util.Properties;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ILookupService;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class AlterCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        InstallerDriver.initConfig();
+        String instanceName = ((AlterConfig) config).name;
+        InstallerUtil.validateAsterixInstanceExists(instanceName, State.INACTIVE);
+        ILookupService lookupService = ServiceProvider.INSTANCE.getLookupService();
+        AsterixInstance instance = lookupService.getAsterixInstance(instanceName);
+
+        Properties asterixConfProp = InstallerUtil.getAsterixConfiguration(((AlterConfig) config).confPath);
+        instance.setConfiguration(asterixConfProp);
+        instance.setModifiedTimestamp(new Date());
+        lookupService.updateAsterixInstance(instance);
+        LOGGER.info("Configuration for Asterix instance: " + instanceName + " has been altered");
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new AlterConfig();
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nAlter the instance's configuration settings."
+                + "\nPrior to running this command, the instance is required to be INACTIVE state."
+                + "\n\nAvailable arguments/options" + "\n-n name of the ASTERIX instance"
+                + "\n-conf path to the ASTERIX configuration file.";
+    }
+
+}
+
+class AlterConfig extends CommandConfig {
+
+    @Option(name = "-n", required = true, usage = "Name of Asterix Instance")
+    public String name;
+
+    @Option(name = "-conf", required = true, usage = "Path to instance configuration")
+    public String confPath;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/BackupCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/BackupCommand.java
new file mode 100644
index 0000000..297a168
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/BackupCommand.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import java.util.Date;
+import java.util.List;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.model.BackupInfo;
+import edu.uci.ics.asterix.installer.schema.conf.Backup;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class BackupCommand extends AbstractCommand {
+
+    public static final String ASTERIX_ROOT_METADATA_DIR = "asterix_root_metadata";
+
+    @Override
+    protected void execCommand() throws Exception {
+        InstallerDriver.initConfig();
+        String asterixInstanceName = ((BackupConfig) config).name;
+        AsterixInstance instance = InstallerUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+        List<BackupInfo> backupInfo = instance.getBackupInfo();
+        PatternCreator pc = new PatternCreator();
+        Backup backupConf = InstallerDriver.getConfiguration().getBackup();
+        Patterns patterns = pc.getBackUpAsterixPattern(instance, backupConf);
+        InstallerUtil.getEventrixClient(instance.getCluster()).submit(patterns);
+        int backupId = backupInfo.size();
+        BackupInfo binfo = new BackupInfo(backupId, new Date(), backupConf);
+        backupInfo.add(binfo);
+        LOGGER.info(asterixInstanceName + " backed up " + binfo);
+        ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new BackupConfig();
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nIn an undesirable event of data loss either due to a disk/system"
+                + "\nfailure or accidental execution of a DDL statement (drop dataverse/dataset),"
+                + "\nyou may need to recover the lost data. The backup command allows you to take a"
+                + "\nbackup of the data stored with an ASTERIX instance. "
+                + "\nThe backed up snapshot is stored in HDFS." + "\n\nAvailable arguments/options:"
+                + "\n-n name of the Asterix instance";
+
+    }
+
+}
+
+class BackupConfig extends CommandConfig {
+
+    @Option(name = "-n", required = true, usage = "Name of the Asterix instance")
+    public String name;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandConfig.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandConfig.java
new file mode 100644
index 0000000..55b0c3b
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandConfig.java
@@ -0,0 +1,5 @@
+package edu.uci.ics.asterix.installer.command;
+
+public abstract class CommandConfig {
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java
new file mode 100644
index 0000000..7fc3884
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import edu.uci.ics.asterix.installer.command.ICommand.CommandType;
+
+public class CommandHandler {
+
+    public void processCommand(String args[]) throws Exception {
+        CommandType cmdType = CommandType.valueOf(args[0].toUpperCase());
+        ICommand cmd = null;
+        switch (cmdType) {
+            case CREATE:
+                cmd = new CreateCommand();
+                break;
+            case ALTER:
+                cmd = new AlterCommand();
+                break;
+            case DELETE:
+                cmd = new DeleteCommand();
+                break;
+            case DESCRIBE:
+                cmd = new DescribeCommand();
+                break;
+            case BACKUP:
+                cmd = new BackupCommand();
+                break;
+            case RESTORE:
+                cmd = new RestoreCommand();
+                break;
+            case START:
+                cmd = new StartCommand();
+                break;
+            case STOP:
+                cmd = new StopCommand();
+                break;
+            case VALIDATE:
+                cmd = new ValidateCommand();
+                break;
+            case CONFIGURE:
+                cmd = new ConfigureCommand();
+                break;
+            case SHUTDOWN:
+                cmd = new ShutdownCommand();
+                break;
+            case HELP:
+                cmd = new HelpCommand();
+                break;
+        }
+        cmd.execute(args);
+    }
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ConfigureCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ConfigureCommand.java
new file mode 100644
index 0000000..d22e6ce
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ConfigureCommand.java
@@ -0,0 +1,71 @@
+package edu.uci.ics.asterix.installer.command;
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.WorkingDir;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.schema.conf.Configuration;
+
+public class ConfigureCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        String localClusterPath = InstallerDriver.getManagixHome() + File.separator + "clusters" + File.separator
+                + "local" + File.separator + "local.xml";
+
+        JAXBContext ctx = JAXBContext.newInstance(Cluster.class);
+        Unmarshaller unmarshaller = ctx.createUnmarshaller();
+        Cluster cluster = (Cluster) unmarshaller.unmarshal(new File(localClusterPath));
+
+        String workingDir = InstallerDriver.getManagixHome() + File.separator + "clusters" + File.separator + "local"
+                + File.separator + "working_dir";
+        cluster.setWorkingDir(new WorkingDir(workingDir, true));
+        cluster.setIodevices(workingDir);
+        cluster.setStore("storage");
+        cluster.setLogdir(workingDir + File.separator + "logs");
+        cluster.setJavaHome(System.getenv("JAVA_HOME"));
+        cluster.setJavaOpts("-Xmx1024m");
+
+        Marshaller marshaller = ctx.createMarshaller();
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+        marshaller.marshal(cluster, new FileOutputStream(localClusterPath));
+
+        String installerConfPath = InstallerDriver.getManagixHome() + File.separator + InstallerDriver.MANAGIX_CONF_XML;
+        ctx = JAXBContext.newInstance(Configuration.class);
+        unmarshaller = ctx.createUnmarshaller();
+        Configuration configuration = (Configuration) unmarshaller.unmarshal(new File(installerConfPath));
+
+        configuration.getBackup().setBackupDir(workingDir + File.separator + "backup");
+        configuration.getZookeeper().setHomeDir(
+                InstallerDriver.getManagixHome() + File.separator + InstallerDriver.MANAGIX_INTERNAL_DIR
+                        + File.separator + "zookeeper_home");
+        configuration.getZookeeper().getServers().setJavaHome(System.getenv("JAVA_HOME"));
+
+        marshaller = ctx.createMarshaller();
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+        marshaller.marshal(configuration, new FileOutputStream(installerConfPath));
+
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nAuto-generates the ASTERIX installer configruation settings and ASTERIX cluster "
+                + "\nconfiguration settings for a single node setup.";
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new ConfigureConfig();
+    }
+
+}
+
+class ConfigureConfig extends CommandConfig {
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java
new file mode 100644
index 0000000..fd0af04
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Env;
+import edu.uci.ics.asterix.event.schema.cluster.Property;
+import edu.uci.ics.asterix.event.schema.cluster.WorkingDir;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.error.VerificationUtil;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class CreateCommand extends AbstractCommand {
+
+	private String asterixInstanceName;
+	private Cluster cluster;
+
+	@Override
+	protected void execCommand() throws Exception {
+		InstallerDriver.initConfig();
+		ValidateCommand validateCommand = new ValidateCommand();
+		boolean valid = validateCommand
+				.validateCluster(((CreateConfig) config).clusterPath);
+		if (!valid) {
+			throw new Exception("Cannot create an Asterix instance.");
+		}
+		asterixInstanceName = ((CreateConfig) config).name;
+		InstallerUtil.validateAsterixInstanceNotExists(asterixInstanceName);
+		CreateConfig createConfig = (CreateConfig) config;
+		JAXBContext ctx = JAXBContext.newInstance(Cluster.class);
+		Unmarshaller unmarshaller = ctx.createUnmarshaller();
+		cluster = (Cluster) unmarshaller.unmarshal(new File(
+				createConfig.clusterPath));
+		AsterixInstance asterixInstance = InstallerUtil.createAsterixInstance(
+				asterixInstanceName, cluster);
+		InstallerUtil.evaluateConflictWithOtherInstances(asterixInstance);
+		InstallerUtil.createAsterixZip(asterixInstance, true);
+		List<Property> clusterProperties = new ArrayList<Property>();
+		clusterProperties.add(new Property("ASTERIX_HOME", cluster
+				.getWorkingDir().getDir() + File.separator + "asterix"));
+		StringBuilder javaOpts = new StringBuilder();
+		if (cluster.getJavaOpts() != null) {
+			javaOpts.append(cluster.getJavaOpts());
+		}
+		clusterProperties.add(new Property("JAVA_OPTS", javaOpts.toString()));
+		clusterProperties.add(new Property("CLUSTER_NET_IP", cluster
+				.getMasterNode().getClusterIp()));
+		clusterProperties.add(new Property("CLIENT_NET_IP", cluster
+				.getMasterNode().getClientIp()));
+		clusterProperties.add(new Property("LOG_DIR", cluster.getLogdir()));
+		clusterProperties.add(new Property("JAVA_HOME", cluster.getJavaHome()));
+		clusterProperties.add(new Property("WORKING_DIR", cluster
+				.getWorkingDir().getDir()));
+		cluster.setEnv(new Env(clusterProperties));
+
+		PatternCreator pc = new PatternCreator();
+		Patterns patterns = pc.getStartAsterixPattern(asterixInstanceName,
+				cluster);
+		InstallerUtil.getEventrixClient(cluster).submit(patterns);
+
+		AsterixRuntimeState runtimeState = VerificationUtil
+				.getAsterixRuntimeState(asterixInstance);
+		VerificationUtil.updateInstanceWithRuntimeDescription(asterixInstance,
+				runtimeState, true);
+		ServiceProvider.INSTANCE.getLookupService().writeAsterixInstance(
+				asterixInstance);
+		InstallerUtil.deleteDirectory(InstallerDriver.getManagixHome()
+				+ File.separator + InstallerDriver.ASTERIX_DIR + File.separator
+				+ asterixInstanceName);
+		LOGGER.info(asterixInstance.getDescription(false));
+	}
+
+	@Override
+	protected CommandConfig getCommandConfig() {
+		return new CreateConfig();
+	}
+
+	public Cluster getCluster() {
+		return cluster;
+	}
+
+	public String getAsterixInstanceName() {
+		return asterixInstanceName;
+	}
+
+	@Override
+	protected String getUsageDescription() {
+		return "\nCreates an ASTERIX instance with a specified name."
+				+ "\n\nPost creation, the instance is in ACTIVE state, indicating its "
+				+ "\navailability for executing statements/queries."
+				+ "\n\nUsage arguments/options:"
+				+ "\n-n Name of the ASTERIX instance."
+				+ "\n-c Path to the cluster configuration file";
+	}
+
+}
+
+class CreateConfig extends CommandConfig {
+
+	@Option(name = "-n", required = true, usage = "Name of Asterix Instance")
+	public String name;
+
+	@Option(name = "-c", required = true, usage = "Path to cluster configuration")
+	public String clusterPath;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DeleteCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DeleteCommand.java
new file mode 100644
index 0000000..2279d8f
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DeleteCommand.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class DeleteCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        InstallerDriver.initConfig();
+        String asterixInstanceName = ((DeleteConfig) config).name;
+        AsterixInstance instance = InstallerUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+        PatternCreator pc = new PatternCreator();
+        Patterns patterns = pc.createDeleteInstancePattern(instance);
+        InstallerUtil.getEventrixClient(instance.getCluster()).submit(patterns);
+
+        patterns = pc.createRemoveAsterixWorkingDirPattern(instance);
+        InstallerUtil.getEventrixClient(instance.getCluster()).submit(patterns);
+        ServiceProvider.INSTANCE.getLookupService().removeAsterixInstance(asterixInstanceName);
+        LOGGER.info("Deleted Asterix instance: " + asterixInstanceName);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new DeleteConfig();
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nPermanently deletes an ASTERIX instance." + "\n" + "The instance must be in the INACTIVE state."
+                + "\n\nAvailable arguments/options" + "\n-n name of the ASTERIX instance.";
+    }
+
+}
+
+class DeleteConfig extends CommandConfig {
+
+    @Option(name = "-n", required = true, usage = "Name of Asterix Instance")
+    public String name;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DescribeCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DescribeCommand.java
new file mode 100644
index 0000000..9306a56
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DescribeCommand.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import java.util.List;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.error.InstallerException;
+import edu.uci.ics.asterix.installer.error.VerificationUtil;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class DescribeCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        InstallerDriver.initConfig();
+        String asterixInstanceName = ((DescribeConfig) config).name;
+        boolean adminView = ((DescribeConfig) config).admin;
+        if (asterixInstanceName != null) {
+            InstallerUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE, State.ACTIVE,
+                    State.UNUSABLE);
+            AsterixInstance instance = ServiceProvider.INSTANCE.getLookupService().getAsterixInstance(
+                    asterixInstanceName);
+            if (instance != null) {
+                AsterixRuntimeState state = VerificationUtil.getAsterixRuntimeState(instance);
+                boolean expectedRunning = instance.getState().equals(State.UNUSABLE) ? instance.getPreviousState()
+                        .equals(State.ACTIVE) : !instance.getState().equals(State.INACTIVE);
+                VerificationUtil.updateInstanceWithRuntimeDescription(instance, state, expectedRunning);
+                ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+                LOGGER.info(instance.getDescription(adminView));
+            } else {
+                throw new InstallerException("Asterix instance by the name " + asterixInstanceName + " does not exist.");
+            }
+        } else {
+            List<AsterixInstance> asterixInstances = ServiceProvider.INSTANCE.getLookupService().getAsterixInstances();
+            if (asterixInstances.size() > 0) {
+                for (AsterixInstance instance : asterixInstances) {
+                    AsterixRuntimeState state = VerificationUtil.getAsterixRuntimeState(instance);
+                    boolean expectedRunning = instance.getState().equals(State.UNUSABLE) ? instance.getPreviousState()
+                            .equals(State.ACTIVE) : !instance.getState().equals(State.INACTIVE);
+                    VerificationUtil.updateInstanceWithRuntimeDescription(instance, state, expectedRunning);
+                    ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+                    LOGGER.info(instance.getDescription(adminView));
+                }
+            } else {
+                LOGGER.info("No Asterix instances found!");
+            }
+
+        }
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new DescribeConfig();
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nProvides information about an ASTERIX instance." + "\n\nUsage arguments/options:-"
+                + "\n[-n]       Name of the ASTERIX instance." + "\n[-admin]   Provides a detailed description";
+    }
+
+}
+
+class DescribeConfig extends CommandConfig {
+
+    @Option(name = "-n", required = false, usage = "Name of Asterix Instance")
+    public String name;
+
+    @Option(name = "-admin", required = false, usage = "Detailed description")
+    public boolean admin;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/HelpCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/HelpCommand.java
new file mode 100644
index 0000000..a9864a3
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/HelpCommand.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import org.kohsuke.args4j.Option;
+
+public class HelpCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        HelpConfig helpConfig = (HelpConfig) config;
+        String command = helpConfig.command;
+        CommandType cmdType = CommandType.valueOf(command.toUpperCase());
+        String helpMessage = null;
+        switch (cmdType) {
+            case CREATE:
+                helpMessage = new CreateCommand().getUsageDescription();
+                break;
+            case CONFIGURE:
+                helpMessage = new ConfigureCommand().getUsageDescription();
+                break;
+            case DELETE:
+                helpMessage = new DeleteCommand().getUsageDescription();
+                break;
+            case DESCRIBE:
+                helpMessage = new DescribeCommand().getUsageDescription();
+                break;
+            case RESTORE:
+                helpMessage = new RestoreCommand().getUsageDescription();
+                break;
+            case START:
+                helpMessage = new StartCommand().getUsageDescription();
+                break;
+            case SHUTDOWN:
+                helpMessage = new ShutdownCommand().getUsageDescription();
+                break;
+            case BACKUP:
+                helpMessage = new BackupCommand().getUsageDescription();
+                break;
+            case STOP:
+                helpMessage = new StopCommand().getUsageDescription();
+                break;
+            case VALIDATE:
+                helpMessage = new ValidateCommand().getUsageDescription();
+                break;
+            default:
+                helpMessage = "Unknown command " + command;
+        }
+
+        System.out.println(helpMessage);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new HelpConfig();
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nAlter the instance's configuration settings."
+                + "\nPrior to running this command, the instance is required to be INACTIVE state."
+                + "\n\nAvailable arguments/options" + "\n-n name of the ASTERIX instance"
+                + "\n-conf path to the ASTERIX configuration file.";
+    }
+
+}
+
+class HelpConfig extends CommandConfig {
+
+    @Option(name = "-cmd", required = true, usage = "Name of Asterix Instance")
+    public String command;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java
new file mode 100644
index 0000000..979c414
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+public interface ICommand {
+
+    public enum CommandType {
+        CREATE,
+        DELETE,
+        START,
+        STOP,
+        BACKUP,
+        RESTORE,
+        DESCRIBE,
+        ALTER,
+        VALIDATE,
+        CONFIGURE,
+        SHUTDOWN,
+        HELP
+    }
+
+    public void execute(String args[]) throws Exception;
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/RestoreCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/RestoreCommand.java
new file mode 100644
index 0000000..9ef925a
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/RestoreCommand.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import java.util.List;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.model.BackupInfo;
+
+public class RestoreCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        InstallerDriver.initConfig();
+        String asterixInstanceName = ((RestoreConfig) config).name;
+        AsterixInstance instance = InstallerUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+        int backupId = ((RestoreConfig) config).backupId;
+        List<BackupInfo> backupInfoList = instance.getBackupInfo();
+        if (backupInfoList.size() <= backupId || backupId < 0) {
+            throw new IllegalStateException("Invalid backup id");
+        }
+
+        BackupInfo backupInfo = backupInfoList.get(backupId);
+        PatternCreator pc = new PatternCreator();
+        Patterns patterns = pc.getRestoreAsterixPattern(instance, backupInfo);
+        InstallerUtil.getEventrixClient(instance.getCluster()).submit(patterns);
+        LOGGER.info("Asterix instance: " + asterixInstanceName + " has been restored from backup");
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new RestoreConfig();
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nRestores an ASTERIX instance's data from a previously taken backup snapshot."
+                + "\n\nAvailable arguments/options" + "\n-n name of the ASTERIX instance"
+                + "\n-b id of the backup snapshot ";
+    }
+
+}
+
+class RestoreConfig extends CommandConfig {
+
+    @Option(name = "-n", required = true, usage = "Name of the Asterix instance")
+    public String name;
+
+    @Option(name = "-b", required = true, usage = "Id corresponding to the backed up version")
+    public int backupId;
+
+}
\ No newline at end of file
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ShutdownCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ShutdownCommand.java
new file mode 100644
index 0000000..b9dd23d
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ShutdownCommand.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.service.ILookupService;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class ShutdownCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        InstallerDriver.initConfig();
+        ILookupService lookupService = ServiceProvider.INSTANCE.getLookupService();
+        lookupService.stopService(InstallerDriver.getConfiguration());
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new ShutdownConfig();
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nShuts down the installer's backgrouund processes";
+    }
+
+}
+
+class ShutdownConfig extends CommandConfig {
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java
new file mode 100644
index 0000000..38bcf33
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import java.io.File;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.error.VerificationUtil;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class StartCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        InstallerDriver.initConfig();
+        String asterixInstanceName = ((StartConfig) config).name;
+        AsterixInstance instance = InstallerUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+        InstallerUtil.createAsterixZip(instance, false);
+        PatternCreator pc = new PatternCreator();
+        Patterns patterns = pc.getStartAsterixPattern(asterixInstanceName, instance.getCluster());
+        InstallerUtil.getEventrixClient(instance.getCluster()).submit(patterns);
+        InstallerUtil.deleteDirectory(InstallerDriver.getManagixHome() + File.separator + InstallerDriver.ASTERIX_DIR
+                + File.separator + asterixInstanceName);
+        AsterixRuntimeState runtimeState = VerificationUtil.getAsterixRuntimeState(instance);
+        VerificationUtil.updateInstanceWithRuntimeDescription(instance, runtimeState, true);
+        LOGGER.info(instance.getDescription(false));
+        ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new StartConfig();
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nStarts an ASTERIX instance that is in INACTIVE state."
+                + "\nAfter executing the start command, the ASTERIX instance transits to the ACTIVE state,"
+                + "\nindicating that it is now available for executing statements/queries."
+                + "\n\nAvailable arguments/options" + "\n-n name of the ASTERIX instance. ";
+    }
+}
+
+class StartConfig extends CommandConfig {
+
+    @Option(name = "-n", required = true, usage = "Name of Asterix Instance")
+    public String name;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StopCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StopCommand.java
new file mode 100644
index 0000000..dfd8c5e
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StopCommand.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.management.EventrixClient;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.event.schema.pattern.Pattern;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class StopCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        InstallerDriver.initConfig();
+        String asterixInstanceName = ((StopConfig) config).name;
+        AsterixInstance asterixInstance = InstallerUtil.validateAsterixInstanceExists(asterixInstanceName,
+                State.ACTIVE, State.UNUSABLE);
+        PatternCreator pc = new PatternCreator();
+        EventrixClient client = InstallerUtil.getEventrixClient(asterixInstance.getCluster());
+
+        List<Pattern> ncKillPatterns = new ArrayList<Pattern>();
+        for (Node node : asterixInstance.getCluster().getNode()) {
+            ncKillPatterns.add(pc.createNCStopPattern(node.getId(), asterixInstanceName + "_" + node.getId()));
+        }
+
+        List<Pattern> ccKillPatterns = new ArrayList<Pattern>();
+        ccKillPatterns.add(pc.createCCStopPattern(asterixInstance.getCluster().getMasterNode().getId()));
+
+        try {
+            client.submit(new Patterns(ncKillPatterns));
+            client.submit(new Patterns(ccKillPatterns));
+        } catch (Exception e) {
+            // processes are already dead
+            LOGGER.debug("Attempt to kill non-existing processess");
+        }
+
+        asterixInstance.setState(State.INACTIVE);
+        asterixInstance.setStateChangeTimestamp(new Date());
+        ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(asterixInstance);
+        LOGGER.info("Stopped Asterix instance: " + asterixInstanceName);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new StopConfig();
+    }
+
+    public String getAsterixInstanceName() {
+        return ((StopConfig) config).name;
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nShuts an ASTERIX instance that is in ACTIVE/UNUSABLE state."
+                + "\nAfter executing the stop command, the ASTERIX instance transits"
+                + "\nto the INACTIVE state, indicating that it is no longer available"
+                + "\nfor executing statements/queries." + "\n\nAvailable arguments/options"
+                + "\n-n name of the ASTERIX instance.";
+
+    }
+
+}
+
+class StopConfig extends CommandConfig {
+
+    @Option(name = "-n", required = true, usage = "Name of Asterix Instance")
+    public String name;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ValidateCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ValidateCommand.java
new file mode 100644
index 0000000..3d292a9
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ValidateCommand.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.command;
+
+import java.io.File;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.MasterNode;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.schema.conf.Configuration;
+import edu.uci.ics.asterix.installer.schema.conf.Zookeeper;
+
+public class ValidateCommand extends AbstractCommand {
+
+	private static final String OK = " [" + "OK" + "]";
+	private static final String ERROR = " [" + "ERROR" + "]";
+	private static final String WARNING = " [" + "WARNING" + "]";
+
+	@Override
+	protected void execCommand() throws Exception {
+		ValidateConfig vConfig = (ValidateConfig) config;
+		logValidationResult("Environment", validateEnvironment());
+		if (((ValidateConfig) config).cluster != null) {
+			logValidationResult("Cluster configuration",
+					validateCluster(vConfig.cluster));
+		} else {
+			logValidationResult("Installer Configuration",
+					validateConfiguration());
+		}
+	}
+
+	private void logValidationResult(String prefix, boolean isValid) {
+		if (!isValid) {
+			LOGGER.fatal(prefix + ERROR);
+		} else {
+			LOGGER.info(prefix + OK);
+		}
+	}
+
+	@Override
+	protected CommandConfig getCommandConfig() {
+		return new ValidateConfig();
+	}
+
+	@Override
+	protected String getUsageDescription() {
+		return "\nValidate the installer's configuration or a cluster configuration"
+				+ "\nUsage"
+				+ "\nFor validating the installer configuration"
+				+ "\nuse managix validate"
+				+ "\n\nFor validating a cluster configuration"
+				+ "\nuse managix validate -c <path to the cluster configuration file>";
+	}
+
+	public boolean validateEnvironment() throws Exception {
+		boolean valid = true;
+		String managixHome = System.getenv(InstallerDriver.ENV_MANAGIX_HOME);
+		if (managixHome == null) {
+			valid = false;
+			LOGGER.fatal(InstallerDriver.ENV_MANAGIX_HOME + " not set " + ERROR);
+		} else {
+			File home = new File(managixHome);
+			if (!home.exists()) {
+				valid = false;
+				LOGGER.fatal(InstallerDriver.ENV_MANAGIX_HOME + ": "
+						+ home.getAbsolutePath() + " does not exist!" + ERROR);
+			}
+		}
+		return valid;
+
+	}
+
+	public boolean validateCluster(String clusterPath) throws Exception {
+		boolean valid = true;
+		Cluster cluster = null;
+		File f = new File(clusterPath);
+		if (!f.exists() || !f.isFile()) {
+			LOGGER.error(" Invalid path " + f.getAbsolutePath() + ERROR);
+			valid = false;
+		} else {
+			JAXBContext ctx = JAXBContext.newInstance(Cluster.class);
+			Unmarshaller unmarshaller = ctx.createUnmarshaller();
+			cluster = (Cluster) unmarshaller.unmarshal(new File(clusterPath));
+			validateClusterProperties(cluster);
+
+			Set<String> servers = new HashSet<String>();
+			Set<String> serverIds = new HashSet<String>();
+			servers.add(cluster.getMasterNode().getClusterIp());
+			serverIds.add(cluster.getMasterNode().getId());
+
+			MasterNode masterNode = cluster.getMasterNode();
+			Node master = new Node(masterNode.getId(),
+					masterNode.getClusterIp(), masterNode.getJavaOpts(),
+					masterNode.getJavaHome(), masterNode.getLogdir(), null,
+					null, null);
+
+			valid = valid & validateNodeConfiguration(master, cluster);
+
+			for (Node node : cluster.getNode()) {
+				servers.add(node.getClusterIp());
+				if (serverIds.contains(node.getId())) {
+					valid = false;
+					LOGGER.error("Duplicate node id :" + node.getId() + ERROR);
+				} else {
+					valid = valid & validateNodeConfiguration(node, cluster);
+				}
+			}
+		}
+
+		return valid;
+	}
+
+	private void validateClusterProperties(Cluster cluster) {
+		List<String> tempDirs = new ArrayList<String>();
+		if (cluster.getLogdir() != null
+				&& checkTemporaryPath(cluster.getLogdir())) {
+			tempDirs.add("Log directory: " + cluster.getLogdir());
+		}
+		if (cluster.getIodevices() != null
+				&& checkTemporaryPath(cluster.getIodevices())) {
+			tempDirs.add("IO Device: " + cluster.getIodevices());
+		}
+
+		if (tempDirs.size() > 0) {
+			StringBuffer msg = new StringBuffer();
+			msg.append("The following paths are subject to be cleaned up by OS");
+			for (String tempDir : tempDirs) {
+				msg.append("\n" + tempDir + WARNING);
+			}
+			LOGGER.warn(msg);
+		}
+
+	}
+
+	private boolean validateNodeConfiguration(Node node, Cluster cluster) {
+		boolean valid = true;
+		valid = checkNodeReachability(node.getClusterIp());
+		if (node.getJavaHome() == null || node.getJavaHome().length() == 0) {
+			if (cluster.getJavaHome() == null
+					|| cluster.getJavaHome().length() == 0) {
+				valid = false;
+				LOGGER.fatal("java_home not defined at cluster/node level for node: "
+						+ node.getId() + ERROR);
+			}
+		}
+
+		if (node.getLogdir() == null || node.getLogdir().length() == 0) {
+			if (cluster.getLogdir() == null
+					|| cluster.getLogdir().length() == 0) {
+				valid = false;
+				LOGGER.fatal("log_dir not defined at cluster/node level for node: "
+						+ node.getId() + ERROR);
+			}
+		}
+
+		if (node.getStore() == null || node.getStore().length() == 0) {
+			if (!cluster.getMasterNode().getId().equals(node.getId())
+					&& (cluster.getStore() == null || cluster.getStore()
+							.length() == 0)) {
+				valid = false;
+				LOGGER.fatal("store not defined at cluster/node level for node: "
+						+ node.getId() + ERROR);
+			}
+		}
+
+		if (node.getIodevices() == null || node.getIodevices().length() == 0) {
+			if (!cluster.getMasterNode().getId().equals(node.getId())
+					&& (cluster.getIodevices() == null || cluster
+							.getIodevices().length() == 0)) {
+				valid = false;
+				LOGGER.fatal("iodevice(s) not defined at cluster/node level for node: "
+						+ node.getId() + ERROR);
+			}
+		}
+
+		return valid;
+	}
+
+	private boolean checkTemporaryPath(String logdir) {
+		return logdir.startsWith("/tmp/");
+
+	}
+
+	public boolean validateConfiguration() throws Exception {
+		String managixHome = System.getenv(InstallerDriver.ENV_MANAGIX_HOME);
+		File configFile = new File(managixHome + File.separator
+				+ InstallerDriver.MANAGIX_CONF_XML);
+		JAXBContext configCtx = JAXBContext.newInstance(Configuration.class);
+		Unmarshaller unmarshaller = configCtx.createUnmarshaller();
+		Configuration conf = (Configuration) unmarshaller.unmarshal(configFile);
+		return validateZookeeperConfiguration(conf);
+	}
+
+	private boolean validateZookeeperConfiguration(Configuration conf)
+			throws Exception {
+		boolean valid = true;
+		Zookeeper zk = conf.getZookeeper();
+
+		if (zk.getHomeDir() == null || zk.getHomeDir().length() == 0) {
+			valid = false;
+			LOGGER.fatal("Zookeeper home dir not configured" + ERROR);
+		} else if (checkTemporaryPath(zk.getHomeDir())) {
+			LOGGER.warn("Zookeeper home dir is subject to be cleaned up by OS"
+					+ WARNING);
+		}
+
+		if (zk.getServers().getServer().isEmpty()) {
+			valid = false;
+			LOGGER.fatal("Zookeeper servers not configured" + ERROR);
+		}
+
+		boolean validEnsemble = true;
+		for (String server : zk.getServers().getServer()) {
+			validEnsemble = validEnsemble && checkNodeReachability(server);
+		}
+
+		return valid;
+	}
+
+	private boolean checkNodeReachability(String server) {
+		boolean reachable = true;
+		try {
+			InetAddress address = InetAddress.getByName(server);
+			if (!address.isReachable(1000)) {
+				LOGGER.fatal("\n" + "Server: " + server + " unreachable"
+						+ ERROR);
+				reachable = false;
+			}
+		} catch (Exception e) {
+			reachable = false;
+			LOGGER.fatal("\n" + "Server: " + server + " Invalid address"
+					+ ERROR);
+		}
+		return reachable;
+	}
+
+}
+
+class ValidateConfig extends CommandConfig {
+
+	@Option(name = "-c", required = false, usage = "Path to the cluster configuration xml")
+	public String cluster;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerDriver.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerDriver.java
new file mode 100644
index 0000000..8083427
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerDriver.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.driver;
+
+import java.io.File;
+import java.io.FileFilter;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+import edu.uci.ics.asterix.installer.command.CommandHandler;
+import edu.uci.ics.asterix.installer.schema.conf.Configuration;
+import edu.uci.ics.asterix.installer.service.ILookupService;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class InstallerDriver {
+
+	public static final String MANAGIX_INTERNAL_DIR = ".installer";
+	public static final String MANAGIX_EVENT_DIR = MANAGIX_INTERNAL_DIR
+			+ File.separator + "eventrix";
+	public static final String MANAGIX_EVENT_SCRIPTS_DIR = MANAGIX_INTERNAL_DIR
+			+ File.separator + "eventrix" + File.separator + "scripts";
+	public static final String ASTERIX_DIR = "asterix";
+	public static final String EVENTS_DIR = "events";
+
+	private static final Logger LOGGER = Logger.getLogger(InstallerDriver.class
+			.getName());
+	public static final String ENV_MANAGIX_HOME = "MANAGIX_HOME";
+	public static final String MANAGIX_CONF_XML = "conf" + File.separator
+			+ "managix-conf.xml";
+
+	private static Configuration conf;
+	private static String managixHome;
+	private static String asterixZip;
+
+	public static String getAsterixZip() {
+		return asterixZip;
+	}
+
+	public static Configuration getConfiguration() {
+		return conf;
+	}
+
+	public static void initConfig() throws Exception {
+		File configFile = new File(managixHome + File.separator
+				+ MANAGIX_CONF_XML);
+		JAXBContext configCtx = JAXBContext.newInstance(Configuration.class);
+		Unmarshaller unmarshaller = configCtx.createUnmarshaller();
+		conf = (Configuration) unmarshaller.unmarshal(configFile);
+		asterixZip = initBinary("asterix-server");
+
+		ILookupService lookupService = ServiceProvider.INSTANCE
+				.getLookupService();
+		if (!lookupService.isRunning(conf)) {
+			lookupService.startService(conf);
+		}
+	}
+
+	private static String initBinary(final String fileNamePattern) {
+		String asterixDir = InstallerDriver.getAsterixDir();
+		File file = new File(asterixDir);
+		File[] zipFiles = file.listFiles(new FileFilter() {
+			public boolean accept(File arg0) {
+				return arg0.getAbsolutePath().contains(fileNamePattern)
+						&& arg0.isFile();
+			}
+		});
+		if (zipFiles.length == 0) {
+			String msg = " Binary not found at " + asterixDir;
+			LOGGER.log(Level.FATAL, msg);
+			throw new IllegalStateException(msg);
+		}
+		if (zipFiles.length > 1) {
+			String msg = " Multiple binaries found at " + asterixDir;
+			LOGGER.log(Level.FATAL, msg);
+			throw new IllegalStateException(msg);
+		}
+
+		return zipFiles[0].getAbsolutePath();
+	}
+
+	public static String getManagixHome() {
+		return managixHome;
+	}
+
+	public static String getAsterixDir() {
+		return managixHome + File.separator + ASTERIX_DIR;
+	}
+
+	public static void main(String args[]) {
+		try {
+			if (args.length != 0) {
+				managixHome = System.getenv(ENV_MANAGIX_HOME);
+				CommandHandler cmdHandler = new CommandHandler();
+				cmdHandler.processCommand(args);
+			} else {
+				printUsage();
+			}
+		} catch (IllegalArgumentException iae) {
+			LOGGER.error("Unknown command");
+			printUsage();
+		} catch (Exception e) {
+			LOGGER.error(e.getMessage());
+			if (e.getMessage() == null || e.getMessage().length() == 0) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private static void printUsage() {
+		StringBuffer buffer = new StringBuffer("managix <command> <options>"
+				+ "\n");
+		buffer.append("Commands" + "\n");
+		buffer.append("create   " + ":" + " Creates a new asterix instance"
+				+ "\n");
+		buffer.append("delete   " + ":" + " Deletes an asterix instance" + "\n");
+		buffer.append("start    " + ":" + " Starts an  asterix instance" + "\n");
+		buffer.append("stop     " + ":"
+				+ " Stops an asterix instance that is in ACTIVE state" + "\n");
+		buffer.append("backup   " + ":"
+				+ " Creates a back up for an existing asterix instance" + "\n");
+		buffer.append("restore  " + ":" + " Restores an asterix instance"
+				+ "\n");
+		buffer.append("describe " + ":"
+				+ " Describes an existing asterix instance" + "\n");
+		buffer.append("validate " + ":"
+				+ " Validates the installer/cluster configuration" + "\n");
+		buffer.append("configure"
+				+ ":"
+				+ " Auto-generate configuration for local psedu-distributed Asterix instance"
+				+ "\n");
+		buffer.append("shutdown " + ":" + " Shutdown the installer service"
+				+ "\n");
+		buffer.append("validate " + ":"
+				+ " Validates the installer/cluster configuration" + "\n");
+		buffer.append("configure"
+				+ ":"
+				+ " Auto-generate configuration for local psedu-distributed Asterix instance"
+				+ "\n");
+		buffer.append("shutdown " + ":" + " Shutdown the installer service"
+				+ "\n");
+		buffer.append("help     " + ":"
+				+ " Provides usage description of a command" + "\n");
+
+		LOGGER.info(buffer.toString());
+	}
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerUtil.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerUtil.java
new file mode 100644
index 0000000..e2be142
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerUtil.java
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.driver;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Random;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.commons.io.IOUtils;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.management.EventrixClient;
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.installer.error.InstallerException;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class InstallerUtil {
+
+    public static final String TXN_LOG_DIR = "txnLogs";
+    public static final String TXN_LOG_DIR_KEY_SUFFIX = "txnLogDir";
+
+    public static AsterixInstance createAsterixInstance(String asterixInstanceName, Cluster cluster)
+            throws FileNotFoundException, IOException {
+        Properties asterixConfProp = new Properties();
+        asterixConfProp.put("output_dir", cluster.getWorkingDir().getDir() + File.separator + "asterix_output");
+        Node metadataNode = getMetadataNode(cluster);
+        String asterixZipName = InstallerDriver.getAsterixZip().substring(
+                InstallerDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+        String asterixVersion = asterixZipName.substring("asterix-server-".length(),
+                asterixZipName.indexOf("-binary-assembly"));
+        AsterixInstance instance = new AsterixInstance(asterixInstanceName, cluster, asterixConfProp,
+                metadataNode.getId(), asterixVersion);
+        return instance;
+    }
+
+    public static void createAsterixZip(AsterixInstance asterixInstance, boolean newDeployment) throws IOException,
+            InterruptedException {
+
+        String modifiedZipPath = injectAsterixPropertyFile(InstallerDriver.getAsterixZip(), asterixInstance,
+                newDeployment);
+        injectAsterixLogPropertyFile(modifiedZipPath, asterixInstance);
+    }
+
+    private static String injectAsterixPropertyFile(String origZipFile, AsterixInstance asterixInstance,
+            boolean newDeployment) throws IOException {
+        writeAsterixConfigurationFile(asterixInstance, newDeployment);
+        String asterixInstanceDir = InstallerDriver.getAsterixDir() + File.separator + asterixInstance.getName();
+        unzip(origZipFile, asterixInstanceDir);
+        File sourceJar = new File(asterixInstanceDir + File.separator + "lib" + File.separator + "asterix-app-"
+                + asterixInstance.getAsterixVersion() + ".jar");
+        String asterixPropertyFile = "test.properties";
+        File replacementFile = new File(asterixInstanceDir + File.separator + "test.properties");
+        replaceInJar(sourceJar, asterixPropertyFile, replacementFile);
+        new File(asterixInstanceDir + File.separator + "test.properties").delete();
+        String asterixZipName = InstallerDriver.getAsterixZip().substring(
+                InstallerDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+        zipDir(new File(asterixInstanceDir), new File(asterixInstanceDir + File.separator + asterixZipName));
+        return asterixInstanceDir + File.separator + asterixZipName;
+    }
+
+    private static String injectAsterixLogPropertyFile(String origZipFile, AsterixInstance asterixInstance)
+            throws IOException {
+        String asterixInstanceDir = InstallerDriver.getAsterixDir() + File.separator + asterixInstance.getName();
+        unzip(origZipFile, asterixInstanceDir);
+        File sourceJar1 = new File(asterixInstanceDir + File.separator + "lib" + File.separator + "asterix-app-"
+                + asterixInstance.getAsterixVersion() + ".jar");
+        String txnLogPropertyFile = "log.properties";
+        Properties txnLogProperties = new Properties();
+        URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { sourceJar1.toURI().toURL() });
+        InputStream in = urlClassLoader.getResourceAsStream(txnLogPropertyFile);
+        if (in != null) {
+            txnLogProperties.load(in);
+        }
+
+        writeAsterixLogConfigurationFile(asterixInstance.getName(), asterixInstance.getCluster(), txnLogProperties);
+
+        File sourceJar2 = new File(asterixInstanceDir + File.separator + "lib" + File.separator + "asterix-app-"
+                + asterixInstance.getAsterixVersion() + ".jar");
+        File replacementFile = new File(asterixInstanceDir + File.separator + "log.properties");
+        replaceInJar(sourceJar2, txnLogPropertyFile, replacementFile);
+
+        new File(asterixInstanceDir + File.separator + "log.properties").delete();
+        String asterixZipName = InstallerDriver.getAsterixZip().substring(
+                InstallerDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+        zipDir(new File(asterixInstanceDir), new File(asterixInstanceDir + File.separator + asterixZipName));
+        return asterixInstanceDir + File.separator + asterixZipName;
+    }
+
+    public static void addLibraryToAsterixZip(AsterixInstance asterixInstance, String dataverseName,
+            String libraryName, String libraryPath) throws IOException {
+        File instanceDir = new File(InstallerDriver.getAsterixDir() + File.separator + asterixInstance.getName());
+        if (!instanceDir.exists()) {
+            instanceDir.mkdirs();
+        }
+        String asterixZipName = InstallerDriver.getAsterixZip().substring(
+                InstallerDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+
+        String sourceZip = instanceDir.getAbsolutePath() + File.separator + asterixZipName;
+        unzip(sourceZip, instanceDir.getAbsolutePath());
+        File libraryPathInZip = new File(instanceDir.getAbsolutePath() + File.separator + "external" + File.separator
+                + "library" + dataverseName + File.separator + "to-add" + File.separator + libraryName);
+        libraryPathInZip.mkdirs();
+        Runtime.getRuntime().exec("cp" + " " + libraryPath + " " + libraryPathInZip.getAbsolutePath());
+        Runtime.getRuntime().exec("rm " + sourceZip);
+        String destZip = InstallerDriver.getAsterixDir() + File.separator + asterixInstance.getName() + File.separator
+                + asterixZipName;
+        zipDir(instanceDir, new File(destZip));
+        Runtime.getRuntime().exec("mv" + " " + destZip + " " + sourceZip);
+    }
+
+    private static Node getMetadataNode(Cluster cluster) {
+        Random random = new Random();
+        int nNodes = cluster.getNode().size();
+        return cluster.getNode().get(random.nextInt(nNodes));
+    }
+
+    public static String getNodeDirectories(String asterixInstanceName, Node node, Cluster cluster) {
+        String storeDataSubDir = asterixInstanceName + File.separator + "data" + File.separator;
+        String[] storeDirs = null;
+        StringBuffer nodeDataStore = new StringBuffer();
+        String storeDirValue = node.getStore();
+        if (storeDirValue == null) {
+            storeDirValue = cluster.getStore();
+            if (storeDirValue == null) {
+                throw new IllegalStateException(" Store not defined for node " + node.getId());
+            }
+            storeDataSubDir = node.getId() + File.separator + storeDataSubDir;
+        }
+
+        storeDirs = storeDirValue.split(",");
+        for (String ns : storeDirs) {
+            nodeDataStore.append(ns + File.separator + storeDataSubDir.trim());
+            nodeDataStore.append(",");
+        }
+        nodeDataStore.deleteCharAt(nodeDataStore.length() - 1);
+        return nodeDataStore.toString();
+    }
+
+    private static void writeAsterixConfigurationFile(AsterixInstance asterixInstance, boolean newData)
+            throws IOException {
+        String asterixInstanceName = asterixInstance.getName();
+        Cluster cluster = asterixInstance.getCluster();
+        String metadataNodeId = asterixInstance.getMetadataNodeId();
+
+        StringBuffer conf = new StringBuffer();
+        conf.append("MetadataNode=" + asterixInstanceName + "_" + metadataNodeId + "\n");
+        conf.append("NewUniverse=" + newData + "\n");
+
+        String storeDir = null;
+        for (Node node : cluster.getNode()) {
+            storeDir = node.getStore() == null ? cluster.getStore() : node.getStore();
+            conf.append(asterixInstanceName + "_" + node.getId() + ".stores" + "=" + storeDir + "\n");
+        }
+
+        Properties asterixConfProp = asterixInstance.getConfiguration();
+        String outputDir = asterixConfProp.getProperty("output_dir");
+        conf.append("OutputDir=" + outputDir);
+
+        File asterixConfDir = new File(InstallerDriver.getAsterixDir() + File.separator + asterixInstanceName);
+        asterixConfDir.mkdirs();
+        dumpToFile(InstallerDriver.getAsterixDir() + File.separator + asterixInstanceName + File.separator
+                + "test.properties", conf.toString());
+    }
+
+    private static void writeAsterixLogConfigurationFile(String asterixInstanceName, Cluster cluster,
+            Properties logProperties) throws IOException {
+        StringBuffer conf = new StringBuffer();
+        for (Map.Entry<Object, Object> p : logProperties.entrySet()) {
+            conf.append(p.getKey() + "=" + p.getValue() + "\n");
+        }
+
+        for (Node node : cluster.getNode()) {
+            String iodevices = node.getIodevices() == null ? cluster.getIodevices() : node.getIodevices();
+            String txnLogDir = iodevices.split(",")[0].trim() + File.separator + InstallerUtil.TXN_LOG_DIR;
+            conf.append(asterixInstanceName + "_" + node.getId() + "." + TXN_LOG_DIR_KEY_SUFFIX + "=" + txnLogDir
+                    + "\n");
+        }
+        dumpToFile(InstallerDriver.getAsterixDir() + File.separator + asterixInstanceName + File.separator
+                + "log.properties", conf.toString());
+
+    }
+
+    public static Properties getAsterixConfiguration(String asterixConf) throws FileNotFoundException, IOException {
+        Properties prop = new Properties();
+        prop.load(new FileInputStream(asterixConf));
+        return prop;
+    }
+
+    public static void unzip(String sourceFile, String destDir) throws IOException {
+        BufferedOutputStream dest = null;
+        FileInputStream fis = new FileInputStream(sourceFile);
+        ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
+        ZipEntry entry = null;
+
+        int BUFFER_SIZE = 4096;
+        while ((entry = zis.getNextEntry()) != null) {
+            String dst = destDir + File.separator + entry.getName();
+            if (entry.isDirectory()) {
+                createDir(destDir, entry);
+                continue;
+            }
+            int count;
+            byte data[] = new byte[BUFFER_SIZE];
+
+            // write the file to the disk
+            FileOutputStream fos = new FileOutputStream(dst);
+            dest = new BufferedOutputStream(fos, BUFFER_SIZE);
+            while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
+                dest.write(data, 0, count);
+            }
+            // close the output streams
+            dest.flush();
+            dest.close();
+        }
+
+        zis.close();
+    }
+
+    public static void zipDir(File sourceDir, File destFile) throws IOException {
+        FileOutputStream fos = new FileOutputStream(destFile);
+        ZipOutputStream zos = new ZipOutputStream(fos);
+        zipDir(sourceDir, destFile, zos);
+        zos.close();
+    }
+
+    private static void zipDir(File sourceDir, final File destFile, ZipOutputStream zos) throws IOException {
+        File[] dirList = sourceDir.listFiles(new FileFilter() {
+            public boolean accept(File f) {
+                return !f.getName().endsWith(destFile.getName());
+            }
+        });
+        for (int i = 0; i < dirList.length; i++) {
+            File f = dirList[i];
+            if (f.isDirectory()) {
+                zipDir(f, destFile, zos);
+            } else {
+                int bytesIn = 0;
+                byte[] readBuffer = new byte[2156];
+                FileInputStream fis = new FileInputStream(f);
+                ZipEntry entry = new ZipEntry(sourceDir.getName() + File.separator + f.getName());
+                zos.putNextEntry(entry);
+                while ((bytesIn = fis.read(readBuffer)) != -1) {
+                    zos.write(readBuffer, 0, bytesIn);
+                }
+                fis.close();
+            }
+        }
+    }
+
+    private static void replaceInJar(File sourceJar, String origFile, File replacementFile) throws IOException {
+        File destJar = new File(sourceJar.getAbsolutePath() + ".modified");
+        InputStream jarIs = null;
+        FileInputStream fis = new FileInputStream(replacementFile);
+        JarFile sourceJarFile = new JarFile(sourceJar);
+        Enumeration<JarEntry> entries = sourceJarFile.entries();
+        JarOutputStream jos = new JarOutputStream(new FileOutputStream(destJar));
+        byte[] buffer = new byte[2048];
+        int read;
+        while (entries.hasMoreElements()) {
+            JarEntry entry = (JarEntry) entries.nextElement();
+            String name = entry.getName();
+            if (name.equals(origFile)) {
+                continue;
+            }
+            jarIs = sourceJarFile.getInputStream(entry);
+            jos.putNextEntry(entry);
+            while ((read = jarIs.read(buffer)) != -1) {
+                jos.write(buffer, 0, read);
+            }
+        }
+        JarEntry entry = new JarEntry(origFile);
+        jos.putNextEntry(entry);
+        while ((read = fis.read(buffer)) != -1) {
+            jos.write(buffer, 0, read);
+        }
+        fis.close();
+        jos.close();
+        jarIs.close();
+        sourceJar.delete();
+        destJar.renameTo(sourceJar);
+        sourceJar.setExecutable(true);
+    }
+
+    public static void dumpToFile(String dest, String content) throws IOException {
+        FileWriter writer = new FileWriter(dest);
+        writer.write(content);
+        writer.close();
+    }
+
+    private static void createDir(String destDirectory, ZipEntry entry) {
+        String name = entry.getName();
+        int index = name.lastIndexOf(File.separator);
+        String dirSequence = name.substring(0, index);
+        File newDirs = new File(destDirectory + File.separator + dirSequence);
+        newDirs.mkdirs();
+    }
+
+    public static AsterixInstance validateAsterixInstanceExists(String name, State... permissibleStates)
+            throws Exception {
+        AsterixInstance instance = ServiceProvider.INSTANCE.getLookupService().getAsterixInstance(name);
+        if (instance == null) {
+            throw new InstallerException("Asterix instance by name " + name + " does not exist.");
+        }
+        boolean valid = false;
+        for (State state : permissibleStates) {
+            if (state.equals(instance.getState())) {
+                valid = true;
+                break;
+            }
+        }
+        if (!valid) {
+            throw new InstallerException("Asterix instance by the name " + name + " is in " + instance.getState()
+                    + " state ");
+        }
+        return instance;
+    }
+
+    public static void validateAsterixInstanceNotExists(String name) throws Exception {
+        AsterixInstance instance = ServiceProvider.INSTANCE.getLookupService().getAsterixInstance(name);
+        if (instance != null) {
+            throw new InstallerException("Asterix instance by name " + name + " already exists.");
+        }
+    }
+
+    public static void evaluateConflictWithOtherInstances(AsterixInstance instance) throws Exception {
+        List<AsterixInstance> existingInstances = ServiceProvider.INSTANCE.getLookupService().getAsterixInstances();
+        List<String> usedIps = new ArrayList<String>();
+        String masterIp = instance.getCluster().getMasterNode().getClusterIp();
+        for (Node node : instance.getCluster().getNode()) {
+            usedIps.add(node.getClusterIp());
+        }
+        usedIps.add(instance.getCluster().getMasterNode().getClusterIp());
+        boolean conflictFound = false;
+        AsterixInstance conflictingInstance = null;
+        for (AsterixInstance existing : existingInstances) {
+            conflictFound = existing.getCluster().getMasterNode().getClusterIp().equals(masterIp);
+            if (conflictFound) {
+                conflictingInstance = existing;
+                break;
+            }
+            for (Node n : existing.getCluster().getNode()) {
+                if (usedIps.contains(n.getClusterIp())) {
+                    conflictFound = true;
+                    conflictingInstance = existing;
+                    break;
+                }
+            }
+        }
+        if (conflictFound) {
+            throw new Exception("Cluster definition conflicts with an existing instance of Asterix: "
+                    + conflictingInstance.getName());
+        }
+    }
+
+    public static void deleteDirectory(String path) throws IOException {
+        Runtime.getRuntime().exec("rm -rf " + path);
+    }
+
+    public static String executeLocalScript(String path, List<String> args) throws Exception {
+        List<String> pargs = new ArrayList<String>();
+        pargs.add("/bin/bash");
+        pargs.add(path);
+        if (args != null) {
+            pargs.addAll(args);
+        }
+        ProcessBuilder pb = new ProcessBuilder(pargs);
+        pb.environment().putAll(EventDriver.getEnvironment());
+        pb.environment().put("IP_LOCATION", EventDriver.CLIENT_NODE.getClusterIp());
+        Process p = pb.start();
+        BufferedInputStream bis = new BufferedInputStream(p.getInputStream());
+        StringWriter writer = new StringWriter();
+        IOUtils.copy(bis, writer, "UTF-8");
+        return writer.toString();
+    }
+
+    public static EventrixClient getEventrixClient(Cluster cluster) throws Exception {
+        return new EventrixClient(
+                InstallerDriver.getManagixHome() + File.separator + InstallerDriver.MANAGIX_EVENT_DIR, cluster, false,
+                OutputHandler.INSTANCE);
+    }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/InstallerException.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/InstallerException.java
new file mode 100644
index 0000000..89dedb6
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/InstallerException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.error;
+
+public class InstallerException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    public InstallerException(String message) {
+        super(message);
+    }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/OutputHandler.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/OutputHandler.java
new file mode 100644
index 0000000..4699402
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/OutputHandler.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.error;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import edu.uci.ics.asterix.event.management.IOutputHandler;
+import edu.uci.ics.asterix.event.management.OutputAnalysis;
+import edu.uci.ics.asterix.event.schema.pattern.Event;
+import edu.uci.ics.asterix.installer.model.EventList.EventType;
+
+public class OutputHandler implements IOutputHandler {
+
+    public static IOutputHandler INSTANCE = new OutputHandler();
+
+    private OutputHandler() {
+
+    }
+
+    public OutputAnalysis reportEventOutput(Event event, String output) {
+
+        EventType eventType = EventType.valueOf(event.getType().toUpperCase());
+        boolean ignore = true;
+        String trimmedOutput = output.trim();
+        StringBuffer errorMessage = new StringBuffer();
+        switch (eventType) {
+            case FILE_TRANSFER:
+                if (trimmedOutput.length() > 0) {
+                    if (output.contains("Permission denied") || output.contains("cannot find or open")) {
+                        ignore = false;
+                        break;
+                    }
+                }
+                break;
+
+            case BACKUP:
+            case RESTORE:
+                if (trimmedOutput.length() > 0) {
+                    if (trimmedOutput.contains("AccessControlException")) {
+                        errorMessage.append("Insufficient permissions on back up directory");
+                        ignore = false;
+                    }
+                    if (output.contains("does not exist") || output.contains("File exist")
+                            || (output.contains("No such file or directory"))) {
+                        ignore = true;
+                    } else {
+                        ignore = false;
+                    }
+                }
+                break;
+
+            case NODE_INFO:
+                Properties p = new Properties();
+                try {
+                    p.load(new ByteArrayInputStream(trimmedOutput.getBytes()));
+                } catch (IOException e) {
+                }
+                String javaVersion = (String) p.get("java_version");
+                if (p.get("java_version") == null) {
+                    errorMessage.append("Java not installed on " + event.getNodeid().getValue().getAbsvalue());
+                    ignore = false;
+                } else if (!javaVersion.contains("1.7")) {
+                    errorMessage.append("Asterix requires Java 1.7.x. Incompatible version found on  "
+                            + event.getNodeid().getValue().getAbsvalue() + "\n");
+                    ignore = false;
+                }
+                break;
+        }
+        if (ignore) {
+            return new OutputAnalysis(true, null);
+        } else {
+            return new OutputAnalysis(false, errorMessage.toString());
+        }
+    }
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/VerificationUtil.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/VerificationUtil.java
new file mode 100644
index 0000000..9cb1b96e
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/VerificationUtil.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.error;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.model.ProcessInfo;
+
+public class VerificationUtil {
+
+	private static final String VERIFY_SCRIPT_PATH = InstallerDriver
+			.getManagixHome()
+			+ File.separator
+			+ InstallerDriver.MANAGIX_INTERNAL_DIR
+			+ File.separator
+			+ "scripts"
+			+ File.separator + "verify.sh";
+
+	public static AsterixRuntimeState getAsterixRuntimeState(
+			AsterixInstance instance) throws Exception {
+
+		Cluster cluster = instance.getCluster();
+		List<String> args = new ArrayList<String>();
+		args.add(instance.getName());
+		args.add(instance.getCluster().getMasterNode().getClusterIp());
+		for (Node node : cluster.getNode()) {
+			args.add(node.getClusterIp());
+			args.add(instance.getName() + "_" + node.getId());
+		}
+		Thread.sleep(2000);
+		String output = InstallerUtil.executeLocalScript(VERIFY_SCRIPT_PATH,
+				args);
+		boolean ccRunning = true;
+		List<String> failedNCs = new ArrayList<String>();
+		String[] infoFields;
+		ProcessInfo pInfo;
+		List<ProcessInfo> processes = new ArrayList<ProcessInfo>();
+
+		for (String line : output.split("\n")) {
+			String nodeid = null;
+			infoFields = line.split(":");
+			try {
+				int pid = Integer.parseInt(infoFields[3]);
+				if (infoFields[0].equals("NC")) {
+					nodeid = infoFields[2].split("_")[1];
+				} else {
+					nodeid = instance.getCluster().getMasterNode().getId();
+				}
+				pInfo = new ProcessInfo(infoFields[0], infoFields[1], nodeid,
+						pid);
+				processes.add(pInfo);
+			} catch (Exception e) {
+				if (infoFields[0].equalsIgnoreCase("CC")) {
+					ccRunning = false;
+				} else {
+					failedNCs.add(infoFields[1]);
+				}
+			}
+		}
+		return new AsterixRuntimeState(processes, failedNCs, ccRunning);
+	}
+
+	public static void updateInstanceWithRuntimeDescription(
+			AsterixInstance instance, AsterixRuntimeState state,
+			boolean expectedRunning) {
+		StringBuffer summary = new StringBuffer();
+		if (expectedRunning) {
+			if (!state.isCcRunning()) {
+				summary.append("Cluster Controller not running at "
+						+ instance.getCluster().getMasterNode().getId() + "\n");
+				instance.setState(State.UNUSABLE);
+			}
+			if (state.getFailedNCs() != null && !state.getFailedNCs().isEmpty()) {
+				summary.append("Node Controller not running at the following nodes"
+						+ "\n");
+				for (String failedNC : state.getFailedNCs()) {
+					summary.append(failedNC + "\n");
+				}
+				instance.setState(State.UNUSABLE);
+			}
+			if (!(instance.getState().equals(State.UNUSABLE))) {
+				instance.setState(State.ACTIVE);
+			}
+		} else {
+			if (state.getProcesses() != null && state.getProcesses().size() > 0) {
+				summary.append("Following process still running " + "\n");
+				for (ProcessInfo pInfo : state.getProcesses()) {
+					summary.append(pInfo + "\n");
+				}
+				instance.setState(State.UNUSABLE);
+			} else {
+				instance.setState(State.INACTIVE);
+			}
+		}
+		state.setSummary(summary.toString());
+		instance.setAsterixRuntimeStates(state);
+	}
+
+	public static void verifyBackupRestoreConfiguration(String hdfsUrl,
+			String hadoopVersion, String hdfsBackupDir) throws Exception {
+		StringBuffer errorCheck = new StringBuffer();
+		if (hdfsUrl == null || hdfsUrl.length() == 0) {
+			errorCheck.append("\n HDFS Url not configured");
+		}
+		if (hadoopVersion == null || hadoopVersion.length() == 0) {
+			errorCheck.append("\n HDFS version not configured");
+		}
+		if (hdfsBackupDir == null || hdfsBackupDir.length() == 0) {
+			errorCheck.append("\n HDFS backup directory not configured");
+		}
+		if (errorCheck.length() > 0) {
+			throw new Exception("Incomplete hdfs configuration in "
+					+ InstallerDriver.getManagixHome() + File.separator
+					+ InstallerDriver.MANAGIX_CONF_XML + errorCheck);
+		}
+	}
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java
new file mode 100644
index 0000000..f6aeafe
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.events;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.event.schema.pattern.Delay;
+import edu.uci.ics.asterix.event.schema.pattern.Event;
+import edu.uci.ics.asterix.event.schema.pattern.Nodeid;
+import edu.uci.ics.asterix.event.schema.pattern.Pattern;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.event.schema.pattern.Value;
+import edu.uci.ics.asterix.installer.command.BackupCommand;
+import edu.uci.ics.asterix.installer.command.StopCommand;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.error.VerificationUtil;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.BackupInfo;
+import edu.uci.ics.asterix.installer.model.BackupInfo.BackupType;
+import edu.uci.ics.asterix.installer.schema.conf.Backup;
+import edu.uci.ics.asterix.installer.service.ILookupService;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class PatternCreator {
+
+    private ILookupService lookupService = ServiceProvider.INSTANCE.getLookupService();
+
+    private void addInitialDelay(Pattern p, int delay, String unit) {
+        Delay d = new Delay(new Value(null, "" + delay), unit);
+        p.setDelay(d);
+    }
+
+    public Patterns getStartAsterixPattern(String asterixInstanceName, Cluster cluster) throws Exception {
+        String ccLocationId = cluster.getMasterNode().getId();
+        String ccLocationIp = cluster.getMasterNode().getClusterIp();
+
+        String destDir = cluster.getWorkingDir().getDir() + File.separator + "asterix";
+        List<Pattern> ps = new ArrayList<Pattern>();
+
+        Pattern copyHyracks = createCopyHyracksPattern(asterixInstanceName, cluster, ccLocationIp, destDir);
+        ps.add(copyHyracks);
+
+        Pattern createCC = createCCStartPattern(ccLocationId);
+        addInitialDelay(createCC, 3, "sec");
+        ps.add(createCC);
+
+        boolean copyHyracksToNC = !cluster.getWorkingDir().isNFS();
+        for (Node node : cluster.getNode()) {
+            if (copyHyracksToNC) {
+                Pattern copyHyracksForNC = createCopyHyracksPattern(asterixInstanceName, cluster, node.getClusterIp(),
+                        destDir);
+                ps.add(copyHyracksForNC);
+            }
+            String iodevices = node.getIodevices() == null ? cluster.getIodevices() : node.getIodevices();
+            Pattern createNC = createNCStartPattern(cluster.getMasterNode().getClusterIp(), node.getId(),
+                    asterixInstanceName + "_" + node.getId(), iodevices);
+            addInitialDelay(createNC, 5, "sec");
+            ps.add(createNC);
+        }
+
+        Patterns patterns = new Patterns(ps);
+        patterns.getPattern().addAll(createHadoopLibraryTransferPattern(cluster).getPattern());
+        return patterns;
+    }
+
+    public Patterns getStopCommandPattern(StopCommand stopCommand) throws Exception {
+        List<Pattern> ps = new ArrayList<Pattern>();
+        AsterixInstance asterixInstance = lookupService.getAsterixInstance(stopCommand.getAsterixInstanceName());
+        Cluster cluster = asterixInstance.getCluster();
+
+        String ccLocation = cluster.getMasterNode().getId();
+        Pattern createCC = createCCStopPattern(ccLocation);
+        addInitialDelay(createCC, 5, "sec");
+        ps.add(createCC);
+
+        String asterixInstanceName = stopCommand.getAsterixInstanceName();
+        int nodeControllerIndex = 1;
+        for (Node node : cluster.getNode()) {
+            Pattern createNC = createNCStopPattern(node.getId(), asterixInstanceName + "_" + nodeControllerIndex);
+            ps.add(createNC);
+            nodeControllerIndex++;
+        }
+
+        Patterns patterns = new Patterns(ps);
+        return patterns;
+    }
+
+    public Patterns getBackUpAsterixPattern(AsterixInstance instance, Backup backupConf) throws Exception {
+        BackupType backupType = BackupInfo.getBackupType(backupConf);
+        Patterns patterns = null;
+        switch (backupType) {
+            case HDFS:
+                patterns = getHDFSBackUpAsterixPattern(instance, backupConf);
+                break;
+            case LOCAL:
+                patterns = getLocalBackUpAsterixPattern(instance, backupConf);
+                break;
+        }
+        return patterns;
+    }
+
+    public Patterns getRestoreAsterixPattern(AsterixInstance instance, BackupInfo backupInfo) throws Exception {
+        BackupType backupType = backupInfo.getBackupType();
+        Patterns patterns = null;
+        switch (backupType) {
+            case HDFS:
+                patterns = getHDFSRestoreAsterixPattern(instance, backupInfo);
+                break;
+            case LOCAL:
+                patterns = getLocalRestoreAsterixPattern(instance, backupInfo);
+                break;
+        }
+        return patterns;
+    }
+
+    private Patterns getHDFSBackUpAsterixPattern(AsterixInstance instance, Backup backupConf) throws Exception {
+        Cluster cluster = instance.getCluster();
+        String hdfsUrl = backupConf.getHdfs().getUrl();
+        String hadoopVersion = backupConf.getHdfs().getVersion();
+        String hdfsBackupDir = backupConf.getBackupDir();
+        VerificationUtil.verifyBackupRestoreConfiguration(hdfsUrl, hadoopVersion, hdfsBackupDir);
+        String workingDir = cluster.getWorkingDir().getDir();
+        String backupId = "" + instance.getBackupInfo().size();
+        String store;
+        String pargs;
+        String iodevices;
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        for (Node node : cluster.getNode()) {
+            Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+            iodevices = node.getIodevices() == null ? instance.getCluster().getIodevices() : node.getIodevices();
+            store = node.getStore() == null ? cluster.getStore() : node.getStore();
+            pargs = workingDir + " " + instance.getName() + " " + iodevices + " " + store + " "
+                    + BackupCommand.ASTERIX_ROOT_METADATA_DIR + " " + InstallerUtil.TXN_LOG_DIR + " " + backupId + " "
+                    + hdfsBackupDir + " " + "hdfs" + " " + node.getId() + " " + hdfsUrl + " " + hadoopVersion;
+            Event event = new Event("backup", nodeid, pargs);
+            patternList.add(new Pattern(null, 1, null, event));
+        }
+        return new Patterns(patternList);
+    }
+
+    private Patterns getLocalBackUpAsterixPattern(AsterixInstance instance, Backup backupConf) throws Exception {
+        Cluster cluster = instance.getCluster();
+        String backupDir = backupConf.getBackupDir();
+        String workingDir = cluster.getWorkingDir().getDir();
+        String backupId = "" + instance.getBackupInfo().size();
+        String iodevices;
+        String store;
+        String pargs;
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        for (Node node : cluster.getNode()) {
+            Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+            iodevices = node.getIodevices() == null ? instance.getCluster().getIodevices() : node.getIodevices();
+            store = node.getStore() == null ? cluster.getStore() : node.getStore();
+            pargs = workingDir + " " + instance.getName() + " " + iodevices + " " + store + " "
+                    + BackupCommand.ASTERIX_ROOT_METADATA_DIR + " " + InstallerUtil.TXN_LOG_DIR + " " + backupId + " "
+                    + backupDir + " " + "local" + " " + node.getId();
+            Event event = new Event("backup", nodeid, pargs);
+            patternList.add(new Pattern(null, 1, null, event));
+        }
+        return new Patterns(patternList);
+    }
+
+    public Patterns getHDFSRestoreAsterixPattern(AsterixInstance instance, BackupInfo backupInfo) throws Exception {
+        Cluster cluster = instance.getCluster();
+        String clusterStore = instance.getCluster().getStore();
+        String hdfsUrl = backupInfo.getBackupConf().getHdfs().getUrl();
+        String hadoopVersion = backupInfo.getBackupConf().getHdfs().getVersion();
+        String hdfsBackupDir = backupInfo.getBackupConf().getBackupDir();
+        VerificationUtil.verifyBackupRestoreConfiguration(hdfsUrl, hadoopVersion, hdfsBackupDir);
+        String workingDir = cluster.getWorkingDir().getDir();
+        int backupId = backupInfo.getId();
+        String nodeStore;
+        String pargs;
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        for (Node node : cluster.getNode()) {
+            Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+            String iodevices = node.getIodevices() == null ? cluster.getIodevices() : node.getIodevices();
+            nodeStore = node.getStore() == null ? clusterStore : node.getStore();
+            pargs = workingDir + " " + instance.getName() + " " + iodevices + " " + nodeStore + " "
+                    + BackupCommand.ASTERIX_ROOT_METADATA_DIR + " " + InstallerUtil.TXN_LOG_DIR + " " + backupId + " "
+                    + " " + hdfsBackupDir + " " + "hdfs" + " " + node.getId() + " " + hdfsUrl + " " + hadoopVersion;
+            Event event = new Event("restore", nodeid, pargs);
+            patternList.add(new Pattern(null, 1, null, event));
+        }
+        return new Patterns(patternList);
+    }
+
+    public Patterns getLocalRestoreAsterixPattern(AsterixInstance instance, BackupInfo backupInfo) throws Exception {
+        Cluster cluster = instance.getCluster();
+        String clusterStore = instance.getCluster().getStore();
+        String backupDir = backupInfo.getBackupConf().getBackupDir();
+        String workingDir = cluster.getWorkingDir().getDir();
+        int backupId = backupInfo.getId();
+        String nodeStore;
+        String pargs;
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        for (Node node : cluster.getNode()) {
+            Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+            String iodevices = node.getIodevices() == null ? cluster.getIodevices() : node.getIodevices();
+            nodeStore = node.getStore() == null ? clusterStore : node.getStore();
+            pargs = workingDir + " " + instance.getName() + " " + iodevices + " " + nodeStore + " "
+                    + BackupCommand.ASTERIX_ROOT_METADATA_DIR + " " + InstallerUtil.TXN_LOG_DIR + " " + backupId + " "
+                    + backupDir + " " + "local" + " " + node.getId();
+            Event event = new Event("restore", nodeid, pargs);
+            patternList.add(new Pattern(null, 1, null, event));
+        }
+        return new Patterns(patternList);
+    }
+
+    public Patterns createHadoopLibraryTransferPattern(Cluster cluster) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        String workingDir = cluster.getWorkingDir().getDir();
+        String hadoopVersion = InstallerDriver.getConfiguration().getBackup().getHdfs().getVersion();
+        File hadoopDir = new File(InstallerDriver.getManagixHome() + File.separator
+                + InstallerDriver.MANAGIX_INTERNAL_DIR + File.separator + "hadoop-" + hadoopVersion);
+        if (!hadoopDir.exists()) {
+            throw new IllegalStateException("Hadoop version :" + hadoopVersion + " not supported");
+        }
+
+        Nodeid nodeid = new Nodeid(new Value(null, EventDriver.CLIENT_NODE.getId()));
+        String username = cluster.getUsername() != null ? cluster.getUsername() : System.getProperty("user.name");
+        String pargs = username + " " + hadoopDir.getAbsolutePath() + " " + cluster.getMasterNode().getClusterIp()
+                + " " + workingDir;
+        Event event = new Event("directory_transfer", nodeid, pargs);
+        Pattern p = new Pattern(null, 1, null, event);
+        addInitialDelay(p, 2, "sec");
+        patternList.add(p);
+
+        boolean copyToNC = !cluster.getWorkingDir().isNFS();
+        if (copyToNC) {
+            for (Node node : cluster.getNode()) {
+                nodeid = new Nodeid(new Value(null, node.getId()));
+                pargs = cluster.getUsername() + " " + hadoopDir.getAbsolutePath() + " " + node.getClusterIp() + " "
+                        + workingDir;
+                event = new Event("directory_transfer", nodeid, pargs);
+                p = new Pattern(null, 1, null, event);
+                addInitialDelay(p, 2, "sec");
+                patternList.add(p);
+            }
+        }
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    public Patterns createDeleteInstancePattern(AsterixInstance instance) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        patternList.addAll(createRemoveAsterixStoragePattern(instance).getPattern());
+        if (instance.getBackupInfo() != null && instance.getBackupInfo().size() > 0) {
+            List<BackupInfo> backups = instance.getBackupInfo();
+            Set<String> removedBackupDirsHDFS = new HashSet<String>();
+            Set<String> removedBackupDirsLocal = new HashSet<String>();
+
+            String backupDir;
+            for (BackupInfo binfo : backups) {
+                backupDir = binfo.getBackupConf().getBackupDir();
+                switch (binfo.getBackupType()) {
+                    case HDFS:
+                        if (removedBackupDirsHDFS.contains(backups)) {
+                            continue;
+                        }
+                        patternList.addAll(createRemoveHDFSBackupPattern(instance, backupDir).getPattern());
+                        removedBackupDirsHDFS.add(backupDir);
+                        break;
+
+                    case LOCAL:
+                        if (removedBackupDirsLocal.contains(backups)) {
+                            continue;
+                        }
+                        patternList.addAll(createRemoveLocalBackupPattern(instance, backupDir).getPattern());
+                        removedBackupDirsLocal.add(backupDir);
+                        break;
+                }
+
+            }
+        }
+        patternList.addAll(createRemoveAsterixLogDirPattern(instance).getPattern());
+        patternList.addAll(createRemoveAsterixRootMetadata(instance).getPattern());
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    private Patterns createRemoveHDFSBackupPattern(AsterixInstance instance, String hdfsBackupDir) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        Cluster cluster = instance.getCluster();
+        String hdfsUrl = InstallerDriver.getConfiguration().getBackup().getHdfs().getUrl();
+        String hadoopVersion = InstallerDriver.getConfiguration().getBackup().getHdfs().getVersion();
+        String workingDir = cluster.getWorkingDir().getDir();
+        Node launchingNode = cluster.getNode().get(0);
+        Nodeid nodeid = new Nodeid(new Value(null, launchingNode.getId()));
+        String pathToDelete = hdfsBackupDir + File.separator + instance.getName();
+        String pargs = workingDir + " " + hadoopVersion + " " + hdfsUrl + " " + pathToDelete;
+        Event event = new Event("hdfs_delete", nodeid, pargs);
+        patternList.add(new Pattern(null, 1, null, event));
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    private Patterns createRemoveLocalBackupPattern(AsterixInstance instance, String localBackupDir) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        Cluster cluster = instance.getCluster();
+
+        String pathToDelete = localBackupDir + File.separator + instance.getName();
+        String pargs = pathToDelete;
+        List<String> removedBackupDirs = new ArrayList<String>();
+        for (Node node : cluster.getNode()) {
+            if (removedBackupDirs.contains(node.getClusterIp())) {
+                continue;
+            }
+            Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+            Event event = new Event("file_delete", nodeid, pargs);
+            patternList.add(new Pattern(null, 1, null, event));
+            removedBackupDirs.add(node.getClusterIp());
+        }
+
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    public Patterns createRemoveAsterixWorkingDirPattern(AsterixInstance instance) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        Cluster cluster = instance.getCluster();
+        String workingDir = cluster.getWorkingDir().getDir();
+        String pargs = workingDir;
+        Nodeid nodeid = new Nodeid(new Value(null, cluster.getMasterNode().getId()));
+        Event event = new Event("file_delete", nodeid, pargs);
+        patternList.add(new Pattern(null, 1, null, event));
+
+        if (!cluster.getWorkingDir().isNFS()) {
+            for (Node node : cluster.getNode()) {
+                nodeid = new Nodeid(new Value(null, node.getId()));
+                event = new Event("file_delete", nodeid, pargs);
+                patternList.add(new Pattern(null, 1, null, event));
+            }
+        }
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    private Patterns createRemoveAsterixRootMetadata(AsterixInstance instance) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        Cluster cluster = instance.getCluster();
+        Nodeid nodeid = null;
+        String pargs = null;
+        Event event = null;
+        for (Node node : cluster.getNode()) {
+            String iodevices = node.getIodevices() == null ? cluster.getIodevices() : node.getIodevices();
+            String primaryIODevice = iodevices.split(",")[0].trim();
+            pargs = primaryIODevice + File.separator + BackupCommand.ASTERIX_ROOT_METADATA_DIR;
+            nodeid = new Nodeid(new Value(null, node.getId()));
+            event = new Event("file_delete", nodeid, pargs);
+            patternList.add(new Pattern(null, 1, null, event));
+        }
+
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    private Patterns createRemoveAsterixLogDirPattern(AsterixInstance instance) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        Cluster cluster = instance.getCluster();
+        String pargs = instance.getCluster().getLogdir();
+        Nodeid nodeid = new Nodeid(new Value(null, cluster.getMasterNode().getId()));
+        Event event = new Event("file_delete", nodeid, pargs);
+        patternList.add(new Pattern(null, 1, null, event));
+
+        for (Node node : cluster.getNode()) {
+            nodeid = new Nodeid(new Value(null, node.getId()));
+            event = new Event("file_delete", nodeid, pargs);
+            patternList.add(new Pattern(null, 1, null, event));
+        }
+
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    private Patterns createRemoveAsterixStoragePattern(AsterixInstance instance) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        Cluster cluster = instance.getCluster();
+        String pargs = null;
+
+        for (Node node : cluster.getNode()) {
+            Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+            String[] nodeIODevices;
+            String iodevices = node.getIodevices() == null ? cluster.getIodevices() : node.getIodevices();
+            nodeIODevices = iodevices.trim().split(",");
+            for (String nodeIODevice : nodeIODevices) {
+                String nodeStore = node.getStore() == null ? cluster.getStore() : node.getStore();
+                pargs = nodeIODevice.trim() + File.separator + nodeStore;
+                Event event = new Event("file_delete", nodeid, pargs);
+                patternList.add(new Pattern(null, 1, null, event));
+            }
+        }
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    private Pattern createCopyHyracksPattern(String instanceName, Cluster cluster, String destinationIp, String destDir) {
+        Nodeid nodeid = new Nodeid(new Value(null, EventDriver.CLIENT_NODE.getId()));
+        String username = cluster.getUsername() != null ? cluster.getUsername() : System.getProperty("user.name");
+        String asterixZipName = InstallerDriver.getAsterixZip().substring(
+                InstallerDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+        String fileToTransfer = new File(InstallerDriver.getAsterixDir() + File.separator + instanceName
+                + File.separator + asterixZipName).getAbsolutePath();
+        String pargs = username + " " + fileToTransfer + " " + destinationIp + " " + destDir + " " + "unpack";
+        Event event = new Event("file_transfer", nodeid, pargs);
+        return new Pattern(null, 1, null, event);
+    }
+
+    private Pattern createCCStartPattern(String hostId) {
+        Nodeid nodeid = new Nodeid(new Value(null, hostId));
+        Event event = new Event("cc_start", nodeid, "");
+        return new Pattern(null, 1, null, event);
+    }
+
+    public Pattern createCCStopPattern(String hostId) {
+        Nodeid nodeid = new Nodeid(new Value(null, hostId));
+        Event event = new Event("cc_failure", nodeid, null);
+        return new Pattern(null, 1, null, event);
+    }
+
+    public Pattern createNCStartPattern(String ccHost, String hostId, String nodeControllerId, String iodevices) {
+        Nodeid nodeid = new Nodeid(new Value(null, hostId));
+        String pargs = ccHost + " " + nodeControllerId + " " + iodevices;
+        Event event = new Event("node_join", nodeid, pargs);
+        return new Pattern(null, 1, null, event);
+    }
+
+    public Pattern createNCStopPattern(String hostId, String nodeControllerId) {
+        Nodeid nodeid = new Nodeid(new Value(null, hostId));
+        Event event = new Event("node_failure", nodeid, nodeControllerId);
+        return new Pattern(null, 1, null, event);
+    }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java
new file mode 100644
index 0000000..9f8b28d
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import edu.uci.ics.asterix.event.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+
+public class AsterixInstance implements Serializable {
+
+	private static final long serialVersionUID = 2874439550187520449L;
+
+	public enum State {
+		ACTIVE, INACTIVE, UNUSABLE
+	}
+
+	private final Cluster cluster;
+	private final String name;
+	private final Date createdTimestamp;
+	private Date stateChangeTimestamp;
+	private Date modifiedTimestamp;
+	private Properties configuration;
+	private State state;
+	private final String metadataNodeId;
+	private final String asterixVersion;
+	private final List<BackupInfo> backupInfo;
+	private final String webInterfaceUrl;
+	private AsterixRuntimeState runtimeState;
+	private State previousState;
+
+	public AsterixInstance(String name, Cluster cluster,
+			Properties configuration, String metadataNodeId,
+			String asterixVersion) {
+		this.name = name;
+		this.cluster = cluster;
+		this.configuration = configuration;
+		this.metadataNodeId = metadataNodeId;
+		this.state = State.ACTIVE;
+		this.previousState = State.UNUSABLE;
+		this.asterixVersion = asterixVersion;
+		this.createdTimestamp = new Date();
+		this.backupInfo = new ArrayList<BackupInfo>();
+		this.webInterfaceUrl = "http://"
+				+ cluster.getMasterNode().getClusterIp() + ":" + 19001;
+	}
+
+	public Date getModifiedTimestamp() {
+		return stateChangeTimestamp;
+	}
+
+	public Properties getConfiguration() {
+		return configuration;
+	}
+
+	public void setConfiguration(Properties properties) {
+		this.configuration = properties;
+	}
+
+	public State getState() {
+		return state;
+	}
+
+	public void setState(State state) {
+		this.previousState = this.state;
+		this.state = state;
+	}
+
+	public Cluster getCluster() {
+		return cluster;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Date getCreatedTimestamp() {
+		return createdTimestamp;
+	}
+
+	public Date getStateChangeTimestamp() {
+		return stateChangeTimestamp;
+	}
+
+	public void setStateChangeTimestamp(Date stateChangeTimestamp) {
+		this.stateChangeTimestamp = stateChangeTimestamp;
+	}
+
+	public void setModifiedTimestamp(Date modifiedTimestamp) {
+		this.modifiedTimestamp = modifiedTimestamp;
+	}
+
+	public String getMetadataNodeId() {
+		return metadataNodeId;
+	}
+
+	public String getAsterixVersion() {
+		return asterixVersion;
+	}
+
+	public String getDescription(boolean detailed) {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("Name:" + name + "\n");
+		buffer.append("Created:" + createdTimestamp + "\n");
+		buffer.append("Web-Url:" + webInterfaceUrl + "\n");
+		buffer.append("State:" + state);
+		if (!state.equals(State.UNUSABLE) && stateChangeTimestamp != null) {
+			buffer.append(" (" + stateChangeTimestamp + ")" + "\n");
+		} else {
+			buffer.append("\n");
+		}
+		if (modifiedTimestamp != null) {
+			buffer.append("Last modified timestamp:" + modifiedTimestamp + "\n");
+		}
+
+		if (runtimeState.getSummary() != null
+				&& runtimeState.getSummary().length() > 0) {
+			buffer.append("\nWARNING!:" + runtimeState.getSummary() + "\n");
+		}
+		if (detailed) {
+			addDetailedInformation(buffer);
+		}
+		return buffer.toString();
+	}
+
+	public List<BackupInfo> getBackupInfo() {
+		return backupInfo;
+	}
+
+	public String getWebInterfaceUrl() {
+		return webInterfaceUrl;
+	}
+
+	public AsterixRuntimeState getAsterixRuntimeState() {
+		return runtimeState;
+	}
+
+	public void setAsterixRuntimeStates(AsterixRuntimeState runtimeState) {
+		this.runtimeState = runtimeState;
+	}
+
+	private void addDetailedInformation(StringBuffer buffer) {
+		buffer.append("Master node:" + cluster.getMasterNode().getId() + ":"
+				+ cluster.getMasterNode().getClusterIp() + "\n");
+		for (Node node : cluster.getNode()) {
+			buffer.append(node.getId() + ":" + node.getClusterIp() + "\n");
+		}
+
+		if (backupInfo != null && backupInfo.size() > 0) {
+			for (BackupInfo info : backupInfo) {
+				buffer.append(info + "\n");
+			}
+		}
+		buffer.append("\n");
+		buffer.append("Asterix version:" + asterixVersion + "\n");
+		buffer.append("Metadata Node:" + metadataNodeId + "\n");
+		buffer.append("Processes" + "\n");
+		for (ProcessInfo pInfo : runtimeState.getProcesses()) {
+			buffer.append(pInfo + "\n");
+		}
+
+	}
+
+	public State getPreviousState() {
+		return previousState;
+	}
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixRuntimeState.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixRuntimeState.java
new file mode 100644
index 0000000..207c570
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixRuntimeState.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class AsterixRuntimeState implements Serializable {
+
+    private final List<ProcessInfo> processes;
+    private final List<String> failedNCs;
+    private final boolean ccRunning;
+    private String summary;
+
+    public AsterixRuntimeState(List<ProcessInfo> processes, List<String> failedNCs, boolean ccRunning) {
+        this.processes = processes;
+        this.failedNCs = failedNCs;
+        this.ccRunning = ccRunning;
+    }
+
+    public List<ProcessInfo> getProcesses() {
+        return processes;
+    }
+
+    public List<String> getFailedNCs() {
+        return failedNCs;
+    }
+
+    public boolean isCcRunning() {
+        return ccRunning;
+    }
+
+    public void setSummary(String summary) {
+        this.summary = summary;
+    }
+
+    public String getSummary() {
+        return summary;
+    }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/BackupInfo.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/BackupInfo.java
new file mode 100644
index 0000000..cea8087
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/BackupInfo.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import edu.uci.ics.asterix.installer.schema.conf.Backup;
+import edu.uci.ics.asterix.installer.schema.conf.Hdfs;
+
+public class BackupInfo implements Serializable {
+
+    public static enum BackupType {
+        LOCAL,
+        HDFS
+    };
+
+    private final int id;
+    private final Date date;
+    private final Backup backupConf;
+
+    public BackupInfo(int id, Date date, Backup backupConf) {
+        this.id = id;
+        this.date = date;
+        this.backupConf = backupConf;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public Backup getBackupConf() {
+        return backupConf;
+    }
+
+    @Override
+    public String toString() {
+        return id + " " + date + " " + "(" + getBackupType() + ")" + " " + "[ " + this.getBackupConf().getBackupDir()
+                + " ]";
+
+    }
+
+    public BackupType getBackupType() {
+        return getBackupType(this.getBackupConf());
+    }
+
+    public static BackupType getBackupType(Backup backupConf) {
+        Hdfs hdfs = backupConf.getHdfs();
+        return (hdfs != null && hdfs.getUrl() != null && hdfs.getUrl().length() > 0) ? BackupType.HDFS
+                : BackupType.LOCAL;
+    }
+}
\ No newline at end of file
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java
new file mode 100644
index 0000000..b605889
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.model;
+
+public class EventList {
+
+    public enum EventType {
+        NODE_JOIN,
+        NODE_FAILURE,
+        CC_START,
+        CC_FAILURE,
+        BACKUP,
+        RESTORE,
+        FILE_DELETE,
+        HDFS_DELETE,
+        FILE_TRANSFER,
+        FILE_CREATE,
+        DIRECTORY_TRANSFER,
+        NODE_INFO
+    }
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/ProcessInfo.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/ProcessInfo.java
new file mode 100644
index 0000000..42ee112
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/ProcessInfo.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.model;
+
+import java.io.Serializable;
+
+public class ProcessInfo implements Serializable {
+
+    private static final long serialVersionUID = 304186774065853730L;
+    private final String processName;
+    private final String host;
+    private final String nodeId;
+    private final int processId;
+
+    public ProcessInfo(String processName, String host, String nodeId, int processId) {
+        this.processName = processName;
+        this.host = host;
+        this.nodeId = nodeId;
+        this.processId = processId;
+    }
+
+    public String getProcessName() {
+        return processName;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public int getProcessId() {
+        return processId;
+    }
+
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public String toString() {
+        return processName + " at " + nodeId + " [ " + processId + " ] ";
+    }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ILookupService.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ILookupService.java
new file mode 100644
index 0000000..aad963f
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ILookupService.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.service;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.schema.conf.Configuration;
+
+public interface ILookupService {
+
+    public void writeAsterixInstance(AsterixInstance asterixInstance) throws Exception;
+
+    public AsterixInstance getAsterixInstance(String name) throws Exception;
+
+    public boolean isRunning(Configuration conf) throws Exception;
+
+    public void startService(Configuration conf) throws Exception;
+
+    public void stopService(Configuration conf) throws Exception;
+
+    public boolean exists(String name) throws Exception;
+
+    public void removeAsterixInstance(String name) throws Exception;
+
+    public List<AsterixInstance> getAsterixInstances() throws Exception;
+
+    public void updateAsterixInstance(AsterixInstance updatedInstance) throws Exception;
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ServiceProvider.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ServiceProvider.java
new file mode 100644
index 0000000..1a9e9e6
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ServiceProvider.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.service;
+
+public class ServiceProvider {
+
+    public static ServiceProvider INSTANCE = new ServiceProvider();
+    private static ILookupService lookupService = new ZooKeeperService();
+    
+    private ServiceProvider() {
+
+    }
+
+    public ILookupService getLookupService() {
+        return lookupService;
+    }
+ 
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ZooKeeperService.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ZooKeeperService.java
new file mode 100644
index 0000000..b87d721
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ZooKeeperService.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * 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 edu.uci.ics.asterix.installer.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.error.InstallerException;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.schema.conf.Configuration;
+
+public class ZooKeeperService implements ILookupService {
+
+    private static final Logger LOGGER = Logger.getLogger(ZooKeeperService.class.getName());
+
+    private static final int ZOOKEEPER_LEADER_CONN_PORT = 2222;
+    private static final int ZOOKEEPER_LEADER_ELEC_PORT = 2223;
+    private static final int ZOOKEEPER_SESSION_TIME_OUT = 40 * 1000; //milliseconds
+    private static final String ZOOKEEPER_HOME = InstallerDriver.getManagixHome() + File.separator
+            + InstallerDriver.MANAGIX_INTERNAL_DIR + File.separator + "zookeeper";
+    private static final String ZOO_KEEPER_CONFIG = ZOOKEEPER_HOME + File.separator + "zk.cfg";
+
+    private boolean isRunning = false;
+    private ZooKeeper zk;
+    private String zkConnectionString;
+    private static final String ASTERIX_INSTANCE_BASE_PATH = "/Asterix";
+    private static final int DEFAULT_NODE_VERSION = -1;
+    private LinkedBlockingQueue<String> msgQ = new LinkedBlockingQueue<String>();
+    private ZooKeeperWatcher watcher = new ZooKeeperWatcher(msgQ);
+
+    public boolean isRunning(Configuration conf) throws Exception {
+        List<String> servers = conf.getZookeeper().getServers().getServer();
+        int clientPort = conf.getZookeeper().getClientPort().intValue();
+        StringBuffer connectionString = new StringBuffer();
+        for (String serverAddress : servers) {
+            connectionString.append(serverAddress);
+            connectionString.append(":");
+            connectionString.append(clientPort);
+            connectionString.append(",");
+        }
+        if (connectionString.length() > 0) {
+            connectionString.deleteCharAt(connectionString.length() - 1);
+        }
+        zkConnectionString = connectionString.toString();
+
+        zk = new ZooKeeper(zkConnectionString, ZOOKEEPER_SESSION_TIME_OUT, watcher);
+        try {
+            zk.exists("/dummy", watcher);
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("ZooKeeper running at " + connectionString);
+            }
+            createRootIfNotExist();
+            isRunning = true;
+        } catch (KeeperException ke) {
+            isRunning = false;
+        }
+        return isRunning;
+    }
+
+    public void startService(Configuration conf) throws Exception {
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("Starting ZooKeeper at " + zkConnectionString);
+        }
+        ZookeeperUtil.writeConfiguration(ZOO_KEEPER_CONFIG, conf, ZOOKEEPER_LEADER_CONN_PORT,
+                ZOOKEEPER_LEADER_ELEC_PORT);
+        String initScript = ZOOKEEPER_HOME + File.separator + "bin" + File.separator + "zk.init";
+        StringBuffer cmdBuffer = new StringBuffer();
+        cmdBuffer.append(initScript + " ");
+        cmdBuffer.append(conf.getZookeeper().getHomeDir() + " ");
+        cmdBuffer.append(conf.getZookeeper().getServers().getJavaHome() + " ");
+        List<String> zkServers = conf.getZookeeper().getServers().getServer();
+        for (String zkServer : zkServers) {
+            cmdBuffer.append(zkServer + " ");
+        }
+        Runtime.getRuntime().exec(cmdBuffer.toString());
+        zk = new ZooKeeper(zkConnectionString, ZOOKEEPER_SESSION_TIME_OUT, watcher);
+        String head = msgQ.poll(10, TimeUnit.SECONDS);
+        if (head == null) {
+            String msg = "Unable to start Zookeeper Service. Please verify the configuration at "
+                    + InstallerDriver.getManagixHome() + File.separator + InstallerDriver.MANAGIX_CONF_XML;
+            throw new Exception(msg);
+        }
+        msgQ.take();
+        createRootIfNotExist();
+    }
+
+    public void stopService(Configuration conf) throws Exception {
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("Stopping ZooKeeper running at " + zkConnectionString);
+        }
+        String stopScript = ZOOKEEPER_HOME + File.separator + "bin" + File.separator + "stop_zk";
+        StringBuffer cmdBuffer = new StringBuffer();
+        cmdBuffer.append(stopScript + " ");
+        cmdBuffer.append(conf.getZookeeper().getHomeDir() + " ");
+        List<String> zkServers = conf.getZookeeper().getServers().getServer();
+        for (String zkServer : zkServers) {
+            cmdBuffer.append(zkServer + " ");
+        }
+        Runtime.getRuntime().exec(cmdBuffer.toString());
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("Stopped ZooKeeper service at " + zkConnectionString);
+        }
+    }
+
+    public void writeAsterixInstance(AsterixInstance asterixInstance) throws Exception {
+        String instanceBasePath = ASTERIX_INSTANCE_BASE_PATH + File.separator + asterixInstance.getName();
+        ByteArrayOutputStream b = new ByteArrayOutputStream();
+        ObjectOutputStream o = new ObjectOutputStream(b);
+        o.writeObject(asterixInstance);
+        zk.create(instanceBasePath, b.toByteArray(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+    }
+
+    private void createRootIfNotExist() throws Exception {
+        try {
+            Stat stat = zk.exists(ASTERIX_INSTANCE_BASE_PATH, false);
+            if (stat == null) {
+                zk.create(ASTERIX_INSTANCE_BASE_PATH, "root".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            }
+        } catch (Exception e) {
+            createRootIfNotExist();
+        }
+    }
+
+    public AsterixInstance getAsterixInstance(String name) throws Exception {
+        String path = ASTERIX_INSTANCE_BASE_PATH + File.separator + name;
+        Stat stat = zk.exists(ASTERIX_INSTANCE_BASE_PATH + File.separator + name, false);
+        if (stat == null) {
+            return null;
+        }
+        byte[] asterixInstanceBytes = zk.getData(path, false, new Stat());
+        return readAsterixInstanceObject(asterixInstanceBytes);
+    }
+
+    public boolean exists(String asterixInstanceName) throws Exception {
+        return zk.exists(ASTERIX_INSTANCE_BASE_PATH + File.separator + asterixInstanceName, false) != null;
+    }
+
+    public void removeAsterixInstance(String name) throws Exception {
+        if (!exists(name)) {
+            throw new InstallerException("Asterix instance by name " + name + " does not exists.");
+        }
+        zk.delete(ASTERIX_INSTANCE_BASE_PATH + File.separator + name, DEFAULT_NODE_VERSION);
+    }
+
+    public List<AsterixInstance> getAsterixInstances() throws Exception {
+        List<String> instanceNames = zk.getChildren(ASTERIX_INSTANCE_BASE_PATH, false);
+        List<AsterixInstance> asterixInstances = new ArrayList<AsterixInstance>();
+        String path;
+        for (String instanceName : instanceNames) {
+            path = ASTERIX_INSTANCE_BASE_PATH + File.separator + instanceName;
+            byte[] asterixInstanceBytes = zk.getData(path, false, new Stat());
+            asterixInstances.add(readAsterixInstanceObject(asterixInstanceBytes));
+        }
+        return asterixInstances;
+    }
+
+    private AsterixInstance readAsterixInstanceObject(byte[] asterixInstanceBytes) throws IOException,
+            ClassNotFoundException {
+        ByteArrayInputStream b = new ByteArrayInputStream(asterixInstanceBytes);
+        ObjectInputStream ois = new ObjectInputStream(b);
+        return (AsterixInstance) ois.readObject();
+    }
+
+    public void updateAsterixInstance(AsterixInstance updatedInstance) throws Exception {
+        removeAsterixInstance(updatedInstance.getName());
+        writeAsterixInstance(updatedInstance);
+    }
+
+}
+
+class ZooKeeperWatcher implements Watcher {
+
+    private boolean isRunning = true;
+    private LinkedBlockingQueue<String> msgQ;
+
+    public ZooKeeperWatcher(LinkedBlockingQueue<String> msgQ) {
+        this.msgQ = msgQ;
+    }
+
+    public void process(WatchedEvent wEvent) {
+        switch (wEvent.getState()) {
+            case SyncConnected:
+                msgQ.add("connected");
+                break;
+        }
+    }
+
+    public boolean isRunning() {
+        return isRunning;
+    }
+
+}
+
+class ZookeeperUtil {
+
+    public static void writeConfiguration(String zooKeeperConfigPath, Configuration conf, int leaderConnPort,
+            int leaderElecPort) throws IOException {
+
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("tickTime=1000" + "\n");
+        buffer.append("dataDir=" + conf.getZookeeper().getHomeDir() + File.separator + "data" + "\n");
+        buffer.append("clientPort=" + conf.getZookeeper().getClientPort().intValue() + "\n");
+        buffer.append("initLimit=" + 2 + "\n");
+        buffer.append("syncLimit=" + 2 + "\n");
+
+        List<String> servers = conf.getZookeeper().getServers().getServer();
+        int serverId = 1;
+        for (String server : servers) {
+            buffer.append("server" + "." + serverId + "=" + server + ":" + leaderConnPort + ":" + leaderElecPort + "\n");
+            serverId++;
+        }
+        InstallerUtil.dumpToFile(zooKeeperConfigPath, buffer.toString());
+    }
+
+}
diff --git a/asterix-installer/src/main/resources/clusters/local/conf/asterix.conf b/asterix-installer/src/main/resources/clusters/local/conf/asterix.conf
new file mode 100644
index 0000000..659b48e
--- /dev/null
+++ b/asterix-installer/src/main/resources/clusters/local/conf/asterix.conf
@@ -0,0 +1 @@
+output_dir=/tmp/asterix_output/
diff --git a/asterix-installer/src/main/resources/clusters/local/local.xml b/asterix-installer/src/main/resources/clusters/local/local.xml
new file mode 100644
index 0000000..d397bcd
--- /dev/null
+++ b/asterix-installer/src/main/resources/clusters/local/local.xml
@@ -0,0 +1,21 @@
+<cluster xmlns="cluster">
+  <name>local</name>
+  <workingDir>
+    <dir>/tmp/asterix-installer</dir>
+    <NFS>true</NFS>
+  </workingDir>
+  <logdir>/tmp/asterix/logs</logdir>
+  <iodevices>/tmp</iodevices>
+  <store>asterix/storage</store>
+  <java_home></java_home>
+  <java_opts>-Xmx1024m</java_opts>
+  <master-node>
+    <id>master</id>
+    <client-ip>127.0.0.1</client-ip>
+    <cluster-ip>127.0.0.1</cluster-ip>
+  </master-node>
+  <node>
+    <id>node1</id>
+    <cluster-ip>127.0.0.1</cluster-ip>
+  </node>
+</cluster>
diff --git a/asterix-installer/src/main/resources/conf/log4j.properties b/asterix-installer/src/main/resources/conf/log4j.properties
new file mode 100644
index 0000000..fedf941
--- /dev/null
+++ b/asterix-installer/src/main/resources/conf/log4j.properties
@@ -0,0 +1,9 @@
+log4j.rootLogger=info, A1
+
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+# Print the date in ISO 8601 format
+log4j.appender.A1.layout.ConversionPattern=%-p: %m%n
+
+log4j.logger.edu.uci.ics.asterix.event.management=error
+log4j.logger.org.apache.zookeeper=error
diff --git a/asterix-installer/src/main/resources/conf/managix-conf.xml b/asterix-installer/src/main/resources/conf/managix-conf.xml
new file mode 100644
index 0000000..10a62a9
--- /dev/null
+++ b/asterix-installer/src/main/resources/conf/managix-conf.xml
@@ -0,0 +1,16 @@
+<configuration xmlns="installer">
+  <backup>
+    <hdfs>
+      <version>0.20.2</version>
+      <url></url>
+      <backupDir></backupDir>
+    </hdfs>
+  </backup>
+  <zookeeper>
+    <homeDir>/tmp/zookeeper</homeDir>
+    <clientPort>2900</clientPort>
+    <servers>
+      <server>127.0.0.1</server>
+    </servers>
+  </zookeeper>
+</configuration>
diff --git a/asterix-installer/src/main/resources/hadoop-0.20.2/bin/hadoop b/asterix-installer/src/main/resources/hadoop-0.20.2/bin/hadoop
new file mode 100755
index 0000000..683e95d
--- /dev/null
+++ b/asterix-installer/src/main/resources/hadoop-0.20.2/bin/hadoop
@@ -0,0 +1,290 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+
+# The Hadoop command script
+#
+# Environment Variables
+#
+#   JAVA_HOME        The java implementation to use.  Overrides JAVA_HOME.
+#
+#   HADOOP_CLASSPATH Extra Java CLASSPATH entries.
+#
+#   HADOOP_HEAPSIZE  The maximum amount of heap to use, in MB. 
+#                    Default is 1000.
+#
+#   HADOOP_OPTS      Extra Java runtime options.
+#   
+#   HADOOP_NAMENODE_OPTS       These options are added to HADOOP_OPTS 
+#   HADOOP_CLIENT_OPTS         when the respective command is run.
+#   HADOOP_{COMMAND}_OPTS etc  HADOOP_JT_OPTS applies to JobTracker 
+#                              for e.g.  HADOOP_CLIENT_OPTS applies to 
+#                              more than one command (fs, dfs, fsck, 
+#                              dfsadmin etc)  
+#
+#   HADOOP_CONF_DIR  Alternate conf dir. Default is ${HADOOP_HOME}/conf.
+#
+#   HADOOP_ROOT_LOGGER The root appender. Default is INFO,console
+#
+
+bin=`dirname "$0"`
+bin=`cd "$bin"; pwd`
+
+. "$bin"/hadoop-config.sh
+
+cygwin=false
+case "`uname`" in
+CYGWIN*) cygwin=true;;
+esac
+
+# if no args specified, show usage
+if [ $# = 0 ]; then
+  echo "Usage: hadoop [--config confdir] COMMAND"
+  echo "where COMMAND is one of:"
+  echo "  namenode -format     format the DFS filesystem"
+  echo "  secondarynamenode    run the DFS secondary namenode"
+  echo "  namenode             run the DFS namenode"
+  echo "  datanode             run a DFS datanode"
+  echo "  dfsadmin             run a DFS admin client"
+  echo "  mradmin              run a Map-Reduce admin client"
+  echo "  fsck                 run a DFS filesystem checking utility"
+  echo "  fs                   run a generic filesystem user client"
+  echo "  balancer             run a cluster balancing utility"
+  echo "  jobtracker           run the MapReduce job Tracker node" 
+  echo "  pipes                run a Pipes job"
+  echo "  tasktracker          run a MapReduce task Tracker node" 
+  echo "  job                  manipulate MapReduce jobs"
+  echo "  queue                get information regarding JobQueues" 
+  echo "  version              print the version"
+  echo "  jar <jar>            run a jar file"
+  echo "  distcp <srcurl> <desturl> copy file or directories recursively"
+  echo "  archive -archiveName NAME <src>* <dest> create a hadoop archive"
+  echo "  daemonlog            get/set the log level for each daemon"
+  echo " or"
+  echo "  CLASSNAME            run the class named CLASSNAME"
+  echo "Most commands print help when invoked w/o parameters."
+  exit 1
+fi
+
+# get arguments
+COMMAND=$1
+shift
+
+if [ -f "${HADOOP_CONF_DIR}/hadoop-env.sh" ]; then
+  . "${HADOOP_CONF_DIR}/hadoop-env.sh"
+fi
+
+# some Java parameters
+if [ "$JAVA_HOME" != "" ]; then
+  #echo "run java in $JAVA_HOME"
+  JAVA_HOME=$JAVA_HOME
+fi
+  
+if [ "$JAVA_HOME" = "" ]; then
+  echo "Error: JAVA_HOME is not set."
+  exit 1
+fi
+
+JAVA=$JAVA_HOME/bin/java
+JAVA_HEAP_MAX=-Xmx1000m 
+
+# check envvars which might override default args
+if [ "$HADOOP_HEAPSIZE" != "" ]; then
+  #echo "run with heapsize $HADOOP_HEAPSIZE"
+  JAVA_HEAP_MAX="-Xmx""$HADOOP_HEAPSIZE""m"
+  #echo $JAVA_HEAP_MAX
+fi
+
+# CLASSPATH initially contains $HADOOP_CONF_DIR
+CLASSPATH=${HADOOP_CONF_DIR}
+CLASSPATH=${CLASSPATH}:$JAVA_HOME/lib/tools.jar
+
+# for developers, add Hadoop classes to CLASSPATH
+if [ -d "$HADOOP_HOME/build/classes" ]; then
+  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build/classes
+fi
+if [ -d "$HADOOP_HOME/build/webapps" ]; then
+  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build
+fi
+if [ -d "$HADOOP_HOME/build/test/classes" ]; then
+  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build/test/classes
+fi
+if [ -d "$HADOOP_HOME/build/tools" ]; then
+  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build/tools
+fi
+
+# so that filenames w/ spaces are handled correctly in loops below
+IFS=
+
+# for releases, add core hadoop jar & webapps to CLASSPATH
+if [ -d "$HADOOP_HOME/webapps" ]; then
+  CLASSPATH=${CLASSPATH}:$HADOOP_HOME
+fi
+for f in $HADOOP_HOME/hadoop-*-core.jar; do
+  CLASSPATH=${CLASSPATH}:$f;
+done
+
+# add libs to CLASSPATH
+for f in $HADOOP_HOME/lib/*.jar; do
+  CLASSPATH=${CLASSPATH}:$f;
+done
+
+if [ -d "$HADOOP_HOME/build/ivy/lib/Hadoop/common" ]; then
+for f in $HADOOP_HOME/build/ivy/lib/Hadoop/common/*.jar; do
+  CLASSPATH=${CLASSPATH}:$f;
+done
+fi
+
+for f in $HADOOP_HOME/lib/jsp-2.1/*.jar; do
+  CLASSPATH=${CLASSPATH}:$f;
+done
+
+for f in $HADOOP_HOME/hadoop-*-tools.jar; do
+  TOOL_PATH=${TOOL_PATH}:$f;
+done
+for f in $HADOOP_HOME/build/hadoop-*-tools.jar; do
+  TOOL_PATH=${TOOL_PATH}:$f;
+done
+
+# add user-specified CLASSPATH last
+if [ "$HADOOP_CLASSPATH" != "" ]; then
+  CLASSPATH=${HADOOP_CLASSPATH}:${CLASSPATH}
+fi
+
+# default log directory & file
+if [ "$HADOOP_LOG_DIR" = "" ]; then
+  HADOOP_LOG_DIR="$HADOOP_HOME/logs"
+fi
+if [ "$HADOOP_LOGFILE" = "" ]; then
+  HADOOP_LOGFILE='hadoop.log'
+fi
+
+# default policy file for service-level authorization
+if [ "$HADOOP_POLICYFILE" = "" ]; then
+  HADOOP_POLICYFILE="hadoop-policy.xml"
+fi
+
+# restore ordinary behaviour
+unset IFS
+
+# figure out which class to run
+if [ "$COMMAND" = "namenode" ] ; then
+  CLASS='org.apache.hadoop.hdfs.server.namenode.NameNode'
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_NAMENODE_OPTS"
+elif [ "$COMMAND" = "secondarynamenode" ] ; then
+  CLASS='org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode'
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_SECONDARYNAMENODE_OPTS"
+elif [ "$COMMAND" = "datanode" ] ; then
+  CLASS='org.apache.hadoop.hdfs.server.datanode.DataNode'
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_DATANODE_OPTS"
+elif [ "$COMMAND" = "fs" ] ; then
+  CLASS=org.apache.hadoop.fs.FsShell
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "dfs" ] ; then
+  CLASS=org.apache.hadoop.fs.FsShell
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "dfsadmin" ] ; then
+  CLASS=org.apache.hadoop.hdfs.tools.DFSAdmin
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "mradmin" ] ; then
+  CLASS=org.apache.hadoop.mapred.tools.MRAdmin
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "fsck" ] ; then
+  CLASS=org.apache.hadoop.hdfs.tools.DFSck
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "balancer" ] ; then
+  CLASS=org.apache.hadoop.hdfs.server.balancer.Balancer
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_BALANCER_OPTS"
+elif [ "$COMMAND" = "jobtracker" ] ; then
+  CLASS=org.apache.hadoop.mapred.JobTracker
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_JOBTRACKER_OPTS"
+elif [ "$COMMAND" = "tasktracker" ] ; then
+  CLASS=org.apache.hadoop.mapred.TaskTracker
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_TASKTRACKER_OPTS"
+elif [ "$COMMAND" = "job" ] ; then
+  CLASS=org.apache.hadoop.mapred.JobClient
+elif [ "$COMMAND" = "queue" ] ; then
+  CLASS=org.apache.hadoop.mapred.JobQueueClient
+elif [ "$COMMAND" = "pipes" ] ; then
+  CLASS=org.apache.hadoop.mapred.pipes.Submitter
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "version" ] ; then
+  CLASS=org.apache.hadoop.util.VersionInfo
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "jar" ] ; then
+  CLASS=org.apache.hadoop.util.RunJar
+elif [ "$COMMAND" = "distcp" ] ; then
+  CLASS=org.apache.hadoop.tools.DistCp
+  CLASSPATH=${CLASSPATH}:${TOOL_PATH}
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "daemonlog" ] ; then
+  CLASS=org.apache.hadoop.log.LogLevel
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "archive" ] ; then
+  CLASS=org.apache.hadoop.tools.HadoopArchives
+  CLASSPATH=${CLASSPATH}:${TOOL_PATH}
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+elif [ "$COMMAND" = "sampler" ] ; then
+  CLASS=org.apache.hadoop.mapred.lib.InputSampler
+  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
+else
+  CLASS=$COMMAND
+fi
+
+# cygwin path translation
+if $cygwin; then
+  CLASSPATH=`cygpath -p -w "$CLASSPATH"`
+  HADOOP_HOME=`cygpath -w "$HADOOP_HOME"`
+  HADOOP_LOG_DIR=`cygpath -w "$HADOOP_LOG_DIR"`
+  TOOL_PATH=`cygpath -p -w "$TOOL_PATH"`
+fi
+# setup 'java.library.path' for native-hadoop code if necessary
+JAVA_LIBRARY_PATH=''
+if [ -d "${HADOOP_HOME}/build/native" -o -d "${HADOOP_HOME}/lib/native" ]; then
+  JAVA_PLATFORM=`CLASSPATH=${CLASSPATH} ${JAVA} -Xmx32m org.apache.hadoop.util.PlatformName | sed -e "s/ /_/g"`
+  
+  if [ -d "$HADOOP_HOME/build/native" ]; then
+    JAVA_LIBRARY_PATH=${HADOOP_HOME}/build/native/${JAVA_PLATFORM}/lib
+  fi
+  
+  if [ -d "${HADOOP_HOME}/lib/native" ]; then
+    if [ "x$JAVA_LIBRARY_PATH" != "x" ]; then
+      JAVA_LIBRARY_PATH=${JAVA_LIBRARY_PATH}:${HADOOP_HOME}/lib/native/${JAVA_PLATFORM}
+    else
+      JAVA_LIBRARY_PATH=${HADOOP_HOME}/lib/native/${JAVA_PLATFORM}
+    fi
+  fi
+fi
+
+# cygwin path translation
+if $cygwin; then
+  JAVA_LIBRARY_PATH=`cygpath -p "$JAVA_LIBRARY_PATH"`
+fi
+
+HADOOP_OPTS="$HADOOP_OPTS -Dhadoop.log.dir=$HADOOP_LOG_DIR"
+HADOOP_OPTS="$HADOOP_OPTS -Dhadoop.log.file=$HADOOP_LOGFILE"
+HADOOP_OPTS="$HADOOP_OPTS -Dhadoop.home.dir=$HADOOP_HOME"
+HADOOP_OPTS="$HADOOP_OPTS -Dhadoop.id.str=$HADOOP_IDENT_STRING"
+HADOOP_OPTS="$HADOOP_OPTS -Dhadoop.root.logger=${HADOOP_ROOT_LOGGER:-INFO,console}"
+if [ "x$JAVA_LIBRARY_PATH" != "x" ]; then
+  HADOOP_OPTS="$HADOOP_OPTS -Djava.library.path=$JAVA_LIBRARY_PATH"
+fi  
+HADOOP_OPTS="$HADOOP_OPTS -Dhadoop.policy.file=$HADOOP_POLICYFILE"
+
+# run it
+#echo "exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS -classpath "$CLASSPATH" $CLASS "$@""
+exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS -classpath "$CLASSPATH" $CLASS "$@"
diff --git a/asterix-installer/src/main/resources/hadoop-0.20.2/bin/hadoop-config.sh b/asterix-installer/src/main/resources/hadoop-0.20.2/bin/hadoop-config.sh
new file mode 100755
index 0000000..1f9d52d
--- /dev/null
+++ b/asterix-installer/src/main/resources/hadoop-0.20.2/bin/hadoop-config.sh
@@ -0,0 +1,68 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+
+# included in all the hadoop scripts with source command
+# should not be executable directly
+# also should not be passed any arguments, since we need original $*
+
+# resolve links - $0 may be a softlink
+
+this="$0"
+while [ -h "$this" ]; do
+  ls=`ls -ld "$this"`
+  link=`expr "$ls" : '.*-> \(.*\)$'`
+  if expr "$link" : '.*/.*' > /dev/null; then
+    this="$link"
+  else
+    this=`dirname "$this"`/"$link"
+  fi
+done
+
+# convert relative path to absolute path
+bin=`dirname "$this"`
+script=`basename "$this"`
+bin=`cd "$bin"; pwd`
+this="$bin/$script"
+
+# the root of the Hadoop installation
+export HADOOP_HOME=`dirname "$this"`/..
+
+#check to see if the conf dir is given as an optional argument
+if [ $# -gt 1 ]
+then
+    if [ "--config" = "$1" ]
+	  then
+	      shift
+	      confdir=$1
+	      shift
+	      HADOOP_CONF_DIR=$confdir
+    fi
+fi
+ 
+# Allow alternate conf dir location.
+HADOOP_CONF_DIR="${HADOOP_CONF_DIR:-$HADOOP_HOME/conf}"
+
+#check to see it is specified whether to use the slaves or the
+# masters file
+if [ $# -gt 1 ]
+then
+    if [ "--hosts" = "$1" ]
+    then
+        shift
+        slavesfile=$1
+        shift
+        export HADOOP_SLAVES="${HADOOP_CONF_DIR}/$slavesfile"
+    fi
+fi
diff --git a/asterix-installer/src/main/resources/hadoop-0.20.2/conf/hadoop-env.sh b/asterix-installer/src/main/resources/hadoop-0.20.2/conf/hadoop-env.sh
new file mode 100644
index 0000000..e9396a4
--- /dev/null
+++ b/asterix-installer/src/main/resources/hadoop-0.20.2/conf/hadoop-env.sh
@@ -0,0 +1,54 @@
+# Set Hadoop-specific environment variables here.
+
+# The only required environment variable is JAVA_HOME.  All others are
+# optional.  When running a distributed configuration it is best to
+# set JAVA_HOME in this file, so that it is correctly defined on
+# remote nodes.
+
+# The java implementation to use.  Required.
+# export JAVA_HOME=$JAVA_HOME
+
+# Extra Java CLASSPATH elements.  Optional.
+# export HADOOP_CLASSPATH=
+
+# The maximum amount of heap to use, in MB. Default is 1000.
+# export HADOOP_HEAPSIZE=2000
+
+# Extra Java runtime options.  Empty by default.
+# export HADOOP_OPTS=-server
+
+# Command specific options appended to HADOOP_OPTS when specified
+export HADOOP_NAMENODE_OPTS="-Dcom.sun.management.jmxremote $HADOOP_NAMENODE_OPTS"
+export HADOOP_SECONDARYNAMENODE_OPTS="-Dcom.sun.management.jmxremote $HADOOP_SECONDARYNAMENODE_OPTS"
+export HADOOP_DATANODE_OPTS="-Dcom.sun.management.jmxremote $HADOOP_DATANODE_OPTS"
+export HADOOP_BALANCER_OPTS="-Dcom.sun.management.jmxremote $HADOOP_BALANCER_OPTS"
+export HADOOP_JOBTRACKER_OPTS="-Dcom.sun.management.jmxremote $HADOOP_JOBTRACKER_OPTS"
+# export HADOOP_TASKTRACKER_OPTS=
+# The following applies to multiple commands (fs, dfs, fsck, distcp etc)
+# export HADOOP_CLIENT_OPTS
+
+# Extra ssh options.  Empty by default.
+# export HADOOP_SSH_OPTS="-o ConnectTimeout=1 -o SendEnv=HADOOP_CONF_DIR"
+
+# Where log files are stored.  $HADOOP_HOME/logs by default.
+# export HADOOP_LOG_DIR=${HADOOP_HOME}/logs
+
+# File naming remote slave hosts.  $HADOOP_HOME/conf/slaves by default.
+# export HADOOP_SLAVES=${HADOOP_HOME}/conf/slaves
+
+# host:path where hadoop code should be rsync'd from.  Unset by default.
+# export HADOOP_MASTER=master:/home/$USER/src/hadoop
+
+# Seconds to sleep between slave commands.  Unset by default.  This
+# can be useful in large clusters, where, e.g., slave rsyncs can
+# otherwise arrive faster than the master can service them.
+# export HADOOP_SLAVE_SLEEP=0.1
+
+# The directory where pid files are stored. /tmp by default.
+# export HADOOP_PID_DIR=/var/hadoop/pids
+
+# A string representing this instance of hadoop. $USER by default.
+# export HADOOP_IDENT_STRING=$USER
+
+# The scheduling priority for daemon processes.  See 'man nice'.
+# export HADOOP_NICENESS=10
diff --git a/asterix-installer/src/main/resources/schema/installer-conf.xsd b/asterix-installer/src/main/resources/schema/installer-conf.xsd
new file mode 100644
index 0000000..c21fc5b
--- /dev/null
+++ b/asterix-installer/src/main/resources/schema/installer-conf.xsd
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mg="installer" targetNamespace="installer" elementFormDefault="qualified">
+
+<!-- definition of simple types --> 
+<xs:element name="asterix_home" type="xs:string"/>
+<xs:element name="hyracks_home" type="xs:string"/>
+<xs:element name="hdfsurl" type="xs:string"/>
+<xs:element name="server" type="xs:string"/>
+<xs:element name="clientPort" type="xs:integer"/>
+<xs:element name="homeDir" type="xs:string"/>
+<xs:element name="version" type="xs:string"/>
+<xs:element name="url" type="xs:string"/>
+<xs:element name="backupDir" type="xs:string"/>
+<xs:element name="java_home" type="xs:string"/>
+
+<!-- definition of complex elements -->
+<xs:element name="hdfs">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="mg:version"/>
+      <xs:element ref="mg:url"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="backup">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="mg:hdfs" minOccurs="0"/> 
+      <xs:element ref="mg:backupDir"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="zookeeper">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="mg:homeDir"/>
+      <xs:element ref="mg:clientPort"/>
+      <xs:element ref="mg:servers"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="servers">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="mg:java_home"/>
+      <xs:element ref="mg:server" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="configuration">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="mg:backup" minOccurs="0"/>
+      <xs:element ref="mg:asterix_home" minOccurs="0"/>
+      <xs:element ref="mg:hyracks_home" minOccurs="0"/>
+      <xs:element ref="mg:hdfsurl" minOccurs="0"/>
+      <xs:element ref="mg:zookeeper"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+</xs:schema>     
diff --git a/asterix-installer/src/main/resources/schema/jaxb-bindings.xjb b/asterix-installer/src/main/resources/schema/jaxb-bindings.xjb
new file mode 100644
index 0000000..b5982e0
--- /dev/null
+++ b/asterix-installer/src/main/resources/schema/jaxb-bindings.xjb
@@ -0,0 +1,9 @@
+<jxb:bindings version="1.0"
+xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
+xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<jxb:globalBindings>
+  <jxb:serializable uid="1"/>
+</jxb:globalBindings>
+
+</jxb:bindings>
diff --git a/asterix-installer/src/main/resources/scripts/managix b/asterix-installer/src/main/resources/scripts/managix
new file mode 100755
index 0000000..cd0794e
--- /dev/null
+++ b/asterix-installer/src/main/resources/scripts/managix
@@ -0,0 +1,20 @@
+if [ -z $MANAGIX_HOME ] 
+ then
+   echo "MANAGIX_HOME is not defined"
+   exit 1
+fi
+
+VERSION=0.0.4-SNAPSHOT
+
+for jar in `ls $MANAGIX_HOME/lib/*.jar`
+  do 
+  if [ -z $MANAGIX_CLASSPATH ] 
+  then 
+    MANAGIX_CLASSPATH=$jar 
+  else
+    MANAGIX_CLASSPATH=$MANAGIX_CLASSPATH:$jar 
+  fi
+done
+
+MANAGIX_CLASSPATH=$MANAGIX_CLASSPATH:$MANAGIX_HOME/conf/log4j.properties
+java $JAVA_OPTS -Dlog4j.configuration=file:$MANAGIX_HOME/conf/log4j.properties -cp $MANAGIX_CLASSPATH edu.uci.ics.asterix.installer.driver.InstallerDriver $@
diff --git a/asterix-installer/src/main/resources/scripts/verify.sh b/asterix-installer/src/main/resources/scripts/verify.sh
new file mode 100755
index 0000000..cac8189
--- /dev/null
+++ b/asterix-installer/src/main/resources/scripts/verify.sh
@@ -0,0 +1,21 @@
+INSTANCE_NAME=$1
+MASTER_NODE=$2
+shift 2
+numargs=$#
+for ((i=1 ; i <= numargs ; i=i+2))
+do
+ host=$1
+ nc_id=$2
+ INFO=$(ssh $host "ps -ef | grep nc_join | grep -v grep | grep -v ssh| grep $nc_id" | head -n 1 )
+ PARENT_ID=`echo  $INFO | cut -d " "  -f2`
+ PID_INFO=$(ssh $host "ps -ef |  grep asterix | grep -v grep | grep -v nc_join |  grep $PARENT_ID") 
+ PID=`echo $PID_INFO | cut -d " " -f2`
+ echo "NC:$host:$nc_id:$PID"
+ shift 2
+done
+
+CC_PARENT_ID_INFO=$(ssh $MASTER_NODE "ps -ef  | grep asterix | grep cc_start | grep -v ssh")
+CC_PARENT_ID=`echo $CC_PARENT_ID_INFO | tr -s " " | cut -d " " -f2` 
+CC_ID_INFO=$(ssh $MASTER_NODE "ps -ef | grep asterix | grep $CC_PARENT_ID | grep -v bash")
+CC_ID=`echo $CC_ID_INFO |  tr -s " " | cut -d " " -f2`
+echo "CC:$MASTER_NODE:N/A:$CC_ID"
diff --git a/asterix-installer/src/main/resources/zookeeper/start_zk.sh b/asterix-installer/src/main/resources/zookeeper/start_zk.sh
new file mode 100755
index 0000000..68ced54
--- /dev/null
+++ b/asterix-installer/src/main/resources/zookeeper/start_zk.sh
@@ -0,0 +1,9 @@
+ZK_HOME=$1
+ZK_ID=$2
+JAVA_HOME=$3
+mkdir $ZK_HOME/data
+echo $2 > $ZK_HOME/data/myid
+CLASSPATH=$ZK_HOME/lib/zookeeper-3.4.5.jar:$ZK_HOME/lib/log4j-1.2.15.jar:$ZK_HOME/lib/slf4j-api-1.6.1.jar:$ZK_HOME/conf:$ZK_HOME/conf/log4j.properties
+ZK_CONF=$ZK_HOME/zk.cfg
+export JAVA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8400,server=y,suspend=n"
+$JAVA_HOME/bin/java $JAVA_OPTS -Dlog4j.configuration="file:$ZK_HOME/conf/log4j.properties" -cp $CLASSPATH org.apache.zookeeper.server.quorum.QuorumPeerMain $ZK_CONF
diff --git a/asterix-installer/src/main/resources/zookeeper/stop_zk b/asterix-installer/src/main/resources/zookeeper/stop_zk
new file mode 100755
index 0000000..9bef86e
--- /dev/null
+++ b/asterix-installer/src/main/resources/zookeeper/stop_zk
@@ -0,0 +1,6 @@
+ZK_HOME=$1
+shift 1
+for zk_host in  $@
+do
+  ssh $zk_host "kill -15 `jps | grep QuorumPeerMain | cut -d " "  -f1`" &
+done
diff --git a/asterix-installer/src/main/resources/zookeeper/zk.init b/asterix-installer/src/main/resources/zookeeper/zk.init
new file mode 100755
index 0000000..8ef6f5f
--- /dev/null
+++ b/asterix-installer/src/main/resources/zookeeper/zk.init
@@ -0,0 +1,14 @@
+ZK_HOME=$1
+SERVER_JAVA_HOME=$2
+shift 2
+cd $MANAGIX_HOME/.installer/zookeeper
+tar cf zk.pkg.tar *
+zk_server_id=1
+for zk_host in  $@
+do
+  ssh $zk_host "mkdir -p $ZK_HOME"
+  scp ./zk.pkg.tar $zk_host:$ZK_HOME/
+  ssh $zk_host "cd $ZK_HOME && tar xf $ZK_HOME/zk.pkg.tar && chmod +x $ZK_HOME/bin/start_zk.sh"
+  ssh $zk_host "$ZK_HOME/bin/start_zk.sh $ZK_HOME $zk_server_id $SERVER_JAVA_HOME" &
+  zk_server_id=`expr $zk_server_id + 1`	
+done