Added source for asterix installer and event execution framework as modules under the asterix source tree

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_installer@1202 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-events/pom.xml b/asterix-events/pom.xml
new file mode 100644
index 0000000..a9aeaa5
--- /dev/null
+++ b/asterix-events/pom.xml
@@ -0,0 +1,156 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+          <artifactId>asterix</artifactId>
+          <groupId>edu.uci.ics.asterix</groupId>
+          <version>0.0.4-SNAPSHOT</version>
+  </parent>
+  <groupId>edu.uci.ics.asterix</groupId>
+  <artifactId>asterix-events</artifactId>
+  <version>0.0.4-SNAPSHOT</version>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+       <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>2.0.2</version>
+          <configuration>
+             <source>1.6</source>
+             <target>1.6</target>
+          </configuration>
+       </plugin>
+       <plugin>
+          <groupId>org.jvnet.jaxb2.maven2</groupId>
+          <artifactId>maven-jaxb2-plugin</artifactId>
+          <executions>
+            <execution>
+              <id>event</id>
+              <goals>
+                <goal>generate</goal>
+              </goals>
+              <configuration>
+                <args>
+                  <arg>-Xsetters</arg>
+                  <arg>-Xvalue-constructor</arg>
+                </args>
+                <plugins>
+                  <plugin>
+                    <groupId>org.jvnet.jaxb2_commons</groupId>
+                    <artifactId>jaxb2-basics</artifactId>
+                    <version>0.6.2</version>
+                  </plugin>
+                  <plugin>
+                    <groupId>org.jvnet.jaxb2_commons</groupId>
+                    <artifactId>jaxb2-value-constructor</artifactId>
+                    <version>3.0</version>
+                  </plugin>
+                </plugins>
+                <schemaDirectory>src/main/resources/schema</schemaDirectory>
+                <schemaIncludes>
+	          <include>event.xsd</include>
+	        </schemaIncludes>
+                <generatePackage>edu.uci.ics.asterix.event.schema.event</generatePackage>
+                <generateDirectory>${project.build.directory}/generated-sources/event</generateDirectory>
+              </configuration>
+            </execution>
+            <execution>
+              <id>pattern</id>
+              <goals>
+                <goal>generate</goal>
+              </goals>
+              <configuration>
+                <args>
+                  <arg>-Xsetters</arg>
+                  <arg>-Xvalue-constructor</arg>
+                </args>
+                <plugins>
+                  <plugin>
+                    <groupId>org.jvnet.jaxb2_commons</groupId>
+                    <artifactId>jaxb2-basics</artifactId>
+                    <version>0.6.2</version>
+                  </plugin>
+                  <plugin>
+                    <groupId>org.jvnet.jaxb2_commons</groupId>
+                    <artifactId>jaxb2-value-constructor</artifactId>
+                    <version>3.0</version>
+                  </plugin>
+                </plugins>
+                <schemaDirectory>src/main/resources/schema</schemaDirectory>
+                <schemaIncludes>
+	          <include>pattern.xsd</include>
+	        </schemaIncludes>
+                <generatePackage>edu.uci.ics.asterix.event.schema.pattern</generatePackage>
+                <generateDirectory>${project.build.directory}/generated-sources/pattern</generateDirectory>
+              </configuration>
+            </execution>
+            <execution>
+              <id>cluster</id>
+              <goals>
+                <goal>generate</goal>
+              </goals>
+              <configuration>
+                <args>
+                  <arg>-Xsetters</arg>
+                  <arg>-Xvalue-constructor</arg>
+                </args>
+                <plugins>
+                  <plugin>
+                    <groupId>org.jvnet.jaxb2_commons</groupId>
+                    <artifactId>jaxb2-basics</artifactId>
+                    <version>0.6.2</version>
+                  </plugin>
+                  <plugin>
+                    <groupId>org.jvnet.jaxb2_commons</groupId>
+                    <artifactId>jaxb2-value-constructor</artifactId>
+                    <version>3.0</version>
+                  </plugin>
+                </plugins>
+                <schemaDirectory>src/main/resources/schema</schemaDirectory>
+                <schemaIncludes>
+	          <include>cluster.xsd</include>
+	        </schemaIncludes>
+                <generatePackage>edu.uci.ics.asterix.event.schema.cluster</generatePackage>
+                <generateDirectory>${project.build.directory}/generated-sources/cluster</generateDirectory>
+                <bindingDirectory>src/main/resources/schema</bindingDirectory>
+                <bindingIncludes>
+                  <bindingInclude>jaxb-bindings.xjb</bindingInclude>
+                </bindingIncludes>
+              </configuration>
+            </execution>
+          </executions>
+       </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>args4j</groupId>
+      <artifactId>args4j</artifactId>
+      <version>2.0.12</version>
+      <type>jar</type>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jvnet.jaxb2_commons</groupId>
+      <artifactId>jaxb2-value-constructor</artifactId>
+      <version>3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>1.4</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/ClusterInfo.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/ClusterInfo.java
new file mode 100644
index 0000000..630f9b3
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/ClusterInfo.java
@@ -0,0 +1,26 @@
+/*
+ * 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.event.api;
+
+import java.util.List;
+
+public class ClusterInfo {
+
+	List<NodeInfo> nodes;
+
+	public ClusterInfo(List<NodeInfo> nodes) {
+		this.nodes = nodes;
+	}
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/NodeInfo.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/NodeInfo.java
new file mode 100644
index 0000000..835e0dc
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/api/NodeInfo.java
@@ -0,0 +1,34 @@
+/*
+ * 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.event.api;
+
+public class NodeInfo {
+
+	private final String id;
+	private final String ip;
+
+	public NodeInfo(String id, String ip) {
+		this.id = id;
+		this.ip = ip;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getIp() {
+		return ip;
+	}
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventConfig.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventConfig.java
new file mode 100644
index 0000000..9d0138b
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventConfig.java
@@ -0,0 +1,36 @@
+/*
+ * 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.event.driver;
+
+import org.kohsuke.args4j.Option;
+
+public class EventConfig {
+
+	@Option(name = "-h", required = false, usage = "Help")
+	public boolean help = false;
+
+	@Option(name = "-d", required = false, usage = "Show the execution on a timeline")
+	public boolean dryRun = false;
+
+	@Option(name = "-s", required = false, usage = "Seed for randomization")
+	public int seed = -1;
+
+	@Option(name = "-c", required = true, usage = "Path to cluster configuration (REQUIRED)")
+	public String clusterPath;
+
+	@Option(name = "-p", required = true, usage = "Path to pattern configuration (REQUIRED)")
+	public String patternPath;
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventDriver.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventDriver.java
new file mode 100644
index 0000000..379d811
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/driver/EventDriver.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.event.driver;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.kohsuke.args4j.CmdLineParser;
+
+import edu.uci.ics.asterix.event.management.DefaultOutputHandler;
+import edu.uci.ics.asterix.event.management.EventUtil;
+import edu.uci.ics.asterix.event.management.EventrixClient;
+import edu.uci.ics.asterix.event.management.IOutputHandler;
+import edu.uci.ics.asterix.event.management.Randomizer;
+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.cluster.Property;
+import edu.uci.ics.asterix.event.schema.event.Events;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+
+public class EventDriver {
+
+    public static final String CLIENT_NODE_ID = "client_node";
+    public static final Node CLIENT_NODE = new Node(CLIENT_NODE_ID, "127.0.0.1", null, null, null);
+
+    private static final Logger LOGGER = Logger.getLogger(EventDriver.class.getName());
+
+    private static String homeDir;
+    private static Events events;
+    private static Map<String, String> env = new HashMap<String, String>();
+    private static String scriptDirSuffix;
+
+    public static String getHomeDir() {
+        return homeDir;
+    }
+
+    public static void setHomeDir(String homeDir) {
+        EventDriver.homeDir = homeDir;
+    }
+
+    public static Events getEvents() {
+        return events;
+    }
+
+    public static void setEvents(Events events) {
+        EventDriver.events = events;
+    }
+
+    public static Map<String, String> getEnvironment() {
+        return env;
+    }
+
+    public static String getStringifiedEnv(Cluster cluster) {
+        StringBuffer buffer = new StringBuffer();
+        for (Property p : cluster.getEnv().getProperty()) {
+            buffer.append(p.getKey() + "=" + p.getValue() + " ");
+        }
+        return buffer.toString();
+    }
+
+    public static void initializeEvents(String path) throws IOException {
+        try {
+            File eventsFile = new File(path);
+            JAXBContext ctx = JAXBContext.newInstance(Events.class);
+            Unmarshaller unmarshaller = ctx.createUnmarshaller();
+            events = (Events) unmarshaller.unmarshal(eventsFile);
+        } catch (JAXBException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static Cluster initializeCluster(String path) throws JAXBException, IOException {
+        File file = new File(path);
+        JAXBContext ctx = JAXBContext.newInstance(Cluster.class);
+        Unmarshaller unmarshaller = ctx.createUnmarshaller();
+        Cluster cluster = (Cluster) unmarshaller.unmarshal(file);
+        for (Property p : cluster.getEnv().getProperty()) {
+            env.put(p.getKey(), p.getValue());
+        }
+        return cluster;
+    }
+
+    public static Patterns initializePatterns(String path) throws JAXBException, IOException {
+        File file = new File(path);
+        JAXBContext ctx = JAXBContext.newInstance(Patterns.class);
+        Unmarshaller unmarshaller = ctx.createUnmarshaller();
+        return (Patterns) unmarshaller.unmarshal(file);
+    }
+
+    private static void initialize(EventConfig eventConfig) throws IOException, JAXBException {
+        homeDir = System.getenv("EVENT_HOME");
+        if (homeDir == null) {
+            throw new IllegalStateException("EVENT_HOME is not set");
+        }
+        initializeEvents(homeDir + "/" + EventUtil.EVENTS_DIR + "/" + "events.xml");
+    }
+
+    public static EventrixClient getClient(Cluster cluster, boolean dryRun) throws Exception {
+        return new EventrixClient(cluster, dryRun, new DefaultOutputHandler());
+    }
+
+    public static EventrixClient getClient(Cluster cluster, boolean dryRun, IOutputHandler outputHandler)
+            throws Exception {
+        return new EventrixClient(cluster, dryRun, outputHandler);
+    }
+
+    public static void main(String[] args) throws Exception {
+        EventConfig eventConfig = new EventConfig();
+        CmdLineParser parser = new CmdLineParser(eventConfig);
+        try {
+            parser.parseArgument(args);
+            if (eventConfig.help) {
+                parser.printUsage(System.out);
+            }
+            if (eventConfig.seed > 0) {
+                Randomizer.getInstance(eventConfig.seed);
+            }
+            Cluster cluster = initializeCluster(eventConfig.clusterPath);
+            Patterns patterns = initializePatterns(eventConfig.patternPath);
+
+            initialize(eventConfig);
+            if (!eventConfig.dryRun) {
+                prepare(cluster);
+            }
+            EventrixClient client = new EventrixClient(cluster, eventConfig.dryRun, new DefaultOutputHandler());
+            client.submit(patterns);
+            if (!eventConfig.dryRun) {
+                cleanup(cluster);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            parser.printUsage(System.err);
+        }
+    }
+
+    private static void prepare(Cluster cluster) throws IOException, InterruptedException {
+
+        scriptDirSuffix = "" + System.nanoTime();
+        List<String> args = new ArrayList<String>();
+        args.add(scriptDirSuffix);
+        Node clientNode = new Node();
+        clientNode.setId("client");
+        clientNode.setIp("127.0.0.1");
+        for (Node node : cluster.getNode()) {
+            args.add(node.getIp());
+        }
+        EventUtil.executeLocalScript(clientNode, homeDir + "/" + "events" + "/" + "prepare.sh", args);
+    }
+
+    private static void cleanup(Cluster cluster) throws IOException, InterruptedException {
+        List<String> args = new ArrayList<String>();
+        args.add(scriptDirSuffix);
+        Node clientNode = new Node();
+        clientNode.setId("client");
+        clientNode.setIp("127.0.0.1");
+        for (Node node : cluster.getNode()) {
+            args.add(node.getIp());
+        }
+        EventUtil.executeLocalScript(clientNode, homeDir + "/" + "events" + "/" + "cleanup.sh", args);
+    }
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/DefaultOutputHandler.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/DefaultOutputHandler.java
new file mode 100644
index 0000000..e8f06a0
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/DefaultOutputHandler.java
@@ -0,0 +1,26 @@
+/*
+ * 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.event.management;
+
+import edu.uci.ics.asterix.event.schema.pattern.Event;
+
+public class DefaultOutputHandler implements IOutputHandler {
+
+    @Override
+    public OutputAnalysis reportEventOutput(Event event, String output) {
+        return new OutputAnalysis(true, null);
+    }
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ErrorHandler.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ErrorHandler.java
new file mode 100644
index 0000000..a6c038b
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ErrorHandler.java
@@ -0,0 +1,19 @@
+/*
+ * 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.event.management;
+
+public class ErrorHandler {
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventExecutor.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventExecutor.java
new file mode 100644
index 0000000..869edd7
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventExecutor.java
@@ -0,0 +1,77 @@
+/*
+ * 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.event.management;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+
+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.Pattern;
+
+public class EventExecutor {
+
+    public static final String EVENTS_DIR = "events";
+    private static final String EXECUTE_SCRIPT = "execute.sh";
+    private static final String IP_LOCATION = "IP_LOCATION";
+    private static final String CLUSTER_ENV = "ENV";
+    private static final String SCRIPT = "SCRIPT";
+    private static final String ARGS = "ARGS";
+    private static final String DAEMON = "DAEMON";
+
+    public void executeEvent(Node node, String script, List<String> args, boolean isDaemon, Cluster cluster,
+            Pattern pattern, IOutputHandler outputHandler) throws IOException {
+        List<String> pargs = new ArrayList<String>();
+        pargs.add("/bin/bash");
+        pargs.add(EventDriver.getHomeDir() + File.separator + "events.pkg" + File.separator + EXECUTE_SCRIPT);
+        StringBuffer argBuffer = new StringBuffer();
+        StringBuffer envBuffer = new StringBuffer(IP_LOCATION + "=" + node.getIp());
+        if (!node.getId().equals(EventDriver.CLIENT_NODE_ID)) {
+            envBuffer.append(" " + EventDriver.getStringifiedEnv(cluster));
+            pargs.add(cluster.getUsername() == null ? System.getProperty("user.name") : cluster.getUsername());
+        }
+        if (args != null && args.size() > 0) {
+            for (String arg : args) {
+                argBuffer.append(arg + " ");
+            }
+        }
+        ProcessBuilder pb = new ProcessBuilder(pargs);
+        pb.environment().putAll(EventDriver.getEnvironment());
+        pb.environment().put(IP_LOCATION, node.getIp());
+        pb.environment().put(CLUSTER_ENV, envBuffer.toString());
+        pb.environment().put(SCRIPT, script);
+        pb.environment().put(ARGS, argBuffer.toString());
+        pb.environment().put(DAEMON, isDaemon ? "true" : "false");
+
+        Process p = pb.start();
+        if (!isDaemon) {
+            BufferedInputStream bis = new BufferedInputStream(p.getInputStream());
+            StringWriter writer = new StringWriter();
+            IOUtils.copy(bis, writer, "UTF-8");
+            String result = writer.getBuffer().toString();
+            OutputAnalysis analysis = outputHandler.reportEventOutput(pattern.getEvent(), result);
+            if (!analysis.isExpected()) {
+                throw new IOException(analysis.getErrorMessage());
+            }
+        }
+    }
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTask.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTask.java
new file mode 100644
index 0000000..aac2604
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTask.java
@@ -0,0 +1,155 @@
+/*
+ * 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.event.management;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+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.Period;
+
+public class EventTask extends TimerTask {
+
+    public static enum State {
+        INITIALIZED,
+        IN_PROGRESS,
+        COMPLETED,
+        FAILED
+    }
+
+    private static final Logger logger = Logger.getLogger(EventTask.class.getName());
+
+    private Pattern pattern;
+    private long interval = 0;
+    private long initialDelay = 0;
+    private int maxOccurs = Integer.MAX_VALUE;
+    private int occurrenceCount = 0;
+    private Timer timer;
+    private String taskScript;
+    private Node location;
+    private List<String> taskArgs;
+    private EventrixClient scheduler;
+    private List<Node> candidateLocations;
+    private boolean dynamicLocation = false;
+    private boolean reuseLocation = false;
+    private State state;
+
+    static {
+        logger.setLevel(Level.WARNING);
+    }
+
+    public EventTask(Pattern pattern, EventrixClient client) {
+        this.pattern = pattern;
+        this.scheduler = client;
+        Period period = pattern.getPeriod();
+        if (period != null && period.getAbsvalue() != null) {
+            this.interval = EventUtil.parseTimeInterval(period.getAbsvalue(), period.getUnit());
+        }
+        if (pattern.getDelay() != null) {
+            this.initialDelay = EventUtil.parseTimeInterval(new ValueType(pattern.getDelay().getValue()), pattern
+                    .getDelay().getUnit());
+        }
+        if (pattern.getMaxOccurs() != null) {
+            this.maxOccurs = pattern.getMaxOccurs();
+        }
+        this.timer = new Timer();
+        taskArgs = EventUtil.getEventArgs(pattern);
+        candidateLocations = EventUtil.getCandidateLocations(pattern, client.getCluster());
+        if (pattern.getEvent().getNodeid().getValue().getRandom() != null && period != null && maxOccurs > 1) {
+            dynamicLocation = true;
+            reuseLocation = pattern.getEvent().getNodeid().getValue().getRandom().getRange().isReuse();
+        } else {
+            location = EventUtil.getEventLocation(pattern, candidateLocations, scheduler.getCluster());
+        }
+        String scriptsDir;
+        if (location.getId().equals(EventDriver.CLIENT_NODE_ID)) {
+            scriptsDir = EventDriver.getHomeDir() + File.separator + "events.pkg";
+        } else {
+            scriptsDir = client.getCluster().getWorkingDir().getDir() + File.separator + "events.pkg";
+        }
+        taskScript = scriptsDir + File.separator + EventUtil.getEvent(pattern).getScript();
+        state = State.INITIALIZED;
+    }
+
+    public void start() {
+        if (interval > 0) {
+            timer.schedule(this, initialDelay, interval);
+        } else {
+            timer.schedule(this, initialDelay);
+        }
+    }
+
+    @Override
+    public void run() {
+        if (candidateLocations.size() == 0) {
+            timer.cancel();
+            scheduler.notifyCompletion(new EventTaskReport(this));
+        } else {
+            if (dynamicLocation) {
+                location = EventUtil.getEventLocation(pattern, candidateLocations, scheduler.getCluster());
+                if (!reuseLocation) {
+                    candidateLocations.remove(location);
+                }
+            }
+
+            logger.info(EventUtil.dateFormat.format(new Date()) + " " + "EVENT "
+                    + pattern.getEvent().getType().toUpperCase() + " at " + location.getId().toUpperCase());
+            try {
+                if (!scheduler.isDryRun()) {
+                    new EventExecutor().executeEvent(location, taskScript, taskArgs, EventUtil.getEvent(pattern)
+                            .isDaemon(), scheduler.getCluster(), pattern, scheduler.getErrorHandler());
+                }
+                occurrenceCount++;
+                if (occurrenceCount >= maxOccurs) {
+                    timer.cancel();
+                    scheduler.notifyCompletion(new EventTaskReport(this));
+                }
+            } catch (IOException ioe) {
+                timer.cancel();
+                scheduler.notifyCompletion(new EventTaskReport(this, false, ioe));
+            }
+        }
+
+    }
+
+    public Node getLocation() {
+        return location;
+    }
+
+    public long getInterval() {
+        return interval;
+    }
+
+    public long getInitialDelay() {
+        return initialDelay;
+    }
+
+    public Pattern getPattern() {
+        return pattern;
+    }
+
+    public State getState() {
+        return state;
+    }
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTaskReport.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTaskReport.java
new file mode 100644
index 0000000..7ad3682
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventTaskReport.java
@@ -0,0 +1,50 @@
+/*
+ * 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.event.management;
+
+import java.io.Serializable;
+
+public class EventTaskReport implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private final EventTask task;
+    private final boolean success;
+    private final Exception e;
+
+    public EventTaskReport(EventTask task, boolean success, Exception e) {
+        this.task = task;
+        this.success = success;
+        this.e = e;
+    }
+
+    public EventTaskReport(EventTask task) {
+        this.task = task;
+        this.success = true;
+        this.e = null;
+    }
+
+    public Exception getException() {
+        return e;
+    }
+
+    public EventTask getTask() {
+        return task;
+    }
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventUtil.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventUtil.java
new file mode 100644
index 0000000..80bc0da
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventUtil.java
@@ -0,0 +1,238 @@
+/*
+ * 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.event.management;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.management.ValueType.Type;
+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.event.Event;
+import edu.uci.ics.asterix.event.schema.pattern.Pattern;
+
+public class EventUtil {
+
+    public static final String EVENTS_DIR = "events";
+    public static final String CLUSTER_CONF = "config/cluster.xml";
+    public static final String PATTERN_CONF = "config/pattern.xml";
+    private static final String IP_LOCATION = "IP_LOCATION";
+    private static final String CLUSTER_ENV = "ENV";
+    private static final String SCRIPT = "SCRIPT";
+    private static final String ARGS = "ARGS";
+    private static final String EXECUTE_SCRIPT = "events/execute.sh";
+
+    public static final DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+
+    private static final Logger logger = Logger.getLogger(EventDriver.class.getName());
+
+    public static long parseTimeInterval(ValueType v, String unit) throws IllegalArgumentException {
+        int val = 0;
+        switch (v.getType()) {
+            case ABS:
+                val = Integer.parseInt(v.getAbsoluteValue());
+                break;
+            case RANDOM_MIN_MAX:
+                val = Randomizer.getInstance().getRandomInt(v.getMin(), v.getMax());
+                break;
+            case RANDOM_RANGE:
+                String[] values = v.getRangeSet();
+                val = Integer.parseInt(values[Randomizer.getInstance().getRandomInt(0, values.length - 1)]);
+                break;
+        }
+        return computeInterval(val, unit);
+    }
+
+    public static long parseTimeInterval(String v, String unit) throws IllegalArgumentException {
+        int value = Integer.parseInt(v);
+        return computeInterval(value, unit);
+    }
+
+    private static long computeInterval(int val, String unit) {
+        int vmult = 1;
+        if ("hr".equalsIgnoreCase(unit)) {
+            vmult = 3600 * 1000;
+        } else if ("min".equalsIgnoreCase(unit)) {
+            vmult = 60 * 1000;
+        } else if ("sec".equalsIgnoreCase(unit)) {
+            vmult = 1000;
+        } else
+            throw new IllegalArgumentException(" invalid unit value specified for frequency (hr,min,sec)");
+        return val * vmult;
+
+    }
+
+    public static Event getEvent(Pattern pattern) {
+        for (Event event : EventDriver.getEvents().getEvent()) {
+            if (event.getType().equals(pattern.getEvent().getType())) {
+                return event;
+            }
+        }
+        throw new IllegalArgumentException(" Unknown event type" + pattern.getEvent().getType());
+    }
+
+    public static Node getEventLocation(Pattern pattern, List<Node> candidateLocations, Cluster cluster) {
+        ValueType value = new ValueType(pattern.getEvent().getNodeid().getValue());
+        Node location = null;
+        Type vtype = value.getType();
+
+        switch (vtype) {
+            case ABS:
+                location = getNodeFromId(value.getAbsoluteValue(), cluster);
+                break;
+            case RANDOM_RANGE:
+                int nodeIndex = Randomizer.getInstance().getRandomInt(0, candidateLocations.size() - 1);
+                location = candidateLocations.get(nodeIndex);
+                break;
+            case RANDOM_MIN_MAX:
+                throw new IllegalStateException(" Canont configure a min max value range for location");
+        }
+        return location;
+
+    }
+
+    public static List<Node> getCandidateLocations(Pattern pattern, Cluster cluster) {
+        ValueType value = new ValueType(pattern.getEvent().getNodeid().getValue());
+        List<Node> candidateList = new ArrayList<Node>();
+        switch (value.getType()) {
+            case ABS:
+                candidateList.add(getNodeFromId(value.getAbsoluteValue(), cluster));
+                break;
+            case RANDOM_RANGE:
+                boolean anyOption = false;
+                String[] values = value.getRangeSet();
+                for (String v : values) {
+                    if (v.equalsIgnoreCase("ANY")) {
+                        anyOption = true;
+                    }
+                }
+                if (anyOption) {
+                    for (Node node : cluster.getNode()) {
+                        candidateList.add(node);
+                    }
+                } else {
+                    boolean found = false;
+                    for (String v : values) {
+                        for (Node node : cluster.getNode()) {
+                            if (node.getId().equals(v)) {
+                                candidateList.add(node);
+                                found = true;
+                                break;
+                            }
+                        }
+                        if (!found) {
+                            throw new IllegalStateException("Unknonw nodeId : " + v);
+                        }
+                        found = false;
+                    }
+
+                }
+                String[] excluded = value.getRangeExcluded();
+                if (excluded != null && excluded.length > 0) {
+                    List<Node> markedForRemoval = new ArrayList<Node>();
+                    for (String exclusion : excluded) {
+                        for (Node node : candidateList) {
+                            if (node.getId().equals(exclusion)) {
+                                markedForRemoval.add(node);
+                            }
+                        }
+                    }
+                    candidateList.removeAll(markedForRemoval);
+                }
+                break;
+            case RANDOM_MIN_MAX:
+                throw new IllegalStateException(" Invalid value configured for location");
+        }
+        return candidateList;
+    }
+
+    private static Node getNodeFromId(String nodeid, Cluster cluster) {
+        if (nodeid.equals(EventDriver.CLIENT_NODE.getId())) {
+            return EventDriver.CLIENT_NODE;
+        }
+
+        if (nodeid.equals(cluster.getMasterNode().getId())) {
+            return new Node(cluster.getMasterNode().getId(), cluster.getMasterNode().getIp(), null, null, null);
+        }
+
+        List<Node> nodeList = cluster.getNode();
+        for (Node node : nodeList) {
+            if (node.getId().equals(nodeid)) {
+                return node;
+            }
+        }
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(EventDriver.CLIENT_NODE.getId() + ",");
+        buffer.append(cluster.getMasterNode().getId() + ",");
+        for (Node v : cluster.getNode()) {
+            buffer.append(v.getId() + ",");
+        }
+        buffer.deleteCharAt(buffer.length() - 1);
+        throw new IllegalArgumentException("Unknown node id :" + nodeid + " valid ids:" + buffer);
+    }
+
+    public static void executeEventScript(Node node, String script, List<String> args, Cluster cluster)
+            throws IOException, InterruptedException {
+        List<String> pargs = new ArrayList<String>();
+        pargs.add("/bin/bash");
+        pargs.add(EventDriver.getHomeDir() + "/" + EXECUTE_SCRIPT);
+        StringBuffer argBuffer = new StringBuffer();
+        String env = EventDriver.getStringifiedEnv(cluster) + " " + IP_LOCATION + "=" + node.getIp();
+        if (args != null) {
+            for (String arg : args) {
+                argBuffer.append(arg + " ");
+            }
+        }
+        ProcessBuilder pb = new ProcessBuilder(pargs);
+        pb.environment().putAll(EventDriver.getEnvironment());
+        pb.environment().put(IP_LOCATION, node.getIp());
+        pb.environment().put(CLUSTER_ENV, env);
+        pb.environment().put(SCRIPT, script);
+        pb.environment().put(ARGS, argBuffer.toString());
+        pb.start();
+    }
+
+    public static void executeLocalScript(Node node, String script, List<String> args) throws IOException,
+            InterruptedException {
+        List<String> pargs = new ArrayList<String>();
+        pargs.add("/bin/bash");
+        pargs.add(script);
+        if (args != null) {
+            pargs.addAll(args);
+        }
+        ProcessBuilder pb = new ProcessBuilder(pargs);
+        pb.environment().putAll(EventDriver.getEnvironment());
+        pb.environment().put(IP_LOCATION, node.getIp());
+        pb.start();
+    }
+
+    public static List<String> getEventArgs(Pattern pattern) {
+        List<String> pargs = new ArrayList<String>();
+        if (pattern.getEvent().getPargs() == null) {
+            return pargs;
+        }
+        String[] args = pattern.getEvent().getPargs().split(" ");
+        for (String arg : args) {
+            pargs.add(arg.trim());
+        }
+        return pargs;
+    }
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventrixClient.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventrixClient.java
new file mode 100644
index 0000000..3792eb8
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/EventrixClient.java
@@ -0,0 +1,177 @@
+/*
+ * 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.event.management;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Logger;
+
+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.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;
+
+public class EventrixClient {
+
+    private static final Logger LOGGER = Logger.getLogger(EventrixClient.class.getName());
+
+    private EventTask[] tasks;
+    private boolean dryRun = false;
+    private LinkedBlockingQueue<EventTaskReport> msgInbox = new LinkedBlockingQueue<EventTaskReport>();
+    private AtomicInteger pendingTasks = new AtomicInteger(0);
+    private final Cluster cluster;
+    private IPatternListener listener;
+    private IOutputHandler outputHandler;
+
+    public EventrixClient(Cluster cluster, boolean dryRun, IOutputHandler outputHandler) throws Exception {
+        this.cluster = cluster;
+        this.dryRun = dryRun;
+        this.outputHandler = outputHandler;
+        if (!dryRun) {
+            initializeCluster();
+        }
+    }
+
+    public void submit(Patterns patterns) throws Exception {
+        initTasks(patterns);
+        try {
+            waitForCompletion();
+        } catch (InterruptedException ie) {
+            LOGGER.info("Interrupted exception :" + ie);
+        } catch (Exception e) {
+            throw e;
+        }
+
+    }
+
+    public void submit(Patterns patterns, IPatternListener listener) throws Exception {
+        this.listener = listener;
+        initTasks(patterns);
+    }
+
+    private void initTasks(Patterns patterns) {
+        tasks = new EventTask[patterns.getPattern().size()];
+        pendingTasks.set(tasks.length);
+        int index = 0;
+        for (Pattern pattern : patterns.getPattern()) {
+            tasks[index] = new EventTask(pattern, this);
+            tasks[index].start();
+            index++;
+        }
+    }
+
+    public Cluster getCluster() {
+        return cluster;
+    }
+
+    public boolean isDryRun() {
+        return dryRun;
+    }
+
+    public void notifyCompletion(EventTaskReport report) {
+
+        if (report.isSuccess()) {
+            pendingTasks.decrementAndGet();
+            if (listener != null) {
+                listener.eventCompleted(report);
+                if (pendingTasks.get() == 0) {
+                    listener.jobCompleted();
+                }
+            } else {
+                try {
+                    msgInbox.put(report);
+                } catch (InterruptedException e) {
+                }
+            }
+        } else {
+            for (EventTask t : tasks) {
+                if (t.getState() == EventTask.State.INITIALIZED || t.getState() == EventTask.State.IN_PROGRESS) {
+                    t.cancel();
+                }
+            }
+            if (listener != null) {
+                listener.jobFailed(report);
+            } else {
+                try {
+                    msgInbox.put(report);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    public void notifyFailure(EventTaskReport report) {
+
+    }
+
+    private void waitForCompletion() throws Exception {
+        while (true) {
+            EventTaskReport report = msgInbox.take();
+            if (report.isSuccess()) {
+                if (pendingTasks.get() == 0) {
+                    break;
+                }
+            } else {
+                throw new RuntimeException(report.getException().getMessage());
+            }
+        }
+    }
+
+    private void initializeCluster() throws Exception {
+        Patterns patterns = initPattern();
+        submit(patterns);
+    }
+
+    private Patterns initPattern() {
+        Nodeid nodeid = new Nodeid(new Value(null, EventDriver.CLIENT_NODE.getId()));
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        String workingDir = cluster.getWorkingDir().getDir();
+        File eventsPkg = new File(EventDriver.getHomeDir() + File.separator + "events.pkg.tar");
+        if (!eventsPkg.exists()) {
+            throw new IllegalStateException(" Events package does not exist (" + eventsPkg.getAbsolutePath() + ")");
+        }
+
+        String username = cluster.getUsername() == null ? System.getProperty("user.name") : cluster.getUsername();
+        patternList.add(getFileTransferPattern(username, eventsPkg.getAbsolutePath(), nodeid, cluster.getMasterNode()
+                .getIp(), workingDir, true));
+
+        if (!cluster.getWorkingDir().isNFS()) {
+            for (Node node : cluster.getNode()) {
+                patternList.add(getFileTransferPattern(username, eventsPkg.getAbsolutePath(), nodeid, node.getIp(),
+                        workingDir, true));
+            }
+        }
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    private Pattern getFileTransferPattern(String username, String src, Nodeid srcNode, String destNodeIp,
+            String destDir, boolean unpack) {
+        String pargs = username + " " + src + " " + destNodeIp + " " + destDir + " " + "unpack";
+        Event event = new Event("file_transfer", srcNode, pargs);
+        return new Pattern(null, 1, null, event);
+    }
+
+    public IOutputHandler getErrorHandler() {
+        return outputHandler;
+    }
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IOutputHandler.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IOutputHandler.java
new file mode 100644
index 0000000..c7929cb
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IOutputHandler.java
@@ -0,0 +1,22 @@
+/*
+ * 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.event.management;
+
+import edu.uci.ics.asterix.event.schema.pattern.Event;
+
+public interface IOutputHandler {
+
+    public OutputAnalysis reportEventOutput(Event event, String output);
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IPatternListener.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IPatternListener.java
new file mode 100644
index 0000000..06a56cf
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/IPatternListener.java
@@ -0,0 +1,24 @@
+/*
+ * 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.event.management;
+
+public interface IPatternListener {
+
+    public void eventCompleted(EventTaskReport report);
+
+    public void jobCompleted();
+
+    public void jobFailed(EventTaskReport report);
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/OutputAnalysis.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/OutputAnalysis.java
new file mode 100644
index 0000000..2845ede
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/OutputAnalysis.java
@@ -0,0 +1,34 @@
+/*
+ * 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.event.management;
+
+public class OutputAnalysis {
+
+    private final boolean expected;
+    private final String errorMessage;
+
+    public OutputAnalysis(boolean expected, String errorMessage) {
+        this.expected = expected;
+        this.errorMessage = errorMessage;
+    }
+
+    public boolean isExpected() {
+        return expected;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/Randomizer.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/Randomizer.java
new file mode 100644
index 0000000..e59e154
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/Randomizer.java
@@ -0,0 +1,66 @@
+/*
+ * 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.event.management;
+
+import java.util.Random;
+import java.util.logging.Logger;
+
+public class Randomizer {
+
+	private static final Logger LOGGER = Logger.getLogger(Randomizer.class
+			.getName());
+	private static Randomizer INSTANCE;
+	private final Random random;
+	private final int seed;
+
+	public static Randomizer getInstance(int seed) {
+		if (INSTANCE == null) {
+			INSTANCE = new Randomizer(seed);
+		}
+		return INSTANCE;
+	}
+
+	public static Randomizer getInstance() {
+		if (INSTANCE == null) {
+			INSTANCE = new Randomizer();
+		}
+		return INSTANCE;
+	}
+
+	private Randomizer() {
+		Random rm = new Random();
+		seed = rm.nextInt(10000);
+		random = new Random(seed);
+		LOGGER.info("SEED:" + seed);
+	}
+
+	private Randomizer(int seed) {
+		this.seed = seed;
+		random = new Random(seed);
+		LOGGER.info("SEED:" + seed);
+	}
+
+	public Random getRandom() {
+		return random;
+	}
+
+	public int getSeed() {
+		return seed;
+	}
+
+	public int getRandomInt(int min, int max) {
+		return min + random.nextInt(max - min + 1);
+	}
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ValueType.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ValueType.java
new file mode 100644
index 0000000..8aa5cc5
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/management/ValueType.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.event.management;
+
+import edu.uci.ics.asterix.event.schema.pattern.Value;
+
+public class ValueType {
+
+	public static enum Type {
+		ABS, RANDOM_RANGE, RANDOM_MIN_MAX
+	}
+
+	private Value value;
+	private Type type;
+
+	public ValueType(Value value) {
+		this.value = value;
+		if (value.getAbsvalue() != null) {
+			type = Type.ABS;
+		} else if (value.getRandom() != null) {
+			if (value.getRandom().getMinmax() != null) {
+				type = Type.RANDOM_MIN_MAX;
+			} else if (value.getRandom().getRange() != null) {
+				type = Type.RANDOM_RANGE;
+			} else {
+				throw new IllegalStateException("Incorrect value type");
+			}
+		}
+	}
+
+	public int getMin() {
+		switch (type) {
+		case RANDOM_MIN_MAX:
+			return Integer.parseInt(value.getRandom().getMinmax().getMin());
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public int getMax() {
+		switch (type) {
+		case RANDOM_MIN_MAX:
+			return Integer.parseInt(value.getRandom().getMinmax().getMax());
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public String[] getRangeSet() {
+		switch (type) {
+		case RANDOM_RANGE:
+			return value.getRandom().getRange().getSet().split(" ");
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public String[] getRangeExcluded() {
+		switch (type) {
+		case RANDOM_RANGE:
+			String exl = value.getRandom().getRange().getExclude();
+			return exl != null ? exl.split(" ") : null;
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public String getAbsoluteValue() {
+		switch (type) {
+		case ABS:
+			return value.getAbsvalue();
+		default:
+			throw new IllegalStateException("");
+		}
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/ConfigParser.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/ConfigParser.java
new file mode 100644
index 0000000..b399226
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/ConfigParser.java
@@ -0,0 +1,38 @@
+/*
+ * 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.event.xml;
+
+import java.io.File;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+public class ConfigParser {
+
+	private static final String JAXB_PKG = "edu.uci.ics.asterix.event.trigger";
+	
+	public static void main(String [] args){
+		try {
+			String path = "config/event_pattern1.xml";
+			JAXBContext ctx =  JAXBContext.newInstance(JAXB_PKG);
+		    Unmarshaller unmarshaller = ctx.createUnmarshaller();
+		    Object o = unmarshaller.unmarshal(new File(path));
+	  } catch (JAXBException e) {
+			e.printStackTrace();
+		}
+
+	}
+}
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/PatternParser.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/PatternParser.java
new file mode 100644
index 0000000..426279c
--- /dev/null
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/xml/PatternParser.java
@@ -0,0 +1,23 @@
+/*
+ * 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.event.xml;
+
+public class PatternParser {
+
+	public static void parsePattern(String path){
+		
+	}
+}
+
diff --git a/asterix-events/src/main/resources/schema/cluster.xsd b/asterix-events/src/main/resources/schema/cluster.xsd
new file mode 100644
index 0000000..e5c6511
--- /dev/null
+++ b/asterix-events/src/main/resources/schema/cluster.xsd
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cl="cluster" targetNamespace="cluster" elementFormDefault="qualified">
+
+<!-- definition of simple types --> 
+<xs:element name="name" type="xs:string"/>
+<xs:element name="ram" type="xs:string"/>
+<xs:element name="logdir" type="xs:string"/>
+<xs:element name="id" type="xs:string"/>
+<xs:element name="ip" type="xs:string"/>
+<xs:element name="cluster-ip" type="xs:string"/>
+<xs:element name="key" type="xs:string"/>
+<xs:element name="value" type="xs:string"/>
+<xs:element name="dir" type="xs:string"/>
+<xs:element name="NFS" type="xs:boolean"/>
+<xs:element name="store" type="xs:string"/>
+<xs:element name="java_home" type="xs:string"/>
+<xs:element name="username" type="xs:string"/>
+
+<!-- definition of complex elements -->
+<xs:element name="workingDir">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:dir"/>
+      <xs:element ref="cl:NFS"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="master-node">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:id"/>
+      <xs:element ref="cl:ip"/>
+      <xs:element ref="cl:cluster-ip"/>
+      <xs:element ref="cl:ram" minOccurs="0"/>
+      <xs:element ref="cl:logdir" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="property">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:key"/>
+      <xs:element ref="cl:value"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="env">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:property" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="node">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:id"/>
+      <xs:element ref="cl:ip"/>
+      <xs:element ref="cl:ram" minOccurs="0"/>
+      <xs:element ref="cl:logdir" minOccurs="0"/>
+      <xs:element ref="cl:store" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="cluster">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="cl:name"/>
+      <xs:element ref="cl:username"/>
+      <xs:element ref="cl:env" minOccurs="0"/>
+      <xs:element ref="cl:ram" minOccurs="0"/>
+      <xs:element ref="cl:java_home" minOccurs="1"/>
+      <xs:element ref="cl:logdir" minOccurs="0"/>
+      <xs:element ref="cl:store" minOccurs="0"/>
+      <xs:element ref="cl:workingDir"/>
+      <xs:element ref="cl:master-node"/>
+      <xs:element ref="cl:node" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+</xs:schema>     
diff --git a/asterix-events/src/main/resources/schema/event.xsd b/asterix-events/src/main/resources/schema/event.xsd
new file mode 100644
index 0000000..a233c18
--- /dev/null
+++ b/asterix-events/src/main/resources/schema/event.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:es="events" targetNamespace="events" elementFormDefault="qualified">
+
+<!-- definition of simple types --> 
+<xs:element name="script" type="xs:string"/>
+<xs:element name="type" type="xs:string"/>
+<xs:element name="description" type="xs:string"/>
+<xs:element name="args" type="xs:string"/>
+<xs:element name="daemon" type="xs:boolean"/>
+
+<!-- definition of complex elements -->
+
+<xs:element name="event">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="es:type"/>
+      <xs:element ref="es:script"/>
+      <xs:element ref="es:description"/>
+      <xs:element ref="es:args"/>
+      <xs:element ref="es:daemon"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="events">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="es:event" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+ 
+</xs:schema>     
diff --git a/asterix-events/src/main/resources/schema/jaxb-bindings.xjb b/asterix-events/src/main/resources/schema/jaxb-bindings.xjb
new file mode 100644
index 0000000..b5982e0
--- /dev/null
+++ b/asterix-events/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-events/src/main/resources/schema/pattern.xsd b/asterix-events/src/main/resources/schema/pattern.xsd
new file mode 100644
index 0000000..4eee880
--- /dev/null
+++ b/asterix-events/src/main/resources/schema/pattern.xsd
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:eg="patterns" targetNamespace="patterns">
+
+
+<!-- definition of simple types --> 
+<xs:element name="maxOccurs" type = "xs:int"/> 
+<xs:element name="pargs" type="xs:string"/>
+<xs:element name="absvalue" type="xs:string"/>
+<xs:element name="unit" type="xs:string"/>
+<xs:element name="type" type="xs:string"/>
+<xs:element name="min" type="xs:string"/>
+<xs:element name="max" type="xs:string"/>
+<xs:element name="abs" type="xs:string"/>
+<xs:element name="set" type="xs:string"/>
+<xs:element name="exclude" type="xs:string"/>
+<xs:element name="reuse" type="xs:boolean"/>
+<!-- definition of attributes -->
+
+<!-- definition of complex elements -->
+
+<xs:element name="range">
+  <xs:complexType>
+    <xs:sequence>
+     <xs:element ref="eg:set"/>
+     <xs:element ref="eg:exclude" minOccurs="0"/>
+     <xs:element ref="eg:reuse" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="minmax">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:min"/>
+      <xs:element ref="eg:max"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+
+<xs:element name="random">
+  <xs:complexType>
+    <xs:sequence>
+       <xs:element ref="eg:minmax" minOccurs="0"/>
+       <xs:element ref="eg:range" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="value">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:random" minOccurs="0"/>
+      <xs:element ref="eg:absvalue" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="nodeid">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:value"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="period">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:absvalue"/>
+      <xs:element ref="eg:unit"/>
+    </xs:sequence>   
+  </xs:complexType>
+</xs:element>    
+
+<xs:element name="delay">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:value"/>
+      <xs:element ref="eg:unit"/>
+    </xs:sequence>   
+  </xs:complexType>
+</xs:element>    
+
+<xs:element name="event">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:type"/>
+      <xs:element ref="eg:nodeid"/>
+      <xs:element ref="eg:pargs"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+ 
+<xs:element name="pattern">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:delay"/>
+      <xs:element ref="eg:maxOccurs" maxOccurs="1" minOccurs="0"/>
+      <xs:element ref="eg:period"/>
+      <xs:element ref="eg:event"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="patterns">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="eg:pattern" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+</xs:schema>     
diff --git a/asterix-events/src/main/resources/scripts/execute.sh b/asterix-events/src/main/resources/scripts/execute.sh
new file mode 100755
index 0000000..114a12a
--- /dev/null
+++ b/asterix-events/src/main/resources/scripts/execute.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+val=0
+line=""
+for x in $@
+do
+ if [[ $val == 0 ]]
+ then
+    line="$x="
+    val=1
+ else
+    msg="$line$x"
+    echo $line >> envr
+    val=0
+ fi
+done
+cat ./envr
diff --git a/asterix-events/src/main/resources/scripts/prepare.sh b/asterix-events/src/main/resources/scripts/prepare.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/asterix-events/src/main/resources/scripts/prepare.sh
diff --git a/asterix-installer/pom.xml b/asterix-installer/pom.xml
new file mode 100644
index 0000000..98ca7a2
--- /dev/null
+++ b/asterix-installer/pom.xml
@@ -0,0 +1,133 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+          <artifactId>asterix</artifactId>
+          <groupId>edu.uci.ics.asterix</groupId>
+          <version>0.0.4-SNAPSHOT</version>
+  </parent>
+  <groupId>edu.uci.ics.asterix</groupId>
+  <artifactId>asterix-installer</artifactId>
+  <version>0.0.4-SNAPSHOT</version>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+       <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>2.0.2</version>
+          <configuration>
+             <source>1.6</source>
+             <target>1.6</target>
+          </configuration>
+       </plugin>
+
+       <plugin>
+          <groupId>org.jvnet.jaxb2.maven2</groupId>
+          <artifactId>maven-jaxb2-plugin</artifactId>
+          <executions>
+            <execution>
+              <id>configuration</id>
+              <goals>
+                <goal>generate</goal>
+              </goals>
+              <configuration>
+                <schemaDirectory>src/main/resources/schema</schemaDirectory>
+                <schemaIncludes>
+                  <include>managix-conf.xsd</include>
+                </schemaIncludes>
+                <generatePackage>edu.uci.ics.asterix.installer.schema.conf</generatePackage>
+                <generateDirectory>${project.build.directory}/generated-sources/configuration</generateDirectory>
+              </configuration>
+            </execution>
+            <execution>
+              <id>cluster</id>
+              <goals>
+                <goal>generate</goal>
+              </goals>
+              <configuration>
+                <schemaDirectory>src/main/resources/schema</schemaDirectory>
+                <schemaIncludes>
+                  <include>cluster.xsd</include>
+                </schemaIncludes>
+                <generatePackage>edu.uci.ics.asterix.installer.schema.cluster</generatePackage>
+                <generateDirectory>${project.build.directory}/generated-sources/cluster</generateDirectory>
+              </configuration>
+            </execution>
+          </executions>
+       </plugin>
+    </plugins> 
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>args4j</groupId>
+      <artifactId>args4j</artifactId>
+      <version>2.0.12</version>
+      <type>jar</type>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.zookeeper</groupId>
+      <artifactId>zookeeper</artifactId>
+      <version>3.4.4</version>
+      <exclusions>
+            <exclusion>
+                <groupId>com.sun.jmx</groupId>
+                <artifactId>jmxri</artifactId>
+            </exclusion>
+            <exclusion>
+                <groupId>com.sun.jdmk</groupId>
+                <artifactId>jmxtools</artifactId>
+            </exclusion>
+            <exclusion>
+                <groupId>javax.jms</groupId>
+                <artifactId>jms</artifactId>
+            </exclusion>
+        </exclusions>
+    </dependency>
+    <dependency>
+        <groupId>commons-io</groupId>
+        <artifactId>commons-io</artifactId>
+        <version>1.4</version>
+    </dependency>
+    <dependency>
+        <groupId>edu.uci.ics.asterix</groupId>
+        <artifactId>asterix-events</artifactId>
+        <version>0.0.4-SNAPSHOT</version>
+        <type>jar</type>
+        <scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>edu.uci.ics.hyracks</groupId>
+        <artifactId>hyracks-server</artifactId>
+        <version>0.2.3-SNAPSHOT</version>
+        <type>zip</type>
+        <classifier>binary-assembly</classifier>
+    </dependency>
+    <dependency>
+        <groupId>edu.uci.ics.hyracks</groupId>
+        <artifactId>hyracks-cli</artifactId>
+        <version>0.2.3-SNAPSHOT</version>
+        <type>zip</type>
+        <classifier>binary-assembly</classifier>
+    </dependency>
+    <dependency>
+        <groupId>edu.uci.ics.asterix</groupId>
+        <artifactId>asterix-app</artifactId>
+        <version>0.0.4-SNAPSHOT</version>
+        <type>zip</type>
+        <classifier>binary-assembly</classifier>
+    </dependency>
+  </dependencies>
+</project>
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..ed2e2ff
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AbstractCommand.java
@@ -0,0 +1,39 @@
+/*
+ * 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.logging.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;
+
+    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 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..6dee399
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/AlterCommand.java
@@ -0,0 +1,61 @@
+/*
+ * 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.ManagixUtil;
+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 {
+        String instanceName = ((AlterConfig) config).name;
+        ManagixUtil.validateAsterixInstanceExists(instanceName, State.INACTIVE);
+        ILookupService lookupService = ServiceProvider.INSTANCE.getLookupService();
+        AsterixInstance instance = lookupService.getAsterixInstance(instanceName);
+
+        Properties asterixConfProp = ManagixUtil.getAsterixConfiguration(((AlterConfig) config).confPath);
+        instance.setConfiguration(asterixConfProp);
+        instance.setModifiedTimestamp(new Date());
+        lookupService.updateAsterixInstance(instance);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new AlterConfig();
+    }
+
+}
+
+class AlterConfig implements CommandConfig {
+
+    @Option(name = "-h", required = false, usage = "Help")
+    public boolean help = false;
+
+    @Option(name = "-n", required = false, usage = "Name of Asterix Instance")
+    public String name;
+
+    @Option(name = "-conf", required = false, 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..9a0f7c7
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/BackupCommand.java
@@ -0,0 +1,67 @@
+/*
+ * 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.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.BackupInfo;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class BackupCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        String asterixInstanceName = ((BackupConfig) config).name;
+        AsterixInstance instance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+        List<BackupInfo> backupInfo = instance.getBackupInfo();
+        PatternCreator pc = new PatternCreator();
+        Patterns patterns = pc.getBackUpAsterixPattern(instance, ((BackupConfig) config).localPath);
+        EventDriver.getClient(instance.getCluster(), false, OutputHandler.INSTANCE).submit(patterns);
+        int backupId = backupInfo.size();
+        BackupInfo binfo = new BackupInfo(backupId, new Date());
+        backupInfo.add(binfo);
+        System.out.println(asterixInstanceName + " backed up " + binfo);
+        ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new BackupConfig();
+    }
+
+}
+
+class BackupConfig implements CommandConfig {
+
+    @Option(name = "-h", required = false, usage = "Help")
+    public boolean help = false;
+
+    @Option(name = "-n", required = true, usage = "Name of the Asterix instance")
+    public String name;
+
+    @Option(name = "-local", required = false, usage = "Path on the local file system for backup")
+    public String localPath;
+
+}
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..c0dd480
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandConfig.java
@@ -0,0 +1,19 @@
+/*
+ * 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 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..179412f
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+        }
+        cmd.execute(args);
+    }
+}
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..341baa8
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java
@@ -0,0 +1,107 @@
+/*
+ * 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.driver.EventDriver;
+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.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixDriver;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+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 {
+        asterixInstanceName = ((CreateConfig) config).name;
+        ManagixUtil.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 = ManagixUtil.createAsterixInstance(asterixInstanceName, cluster,
+                ((CreateConfig) config).asterixConf);
+        ManagixUtil.createAsterixZip(asterixInstance, true);
+        List<Property> clusterProperties = new ArrayList<Property>();
+        clusterProperties.add(new Property("HYRACKS_HOME", cluster.getWorkingDir().getDir() + File.separator
+                + "hyracks"));
+        clusterProperties.add(new Property("JAVA_OPTS", "-Xmx" + cluster.getRam()));
+        clusterProperties.add(new Property("CLUSTER_NET_IP", cluster.getMasterNode().getClusterIp()));
+        clusterProperties.add(new Property("CLIENT_NET_IP", cluster.getMasterNode().getIp()));
+        clusterProperties.add(new Property("LOG_DIR", cluster.getLogdir()));
+        clusterProperties.add(new Property("JAVA_HOME", cluster.getJavaHome()));
+        cluster.setEnv(new Env(clusterProperties));
+
+        PatternCreator pc = new PatternCreator();
+        Patterns patterns = pc.getStartAsterixPattern(asterixInstanceName, cluster);
+        EventDriver.getClient(cluster, false, OutputHandler.INSTANCE).submit(patterns);
+
+        AsterixRuntimeState runtimeState = VerificationUtil.getAsterixRuntimeState(asterixInstance);
+        VerificationUtil.updateInstanceWithRuntimeDescription(asterixInstance, runtimeState, true);
+        ServiceProvider.INSTANCE.getLookupService().writeAsterixInstance(asterixInstance);
+        System.out.println(asterixInstance.getDescription(false));
+        ManagixUtil.deleteDirectory(ManagixDriver.getManagixHome() + File.separator + ManagixDriver.ASTERIX_DIR
+                + File.separator + asterixInstanceName);
+
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new CreateConfig();
+    }
+
+    public Cluster getCluster() {
+        return cluster;
+    }
+
+    public String getAsterixInstanceName() {
+        return asterixInstanceName;
+    }
+}
+
+class CreateConfig implements CommandConfig {
+
+    @Option(name = "-h", required = false, usage = "Help")
+    public boolean help = false;
+
+    @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;
+
+    @Option(name = "-a", required = true, usage = "Path to cluster configuration")
+    public String asterixConf;
+
+}
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..3286575
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DeleteCommand.java
@@ -0,0 +1,58 @@
+/*
+ * 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.logging.Level;
+
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+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 {
+        String asterixInstanceName = ((DeleteConfig) config).name;
+        AsterixInstance instance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+        PatternCreator pc = new PatternCreator();
+        Patterns patterns = pc.createDeleteInstancePattern(instance);
+        EventDriver.getClient(instance.getCluster(), false, OutputHandler.INSTANCE).submit(patterns);
+        ServiceProvider.INSTANCE.getLookupService().removeAsterixInstance(asterixInstanceName);
+        LOGGER.log(Level.INFO, " Asterix instance: " + asterixInstanceName + " deleted");
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new DeleteConfig();
+    }
+
+}
+
+class DeleteConfig implements CommandConfig {
+
+    @Option(name = "-h", required = false, usage = "Help")
+    public boolean help = false;
+
+    @Option(name = "-n", required = false, 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..c2713a3
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/DescribeCommand.java
@@ -0,0 +1,86 @@
+/*
+ * 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.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.ManagixException;
+import edu.uci.ics.asterix.installer.error.VerificationUtil;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class DescribeCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        String asterixInstanceName = ((DescribeConfig) config).name;
+        boolean adminView = ((DescribeConfig) config).admin;
+        if (asterixInstanceName != null) {
+            ManagixUtil
+                    .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);
+                System.out.println(instance.getDescription(adminView));
+            } else {
+                throw new ManagixException("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);
+                    System.out.println(instance.getDescription(adminView));
+                }
+            } else {
+                LOGGER.info("No Asterix instances found!");
+            }
+
+        }
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new DescribeConfig();
+    }
+
+}
+
+class DescribeConfig implements CommandConfig {
+
+    @Option(name = "-h", required = false, usage = "Help")
+    public boolean help = false;
+
+    @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/ICommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java
new file mode 100644
index 0000000..2822337
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java
@@ -0,0 +1,24 @@
+/*
+ * 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
+	}
+
+	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..141fc03
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/RestoreCommand.java
@@ -0,0 +1,60 @@
+/*
+ * 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.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+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;
+
+public class RestoreCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        String asterixInstanceName = ((RestoreConfig) config).name;
+        AsterixInstance instance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+        int backupId = ((RestoreConfig) config).backupId;
+        if (instance.getBackupInfo().size() <= backupId || backupId < 0) {
+            throw new IllegalStateException("Invalid backup id");
+        }
+        PatternCreator pc = new PatternCreator();
+        Patterns patterns = pc.getRestoreAsterixPattern(instance, backupId);
+        EventDriver.getClient(instance.getCluster(), false, OutputHandler.INSTANCE).submit(patterns);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new RestoreConfig();
+    }
+
+}
+
+class RestoreConfig implements CommandConfig {
+
+    @Option(name = "-h", required = false, usage = "Help")
+    public boolean help = false;
+
+    @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/StartCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java
new file mode 100644
index 0000000..3aabb75
--- /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.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.ManagixDriver;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+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.model.AsterixInstance.State;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class StartCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        String asterixInstanceName = ((StartConfig) config).name;
+        AsterixInstance instance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE);
+        ManagixUtil.createAsterixZip(instance, false);
+        PatternCreator pc = new PatternCreator();
+        Patterns patterns = pc.getStartAsterixPattern(asterixInstanceName, instance.getCluster());
+        EventDriver.getClient(instance.getCluster(), false, OutputHandler.INSTANCE).submit(patterns);
+        ManagixUtil.deleteDirectory(ManagixDriver.getManagixHome() + File.separator + ManagixDriver.ASTERIX_DIR
+                + File.separator + asterixInstanceName);
+        AsterixRuntimeState runtimeState = VerificationUtil.getAsterixRuntimeState(instance);
+        VerificationUtil.updateInstanceWithRuntimeDescription(instance, runtimeState, true);
+        System.out.println(instance.getDescription(false));
+        ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(instance);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new StartConfig();
+    }
+
+}
+
+class StartConfig implements CommandConfig {
+
+    @Option(name = "-h", required = false, usage = "Help")
+    public boolean help = false;
+
+    @Option(name = "-n", required = false, usage = "Name of Asterix Instance")
+    public String name;
+
+    @Option(name = "-conf", required = false, usage = "Path to instance configuration")
+    public String confPath;
+
+}
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..441b63c
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StopCommand.java
@@ -0,0 +1,79 @@
+/*
+ * 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.driver.EventDriver;
+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.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.OutputHandler;
+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 {
+        String asterixInstanceName = ((StopConfig) config).name;
+        AsterixInstance asterixInstance = ManagixUtil.validateAsterixInstanceExists(asterixInstanceName, State.ACTIVE,
+                State.UNUSABLE);
+        PatternCreator pc = new PatternCreator();
+        List<Pattern> patternsToExecute = new ArrayList<Pattern>();
+        patternsToExecute.add(pc.createCCStopPattern(asterixInstance.getCluster().getMasterNode().getId()));
+
+        for (Node node : asterixInstance.getCluster().getNode()) {
+            patternsToExecute.add(pc.createNCStopPattern(node.getId(), asterixInstanceName + "_" + node.getId()));
+        }
+        EventrixClient client = EventDriver.getClient(asterixInstance.getCluster(), false, OutputHandler.INSTANCE);
+        try {
+            client.submit(new Patterns(patternsToExecute));
+        } catch (Exception e) {
+            // processes are already dead
+        }
+        asterixInstance.setState(State.INACTIVE);
+        asterixInstance.setStateChangeTimestamp(new Date());
+        ServiceProvider.INSTANCE.getLookupService().updateAsterixInstance(asterixInstance);
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new StopConfig();
+    }
+
+    public String getAsterixInstanceName() {
+        return ((StopConfig) config).name;
+    }
+
+}
+
+class StopConfig implements CommandConfig {
+
+    @Option(name = "-h", required = false, usage = "Help")
+    public boolean help = false;
+
+    @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/driver/ManagixConfig.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixConfig.java
new file mode 100644
index 0000000..f955caf
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixConfig.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.driver;
+
+import java.util.Set;
+
+class ManagixConfig {
+
+    public String asterixHome;
+    public String hyracksHome;
+    public String hdfsUrl;
+    public Set<String> zookeeperNodes;
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixDriver.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixDriver.java
new file mode 100644
index 0000000..c79ac61
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixDriver.java
@@ -0,0 +1,156 @@
+/*
+ * 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 java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import edu.uci.ics.asterix.event.driver.EventDriver;
+import edu.uci.ics.asterix.event.schema.event.Events;
+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;
+
+@SuppressWarnings("restriction")
+public class ManagixDriver {
+
+    public static final String MANAGIX_INTERNAL_DIR = ".managix";
+    public static final String ASTERIX_DIR = "asterix";
+    public static final String EVENTS_DIR = "events";
+
+    private static final Logger LOGGER = Logger.getLogger(ManagixDriver.class.getName());
+    private static final String ENV_MANAGIX_HOME = "MANAGIX_HOME";
+    private static final String MANAGIX_CONF_XML = "conf" + File.separator + "managix-conf.xml";
+    private static final String MANAGIX_EVENTS_XML = MANAGIX_INTERNAL_DIR + File.separator + EVENTS_DIR
+            + File.separator + "events.pkg" + File.separator + "events.xml";
+
+    private static Configuration conf;
+    private static String managixHome;
+    private static String hyracksServerZip;
+    private static String hyracksClientZip;
+    private static String asterixZip;
+
+    public static String getHyrackServerZip() {
+        return hyracksServerZip;
+    }
+
+    public static String getHyracksClientZip() {
+        return hyracksClientZip;
+    }
+
+    public static String getAsterixZip() {
+        return asterixZip;
+    }
+
+    public static String getHyracksClientHome() {
+        return ASTERIX_DIR + File.separator + "hyracks-cli";
+    }
+
+    public static Configuration getConfiguration() {
+        return conf;
+    }
+
+    private static void initConfig() throws Exception {
+        managixHome = System.getenv(ENV_MANAGIX_HOME);
+        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);
+
+        File managixEventFile = new File(managixHome + File.separator + MANAGIX_EVENTS_XML);
+        JAXBContext eventCtx = JAXBContext.newInstance(Events.class);
+        unmarshaller = eventCtx.createUnmarshaller();
+        Events events = (Events) unmarshaller.unmarshal(managixEventFile);
+        EventDriver.setHomeDir(managixHome + File.separator + MANAGIX_INTERNAL_DIR + File.separator + EVENTS_DIR);
+        EventDriver.setEvents(events);
+
+        hyracksServerZip = initBinary("hyracks-server");
+        hyracksClientZip = initBinary("hyracks-cli");
+        ManagixUtil.unzip(hyracksClientZip, getHyracksClientHome());
+        asterixZip = initBinary("asterix-app");
+
+        ILookupService lookupService = ServiceProvider.INSTANCE.getLookupService();
+        if (!lookupService.isRunning(conf)) {
+            lookupService.startService(conf);
+        }
+    }
+
+    private static String initBinary(final String fileNamePattern) {
+        String asterixDir = ManagixDriver.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.SEVERE, msg);
+            throw new IllegalStateException(msg);
+        }
+        if (zipFiles.length > 1) {
+            String msg = " Multiple binaries found at " + asterixDir;
+            LOGGER.log(Level.SEVERE, 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) {
+                initConfig();
+                CommandHandler cmdHandler = new CommandHandler();
+                cmdHandler.processCommand(args);
+            } else {
+                printUsage();
+            }
+        } catch (IllegalArgumentException iae) {
+            LOGGER.log(Level.SEVERE, "Unknown command");
+            printUsage();
+        } catch (Exception e) {
+            LOGGER.log(Level.SEVERE, e.getMessage());
+        }
+    }
+
+    private static void printUsage() {
+        StringBuffer buffer = new StringBuffer("managix <command> <args>" + "\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("alter    " + ":" + " Alters the configuration for an existing asterix instance" + "\n");
+        buffer.append("describe " + ":" + " Describes an existing asterix instance" + "\n");
+        LOGGER.log(Level.INFO, buffer.toString());
+    }
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixUtil.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixUtil.java
new file mode 100644
index 0000000..85dcf1e
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/ManagixUtil.java
@@ -0,0 +1,300 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+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.schema.cluster.Cluster;
+import edu.uci.ics.asterix.event.schema.cluster.Node;
+import edu.uci.ics.asterix.installer.error.ManagixException;
+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 ManagixUtil {
+
+    public static AsterixInstance createAsterixInstance(String asterixInstanceName, Cluster cluster, String asterixConf)
+            throws FileNotFoundException, IOException {
+        Properties asterixConfProp = getAsterixConfiguration(asterixConf);
+        Node metadataNode = getMetadataNode(cluster);
+        String asterixZipName = ManagixDriver.getAsterixZip().substring(
+                ManagixDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+        String asterixVersion = asterixZipName.substring("asterix-app-".length(),
+                asterixZipName.indexOf("-binary-assembly"));
+        String hyracksZipName = ManagixDriver.getHyrackServerZip().substring(
+                ManagixDriver.getHyrackServerZip().lastIndexOf(File.separator) + 1);
+        String hyracksVersion = hyracksZipName.substring("hyracks-server-".length(),
+                hyracksZipName.indexOf("-binary-assembly"));
+        AsterixInstance instance = new AsterixInstance(asterixInstanceName, cluster, asterixConfProp,
+                metadataNode.getId(), asterixVersion, hyracksVersion);
+        return instance;
+    }
+
+    public static void createAsterixZip(AsterixInstance asterixInstance, boolean newDeployment) throws IOException {
+        writeAsterixConfigurationFile(asterixInstance, newDeployment);
+        String asterixInstanceDir = ManagixDriver.getAsterixDir() + File.separator + asterixInstance.getName();
+        unzip(ManagixDriver.getAsterixZip(), asterixInstanceDir);
+        File sourceJar = new File(asterixInstanceDir + File.separator + "lib" + File.separator + "asterix-app-"
+                + asterixInstance.getAsterixVersion() + ".jar");
+        String origFile = "test.properties";
+        File replacementFile = new File(asterixInstanceDir + File.separator + "test.properties");
+        replaceInJar(sourceJar, origFile, replacementFile);
+        new File(asterixInstanceDir + File.separator + "test.properties").delete();
+        String asterixZipName = ManagixDriver.getAsterixZip().substring(
+                ManagixDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+        zipDir(new File(asterixInstanceDir), new File(asterixInstanceDir + File.separator + asterixZipName));
+
+    }
+
+    private static Node getMetadataNode(Cluster cluster) {
+        Random random = new Random();
+        int nNodes = cluster.getNode().size();
+        return cluster.getNode().get(random.nextInt(nNodes));
+    }
+
+    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");
+
+        for (Node node : cluster.getNode()) {
+            StringBuffer nodeDataStore = new StringBuffer();
+            if (node.getStore() != null) {
+                String[] nodeStores = node.getStore().split(",");
+                for (String ns : nodeStores) {
+                    nodeDataStore.append(ns + File.separator + asterixInstanceName + File.separator);
+                    nodeDataStore.append(",");
+                }
+                nodeDataStore.deleteCharAt(nodeDataStore.length() - 1);
+            } else {
+                if (cluster.getStore() != null) {
+                    String[] nodeStores = cluster.getStore().split(",");
+                    for (String ns : nodeStores) {
+                        nodeDataStore.append(ns + File.separator + node.getId() + File.separator + asterixInstanceName
+                                + File.separator);
+                        nodeDataStore.append(",");
+                    }
+                    nodeDataStore.deleteCharAt(nodeDataStore.length() - 1);
+                }
+            }
+            if (nodeDataStore.length() == 0) {
+                throw new IllegalStateException(" Store not defined for node " + node.getId());
+            }
+            conf.append(asterixInstanceName + "_" + node.getId() + ".stores" + "=" + nodeDataStore
+                    + "\n");
+
+        }
+        Properties asterixConfProp = asterixInstance.getConfiguration();
+        String outpuDir = asterixConfProp.getProperty("output_dir");
+        conf.append("OutputDir=" + outpuDir);
+        File asterixConfDir = new File(ManagixDriver.getAsterixDir() + File.separator + asterixInstanceName);
+        asterixConfDir.mkdirs();
+        dumpToFile(ManagixDriver.getAsterixDir() + File.separator + asterixInstanceName + File.separator
+                + "test.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 ManagixException(" 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 ManagixException(" 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 ManagixException(" Asterix instance by name " + name + " already exists.");
+        }
+    }
+
+    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.getIp());
+        Process p = pb.start();
+        BufferedInputStream bis = new BufferedInputStream(p.getInputStream());
+        StringWriter writer = new StringWriter();
+        IOUtils.copy(bis, writer, "UTF-8");
+        return writer.toString();
+    }
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/ManagixException.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/ManagixException.java
new file mode 100644
index 0000000..e13a2f4
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/ManagixException.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 ManagixException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    public ManagixException(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..c5ad2a4
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/OutputHandler.java
@@ -0,0 +1,92 @@
+/*
+ * 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 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("does not exist")
+                            || output.contains("File exist")) {
+                        ignore = true;
+                    } else {
+                        ignore = false;
+                    }
+                }
+                break;
+
+            case BACKUP:
+                if (trimmedOutput.length() > 0) {
+                    if (trimmedOutput.contains("AccessControlException")) {
+                        errorMessage.append("Insufficient permissions on HDFS back up directory");
+                        ignore = false;
+                    }
+                    if (output.contains("does not exist") || output.contains("File exist")) {
+                        ignore = true;
+                    } else {
+                        ignore = false;
+                    }
+                }
+                break;
+
+            case RESTORE:
+                if (trimmedOutput.length() > 0) {
+                    if (trimmedOutput.contains("AccessControlException")) {
+                        errorMessage.append("Insufficient permissions on HDFS back up directory");
+                        ignore = false;
+                    }
+                    if (output.contains("does not exist") || output.contains("File exist")) {
+                        ignore = true;
+                    } else {
+                        ignore = false;
+                    }
+                }
+                break;
+
+            case ASTERIX_DEPLOY:
+                if (trimmedOutput.length() > 0) {
+                    if (trimmedOutput.contains("Exception")) {
+                        ignore = false;
+                        errorMessage.append("Error in deploying Asterix: " + output);
+                        errorMessage.append("\nStop the instance to initiate a cleanup");
+                    }
+                }
+        }
+        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..f4634a5
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/error/VerificationUtil.java
@@ -0,0 +1,104 @@
+/*
+ * 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.ManagixDriver;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixRuntimeState;
+import edu.uci.ics.asterix.installer.model.ProcessInfo;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+
+public class VerificationUtil {
+
+    private static final String VERIFY_SCRIPT_PATH = ManagixDriver.getManagixHome() + File.separator
+            + ManagixDriver.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().getIp());
+        for (Node node : cluster.getNode()) {
+            args.add(node.getIp());
+            args.add(instance.getName() + "_" + node.getId());
+        }
+
+        String output = ManagixUtil.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")) {
+            infoFields = line.split(":");
+            try {
+                int pid = Integer.parseInt(infoFields[3]);
+                pInfo = new ProcessInfo(infoFields[0], infoFields[1], 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().getIp()
+                        + "\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);
+    }
+
+}
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..8fe00ab
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java
@@ -0,0 +1,279 @@
+/*
+ * 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.List;
+import java.util.logging.Logger;
+
+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.MasterNode;
+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.StopCommand;
+import edu.uci.ics.asterix.installer.driver.ManagixDriver;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.service.ILookupService;
+import edu.uci.ics.asterix.installer.service.ServiceProvider;
+
+public class PatternCreator {
+
+    private static final Logger LOGGER = Logger.getLogger(PatternCreator.class.getName());
+    private ILookupService lookupService = ServiceProvider.INSTANCE.getLookupService();
+    private static int CC_DEBUG_PORT = 8800;
+    private static int NC_DEBUG_PORT = 8701;
+
+    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().getIp();
+
+        String destDir = cluster.getWorkingDir().getDir() + File.separator + "hyracks";
+        List<Pattern> ps = new ArrayList<Pattern>();
+
+        Pattern createCC = createCCStartPattern(ccLocationId);
+        addInitialDelay(createCC, 2, "sec");
+        ps.add(createCC);
+
+        Pattern copyHyracks = createCopyHyracksPattern(cluster, ccLocationIp, destDir);
+        ps.add(copyHyracks);
+
+        boolean copyHyracksToNC = !cluster.getWorkingDir().isNFS();
+        for (Node node : cluster.getNode()) {
+            if (copyHyracksToNC) {
+                Pattern copyHyracksForNC = createCopyHyracksPattern(cluster, node.getIp(), destDir);
+                ps.add(copyHyracksForNC);
+            }
+            Pattern createNC = createNCStartPattern(cluster.getMasterNode().getIp(), node.getId(), asterixInstanceName
+                    + "_" + node.getId());
+            addInitialDelay(createNC, 3, "sec");
+            ps.add(createNC);
+        }
+
+        Pattern asterixDeploy = createAsterixDeployPattern(asterixInstanceName, cluster);
+        addInitialDelay(asterixDeploy, 4, "sec");
+        ps.add(asterixDeploy);
+
+        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, String backupPath) throws Exception {
+        Cluster cluster = instance.getCluster();
+        String clusterStore = instance.getCluster().getStore();
+        String hdfsUrl = ManagixDriver.getConfiguration().getBackup().getHdfs().getUrl();
+        String hadoopVersion = ManagixDriver.getConfiguration().getBackup().getHdfs().getVersion();
+        String hdfsBackupDir = ManagixDriver.getConfiguration().getBackup().getHdfs().getBackupDir();
+        String workingDir = cluster.getWorkingDir().getDir();
+        String backupId = "" + instance.getBackupInfo().size();
+        String nodeStore;
+        String pargs;
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        for (Node node : cluster.getNode()) {
+            Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+            nodeStore = node.getStore() == null ? clusterStore : node.getStore();
+            pargs = workingDir + " " + instance.getName() + " " + nodeStore + " " + backupId + " " + hdfsUrl + " "
+                    + hadoopVersion + " " + hdfsBackupDir + " " + node.getId();
+            Event event = new Event("backup", nodeid, pargs);
+            patternList.add(new Pattern(null, 1, null, event));
+        }
+        return new Patterns(patternList);
+    }
+
+    public Patterns getRestoreAsterixPattern(AsterixInstance instance, int backupId) throws Exception {
+        Cluster cluster = instance.getCluster();
+        String clusterStore = instance.getCluster().getStore();
+        String hdfsUrl = ManagixDriver.getConfiguration().getBackup().getHdfs().getUrl();
+        String hadoopVersion = ManagixDriver.getConfiguration().getBackup().getHdfs().getVersion();
+        String hdfsBackupDir = ManagixDriver.getConfiguration().getBackup().getHdfs().getBackupDir();
+        String workingDir = cluster.getWorkingDir().getDir();
+        String nodeStore;
+        String pargs;
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        for (Node node : cluster.getNode()) {
+            Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+            nodeStore = node.getStore() == null ? clusterStore : node.getStore();
+            pargs = workingDir + " " + instance.getName() + " " + nodeStore + " " + backupId + " " + hdfsUrl + " "
+                    + hadoopVersion + " " + hdfsBackupDir + " " + 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 = ManagixDriver.getConfiguration().getBackup().getHdfs().getVersion();
+        File hadoopTar = new File(ManagixDriver.getManagixHome() + File.separator + ManagixDriver.MANAGIX_INTERNAL_DIR
+                + File.separator + "hadoop" + File.separator + "hadoop-" + hadoopVersion + ".tar");
+        if (!hadoopTar.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 + " " + hadoopTar.getAbsolutePath() + " " + cluster.getMasterNode().getIp() + " "
+                + workingDir + " " + "unpack";
+        Event event = new Event("file_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() + " " + hadoopTar.getAbsolutePath() + " " + node.getIp() + " "
+                        + workingDir + " " + "unpack";
+                event = new Event("file_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) {
+            patternList.addAll(createRemoveHDFSBackupPattern(instance).getPattern());
+        }
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
+    private Patterns createRemoveHDFSBackupPattern(AsterixInstance instance) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        Cluster cluster = instance.getCluster();
+        String hdfsUrl = ManagixDriver.getConfiguration().getBackup().getHdfs().getUrl();
+        String hadoopVersion = ManagixDriver.getConfiguration().getBackup().getHdfs().getVersion();
+        String hdfsBackupDir = ManagixDriver.getConfiguration().getBackup().getHdfs().getBackupDir();
+        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 createRemoveAsterixStoragePattern(AsterixInstance instance) throws Exception {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        Cluster cluster = instance.getCluster();
+        String clusterStore = cluster.getStore();
+        String nodeStore;
+        String pargs;
+
+        for (Node node : cluster.getNode()) {
+            Nodeid nodeid = new Nodeid(new Value(null, node.getId()));
+            nodeStore = node.getStore() == null ? clusterStore + File.separator + node.getId() : node.getStore();
+            String[] nodeStores = nodeStore.split(",");
+            for (String ns : nodeStores) {
+                pargs = ns + File.separator + node.getId() + instance.getName();
+                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(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 pargs = username + " " + ManagixDriver.getHyrackServerZip() + " " + 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, "" + CC_DEBUG_PORT);
+        CC_DEBUG_PORT++;
+        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) {
+        Nodeid nodeid = new Nodeid(new Value(null, hostId));
+        Event event = new Event("node_join", nodeid, ccHost + " " + nodeControllerId + " " + NC_DEBUG_PORT);
+        NC_DEBUG_PORT++;
+        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);
+    }
+
+    private Pattern createAsterixDeployPattern(String asterixInstanceName, Cluster cluster) {
+        Nodeid nodeid = new Nodeid(new Value(null, EventDriver.CLIENT_NODE.getId()));
+        String asterixZipName = ManagixDriver.getAsterixZip().substring(
+                ManagixDriver.getAsterixZip().lastIndexOf(File.separator) + 1);
+        String asterixInstanceZip = ManagixDriver.getAsterixDir() + File.separator + asterixInstanceName
+                + File.separator + asterixZipName;
+        Event event = new Event("asterix_deploy", nodeid, ManagixDriver.getManagixHome() + " " + asterixInstanceZip
+                + " " + cluster.getMasterNode().getIp());
+        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..d1a6485
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java
@@ -0,0 +1,195 @@
+/*
+ * 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.Map.Entry;
+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 String hyracksVersion;
+    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, String hyracksVersion) {
+        this.name = name;
+        this.cluster = cluster;
+        this.configuration = configuration;
+        this.metadataNodeId = metadataNodeId;
+        this.state = State.ACTIVE;
+        this.previousState = State.UNUSABLE;
+        this.asterixVersion = asterixVersion;
+        this.hyracksVersion = hyracksVersion;
+        this.createdTimestamp = new Date();
+        this.backupInfo = new ArrayList<BackupInfo>();
+        this.webInterfaceUrl = "http://" + cluster.getMasterNode().getIp() + ":" + 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 getHyracksVersion() {
+        return hyracksVersion;
+    }
+
+    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);
+        }
+        buffer.append("\n");
+        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().getIp() + "\n");
+        for (Node node : cluster.getNode()) {
+            buffer.append(node.getId() + ":" + node.getIp() + "\n");
+        }
+
+        buffer.append("\n");
+        if (backupInfo != null && backupInfo.size() > 0) {
+            for (BackupInfo info : backupInfo) {
+                buffer.append("Backup:" + info.getId() + " created at " + info.getDate() + "\n");
+            }
+        }
+        buffer.append("\n");
+        buffer.append("Asterix version:" + asterixVersion + "\n");
+        buffer.append("Hyracks version:" + hyracksVersion + "\n");
+        buffer.append("Asterix Configuration" + "\n");
+        for (Entry<Object, Object> entry : configuration.entrySet()) {
+            buffer.append(entry.getKey() + " = " + entry.getValue() + "\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..a5d2b36
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/BackupInfo.java
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+public class BackupInfo implements Serializable {
+   
+    private final int id;
+    private final Date date;
+
+    public BackupInfo(int id, Date date) {
+        this.id = id;
+        this.date = date;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+    
+    @Override
+    public String toString() {
+        return id + "_" + date;
+    }
+
+}
\ 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..8d1486d
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java
@@ -0,0 +1,29 @@
+/*
+ * 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,
+        ASTERIX_DEPLOY,
+        BACKUP,
+        RESTORE,
+        FILE_TRANSFER
+    }
+}
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..2880671
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/ProcessInfo.java
@@ -0,0 +1,48 @@
+/*
+ * 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 int processId;
+
+    public ProcessInfo(String processName, String host, int processId) {
+        this.processName = processName;
+        this.host = host;
+        this.processId = processId;
+    }
+
+    public String getProcessName() {
+        return processName;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public int getProcessId() {
+        return processId;
+    }
+
+    public String toString() {
+        return processName + " at " + host + " [ " + 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..f258e66
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ILookupService.java
@@ -0,0 +1,39 @@
+/*
+ * 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 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..ec6bd61
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/service/ZooKeeperService.java
@@ -0,0 +1,221 @@
+/*
+ * 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.logging.Level;
+import java.util.logging.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.ManagixDriver;
+import edu.uci.ics.asterix.installer.driver.ManagixUtil;
+import edu.uci.ics.asterix.installer.error.ManagixException;
+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 = ManagixDriver.getManagixHome() + File.separator
+            + ManagixDriver.MANAGIX_INTERNAL_DIR + File.separator + "zookeeper";
+    private static final String ZOO_KEEPER_CONFIG = ZOOKEEPER_HOME + File.separator + "zk.pkg" + 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 {
+        LOGGER.setLevel(Level.WARNING);
+        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.isLoggable(Level.INFO)) {
+                LOGGER.info("ZooKeeper running at " + connectionString);
+            }
+            createRootIfNotExist();
+            isRunning = true;
+        } catch (KeeperException ke) {
+            isRunning = false;
+        }
+        return isRunning;
+    }
+
+    public void startService(Configuration conf) throws Exception {
+        LOGGER.info("Starting ZooKeeper at " + zkConnectionString);
+        ZookeeperUtil.writeConfiguration(ZOO_KEEPER_CONFIG, conf, ZOOKEEPER_LEADER_CONN_PORT,
+                ZOOKEEPER_LEADER_ELEC_PORT);
+        String initScript = ZOOKEEPER_HOME + File.separator + "zk.init";
+        StringBuffer cmdBuffer = new StringBuffer();
+        cmdBuffer.append(initScript + " ");
+        cmdBuffer.append(conf.getZookeeper().getHomeDir() + " ");
+        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);
+        msgQ.take();
+        createRootIfNotExist();
+    }
+
+    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 ManagixException(" 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++;
+        }
+        ManagixUtil.dumpToFile(zooKeeperConfigPath, buffer.toString());
+    }
+
+}
diff --git a/asterix-installer/src/main/resources/schema/managix-conf.xsd b/asterix-installer/src/main/resources/schema/managix-conf.xsd
new file mode 100644
index 0000000..b53c089
--- /dev/null
+++ b/asterix-installer/src/main/resources/schema/managix-conf.xsd
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mg="managix" targetNamespace="managix" 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"/>
+
+<!-- definition of complex elements -->
+<xs:element name="hdfs">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="mg:version"/>
+      <xs:element ref="mg:url"/>
+      <xs:element ref="mg:backupDir"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:element>
+
+<xs:element name="backup">
+  <xs:complexType>
+    <xs:sequence>
+      <xs:element ref="mg:hdfs"/>
+    </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: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/pom.xml b/pom.xml
index fadaa0b..ef66149 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,8 @@
                 <module>asterix-hyracks-glue</module>
                 <module>asterix-external-data</module>
                 <module>asterix-metadata</module>
+                <module>asterix-installer</module>
+                <module>asterix-events</module>
                 <module>asterix-dist</module>
                 <module>asterix-test-framework</module>
         </modules>