diff --git a/Tree/.gitignore b/Tree/.gitignore
new file mode 100644
index 0000000..345e61a
--- /dev/null
+++ b/Tree/.gitignore
@@ -0,0 +1,49 @@
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/dictionaries
+
+# Sensitive or high-churn files:
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.xml
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+
+# Gradle:
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# CMake
+cmake-build-debug/
+
+# Mongo Explorer plugin:
+.idea/**/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
diff --git a/Tree/.idea/compiler.xml b/Tree/.idea/compiler.xml
new file mode 100644
index 0000000..8fac1a3
--- /dev/null
+++ b/Tree/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tree/.idea/misc.xml b/Tree/.idea/misc.xml
new file mode 100644
index 0000000..e8942bd
--- /dev/null
+++ b/Tree/.idea/misc.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tree/.idea/modules.xml b/Tree/.idea/modules.xml
new file mode 100644
index 0000000..2691d43
--- /dev/null
+++ b/Tree/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tree/Tree.iml b/Tree/Tree.iml
new file mode 100644
index 0000000..188419f
--- /dev/null
+++ b/Tree/Tree.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tree/pom.xml b/Tree/pom.xml
new file mode 100644
index 0000000..738fb27
--- /dev/null
+++ b/Tree/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+
+ ru.spbau.mit.kazakov
+ Tree
+ 1.0-SNAPSHOT
+
+
+
+ junit
+ junit
+ 4.8
+
+
+ org.jetbrains
+ annotations
+ 13.0
+
+
+
+
\ No newline at end of file
diff --git a/Tree/src/main/java/ru/srbau/mit/kazakov/Tree.java b/Tree/src/main/java/ru/srbau/mit/kazakov/Tree.java
new file mode 100644
index 0000000..7d2d778
--- /dev/null
+++ b/Tree/src/main/java/ru/srbau/mit/kazakov/Tree.java
@@ -0,0 +1,100 @@
+package ru.srbau.mit.kazakov;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Generic binary search tree.
+ *
+ * @param type of stored data
+ */
+public class Tree> {
+ private int size = 0;
+ @Nullable
+ private Node root = null;
+
+ /**
+ * Node for binary search tree. Stores left, right children and data.
+ */
+ private class Node {
+ private Node left = null;
+ private Node right = null;
+ private T data;
+
+ /**
+ * Initializes data with specified value.
+ *
+ * @param value to initialize with
+ */
+ private Node(@NotNull T value) {
+ data = value;
+ }
+ }
+
+ /**
+ * Returns number of stored elements in the tree.
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Checks if there is a value equals to specified value.
+ *
+ * @param value to check
+ * @return true if there is such value, and false otherwise
+ */
+ public boolean contains(@NotNull T value) {
+ Node current = root;
+
+ while (current != null) {
+ if (current.data.compareTo(value) > 0) {
+ current = current.left;
+ } else if (current.data.compareTo(value) < 0) {
+ current = current.right;
+ } else if (current.data.compareTo(value) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Adds new Node storing specified value to the tree.
+ *
+ * @param value to add
+ * @return false if there was specified value, and true otherwise
+ */
+ public boolean add(@NotNull T value) {
+ if (contains(value)) {
+ return false;
+ }
+ if (root == null) {
+ root = new Node(value);
+ size++;
+ return true;
+ }
+
+ Node current = root;
+ Node parent = null;
+ while (current != null) {
+ parent = current;
+ if (current.data.compareTo(value) > 0) {
+ current = current.left;
+ } else if (current.data.compareTo(value) < 0) {
+ current = current.right;
+ }
+
+ }
+
+ if (parent.data.compareTo(value) < 0) {
+ parent.right = new Node(value);
+ } else if (parent.data.compareTo(value) > 0) {
+ parent.left = new Node(value);
+ }
+
+ size++;
+ return true;
+ }
+}
diff --git a/Tree/src/test/java/ru/srbau/mit/kazakov/TreeTest.java b/Tree/src/test/java/ru/srbau/mit/kazakov/TreeTest.java
new file mode 100644
index 0000000..5bb541f
--- /dev/null
+++ b/Tree/src/test/java/ru/srbau/mit/kazakov/TreeTest.java
@@ -0,0 +1,80 @@
+package ru.srbau.mit.kazakov;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TreeTest {
+ @Test
+ public void testConstructor() {
+ new Tree();
+ }
+
+ @Test
+ public void testAddNotExisting() {
+ Tree tree = new Tree();
+ assertTrue(tree.add(false));
+ assertTrue(tree.contains(false));
+ }
+
+ @Test
+ public void testAddExisting() {
+ Tree tree = new Tree();
+ tree.add(1);
+ assertFalse(tree.add(1));
+ assertTrue(tree.contains(1));
+ }
+
+ @Test
+ public void testAddOneHundred() {
+ Tree tree = new Tree();
+ for (int i = 0; i < 100; i++) {
+ assertTrue(tree.add(i));
+ }
+
+ assertTrue(tree.contains(50));
+ }
+
+ @Test
+ public void sizeEmpty() {
+ Tree tree = new Tree();
+ assertEquals(0, tree.size());
+ }
+
+ @Test
+ public void sizeOne() {
+ Tree tree = new Tree();
+ tree.add("abacaba");
+ assertEquals(1, tree.size());
+ }
+
+ @Test
+ public void testSizeOneHundred() {
+ Tree tree = new Tree();
+ for (int i = 0; i < 100; i++) {
+ assertTrue(tree.add(i));
+ }
+
+ assertEquals(100, tree.size());
+ }
+
+ @Test
+ public void testContainsEmpty() {
+ Tree tree = new Tree();
+ assertFalse(tree.contains('z'));
+ }
+
+ @Test
+ public void testContainsNotExisting() {
+ Tree tree = new Tree();
+ tree.add('a');
+ assertFalse(tree.contains('z'));
+ }
+
+ @Test
+ public void testContainsExisting() {
+ Tree tree = new Tree();
+ tree.add('a');
+ assertTrue(tree.contains('a'));
+ }
+}
\ No newline at end of file