diff --git a/.gitignore b/.gitignore
index aff01a41b54c1ac1fa81e2a282a939e27034a607..54a63ca7b617a3b932d20c9439b1b178442dd532 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
 *.blg
 *DS_Store*
 *.csv
+*/bin
 *.ser
 .idea/
 *.class
diff --git a/Proposals/.DS_Store b/Proposals/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..f15975d6621e185c2e729fc3672df259aa712fcf
Binary files /dev/null and b/Proposals/.DS_Store differ
diff --git a/Proposals/Chris/.DS_Store b/Proposals/Chris/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..f5ba65c9459514dcc1c0f74d2dfae2553fa06873
Binary files /dev/null and b/Proposals/Chris/.DS_Store differ
diff --git a/src/sandbox/.classpath b/src/sandbox/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..ac37fb2e4bca5ec7510383d7e55ea7b6b759e05a
--- /dev/null
+++ b/src/sandbox/.classpath
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/src/sandbox/.project b/src/sandbox/.project
new file mode 100644
index 0000000000000000000000000000000000000000..ff1db54e8e75fcedb2a0b27c0661b0b6c87fc009
--- /dev/null
+++ b/src/sandbox/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>sandbox</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/src/sandbox/GeneralCompare.java b/src/sandbox/GeneralCompare.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e7584c7399a163c5ff6ef9ec6c98829ce1735dc
--- /dev/null
+++ b/src/sandbox/GeneralCompare.java
@@ -0,0 +1,6 @@
+package sandbox;
+
+public interface GeneralCompare {
+	public int eval(Comparable a1, Comparable a2);
+
+}
diff --git a/src/sandbox/TestLambdas.java b/src/sandbox/TestLambdas.java
index 69ac2bc4ac76ff8d89bbf350715f975842e96eef..91dc35c0120ef2193dd16f11cc8e5e4a4c8f975e 100644
--- a/src/sandbox/TestLambdas.java
+++ b/src/sandbox/TestLambdas.java
@@ -7,9 +7,9 @@ package sandbox;
 public class TestLambdas {
 	public static void main(String[] args) {
 		//declare the instances of BinaryIntExpression
-		BinaryIntExpression b0;
-		BinaryIntExpression b1;
-		BinaryIntExpression b2;
+		GeneralCompare<Integer> b0;
+		GeneralCompare<Integer> b1;
+		GeneralCompare<Integer> b2;
 		BinaryIntExpression b3;
 		BinaryIntExpression b4;
 		BinaryIntExpression b5;
@@ -34,13 +34,13 @@ public class TestLambdas {
 		};
 			
 		//call the main function using the instances as a parameter.
-		result = binaryOperation(1,2,b0);
+		result = binaryIntegerOperation(1,2,b0);
 		System.out.println(result);
 		
-		result = binaryOperation(1,2,b1);
+		result = binaryIntegerOperation(1,2,b1);
 		System.out.println(result);
 		
-		result = binaryOperation(1,2,b2);
+		result = binaryIntegerOperation(1,2,b2);
 		System.out.println(result);
 		
 		result = binaryOperation(1,2,b3);
@@ -61,4 +61,9 @@ public class TestLambdas {
 		return exp.eval(a1, a2);
 	}
 	
+	public static int binaryIntegerOperation(int a1, int a2, GeneralCompare<Integer> exp) {
+		//call the eval() function in the given BinaryIntExpression.
+		return exp.eval(a1, a2);
+	}
+	
 }
diff --git a/src/search/CC.java b/src/search/CC.java
new file mode 100644
index 0000000000000000000000000000000000000000..7726bac67040148ddff0916c89ef584aa57ac3fc
--- /dev/null
+++ b/src/search/CC.java
@@ -0,0 +1,50 @@
+package search;
+
+public class CC {
+
+	private boolean[] marked;
+	private int[] id;
+	private int count;
+	
+	public static void main(String[] args) {
+		Graph g = new Graph(5);
+		g.addEdge(4, 3);
+		g.addEdge(2, 3);
+		g.addEdge(1, 2);
+		g.addEdge(0, 2);
+		CC component = new CC(g);
+		System.out.println(component.connected(0, 2));
+	}
+	
+	public CC(Graph G){
+		marked = new boolean[G.V()];
+		id = new int[G.V()];
+		for(int s = 0; s < G.V(); s++){
+			if(!marked[s]){
+				dfs(G,s);
+				count++;
+			}
+		}
+	}
+	
+	private void dfs(Graph G, int v){
+		marked[v] = true;
+		id[v] = count;
+		for(int w : G.adj(v)){
+			if(!marked[w])
+				dfs(G, w);
+		}
+	}
+	
+	public boolean connected(int v, int w){
+		return id[v] == id[w];
+	}
+	
+	public int id(int v){
+		return id[v];
+	}
+	
+	public int count(){
+		return count;
+	}
+}
diff --git a/src/search/DepthFirstSearch.java b/src/search/DepthFirstSearch.java
new file mode 100644
index 0000000000000000000000000000000000000000..000a3e93fbee5c6246a3cbeb2683973a2f6da02f
--- /dev/null
+++ b/src/search/DepthFirstSearch.java
@@ -0,0 +1,39 @@
+package search;
+
+public class DepthFirstSearch {
+
+		private boolean[] marked;
+		private int count;
+		
+		public static void main(String[] args) {
+		
+			Graph g = new Graph(5);
+			g.addEdge(4, 3);
+			g.addEdge(2, 3);
+			g.addEdge(1, 2);
+			g.addEdge(0, 2);
+			DepthFirstSearch s = new DepthFirstSearch(g, g.V());
+		}
+		
+		public DepthFirstSearch(Graph G, int s){
+			marked = new boolean[G.V()];
+			dfs(G, s);
+			
+		}
+		
+		public void dfs(Graph G, int v){
+			marked[v] = true;
+			count++;
+			for(int w : G.adj(v))
+				if(!marked[w])
+					dfs(G, w);
+		}
+		
+		public boolean marked(int w){
+			return marked[w];
+		}
+		
+		public int count(){
+			return count;
+		}
+}
diff --git a/src/search/Field.java b/src/search/Field.java
new file mode 100644
index 0000000000000000000000000000000000000000..46c5d2179860ef9ba54f7c1d77bb965d9fef3a60
--- /dev/null
+++ b/src/search/Field.java
@@ -0,0 +1,7 @@
+package search;
+
+// The interface for a function that returns one field (piece of data) from a record
+public interface Field<Key, Value> {
+	public Comparable<Key> field(Value a1);
+}
+
diff --git a/src/search/Fish.java b/src/search/Fish.java
new file mode 100644
index 0000000000000000000000000000000000000000..3cc9e20d05861a7b7d65b829a30d00becee1de9b
--- /dev/null
+++ b/src/search/Fish.java
@@ -0,0 +1,49 @@
+package search;
+
+import java.util.Iterator;
+
+public class Fish<Integer> implements Iterable<Integer> {
+
+	private Node first;
+	
+	private class Node{
+		Integer item;
+		Node next;
+	}
+	
+	public void add(Integer item){
+		Node oldfirst = first;
+		first = new Node();
+		first.item = item;
+		first.next = oldfirst;
+	}
+	
+	@Override
+	public Iterator<Integer> iterator() {
+		return new ListIterator();
+	}
+	
+	private class ListIterator implements Iterator<Integer>{
+		
+		private Node current = first;
+		
+		public boolean hasNext(){
+			return current != null;
+		}
+		public void remove(){
+			current.next = current.next.next;
+		}
+		public Integer next(){
+			
+			Integer item = current.item;
+			current = current.next;
+			return item;
+			
+		}
+	}
+
+	
+
+	
+
+}
diff --git a/src/search/GeneralCompare.java b/src/search/GeneralCompare.java
new file mode 100644
index 0000000000000000000000000000000000000000..215fddf629ae39a3fec841758c91034af5e200f2
--- /dev/null
+++ b/src/search/GeneralCompare.java
@@ -0,0 +1,5 @@
+package search;
+
+public interface GeneralCompare<T> {
+	public int compare(Comparable<T> a1, Comparable<T> a2);
+}
diff --git a/src/search/Graph.java b/src/search/Graph.java
new file mode 100644
index 0000000000000000000000000000000000000000..093a437d93bbdb0074f1ea138e5359fb9c72e972
--- /dev/null
+++ b/src/search/Graph.java
@@ -0,0 +1,45 @@
+package search;
+
+public class Graph {
+	
+	private final int V; // Number of nodes
+	private int E; // Number of edges
+	private Fish<Integer>[] adj; // Adjacency list for a node
+	
+	public static void main(String[] args) {
+		
+		Graph g = new Graph(5);
+		g.addEdge(4, 3);
+		g.addEdge(2, 3);
+		g.addEdge(1, 2);
+		g.addEdge(0, 2);
+		for(int i = 0; i < 5; i++)
+			System.out.println(g.adj(i));
+	}
+	
+	public Graph(int V){
+		this.V = V;
+		this.E = 0;
+		adj = (Fish<Integer>[]) new Fish[V];
+		for(int v = 0; v < V; v++)
+			adj[v] = new Fish<Integer>(); 
+	}
+	
+	public int V(){
+		return V;
+	}
+	
+	public int E(){
+		return E;
+	}
+	
+	public void addEdge(int v, int w){
+		adj[v].add(w);
+		adj[w].add(v);
+		E++;
+	}
+	
+	public Iterable<Integer> adj(int V){
+		return adj[V];
+	}
+}
diff --git a/src/search/In.java b/src/search/In.java
new file mode 100644
index 0000000000000000000000000000000000000000..f9fe5bbd6f86ff16949b2ec06eb178d6e54e7f2f
--- /dev/null
+++ b/src/search/In.java
@@ -0,0 +1,731 @@
+package search;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.net.*;
+
+public final class In {
+    
+    ///// begin: section (1 of 2) of code duplicated from In to StdIn.
+    
+    // assume Unicode UTF-8 encoding
+    private static final String CHARSET_NAME = "UTF-8";
+
+    // assume language = English, country = US for consistency with System.out.
+    private static final Locale LOCALE = Locale.US;
+
+    // the default token separator; we maintain the invariant that this value 
+    // is held by the scanner's delimiter between calls
+    private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+");
+
+    // makes whitespace characters significant 
+    private static final Pattern EMPTY_PATTERN = Pattern.compile("");
+
+    // used to read the entire input. source:
+    // http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
+    private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A");
+
+    //// end: section (1 of 2) of code duplicated from In to StdIn.
+
+    private Scanner scanner;
+
+   /**
+     * Initializes an input stream from standard input.
+     */
+    public In() {
+        scanner = new Scanner(new BufferedInputStream(System.in), CHARSET_NAME);
+        scanner.useLocale(LOCALE);
+    }
+
+   /**
+     * Initializes an input stream from a socket.
+     *
+     * @param  socket the socket
+     * @throws IllegalArgumentException if cannot open {@code socket}
+     * @throws IllegalArgumentException if {@code socket} is {@code null}
+     */
+    public In(Socket socket) {
+        if (socket == null) throw new IllegalArgumentException("socket argument is null");
+        try {
+            InputStream is = socket.getInputStream();
+            scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME);
+            scanner.useLocale(LOCALE);
+        }
+        catch (IOException ioe) {
+            throw new IllegalArgumentException("Could not open " + socket, ioe);
+        }
+    }
+
+   /**
+     * Initializes an input stream from a URL.
+     *
+     * @param  url the URL
+     * @throws IllegalArgumentException if cannot open {@code url}
+     * @throws IllegalArgumentException if {@code url} is {@code null}
+     */
+    public In(URL url) {
+        if (url == null) throw new IllegalArgumentException("url argument is null");
+        try {
+            URLConnection site = url.openConnection();
+            InputStream is     = site.getInputStream();
+            scanner            = new Scanner(new BufferedInputStream(is), CHARSET_NAME);
+            scanner.useLocale(LOCALE);
+        }
+        catch (IOException ioe) {
+            throw new IllegalArgumentException("Could not open " + url, ioe);
+        }
+    }
+
+   /**
+     * Initializes an input stream from a file.
+     *
+     * @param  file the file
+     * @throws IllegalArgumentException if cannot open {@code file}
+     * @throws IllegalArgumentException if {@code file} is {@code null}
+     */
+    public In(File file) {
+        if (file == null) throw new IllegalArgumentException("file argument is null");
+        try {
+            // for consistency with StdIn, wrap with BufferedInputStream instead of use
+            // file as argument to Scanner
+            FileInputStream fis = new FileInputStream(file);
+            scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME);
+            scanner.useLocale(LOCALE);
+        }
+        catch (IOException ioe) {
+            throw new IllegalArgumentException("Could not open " + file, ioe);
+        }
+    }
+
+
+   /**
+     * Initializes an input stream from a filename or web page name.
+     *
+     * @param  name the filename or web page name
+     * @throws IllegalArgumentException if cannot open {@code name} as
+     *         a file or URL
+     * @throws IllegalArgumentException if {@code name} is {@code null}
+     */
+    public In(String name) {
+        if (name == null) throw new IllegalArgumentException("argument is null");
+        try {
+            // first try to read file from local file system
+            File file = new File(name);
+            if (file.exists()) {
+                // for consistency with StdIn, wrap with BufferedInputStream instead of use
+                // file as argument to Scanner
+                FileInputStream fis = new FileInputStream(file);
+                scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME);
+                scanner.useLocale(LOCALE);
+                return;
+            }
+
+            // next try for files included in jar
+            URL url = getClass().getResource(name);
+
+            // try this as well
+            if (url == null) {
+                url = getClass().getClassLoader().getResource(name);
+            }
+
+            // or URL from web
+            if (url == null) {
+                url = new URL(name);
+            }
+
+            URLConnection site = url.openConnection();
+
+            // in order to set User-Agent, replace above line with these two
+            // HttpURLConnection site = (HttpURLConnection) url.openConnection();
+            // site.addRequestProperty("User-Agent", "Mozilla/4.76");
+
+            InputStream is     = site.getInputStream();
+            scanner            = new Scanner(new BufferedInputStream(is), CHARSET_NAME);
+            scanner.useLocale(LOCALE);
+        }
+        catch (IOException ioe) {
+            throw new IllegalArgumentException("Could not open " + name, ioe);
+        }
+    }
+
+    /**
+     * Initializes an input stream from a given {@link Scanner} source; use with 
+     * {@code new Scanner(String)} to read from a string.
+     * <p>
+     * Note that this does not create a defensive copy, so the
+     * scanner will be mutated as you read on. 
+     *
+     * @param  scanner the scanner
+     * @throws IllegalArgumentException if {@code scanner} is {@code null}
+     */
+    public In(Scanner scanner) {
+        if (scanner == null) throw new IllegalArgumentException("scanner argument is null");
+        this.scanner = scanner;
+    }
+
+    /**
+     * Returns true if this input stream exists.
+     *
+     * @return {@code true} if this input stream exists; {@code false} otherwise
+     */
+    public boolean exists()  {
+        return scanner != null;
+    }
+    
+    ////  begin: section (2 of 2) of code duplicated from In to StdIn,
+    ////  with all methods changed from "public" to "public static".
+
+   /**
+     * Returns true if input stream is empty (except possibly whitespace).
+     * Use this to know whether the next call to {@link #readString()}, 
+     * {@link #readDouble()}, etc will succeed.
+     *
+     * @return {@code true} if this input stream is empty (except possibly whitespace);
+     *         {@code false} otherwise
+     */
+    public boolean isEmpty() {
+        return !scanner.hasNext();
+    }
+
+   /** 
+     * Returns true if this input stream has a next line.
+     * Use this method to know whether the
+     * next call to {@link #readLine()} will succeed.
+     * This method is functionally equivalent to {@link #hasNextChar()}.
+     *
+     * @return {@code true} if this input stream has more input (including whitespace);
+     *         {@code false} otherwise
+     */
+    public boolean hasNextLine() {
+        return scanner.hasNextLine();
+    }
+
+    /**
+     * Returns true if this input stream has more input (including whitespace).
+     * Use this method to know whether the next call to {@link #readChar()} will succeed.
+     * This method is functionally equivalent to {@link #hasNextLine()}.
+     * 
+     * @return {@code true} if this input stream has more input (including whitespace);
+     *         {@code false} otherwise   
+     */
+    public boolean hasNextChar() {
+        scanner.useDelimiter(EMPTY_PATTERN);
+        boolean result = scanner.hasNext();
+        scanner.useDelimiter(WHITESPACE_PATTERN);
+        return result;
+    }
+
+
+   /**
+     * Reads and returns the next line in this input stream.
+     *
+     * @return the next line in this input stream; {@code null} if no such line
+     */
+    public String readLine() {
+        String line;
+        try {
+            line = scanner.nextLine();
+        }
+        catch (NoSuchElementException e) {
+            line = null;
+        }
+        return line;
+    }
+
+    /**
+     * Reads and returns the next character in this input stream.
+     *
+     * @return the next {@code char} in this input stream
+     * @throws NoSuchElementException if the input stream is empty
+     */
+    public char readChar() {
+        scanner.useDelimiter(EMPTY_PATTERN);
+        try {
+            String ch = scanner.next();
+            assert ch.length() == 1 : "Internal (Std)In.readChar() error!"
+                + " Please contact the authors.";
+            scanner.useDelimiter(WHITESPACE_PATTERN);
+            return ch.charAt(0);
+        }
+        catch (NoSuchElementException e) {
+            throw new NoSuchElementException("attempts to read a 'char' value from input stream, but there are no more tokens available");
+        }
+    }  
+
+
+   /**
+     * Reads and returns the remainder of this input stream, as a string.
+     *
+     * @return the remainder of this input stream, as a string
+     */
+    public String readAll() {
+        if (!scanner.hasNextLine())
+            return "";
+
+        String result = scanner.useDelimiter(EVERYTHING_PATTERN).next();
+        // not that important to reset delimeter, since now scanner is empty
+        scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway
+        return result;
+    }
+
+
+   /**
+     * Reads the next token from this input stream and returns it as a {@code String}.
+     *
+     * @return the next {@code String} in this input stream
+     * @throws NoSuchElementException if the input stream is empty
+     */
+    public String readString() {
+        try {
+            return scanner.next();
+        }
+        catch (NoSuchElementException e) {
+            throw new NoSuchElementException("attempts to read a 'String' value from input stream, but there are no more tokens available");
+        }
+    }
+
+   /**
+     * Reads the next token from this input stream, parses it as a {@code int},
+     * and returns the {@code int}.
+     *
+     * @return the next {@code int} in this input stream
+     * @throws NoSuchElementException if the input stream is empty
+     * @throws InputMismatchException if the next token cannot be parsed as an {@code int}
+     */
+    public int readInt() {
+        try {
+            return scanner.nextInt();
+        }
+        catch (InputMismatchException e) {
+            String token = scanner.next();
+            throw new InputMismatchException("attempts to read an 'int' value from input stream, but the next token is \"" + token + "\"");
+        }
+        catch (NoSuchElementException e) {
+            throw new NoSuchElementException("attemps to read an 'int' value from input stream, but there are no more tokens available");
+        }
+    }
+
+   /**
+     * Reads the next token from this input stream, parses it as a {@code double},
+     * and returns the {@code double}.
+     *
+     * @return the next {@code double} in this input stream
+     * @throws NoSuchElementException if the input stream is empty
+     * @throws InputMismatchException if the next token cannot be parsed as a {@code double}
+     */
+    public double readDouble() {
+        try {
+            return scanner.nextDouble();
+        }
+        catch (InputMismatchException e) {
+            String token = scanner.next();
+            throw new InputMismatchException("attempts to read a 'double' value from input stream, but the next token is \"" + token + "\"");
+        }
+        catch (NoSuchElementException e) {
+            throw new NoSuchElementException("attemps to read a 'double' value from input stream, but there are no more tokens available");
+        }
+    }
+
+   /**
+     * Reads the next token from this input stream, parses it as a {@code float},
+     * and returns the {@code float}.
+     *
+     * @return the next {@code float} in this input stream
+     * @throws NoSuchElementException if the input stream is empty
+     * @throws InputMismatchException if the next token cannot be parsed as a {@code float}
+     */
+    public float readFloat() {
+        try {
+            return scanner.nextFloat();
+        }
+        catch (InputMismatchException e) {
+            String token = scanner.next();
+            throw new InputMismatchException("attempts to read a 'float' value from input stream, but the next token is \"" + token + "\"");
+        }
+        catch (NoSuchElementException e) {
+            throw new NoSuchElementException("attemps to read a 'float' value from input stream, but there are no more tokens available");
+        }
+    }
+
+   /**
+     * Reads the next token from this input stream, parses it as a {@code long},
+     * and returns the {@code long}.
+     *
+     * @return the next {@code long} in this input stream
+     * @throws NoSuchElementException if the input stream is empty
+     * @throws InputMismatchException if the next token cannot be parsed as a {@code long}
+     */
+    public long readLong() {
+        try {
+            return scanner.nextLong();
+        }
+        catch (InputMismatchException e) {
+            String token = scanner.next();
+            throw new InputMismatchException("attempts to read a 'long' value from input stream, but the next token is \"" + token + "\"");
+        }
+        catch (NoSuchElementException e) {
+            throw new NoSuchElementException("attemps to read a 'long' value from input stream, but there are no more tokens available");
+        }
+    }
+
+   /**
+     * Reads the next token from this input stream, parses it as a {@code short},
+     * and returns the {@code short}.
+     *
+     * @return the next {@code short} in this input stream
+     * @throws NoSuchElementException if the input stream is empty
+     * @throws InputMismatchException if the next token cannot be parsed as a {@code short}
+     */
+    public short readShort() {
+        try {
+            return scanner.nextShort();
+        }
+        catch (InputMismatchException e) {
+            String token = scanner.next();
+            throw new InputMismatchException("attempts to read a 'short' value from input stream, but the next token is \"" + token + "\"");
+        }
+        catch (NoSuchElementException e) {
+            throw new NoSuchElementException("attemps to read a 'short' value from input stream, but there are no more tokens available");
+        }
+    }
+
+   /**
+     * Reads the next token from this input stream, parses it as a {@code byte},
+     * and returns the {@code byte}.
+     * <p>
+     * To read binary data, use {@link BinaryIn}.
+     *
+     * @return the next {@code byte} in this input stream
+     * @throws NoSuchElementException if the input stream is empty
+     * @throws InputMismatchException if the next token cannot be parsed as a {@code byte}
+     */
+    public byte readByte() {
+        try {
+            return scanner.nextByte();
+        }
+        catch (InputMismatchException e) {
+            String token = scanner.next();
+            throw new InputMismatchException("attempts to read a 'byte' value from input stream, but the next token is \"" + token + "\"");
+        }
+        catch (NoSuchElementException e) {
+            throw new NoSuchElementException("attemps to read a 'byte' value from input stream, but there are no more tokens available");
+        }
+    }
+
+    /**
+     * Reads the next token from this input stream, parses it as a {@code boolean}
+     * (interpreting either {@code "true"} or {@code "1"} as {@code true},
+     * and either {@code "false"} or {@code "0"} as {@code false}).
+     *
+     * @return the next {@code boolean} in this input stream
+     * @throws NoSuchElementException if the input stream is empty
+     * @throws InputMismatchException if the next token cannot be parsed as a {@code boolean}
+     */
+    public boolean readBoolean() {
+        try {
+            String token = readString();
+            if ("true".equalsIgnoreCase(token))  return true;
+            if ("false".equalsIgnoreCase(token)) return false;
+            if ("1".equals(token))               return true;
+            if ("0".equals(token))               return false;
+            throw new InputMismatchException("attempts to read a 'boolean' value from input stream, but the next token is \"" + token + "\"");
+        }
+        catch (NoSuchElementException e) {
+            throw new NoSuchElementException("attempts to read a 'boolean' value from input stream, but there are no more tokens available");
+        }
+    }
+
+    /**
+     * Reads all remaining tokens from this input stream and returns them as
+     * an array of strings.
+     *
+     * @return all remaining tokens in this input stream, as an array of strings
+     */
+    public String[] readAllStrings() {
+        // we could use readAll.trim().split(), but that's not consistent
+        // since trim() uses characters 0x00..0x20 as whitespace
+        String[] tokens = WHITESPACE_PATTERN.split(readAll());
+        if (tokens.length == 0 || tokens[0].length() > 0)
+            return tokens;
+        String[] decapitokens = new String[tokens.length-1];
+        for (int i = 0; i < tokens.length-1; i++)
+            decapitokens[i] = tokens[i+1];
+        return decapitokens;
+    }
+
+    /**
+     * Reads all remaining lines from this input stream and returns them as
+     * an array of strings.
+     *
+     * @return all remaining lines in this input stream, as an array of strings
+     */
+    public String[] readAllLines() {
+        ArrayList<String> lines = new ArrayList<String>();
+        while (hasNextLine()) {
+            lines.add(readLine());
+        }
+        return lines.toArray(new String[lines.size()]);
+    }
+
+
+    /**
+     * Reads all remaining tokens from this input stream, parses them as integers,
+     * and returns them as an array of integers.
+     *
+     * @return all remaining lines in this input stream, as an array of integers
+     */
+    public int[] readAllInts() {
+        String[] fields = readAllStrings();
+        int[] vals = new int[fields.length];
+        for (int i = 0; i < fields.length; i++)
+            vals[i] = Integer.parseInt(fields[i]);
+        return vals;
+    }
+
+    /**
+     * Reads all remaining tokens from this input stream, parses them as longs,
+     * and returns them as an array of longs.
+     *
+     * @return all remaining lines in this input stream, as an array of longs
+     */
+    public long[] readAllLongs() {
+        String[] fields = readAllStrings();
+        long[] vals = new long[fields.length];
+        for (int i = 0; i < fields.length; i++)
+            vals[i] = Long.parseLong(fields[i]);
+        return vals;
+    }
+
+    /**
+     * Reads all remaining tokens from this input stream, parses them as doubles,
+     * and returns them as an array of doubles.
+     *
+     * @return all remaining lines in this input stream, as an array of doubles
+     */
+    public double[] readAllDoubles() {
+        String[] fields = readAllStrings();
+        double[] vals = new double[fields.length];
+        for (int i = 0; i < fields.length; i++)
+            vals[i] = Double.parseDouble(fields[i]);
+        return vals;
+    }
+    
+    ///// end: section (2 of 2) of code duplicated from In to StdIn */
+
+   /**
+     * Closes this input stream.
+     */
+    public void close() {
+        scanner.close();  
+    }
+
+    /**
+     * Reads all integers from a file and returns them as
+     * an array of integers.
+     *
+     * @param      filename the name of the file
+     * @return     the integers in the file
+     * @deprecated Replaced by {@code new In(filename)}.{@link #readAllInts()}.
+     */
+    @Deprecated
+    public static int[] readInts(String filename) {
+        return new In(filename).readAllInts();
+    }
+
+   /**
+     * Reads all doubles from a file and returns them as
+     * an array of doubles.
+     *
+     * @param      filename the name of the file
+     * @return     the doubles in the file
+     * @deprecated Replaced by {@code new In(filename)}.{@link #readAllDoubles()}.
+     */
+    @Deprecated
+    public static double[] readDoubles(String filename) {
+        return new In(filename).readAllDoubles();
+    }
+
+   /**
+     * Reads all strings from a file and returns them as
+     * an array of strings.
+     *
+     * @param      filename the name of the file
+     * @return     the strings in the file
+     * @deprecated Replaced by {@code new In(filename)}.{@link #readAllStrings()}.
+     */
+    @Deprecated
+    public static String[] readStrings(String filename) {
+        return new In(filename).readAllStrings();
+    }
+
+    /**
+     * Reads all integers from standard input and returns them
+     * an array of integers.
+     *
+     * @return     the integers on standard input
+     * @deprecated Replaced by {@link StdIn#readAllInts()}.
+     */
+    @Deprecated
+    public static int[] readInts() {
+        return new In().readAllInts();
+    }
+
+   /**
+     * Reads all doubles from standard input and returns them as
+     * an array of doubles.
+     *
+     * @return     the doubles on standard input
+     * @deprecated Replaced by {@link StdIn#readAllDoubles()}.
+     */
+    @Deprecated
+    public static double[] readDoubles() {
+        return new In().readAllDoubles();
+    }
+
+   /**
+     * Reads all strings from standard input and returns them as
+     *  an array of strings.
+     *
+     * @return     the strings on standard input
+     * @deprecated Replaced by {@link StdIn#readAllStrings()}.
+     */
+    @Deprecated
+    public static String[] readStrings() {
+        return new In().readAllStrings();
+    }
+    
+   /**
+     * Unit tests the {@code In} data type.
+     *
+     * @param args the command-line arguments
+     */
+    public static void main(String[] args) {
+        In in;
+        String urlName = "https://introcs.cs.princeton.edu/stdlib/InTest.txt";
+
+        // read from a URL
+        System.out.println("readAll() from URL " + urlName);
+        System.out.println("---------------------------------------------------------------------------");
+        try {
+            in = new In(urlName);
+            System.out.println(in.readAll());
+        }
+        catch (IllegalArgumentException e) {
+            System.out.println(e);
+        }
+        System.out.println();
+
+        // read one line at a time from URL
+        System.out.println("readLine() from URL " + urlName);
+        System.out.println("---------------------------------------------------------------------------");
+        try {
+            in = new In(urlName);
+            while (!in.isEmpty()) {
+                String s = in.readLine();
+                System.out.println(s);
+            }
+        }
+        catch (IllegalArgumentException e) {
+            System.out.println(e);
+        }
+        System.out.println();
+
+        // read one string at a time from URL
+        System.out.println("readString() from URL " + urlName);
+        System.out.println("---------------------------------------------------------------------------");
+        try {
+            in = new In(urlName);
+            while (!in.isEmpty()) {
+                String s = in.readString();
+                System.out.println(s);
+            }
+        }
+        catch (IllegalArgumentException e) {
+            System.out.println(e);
+        }
+        System.out.println();
+
+
+        // read one line at a time from file in current directory
+        System.out.println("readLine() from current directory");
+        System.out.println("---------------------------------------------------------------------------");
+        try {
+            in = new In("./InTest.txt");
+            while (!in.isEmpty()) {
+                String s = in.readLine();
+                System.out.println(s);
+            }
+        }
+        catch (IllegalArgumentException e) {
+            System.out.println(e);
+        }
+        System.out.println();
+
+
+        // read one line at a time from file using relative path
+        System.out.println("readLine() from relative path");
+        System.out.println("---------------------------------------------------------------------------");
+        try {
+            in = new In("../stdlib/InTest.txt");
+            while (!in.isEmpty()) {
+                String s = in.readLine();
+                System.out.println(s);
+            }
+        }
+        catch (IllegalArgumentException e) {
+            System.out.println(e);
+        }
+        System.out.println();
+
+        // read one char at a time
+        System.out.println("readChar() from file");
+        System.out.println("---------------------------------------------------------------------------");
+        try {
+            in = new In("InTest.txt");
+            while (!in.isEmpty()) {
+                char c = in.readChar();
+                System.out.print(c);
+            }
+        }
+        catch (IllegalArgumentException e) {
+            System.out.println(e);
+        }
+        System.out.println();
+        System.out.println();
+
+        // read one line at a time from absolute OS X / Linux path
+        System.out.println("readLine() from absolute OS X / Linux path");
+        System.out.println("---------------------------------------------------------------------------");
+        in = new In("/n/fs/introcs/www/java/stdlib/InTest.txt");
+        try {
+            while (!in.isEmpty()) {
+                String s = in.readLine();
+                System.out.println(s);
+            }
+        }
+        catch (IllegalArgumentException e) {
+            System.out.println(e);
+        }
+        System.out.println();
+
+
+        // read one line at a time from absolute Windows path
+        System.out.println("readLine() from absolute Windows path");
+        System.out.println("---------------------------------------------------------------------------");
+        try {
+            in = new In("G:\\www\\introcs\\stdlib\\InTest.txt");
+            while (!in.isEmpty()) {
+                String s = in.readLine();
+                System.out.println(s);
+            }
+            System.out.println();
+        }
+        catch (IllegalArgumentException e) {
+            System.out.println(e);
+        }
+        System.out.println();
+
+    }
+
+}
\ No newline at end of file
diff --git a/src/search/Node.java b/src/search/Node.java
new file mode 100644
index 0000000000000000000000000000000000000000..b661f73b6f20207437721739e1f00aa98acf07dd
--- /dev/null
+++ b/src/search/Node.java
@@ -0,0 +1,113 @@
+package search;
+
+// An abstract data type that represents a node in a Red Black Search Tree
+public class Node<Key, Value>{
+	
+	private final Comparable<Key> key;
+	private Value val;
+	private Node<Key, Value> left, right;
+	private int n; 
+	private boolean color;
+
+	/**
+	 * Constructor
+	 * @param key Used to assign order amongst the nodes/implement comparability
+	 * @param val The value stored at a node
+	 * @param n How many nodes are in the subtree beneath this node (inclusive)
+	 * @param color True represents a red connection between the current node and its parent, black represents false
+	 */
+	public Node(Comparable<Key> key, Value val, int n, boolean color){
+		this.key = key;
+		this.val = val;
+		this.n = n;
+		this.color = color;
+	}
+	
+	/**
+	 * Getter for a node's key
+	 * @return The node's key
+	 */
+	public Comparable<Key> key(){
+		return this.key;
+	}
+	
+	/**
+	 * Getter for a node's value
+	 * @return The node's value
+	 */
+	public Value val(){
+		return this.val;
+	} 
+
+	/**
+	 * Setter for a node's value
+	 * @param val New value being assigned
+	 */
+	public void val(Value val){
+		this.val = val;
+	}
+	
+	/**
+	 * Getter for a node's left child
+	 * @return The node's left child
+	 */
+	public Node<Key, Value> left(){
+		return this.left;
+	}
+	
+	/**
+	 * Setter for a node's left child
+	 * @param left The node's new left child
+	 */
+	public void left(Node<Key, Value> left){
+		this.left = left;
+	}
+	
+	/**
+	 * Getter for a node's right child
+	 * @return The node's right child
+	 */
+	public Node<Key, Value> right(){
+		return this.right;
+	}
+	
+	/**
+	 * Setter for a node's right child
+	 * @param left The node's new right child
+	 */
+	public void right(Node<Key, Value> right){
+		this.right = right;
+	}
+	
+	/**
+	 * Getter for the subtree size beneath the current node
+	 * @return Subtree size
+	 */
+	public int n(){
+		return this.n;
+	}
+	
+	/**
+	 * Setter for a subtree's size
+	 * @param n New subtree size
+	 */
+	public void n(int n){
+		this.n = n;
+	}
+	
+	/**
+	 * Getter method for a node's color
+	 * @return The node's color
+	 */
+	public boolean color(){
+		return this.color;
+	}
+	
+	/**
+	 * Setter for a node's color
+	 * @param color New node color
+	 */
+	public void color(boolean color){
+		this.color = color;
+	}
+}
diff --git a/src/search/RedBlackTree.java b/src/search/RedBlackTree.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d5728ef2d2d6a3315e9da2dabed2353e89b5002
--- /dev/null
+++ b/src/search/RedBlackTree.java
@@ -0,0 +1,184 @@
+package search;
+
+public class RedBlackTree<Key, Value> {
+	private Node<Key, Value> root; // Root of the tree
+	private GeneralCompare<Key> compare;
+	private Field<Key, Value> field;
+	
+	// Main method only used for testing
+	
+	public static void main(String[] args) {
+		GeneralCompare<Integer> b1;
+		b1 = (a1, a2) -> (Integer) a1 - (Integer) a2;
+		Field<Integer, Integer[]> fld;
+		fld = (a1) -> (Integer) a1[0];
+		
+		
+		Integer[][] x = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {7, 7}, {8, 8}, {9, 9}};
+		RedBlackTree<Integer, Integer[]> myTree = new RedBlackTree<Integer, Integer[]>(fld, b1);
+		for(int i = 0; i < x.length; i++){
+			myTree.put(x[i]);
+		}
+		Node h = myTree.root(); 
+		System.out.println(h.key());
+		while (h.left() != null) {
+			System.out.println(h.left().key());
+			h = h.left();
+		}
+	}
+	
+	
+	/**
+	 * Constructor for a red black tree object
+	 * @param fld A function that retrieves the desired field from an array of comparable items
+	 * @param gc A function that compares two comparable items
+	 */
+	public RedBlackTree(Field<Key, Value> fld, GeneralCompare<Key> gc) {
+		compare = gc;
+		field = fld;
+	}
+	
+	/**
+	 * Getter method for the root of a tree
+	 * @return The root of a tree object
+	 */
+	public Node<Key, Value> root() {
+		return root;
+	}
+	
+	/**
+	 * Wrapper method for adding a new node
+	 * @param val A new record
+	 */
+	public void put(Value val){
+		Node<Key, Value> newNode = new Node<Key, Value>(field.field(val), val, 1, true);
+		root = put(root, newNode);
+	}
+	
+	/**
+	 * Adds a new node to an existing tree
+	 * @param h An existing node on the tree
+	 * @param newNode A node to be added to the tree
+	 * @return
+	 */
+	private Node<Key, Value> put(Node<Key, Value> h, Node<Key, Value> newNode){
+		// Placing the first node in a tree
+		if (root == null) {
+			root = newNode;
+			root.color(false);
+			return root;
+		}
+		
+		// Place new element in the tree
+		int cmp = compare.compare(newNode.key(), h.key());
+		if (cmp < 0 && (h.left() == null))
+				h.left(newNode);
+		else if (cmp < 0 )
+			h.left(put(h.left(), newNode));
+		else if (cmp > 0 && (h.right() == null))
+			h.right(newNode);
+		else if (cmp > 0)
+			h.right(put(h.right(), newNode));
+		else
+			h = newNode;
+
+		// Rearrange the tree to maintain balance
+		if(h.n() > 2){
+			if(isRed(h.right()) && !isRed(h.left()))
+				h = rotateLeft(h);
+			if(isRed(h.left()) && isRed(h.left().left()))
+				h = rotateRight(h);
+			if(isRed(h.left()) && isRed(h.right()))
+				flipColors(h);
+		}
+
+		// Increment how many nodes are in a subtree
+		if ((h.left() != null) && (h.right() != null))
+			h.n(h.left().n() + h.right().n() + 1);
+		else if (h.left() != null)
+			h.n(h.left().n() + 1);
+		else if (h.right() != null)
+			h.n(h.right().n() + 1);
+		else 
+			h.n(1);
+		
+		return h;
+	}
+
+	/**
+	 * Check if the link to a node's parent is red
+	 * @param x Node in a tree
+	 * @return Boolean result of whether the node is red or not
+	 */
+	private boolean isRed(Node<Key, Value> x){
+		if (x == null)
+			return false; 
+		return x.color();
+	}
+
+	/**
+	 * Rotates a subtree in a counterclockwise direction
+	 * @param h Root of a tree segment to be rotated
+	 * @return New root of the rotated segment
+	 */
+	public Node<Key, Value> rotateLeft(Node<Key, Value> h){
+		System.out.println("Rotate left!");
+		Node<Key, Value> x = h.right();
+		h.right(x.left());
+		x.left(h);
+		x.color(h.color());
+		h.color(true);
+		x.n(h.n());
+		
+		// Increment how many nodes are in a subtree
+		if (h.left() != null & h.right() != null)
+			h.n(h.left().n() + h.right().n() + 1);
+		else if (h.left() != null)
+			h.n(h.left().n() + 1);
+		else if (h.right() != null)
+			h.n(h.right().n() + 1);
+		else 
+			h.n(1);
+		
+		return x;
+	}
+
+	/**
+	 * Rotates a subtree in a clockwise direction
+	 * @param h Root of a tree segment to be rotated
+	 * @return New root of the rotated segment
+	 */
+	public Node<Key, Value> rotateRight(Node<Key, Value> h){
+		Node<Key, Value> x = h.left();
+		h.left(x.right());
+		x.right(h);
+		x.color(h.color());
+		h.color(true);
+		x.n(h.n());
+		
+		// Increment how many nodes are in a subtree
+		if (h.left() != null & h.right() != null)
+			h.n(h.left().n() + h.right().n() + 1);
+		else if (h.left() != null)
+			h.n(h.left().n() + 1);
+		else if (h.right() != null)
+			h.n(h.right().n() + 1);
+		else 
+			h.n(1);
+		
+		return x;
+
+	}
+
+	/**
+	 * Changes two red connections from a single node to black
+	 * @param h Root of tree segment whose colors are to be switched
+	 */
+	private void flipColors(Node<Key, Value> h){
+		if(h.left() != null && h.right() != null){
+			h.left().color(false);
+			h.right().color(false);
+			h.color(true);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/sort/Bound.java b/src/sort/Bound.java
index 990bac2766133a87334256150c9108509b01fb03..2a9e9eb6f23a0dda65b3ff21ebab77de21c0e260 100644
--- a/src/sort/Bound.java
+++ b/src/sort/Bound.java
@@ -1,5 +1,5 @@
-package sort;
+package sort;
 
 public enum Bound {
 	LOWER, UPPER, LOWHIGH, ANY, EQUALS;
-}
+}
diff --git a/src/sort/KDT.java b/src/sort/KDT.java
index 8709fc5cb21d0a07f24894f66fe353053f7ed7bc..3e9f11395813107dbfa9e981689fdc378a70f361 100644
--- a/src/sort/KDT.java
+++ b/src/sort/KDT.java
@@ -1,217 +1,217 @@
-package sort;
-
-import sandbox.Point;
-
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-
-public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable {
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 8807259801436570835L;
-	/**
-	 * 
-	 */
-	KDNode root;
-	ArrayList<GeneralCompare<KeyVal>> axes;
-	
-	public static void main(String[] args) {
-		GeneralCompare<Point> compX = (p1, p2) -> ((Point) p1).getX() - ((Point) p2).getX();
-		GeneralCompare<Point> compY = (p1, p2) -> ((Point) p1).getY() - ((Point) p2).getY();
-		
-		//(2,3), (4,7), (5,4), (7,2), (8,1), (9,6)
-		//(8,1), (7,2), (2,3), (5,4), (9,6), (4,7)
-		Point p1 = new Point(2,3);
-		Point p2 = new Point(5,4);
-		Point p3 = new Point(9,6);
-		Point p4 = new Point(4,7);
-		Point p5 = new Point(8,1);
-		Point p6 = new Point(7,2);
-		
-		ArrayList<GeneralCompare<Point>> axes = new ArrayList<GeneralCompare<Point>>();
-		axes.add(compX);
-		axes.add(compY);
-		
-		Point[] pts = {p1, p2, p3, p4, p5, p6};
-		
-		//KDT<Point> kdt = new KDT<Point>(axes, pts);
-		KDT<Point> kdt = new KDT<Point>("kdtree.ser");
-		System.out.println(kdt.size());
-		System.out.println(kdt.height());
-		
-		//GeneralRange<Point> xRange = p -> 4 <= p.getX() && p.getX() <= 6;
-		//GeneralRange<Point> yRange = p -> 3 <= p.getY() && p.getY() <= 5;
-		
-		GeneralRange<Point> xRange = p -> p.getX() < 2 ? -1 : (p.getX() > 7 ? 1 : 0);
-		GeneralRange<Point> yRange = p -> 0;//p.getY() < 3 ? -1 : (p.getY() > 6 ? 1 : 0);
-		
-		
-		ArrayList<GeneralRange<Point>> ranges = new ArrayList<GeneralRange<Point>>();
-		ranges.add(xRange);
-		ranges.add(yRange);
-		
-		Iterable<Point> results = kdt.rangeSearch(ranges);
-		
-		System.out.println("Results");
-		for (Point p : results) {
-			System.out.println(p);
-		}
-
-		System.out.println(kdt.toString());
-		
-		kdt.writeToFile("kdtree.ser");
-	}
-	
-	private class KDNode implements Serializable{
-		/**
-		 * 
-		 */
-		private static final long serialVersionUID = -664511393872278542L;
-		/**
-		 * 
-		 */
-		private KeyVal keyval;
-		private KDNode left, right;
-		private int n;
-		
-		public KDNode(KeyVal keyval, int n) {
-			this.keyval = keyval;
-			this.n = n;
-		}
-	}
-	
-	/**
-	 * Load a kd-tree from a serialized file.
-	 * @param fn
-	 */
-	public KDT(String fn) {
-		KDT<KeyVal> kdt = null;
-		try {
-	         FileInputStream fileIn = new FileInputStream(fn);
-	         ObjectInputStream in = new ObjectInputStream(fileIn);
-	         kdt = (KDT<KeyVal>) in.readObject();
-	         in.close();
-	         fileIn.close();
-	      } catch (IOException i) {
-	         i.printStackTrace();
-	      } catch (ClassNotFoundException c) {
-	         System.out.println("Employee class not found");
-	         c.printStackTrace();
-	      }
-		//https://stackoverflow.com/questions/26327956/set-this-in-a-class
-		this.root = kdt.root;
-		this.axes = kdt.axes;
-	}
-	
-	public KDT(ArrayList<GeneralCompare<KeyVal>> axes, Comparable<KeyVal>[] keyvals) {
-		this.axes = axes;
-		root = buildTree(keyvals, 0, keyvals.length - 1, 0);
-	}
-	
-	private KDNode buildTree(Comparable<KeyVal>[] keyvals, int lo, int hi, int depth) {
-		if (lo > hi) return null;
-		int axis = depth % getK();
-		
-		int mid = (lo + hi) / 2;
-		MergeSort.sort(keyvals, lo, hi, axes.get(axis));
-		KeyVal median = (KeyVal) keyvals[mid];
-		
-		//TODO: fix size
-		KDNode newNode = new KDNode(median, 0);
-		newNode.left = buildTree(keyvals, lo, mid - 1, depth + 1);
-		newNode.right = buildTree(keyvals, mid + 1, hi, depth + 1);
-		
-		newNode.n = size(newNode.left) + size(newNode.right) + 1;
-		return newNode;
-	}
-	
-	public Iterable<KeyVal> rangeSearch(ArrayList<GeneralRange<KeyVal>> range){
-		ArrayList<KeyVal> result = new ArrayList<KeyVal>();
-		rangeSearch(root, range, result, 0);
-		return result;
-	}
-	
-	private void rangeSearch(KDNode x, ArrayList<GeneralRange<KeyVal>> range, ArrayList<KeyVal> result, int depth) {
-		if (x == null) return;
-		int axis = depth % getK();
-		GeneralRange<KeyVal> rg = range.get(axis);
-		
-		//System.out.println("Try: " + x.keyval);
-		
-		int bounds = rg.isInBounds((KeyVal) x.keyval);
-		if (bounds == 0) {
-			//System.out.println(pointInside(x.keyval, range));
-			if (pointInside(x.keyval, range)) {
-				result.add(x.keyval);
-			}
-			rangeSearch(x.left, range, result, depth + 1);
-			rangeSearch(x.right, range, result, depth + 1);
-		} else if (bounds > 0) {
-			rangeSearch(x.left, range, result, depth + 1);
-		} else if (bounds < 0)
-			rangeSearch(x.right, range, result, depth + 1);
-		
-		return;
-	}
-	
-	private boolean pointInside(KeyVal pt, ArrayList<GeneralRange<KeyVal>> range) {
-		for (int i = 0; i < axes.size(); i++)
-			if (range.get(i).isInBounds(pt) != 0) return false;
-		return true;
-	}
-	
-	public int size() {
-		return size(root);
-	}
-	
-	public int height() {
-		return height(root);
-	}
-	
-	private int height(KDNode x) {
-		if (x == null) return 0;
-		return 1 + Math.max(height(x.left), height(x.right));
-	}
-	
-	private int size(KDNode x) {
-		if (x == null) return 0;
-		else return x.n;
-	}
-	
-	public int getK() {
-		return axes.size();
-	}
-	
-	public String toString() {
-		return toString(root, "");
-	}
-	
-	public void writeToFile(String fn) {
-		try {
-	         FileOutputStream fileOut =
-	        		 new FileOutputStream(fn);
-	         ObjectOutputStream out = new ObjectOutputStream(fileOut);
-	         out.writeObject(this);
-	         out.close();
-	         fileOut.close();
-	         System.out.printf("Serialized data is saved in /tmp/kdtree.ser");
-	      } catch (IOException i) {
-	         i.printStackTrace();
-	      }
-	}
-	
-	private String toString(KDNode x, String depth) {
-		if (x == null) return depth + "null\n";
-		String result = "";
-		result += depth + x.keyval.toString() + "\n";
-		result += toString(x.left, depth + "    ");
-		result += toString(x.right, depth + "    ");
-		return result;
-	}
-}
+package sort;
+
+import sandbox.Point;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+public class KDT<KeyVal extends Comparable<KeyVal>> implements Serializable {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 8807259801436570835L;
+	/**
+	 * 
+	 */
+	KDNode root;
+	ArrayList<GeneralCompare<KeyVal>> axes;
+	
+	public static void main(String[] args) {
+		GeneralCompare<Point> compX = (p1, p2) -> ((Point) p1).getX() - ((Point) p2).getX();
+		GeneralCompare<Point> compY = (p1, p2) -> ((Point) p1).getY() - ((Point) p2).getY();
+		
+		//(2,3), (4,7), (5,4), (7,2), (8,1), (9,6)
+		//(8,1), (7,2), (2,3), (5,4), (9,6), (4,7)
+		Point p1 = new Point(2,3);
+		Point p2 = new Point(5,4);
+		Point p3 = new Point(9,6);
+		Point p4 = new Point(4,7);
+		Point p5 = new Point(8,1);
+		Point p6 = new Point(7,2);
+		
+		ArrayList<GeneralCompare<Point>> axes = new ArrayList<GeneralCompare<Point>>();
+		axes.add(compX);
+		axes.add(compY);
+		
+		Point[] pts = {p1, p2, p3, p4, p5, p6};
+		
+		//KDT<Point> kdt = new KDT<Point>(axes, pts);
+		KDT<Point> kdt = new KDT<Point>("kdtree.ser");
+		System.out.println(kdt.size());
+		System.out.println(kdt.height());
+		
+		//GeneralRange<Point> xRange = p -> 4 <= p.getX() && p.getX() <= 6;
+		//GeneralRange<Point> yRange = p -> 3 <= p.getY() && p.getY() <= 5;
+		
+		GeneralRange<Point> xRange = p -> p.getX() < 2 ? -1 : (p.getX() > 7 ? 1 : 0);
+		GeneralRange<Point> yRange = p -> 0;//p.getY() < 3 ? -1 : (p.getY() > 6 ? 1 : 0);
+		
+		
+		ArrayList<GeneralRange<Point>> ranges = new ArrayList<GeneralRange<Point>>();
+		ranges.add(xRange);
+		ranges.add(yRange);
+		
+		Iterable<Point> results = kdt.rangeSearch(ranges);
+		
+		System.out.println("Results");
+		for (Point p : results) {
+			System.out.println(p);
+		}
+
+		System.out.println(kdt.toString());
+		
+		kdt.writeToFile("kdtree.ser");
+	}
+	
+	private class KDNode implements Serializable{
+		/**
+		 * 
+		 */
+		private static final long serialVersionUID = -664511393872278542L;
+		/**
+		 * 
+		 */
+		private KeyVal keyval;
+		private KDNode left, right;
+		private int n;
+		
+		public KDNode(KeyVal keyval, int n) {
+			this.keyval = keyval;
+			this.n = n;
+		}
+	}
+	
+	/**
+	 * Load a kd-tree from a serialized file.
+	 * @param fn
+	 */
+	public KDT(String fn) {
+		KDT<KeyVal> kdt = null;
+		try {
+	         FileInputStream fileIn = new FileInputStream(fn);
+	         ObjectInputStream in = new ObjectInputStream(fileIn);
+	         kdt = (KDT<KeyVal>) in.readObject();
+	         in.close();
+	         fileIn.close();
+	      } catch (IOException i) {
+	         i.printStackTrace();
+	      } catch (ClassNotFoundException c) {
+	         System.out.println("Employee class not found");
+	         c.printStackTrace();
+	      }
+		//https://stackoverflow.com/questions/26327956/set-this-in-a-class
+		this.root = kdt.root;
+		this.axes = kdt.axes;
+	}
+	
+	public KDT(ArrayList<GeneralCompare<KeyVal>> axes, Comparable<KeyVal>[] keyvals) {
+		this.axes = axes;
+		root = buildTree(keyvals, 0, keyvals.length - 1, 0);
+	}
+	
+	private KDNode buildTree(Comparable<KeyVal>[] keyvals, int lo, int hi, int depth) {
+		if (lo > hi) return null;
+		int axis = depth % getK();
+		
+		int mid = (lo + hi) / 2;
+		MergeSort.sort(keyvals, lo, hi, axes.get(axis));
+		KeyVal median = (KeyVal) keyvals[mid];
+		
+		//TODO: fix size
+		KDNode newNode = new KDNode(median, 0);
+		newNode.left = buildTree(keyvals, lo, mid - 1, depth + 1);
+		newNode.right = buildTree(keyvals, mid + 1, hi, depth + 1);
+		
+		newNode.n = size(newNode.left) + size(newNode.right) + 1;
+		return newNode;
+	}
+	
+	public Iterable<KeyVal> rangeSearch(ArrayList<GeneralRange<KeyVal>> range){
+		ArrayList<KeyVal> result = new ArrayList<KeyVal>();
+		rangeSearch(root, range, result, 0);
+		return result;
+	}
+	
+	private void rangeSearch(KDNode x, ArrayList<GeneralRange<KeyVal>> range, ArrayList<KeyVal> result, int depth) {
+		if (x == null) return;
+		int axis = depth % getK();
+		GeneralRange<KeyVal> rg = range.get(axis);
+		
+		//System.out.println("Try: " + x.keyval);
+		
+		int bounds = rg.isInBounds((KeyVal) x.keyval);
+		if (bounds == 0) {
+			//System.out.println(pointInside(x.keyval, range));
+			if (pointInside(x.keyval, range)) {
+				result.add(x.keyval);
+			}
+			rangeSearch(x.left, range, result, depth + 1);
+			rangeSearch(x.right, range, result, depth + 1);
+		} else if (bounds > 0) {
+			rangeSearch(x.left, range, result, depth + 1);
+		} else if (bounds < 0)
+			rangeSearch(x.right, range, result, depth + 1);
+		
+		return;
+	}
+	
+	private boolean pointInside(KeyVal pt, ArrayList<GeneralRange<KeyVal>> range) {
+		for (int i = 0; i < axes.size(); i++)
+			if (range.get(i).isInBounds(pt) != 0) return false;
+		return true;
+	}
+	
+	public int size() {
+		return size(root);
+	}
+	
+	public int height() {
+		return height(root);
+	}
+	
+	private int height(KDNode x) {
+		if (x == null) return 0;
+		return 1 + Math.max(height(x.left), height(x.right));
+	}
+	
+	private int size(KDNode x) {
+		if (x == null) return 0;
+		else return x.n;
+	}
+	
+	public int getK() {
+		return axes.size();
+	}
+	
+	public String toString() {
+		return toString(root, "");
+	}
+	
+	public void writeToFile(String fn) {
+		try {
+	         FileOutputStream fileOut =
+	        		 new FileOutputStream(fn);
+	         ObjectOutputStream out = new ObjectOutputStream(fileOut);
+	         out.writeObject(this);
+	         out.close();
+	         fileOut.close();
+	         System.out.printf("Serialized data is saved in /tmp/kdtree.ser");
+	      } catch (IOException i) {
+	         i.printStackTrace();
+	      }
+	}
+	
+	private String toString(KDNode x, String depth) {
+		if (x == null) return depth + "null\n";
+		String result = "";
+		result += depth + x.keyval.toString() + "\n";
+		result += toString(x.left, depth + "    ");
+		result += toString(x.right, depth + "    ");
+		return result;
+	}
+}
diff --git a/src/sort/MergeSort.java b/src/sort/MergeSort.java
index defaccfa246c3f0af1d334286489f02e0307f907..836eac549e103cf15d16c4643b70abe2e8f6aac0 100644
--- a/src/sort/MergeSort.java
+++ b/src/sort/MergeSort.java
@@ -1,7 +1,7 @@
 package sort;
 
 public class MergeSort{
-	
+	/*// Main Function for Testing Purposes Only
 	public static void main(String[] args) {
 		GeneralCompare<Integer> b1;
 		b1 = (a1, a2) -> (Integer) a1 - (Integer) a2;
@@ -12,16 +12,30 @@ public class MergeSort{
 		for (int i = 0 ; i < (test.length) ; i++) {
 			System.out.println(test[i]);
 		}
-	}
+	}*/
 
+	/**
+	 * Wrapper function for the MergeSort implementation
+	 * @param x Array of comparable items to be sorted
+	 * @param lo Lower bound of a sub-array to be sorted
+	 * @param hi Upper bound of a  sub-array to be sorted
+	 * @param gc A lambda function that compares two comparable items
+	 */
 	public static <T> void sort(Comparable<T>[] x, int lo, int hi, GeneralCompare<T> gc) {
 		Comparable<T>[] aux;
 		aux = (Comparable<T>[]) new Comparable[x.length];
 		sortWrapped(x, lo, hi, gc, aux);
 	}
 	
+	/**
+	 * Recursively sort each half of a sub-array
+	 * @param lo
+	 * @param hi
+	 * @param gc
+	 * @param aux Auxiliary array to accommodate temporary memory use in the algorithm
+	 */
 	private static <T> void sortWrapped(Comparable<T>[] x, int lo, int hi, GeneralCompare<T> gc, Comparable<T>[] aux) {
-		int n = hi - lo; 
+		int n = hi - lo;
 		if(n < 1)
 			return;
 		// Recursively sort each half of the array
@@ -31,13 +45,18 @@ public class MergeSort{
 		merge(x, lo, hi, gc, aux);
 	}
 
+	/**
+	 * Merges two sorted sub-arrays into a single sorted array
+	 * @param x
+	 * @param lo
+	 * @param hi
+	 * @param gc
+	 * @param aux
+	 */
 	private static <T> void merge(Comparable<T>[] x, int lo, int hi, GeneralCompare<T> gc, Comparable<T>[] aux){
 
 		int n = hi - lo;
 		int mid = lo + (n/2);
-
-		// Fill auxiliary array
-		//System.out.println("lo, mid, hi: " + lo + ", " + mid + ", " + hi);
 		
 		for(int k = lo; k <= hi; k++){
 			aux[k] = x[k];
diff --git a/src/sort/QuickSelect.java b/src/sort/QuickSelect.java
new file mode 100644
index 0000000000000000000000000000000000000000..623352224c0c0e228cba2167722fedb2b5d63e87
--- /dev/null
+++ b/src/sort/QuickSelect.java
@@ -0,0 +1,105 @@
+package sort;
+
+import search.GeneralCompare;
+
+// Code from "Algorithms: 4th Edition" by Robert Sedgewick
+// Adapted from the Sedgewick Quicksort implementation
+
+public class QuickSelect {
+
+	/*
+	// Main function for testing purposes only
+	public static void main(String[] args) {
+		//{1, 2, 3, 4, 5, 6, 7, 8, 9} 5 is median. 
+		Integer[] test = {4, 6, 7, 2, 2, 2, 2,2, 2, 2,2 ,2 ,2, 2, 2};
+		GeneralCompare<Integer> b1;
+		b1 = (a1, a2) -> (Integer) a1 - (Integer) a2;
+		
+		median(test, b1);
+		System.out.println(test[test.length/2]);
+	}
+	*/
+	
+	/**
+	 * Partially sorts a comparable array such that elements smaller than the median occur in
+	 * the first half of the array, and elements larger than the median occur in the second half
+	 * @param a Array of comparable items
+	 * @param gc Lambda function to compare items
+	 */
+	public static <T> void median(Comparable<T>[] a, GeneralCompare<T> gc) {
+		sort(a, 0, a.length - 1, a.length/2, gc);
+	}
+	
+	/**
+	 * Partially sorts a comparable array such that elements smaller than the kth largest element
+	 * occur in the first half of the array, and larger elements occur in the second half
+	 * @param a Array of comparable items
+	 * @param k Pivot element that will be in its sorted place in the array
+	 * @param gc Lambda function to compare items
+	 */
+	public static <T> void partialSort(Comparable<T>[] a, int k, GeneralCompare<T> gc) {
+		sort(a, 0, a.length - 1, k, gc);
+	}
+
+	/**
+	 * Sorts the half of the array containing the kth (or median) index
+	 * @param a Array of comparable items
+	 * @param lo Lower bound index of the subarray to be sorted
+	 * @param hi Upper bound index of the subarray to be sorted
+	 * @param k Pivot element that will be in its sorted place in the array
+	 * @param gc Lambda function to compare items
+	 */
+	public static <T> void sort(Comparable<T>[] a, int lo, int hi, int k, GeneralCompare<T> gc) {
+		if (hi <= lo)
+			return;
+		int j = partition(a, lo, hi, gc);
+		if (j < k)
+			sort(a, j + 1, hi, k, gc); // Sort right part a[j+1 .. hi].
+		else if (j > k)
+			sort(a, lo, j - 1, k, gc); // Sort left part a[lo .. j-1].
+		return;
+	}
+
+	/**
+	 * Places elements smaller than a partitioning element at smaller indices than the partitioning element
+	 * Same algorithm for partitioning as standard QuickSort from 
+	 * @param a Array of comparable items
+	 * @param lo Index that scans from the left side of the array, points to an item to be compared
+	 * @param hi Index that scans from the right side of the array, points to an item to be compared
+	 * @param gc Lambda function to compare items
+	 * @return
+	 */
+	private static <T> int partition(Comparable<T>[] a, int lo, int hi, GeneralCompare<T> gc) {
+		// Partition into a[lo..i-1], a[i], a[i+1..hi].
+		int i = lo, j = hi + 1; // left and right scan indices
+		Comparable<T> v = a[lo]; // partitioning item
+
+		while (true) { // Scan right, scan left, check for scan complete, and exchange.
+			while (gc.compare(a[++i], v) < 0)
+				if (i == hi)
+					break;
+			while (gc.compare(v, a[--j]) < 0)
+				if (j == lo)
+					break;
+			if (i >= j)
+				break;
+			exch(a, i, j);
+		}
+
+		exch(a, lo, j);
+		return j;
+	}
+
+	/**
+	 * Exchanges the values at two indices of an array
+	 * @param a Array of comparable items
+	 * @param b Index of an item to be swapped
+	 * @param c Index of an item to be swapped
+	 */
+	private static <T> void exch(Comparable<T>[] a, int b, int c) {
+		Comparable<T> temp = a[c];
+		a[c] = a[b];
+		a[b] = temp;
+	}
+	
+}
diff --git a/src/sort/Range.java b/src/sort/Range.java
index 4ffa5e71db4df84c414b149504a36e7a32847fcc..59b943785f9b3188d8a55f6dbdd4898114a9874e 100644
--- a/src/sort/Range.java
+++ b/src/sort/Range.java
@@ -37,11 +37,15 @@ public class Range<Key extends Comparable<Key>> {
 		this.boundType = bt;
 	}
 	
+<<<<<<< HEAD
+	public <T> boolean inBounds(T key) {
+=======
 <<<<<<< HEAD
 	public <T> boolean inBounds(T key) {
 =======
 	public boolean inBounds(Key key, GeneralCompare<Key> gc) {
 >>>>>>> fd3aa70... add Bound and Range
+>>>>>>> refs/remotes/origin/master
 		if (boundType == Bound.ANY) return true;
 		else if (boundType == Bound.LOWER) 	return gc.compare(lower, key) <= 0;
 		else if (boundType == Bound.UPPER) 	return gc.compare(upper, key) >= 0;