Added Key class
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9ceb2d2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+S4-Piper Design
+===============
+
+- Eliminate string identifiers completely and make it work nicely with Guice.
+- Use dependency injection, no more "new".
+- Limit property files to simple parameters. Config file should not be
+a programming language.
+- Configure the app in a GuiceModule.
+- Make fields final private whenever possible and use constructors
+instead of setter methods.
+- Make PEs as immutable as possible.
+- Hide details about partitioning from app developer. The idea is to
+create a graph for the prototypes and have the base classes deal with
+the distributed processing details.
+- Use osgi to create s4 app bundles that can be dropped in a directory
+and get loaded by s4.
+
+I think this can be pretty simple and clean. This is just a first
+pass, we need to brainstorm and have a few iterations.
+
+https://github.com/leoneu/s4-piper
+
+
+- no prototype if possible - all pe instances the same.
+- do we need Stream?
+- how do we configure keys
+
+The event/key is a atomic unit
+
+A PE can listen to many event/keys
+
+for a given PE inst. the set of key values of incoming events have to be the same. (pe inst is keyed on the value)
+
+For each pe inst. each event type has to be mapped to a processing method
+
+currently maps to method signature (which takes event as param) we are happy with this approach.
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..156a949
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
+ * 
+ * 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 at
+ * 	        http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License. See accompanying LICENSE file. 
+ */
+
+/* Include handy Gradle plugins. */
+apply plugin: 'eclipse'
+apply plugin: 'java'
+apply plugin: "application"
+
+/* Main application to run ... */
+mainClassName = "io.s4.Main"
+
+/* Set a version number for your app. */
+ version = new Version(major: 0, minor: 1, releaseType: 'SNAPSHOT')
+ group = 'io.s4'
+
+ /* All project libraries must be defined here. */
+ libraries = [
+ json:               'org.json:json:20090211',
+ gson:               'com.google.code.gson:gson:1.6',
+ guice:              'com.google.inject:guice:3.0',
+ guice_grapher:      'com.google.inject:guice-grapher:3.0',
+ log4j:              'log4j:log4j:1.2.15',
+ flexjson:           'net.sf.flexjson:flexjson:2.1',
+ bcel:               'org.apache.bcel:bcel:5.2',
+ jakarta_regexp:     'jakarta-regexp:jakarta-regexp:1.4',
+ kryo:               'com.esotericsoftware:kryo:1.01',
+ reflectasm:         'com.esotericsoftware:reflectasm:0.8',
+ minlog:             'com.esotericsoftware:minlog:1.2',
+ asm:                'asm:asm:3.2',
+ commons_logging:    'commons-logging:commons-logging:1.1.1',
+ commons_io:         'commons-io:commons-io:2.0.1',
+ commons_config:     'commons-configuration:commons-configuration:1.6',
+ commons_codec:      'commons-codec:commons-codec:1.4',
+ commons_httpclient: 'commons-httpclient:commons-httpclient:3.1',
+ junit:              'junit:junit:4.4'
+ ]
+
+/* Set Java version. */
+sourceCompatibility = 1.6
+targetCompatibility = 1.6
+   
+/* Search these repos to find artifacts. Gradle will download and cache. */
+repositories {
+    mavenLocal()
+    mavenCentral()
+    mavenRepo name: "gson", urls: "http://google-gson.googlecode.com/svn/mavenrepo"
+
+    /* Add lib dir as a repo. Some jar files that are not available 
+    in a public repo are distributed in the lib dir. */
+    flatDir name: 'libDir', dirs: "$rootDir/lib"
+}
+   
+/* Dependencies. */
+dependencies {
+	compile( libraries.guice )
+    compile( libraries.json)
+	compile( libraries.gson)
+	compile( libraries.log4j )
+	compile( libraries.commons_logging )
+	compile( libraries.commons_io )
+	compile( libraries.commons_config )
+	compile( libraries.commons_codec )
+	compile( libraries.commons_httpclient )
+	testCompile( libraries.junit )
+}
+
+/* Customize your jar files. */
+manifest.mainAttributes(
+    provider: 'gradle',
+    'Implementation-Url': 'http://s4.io',
+    'Implementation-Version': version,
+    'Implementation-Vendor': 'The S4 Project',
+    'Implementation-Vendor-Id': 'io.s4'
+)
+
+/* Bug workaround. */
+eclipseClasspath {
+    downloadSources = false; // required for eclipseClasspath to work
+}
+
+/* Generates the gradlew scripts.
+http://www.gradle.org/1.0-milestone-3/docs/userguide/gradle_wrapper.html */ 
+task wrapper(type: Wrapper) { 
+    gradleVersion = '1.0-milestone-3' 
+}
+
+class Version {
+    int major
+    int minor
+    int bugfix
+    String releaseType
+ 
+    String toString() {
+        "$major.$minor-$releaseType${bugfix ?: ''}"
+    }
+}
diff --git a/src/main/java/io/s4/Key.java b/src/main/java/io/s4/Key.java
new file mode 100644
index 0000000..c23757a
--- /dev/null
+++ b/src/main/java/io/s4/Key.java
@@ -0,0 +1,28 @@
+package io.s4;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+
+public class Key {
+
+    final private Event event;
+    final private KeyFinder finder;
+    final private String separator;
+
+    public Key(Event event, KeyFinder finder, String separator) {
+        this.event = event;
+        this.finder = finder;
+        this.separator = separator;
+    }
+    
+    public List<String> getList() {
+        return finder.get(event);
+    }
+    
+    public String get() {
+        List<String> keys = getList();
+        
+        return StringUtils.join(keys, separator);
+    }
+}
diff --git a/src/main/java/io/s4/KeyFinder.java b/src/main/java/io/s4/KeyFinder.java
new file mode 100644
index 0000000..43d03ee
--- /dev/null
+++ b/src/main/java/io/s4/KeyFinder.java
@@ -0,0 +1,8 @@
+package io.s4;
+
+import java.util.List;
+
+public interface KeyFinder {
+
+    List<String> get(Event event);
+}
diff --git a/src/main/java/io/s4/MyApp.java b/src/main/java/io/s4/MyApp.java
index bf5d54f..96e352e 100644
--- a/src/main/java/io/s4/MyApp.java
+++ b/src/main/java/io/s4/MyApp.java
@@ -6,21 +6,23 @@
 	final private Stream s2;
 	final private ProcessingElement pe1;
 	final private ProcessingElement pe2;
+	final private Key key;
 	
 	public MyApp(Stream s1, Stream s2, ProcessingElement pe1,
-			ProcessingElement pe2) {
+			ProcessingElement pe2, Key key) {
 		super();
 		this.s1 = s1;
 		this.s2 = s2;
 		this.pe1 = pe1;
 		this.pe2 = pe2;
+		this.key = key;
 	}
 
 	@Override
 	protected void create() {
 		
 		pe1.setOutput(s1);
-		pe2.setInput(s1);
+		pe2.setInput(s1, key);
 		pe2.setOutput(s2);
 	}
 
diff --git a/src/main/java/io/s4/ProcessingElement.java b/src/main/java/io/s4/ProcessingElement.java
index 12b8bba..2e70333 100644
--- a/src/main/java/io/s4/ProcessingElement.java
+++ b/src/main/java/io/s4/ProcessingElement.java
@@ -2,12 +2,15 @@
 
 import java.util.List;
 
+import com.google.inject.Inject;
+
 public abstract class ProcessingElement {
 
 	final private App app;
 	private List<Stream> inputStreams;
 	private List<Stream> outputStreams;
 
+	@Inject
 	public ProcessingElement(App app) {
 	
 		this.app = app;
@@ -15,7 +18,7 @@
 	}
 	
 	
-	public ProcessingElement setInput(Stream stream) {
+	public ProcessingElement setInput(Stream stream, Key key) {
 
 		inputStreams.add(stream);
 		
@@ -38,10 +41,20 @@
 	}
 
 
-	abstract public void processInputEvent(Event event);
+	 public void processInputEvent(Event event) {
+	     
+	     // map event event_type to processInputEvent(EVENT_TYPE)
+	     
+	     // the method gets auto-generated
+	 }
 
 	abstract public void sendOutputEvent();
 
 	abstract public void init();
+	
+	// TODO: Change equals and hashCode in ProcessingElement and 
+	// Stream so we can use sets as collection and make sure there are no duplicate prototypes. 
+	// Great article: http://www.artima.com/lejava/articles/equality.html
+	
 
 }