diff --git a/src/biotree/BioTree.java b/src/biotree/BioTree.java
index 2af55698db3142780c55e2f3d8e126a18ee9e7ae..891480d81191ac7c9eb675ee92ef3ab4f84b3ce2 100644
--- a/src/biotree/BioTree.java
+++ b/src/biotree/BioTree.java
@@ -1,14 +1,18 @@
 package biotree;
 
+import java.io.IOException;
+
+import search.BST;
+
 public class BioTree {
-	private static Species[] species;
+	private static BST<Integer, TaxonNode> nodes;
 	private static int n;
 	
 	/**
 	 * Initialize species abstract object
 	 */
 	public static void init() {
-		species = new Species[500];
+		nodes = new BST<Integer, TaxonNode>();
 		n = 0;
 	}
 
@@ -33,27 +37,48 @@ public class BioTree {
 	}
 
 	/**
-	 * Add a new species to the module
+	 * Process a record. Adds classification to tree if it doesn't exist.
+	 * Returns the taxonId of the new / existing record.
 	 * 
-	 * @param s
-	 *            New Species to add.
-	 * @return speciesid of new species entry
+	 * @param taxonId The taxonId of the possible new entry
+	 * @return taxonId of new species entry
 	 */
-	public static int addSpecies(Species s) {
-		species[n++] = s;
-		return n;
+	public static int processRecord(int taxonId) {
+		processTaxonId(taxonId);
+		return taxonId;
 	}
-
+	
 	/**
-	 * Update an existing species object.
+	 * Process a record. Adds classification to tree if it doesn't exist.
+	 * Returns the taxonId of the new / existing record.
 	 * 
-	 * @param i
-	 *            The index of the species to update.
-	 * @param s
-	 *            The new Species object to overwrite the old one with.
+	 * @param scientificName The scientific name of the possible new entry
+	 * @return taxonId of new / existing entry
+	 * @throws IOException 
+	 */
+	public static int processRecord(String scientificName) throws IOException {
+		int taxonId = WormsAPI.nameToID(scientificName);
+		processTaxonId(taxonId);
+		return taxonId;
+	}
+	
+	/**
+	 * Process a new entry if it doesn't exist.
+	 * @param taxonId
 	 */
-	public static void setSpecies(int i, Species s) {
-		species[i] = s;
+	private static void processTaxonId(int taxonId) {
+		TaxonNode[] newNodes = WormsAPI.idToClassification(taxonId);
+		for (int i = newNodes.length - 1; i > 0; i--) {
+			TaxonNode tx = newNodes[i];
+			TaxonNode result = nodes.get(tx.getTaxonId());
+			TaxonNode parent = nodes.get(newNodes[i - 1].getTaxonId());
+			if (parent == null) parent = newNodes[i - 1];
+			if (result == null) { //if node is not found, add it
+				tx.setParent(parent);
+				parent.addChild(tx);
+			} else
+				break; //stop loop if this node already exists in the tree
+		}
 	}
 
 	/**
@@ -63,58 +88,7 @@ public class BioTree {
 	 *            The speciesid (index) of the species.
 	 * @return The Species object.
 	 */
-	public static Species getSpecies(int i) {
-		return species[i];
+	public static TaxonNode getTaxonRecord(int taxonId) {
+		return nodes.get(taxonId);
 	}
-
-	/**
-	 * Search for a species by name.
-	 * 
-	 * @param s
-	 *            The name of the species.
-	 * @return The speciesid of the species or -1 if it is not found.
-	 */
-	public static int findSpecies(String s) {
-		for (int i = 0; i < n; i++)
-			if (species[i].getSpecies() == s)
-				return i;
-		return -1;
-	}
-
-	/**
-	 * TODO: Implement
-	 * 
-	 * @param s
-	 *            The name of the genus.
-	 * @return Array of speciesid belonging to the genus.
-	 */
-	public static int[] findGenus(String s) {
-		int[] dummy = { 1, 2, 3 };
-		return dummy;
-	}
-
-	/**
-	 * TODO: Implement
-	 * 
-	 * @param s
-	 *            The name of the family.
-	 * @return Array of speciesid belonging to the family.
-	 */
-	public static int[] findFamily(String s) {
-		int[] dummy = { 1, 2, 3 };
-		return dummy;
-	}
-
-	/**
-	 * TODO: Implement
-	 * 
-	 * @param s
-	 *            The name of the order.
-	 * @return Array of speciesid belonging to the order.
-	 */
-	public static int[] findOrder(String s) {
-		int[] dummy = { 1, 2, 3 };
-		return dummy;
-	}
-
 }
diff --git a/src/biotree/TestBioTree.java b/src/biotree/TestBioTree.java
index 3dfe00455c1187808e2cfb1a07b423f0492539a0..b771b0ecd113e4147654c98cc4002ab6f6a8ab34 100644
--- a/src/biotree/TestBioTree.java
+++ b/src/biotree/TestBioTree.java
@@ -24,8 +24,8 @@ public class TestBioTree {
 	
 	@Test
 	public void testGetSpecies() {
-		assert BioTree.getSpecies(0).getSpecies() == "Morone chrysops";
-		assert BioTree.getSpecies(1).getSpecies() == "Perca flavescens";
+		assert BioTree.getTaxonRecord(0).getSpecies() == "Morone chrysops";
+		assert BioTree.getTaxonRecord(1).getSpecies() == "Perca flavescens";
 	}
 
 }
diff --git a/src/biotree/WormsAPI.java b/src/biotree/WormsAPI.java
index 39f47d3bc7b60c4e20f4a98791c82f71f7538905..2ae560cd0c2fe87c6c48130cd3ebc0d438ad4151 100644
--- a/src/biotree/WormsAPI.java
+++ b/src/biotree/WormsAPI.java
@@ -22,7 +22,7 @@ public class WormsAPI {
 	
 	public static void main(String[] args) throws IOException, ParseException {
 		//small test
-		
+		System.out.println(nameToID("Neogobius melanostomus"));
 		/*
 		TaxonNode[] taxnodes = idToClassification(126916);
 
@@ -73,6 +73,7 @@ public class WormsAPI {
 	 * @throws IOException 
 	 * @throws ParseException 
 	 */
+<<<<<<< HEAD
 	public static TaxonNode[] idToClassification(int taxonId) throws IOException, ParseException {
 		String resp = makeRequest(String.format("http://marinespecies.org/rest/AphiaClassificationByAphiaID/%d", taxonId));
 		JSONParser parser = new JSONParser();
@@ -84,6 +85,9 @@ public class WormsAPI {
 		TaxonNode[] copiedArray = new TaxonNode[arraysize];
 
 		System.arraycopy(taxnodes, 0, copiedArray, 0, arraysize);
+=======
+	public static TaxonNode[] idToClassification(int taxonId) {
+>>>>>>> 7713da5ef410b951f64f9d9fda4937386132f0a0
 		
 		return copiedArray;
 		
diff --git a/src/search/BST.java b/src/search/BST.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ec7e8a3cbaaa71e3e0447469386f19a013f8cdb
--- /dev/null
+++ b/src/search/BST.java
@@ -0,0 +1,177 @@
+package search;
+
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+public class BST<Key extends Comparable<Key>, Value> {
+	private Node root;
+	
+	private class Node{
+		private Key key;
+		private Value val;
+		private Node left, right;
+		private int N;
+		
+		public Node(Key key, Value val, int N) {
+			this.key = key;
+			this.val = val;
+			this.N = N;
+		}
+	}
+		
+	public int size() {
+		return size(root);
+	}
+	
+	private int size(Node x) {
+		if (x == null) return 0;
+		else return x.N;
+	}
+	
+	public Value get(Key key) { return get(root, key); }
+	
+	private Value get(Node x, Key key) {
+		if (x == null) return null;
+		int cmp = key.compareTo(x.key);
+		if (cmp < 0) return get(x.left, key);
+		else if (cmp > 0) return get(x.right, key);
+		else return x.val;
+	}
+	
+	public void put(Key key, Value val) {
+		root = put(root, key, val);
+	}
+	
+	private Node put(Node x, Key key, Value val) {
+		if (x == null) return new Node(key, val, 1);
+		
+		int cmp = key.compareTo(x.key);
+		
+		if (cmp < 0) x.left = put(x.left, key, val);
+		else if (cmp > 0) x.right = put(x.right, key, val);
+		else x.val = val;
+		
+		x.N = size(x.left) + size(x.right) + 1;
+		return x;
+	}
+	
+	public boolean isEmpty() {
+		return root == null;
+	}
+	
+	public Key min() {
+		if (isEmpty()) throw new NoSuchElementException();
+		Node x = min(root);
+		return x.key;
+	}
+	
+	private Node min(Node x) {
+		if (x.left == null) return x;
+		return min(x.left);
+	}
+	
+	public Key max() {
+		if (isEmpty()) throw new NoSuchElementException();
+		Node x = max(root);
+		return x.key;
+	}
+	
+	private Node max(Node x) {
+		if (x.right == null) return x;
+		return max(x.right);
+	}
+	
+	public Key floor(Key key) {
+		Node x = floor(root, key);
+		if (x == null) throw new NoSuchElementException();
+		return x.key;
+	}
+	
+	private Node floor(Node x, Key key) {
+		if (x == null) return null;
+		int cmp = key.compareTo(x.key);
+		if (cmp == 0) return x;
+		if (cmp < 0) return floor(x.left, key);
+		Node t = floor(x.right, key);
+		if (t != null) 	return t;
+		else 			return x;
+	}
+	
+	public Key select(int k) {
+		if (k < 0 || k >= size()) throw new IllegalArgumentException();
+		Node x = select(root, k);
+		return x.key;
+	}
+	
+	private Node select(Node x, int k) {
+		if (x == null) return null;
+		int t = size(x.left);
+		if		(t > k)	return select(x.left, k);
+		else if (t < k)	return select(x.right, k - t -1);
+		else				return x;
+	}
+	
+	public int rank(Key key) {
+		return rank(key, root);
+	}
+	
+	private int rank(Key key, Node x) {
+		if (x == null) return 0;
+		int cmp = key.compareTo(x.key);
+		if		(cmp < 0) 	return rank(key, x.left);
+		else if	(cmp > 0) 	return 1 + size(x.left) + rank(key, x.right);
+		else					return size(x.left);
+	}
+	
+	public void deleteMin() {
+		if (isEmpty()) throw new NoSuchElementException();
+		root = deleteMin(root);
+	}
+	
+	private Node deleteMin(Node x) {
+		if (x.left == null) return x.right;
+		x.left = deleteMin(x.left);
+		x.N = size(x.left) + size(x.right) + 1;
+		return x;
+	}
+	
+	public void delete(Key key) {
+		root = delete(root, key);
+	}
+	
+	private Node delete(Node x, Key key) {
+		if (x == null) return null;
+		int cmp = key.compareTo(x.key);
+		if		(cmp < 0) x.left 	= delete(x.left, key);
+		else if 	(cmp > 0) x.right 	= delete(x.right, key);
+		else {
+			if (x.right == null) return x.left;
+			if (x.left == null) return x.right;
+			Node t = x;
+			x = min(t.right);
+			x.right = deleteMin(t.right);
+			x.left = t.left;
+		}
+		x.N  = size(x.left) + size(x.right) + 1;
+		return x;
+	}
+	
+	public Iterable<Key> keys() {
+		return keys(min(), max());
+	}
+	
+	public Iterable<Key> keys(Key lo, Key hi) {
+		ArrayList<Key> al = new ArrayList<Key>();
+		keys(root, al, lo, hi);
+		return al;
+	}
+	
+	private void keys(Node x, ArrayList<Key> al, Key lo, Key hi) {
+		if (x == null) return;
+		int cmplo = lo.compareTo(x.key);
+		int cmphi = hi.compareTo(x.key);
+		if (cmplo < 0) keys(x.left, al, lo, hi);
+		if (cmplo <= 0 && cmphi >= 0) al.add(x.key);
+		if (cmphi > 0) keys(x.right, al, lo, hi);
+	}
+}