diff --git a/students/812350401/pom.xml b/students/812350401/pom.xml
index e33e2dad0..80ef59787 100644
--- a/students/812350401/pom.xml
+++ b/students/812350401/pom.xml
@@ -38,6 +38,7 @@
     	<groupId>junit</groupId>
     	<artifactId>junit</artifactId>
     	<version>4.12</version>
+          <!--<version>3.8.1</version>-->
     </dependency>
       <dependency>
           <groupId>com.google.collections</groupId>
@@ -49,7 +50,6 @@
           <artifactId>commons-codec</artifactId>
           <version>1.6</version>
       </dependency>
-
   </dependencies>
   <repositories>
         <repository>
diff --git a/students/812350401/src/main/java/com/coderising/mydp/command/Client.java b/students/812350401/src/main/java/com/coderising/mydp/command/Client.java
new file mode 100644
index 000000000..ad8c17699
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/command/Client.java
@@ -0,0 +1,21 @@
+package com.coderising.mydp.command;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ * 命令模式
+ */
+public class Client {
+
+    public static void main(String[] args) {
+        Cook cook = new Cook();
+        Waitor waitor = new Waitor();
+
+        Command command1 = new OrderPorkCommand(cook);
+        Command command2 = new OrderSteakCommand(cook);
+
+        waitor.addOrder(command1);
+        waitor.addOrder(command2);
+
+        waitor.sendOrders();
+    }
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/command/Command.java b/students/812350401/src/main/java/com/coderising/mydp/command/Command.java
new file mode 100644
index 000000000..922c77420
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/command/Command.java
@@ -0,0 +1,8 @@
+package com.coderising.mydp.command;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public interface Command {
+    void execute();
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/command/Cook.java b/students/812350401/src/main/java/com/coderising/mydp/command/Cook.java
new file mode 100644
index 000000000..940e17869
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/command/Cook.java
@@ -0,0 +1,23 @@
+package com.coderising.mydp.command;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public class Cook {
+
+    public void cookSteak() {
+        System.out.println("Steak is ok");
+    }
+
+    public void cookPork() {
+        System.out.println("Pork is ok");
+    }
+
+    public static void main(String[] args) {
+        StringBuilder x = new StringBuilder("Hello");
+        String r1 = x.append(",world").toString();
+        String r2 = x.append(",world").toString();
+        System.out.println(r1);
+        System.out.println(r2);
+    }
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/command/OrderPorkCommand.java b/students/812350401/src/main/java/com/coderising/mydp/command/OrderPorkCommand.java
new file mode 100644
index 000000000..a887b6f3f
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/command/OrderPorkCommand.java
@@ -0,0 +1,16 @@
+package com.coderising.mydp.command;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public class OrderPorkCommand implements Command {
+    private Cook cook;
+
+    public OrderPorkCommand(Cook cook) {
+        this.cook = cook;
+    }
+    @Override
+    public void execute() {
+        cook.cookPork();
+    }
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/command/OrderSteakCommand.java b/students/812350401/src/main/java/com/coderising/mydp/command/OrderSteakCommand.java
new file mode 100644
index 000000000..3319d141d
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/command/OrderSteakCommand.java
@@ -0,0 +1,16 @@
+package com.coderising.mydp.command;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public class OrderSteakCommand implements Command {
+    private Cook cook;
+    public OrderSteakCommand(Cook cook) {
+        this.cook = cook;
+    }
+
+    @Override
+    public void execute() {
+        cook.cookSteak();
+    }
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/command/Waitor.java b/students/812350401/src/main/java/com/coderising/mydp/command/Waitor.java
new file mode 100644
index 000000000..5bdf920fc
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/command/Waitor.java
@@ -0,0 +1,20 @@
+package com.coderising.mydp.command;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public class Waitor {
+    List<Command> commands = new ArrayList<>();
+
+    public void addOrder(Command command) {
+        commands.add(command);
+    }
+
+    public void sendOrders() {
+        commands.stream().forEach(Command::execute);
+    }
+
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/responseChain/AbstractLogger.java b/students/812350401/src/main/java/com/coderising/mydp/responseChain/AbstractLogger.java
new file mode 100644
index 000000000..778962e2f
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/responseChain/AbstractLogger.java
@@ -0,0 +1,26 @@
+package com.coderising.mydp.responseChain;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public abstract class AbstractLogger {
+    public static final String DEBUG = "DEBUG";
+    public static final String NOTICE = "NOTICE";
+    public static final String ERR = "ERR";
+
+    /**
+     * 持有下一个处理请求的对象
+     */
+    private AbstractLogger next = null;
+
+    public AbstractLogger getNext() {
+        return next;
+    }
+
+    public AbstractLogger setNext(AbstractLogger next) {
+        this.next = next;
+        return this;
+    }
+
+    public abstract void message(String message, String type);
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/responseChain/Client.java b/students/812350401/src/main/java/com/coderising/mydp/responseChain/Client.java
new file mode 100644
index 000000000..30f27b494
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/responseChain/Client.java
@@ -0,0 +1,23 @@
+package com.coderising.mydp.responseChain;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public class Client {
+
+    public static void main(String[] args) {
+        AbstractLogger logger = new StdoutLogger()
+                .setNext(new EmailLogger()
+                .setNext(new FileLogger()));
+
+        // 由StdoutLogger处理
+        logger.message("进入计算函数", AbstractLogger.DEBUG);
+        // 由StdoutLogger和EmailLogger处理
+        System.out.println("*****************");
+        logger.message("第一步已完成", AbstractLogger.NOTICE);
+        // 由所有logger处理
+        System.out.println("*****************");
+        logger.message("一个致命的错误发生了", AbstractLogger.ERR);
+    }
+
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/responseChain/EmailLogger.java b/students/812350401/src/main/java/com/coderising/mydp/responseChain/EmailLogger.java
new file mode 100644
index 000000000..54605eba5
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/responseChain/EmailLogger.java
@@ -0,0 +1,15 @@
+package com.coderising.mydp.responseChain;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public class EmailLogger extends AbstractLogger {
+
+    @Override
+    public void message(String message, String type) {
+        System.out.println("EmailLogger处理:" + message);
+        if (!AbstractLogger.NOTICE.equals(type)) {
+            getNext().message(message, type);
+        }
+    }
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/responseChain/FileLogger.java b/students/812350401/src/main/java/com/coderising/mydp/responseChain/FileLogger.java
new file mode 100644
index 000000000..2c6d316ee
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/responseChain/FileLogger.java
@@ -0,0 +1,11 @@
+package com.coderising.mydp.responseChain;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public class FileLogger extends AbstractLogger {
+    @Override
+    public void message(String message, String type) {
+        System.out.println("FileLogger处理:" + message);
+    }
+}
diff --git a/students/812350401/src/main/java/com/coderising/mydp/responseChain/StdoutLogger.java b/students/812350401/src/main/java/com/coderising/mydp/responseChain/StdoutLogger.java
new file mode 100644
index 000000000..29ae7a1d1
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/mydp/responseChain/StdoutLogger.java
@@ -0,0 +1,14 @@
+package com.coderising.mydp.responseChain;
+
+/**
+ * Created by thomas_young on 11/8/2017.
+ */
+public class StdoutLogger extends AbstractLogger {
+    @Override
+    public void message(String message, String type) {
+        System.out.println("StdoutLogger处理:" + message);
+        if (!AbstractLogger.DEBUG.equals(type)) {
+            getNext().message(message, type);
+        }
+    }
+}
diff --git a/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/Client.java b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/Client.java
new file mode 100644
index 000000000..40aeb5976
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/Client.java
@@ -0,0 +1,37 @@
+package com.coderising.myknowledgepoint.myResponseChain;
+
+/**
+ * Created by thomas_young on 10/8/2017.
+ * http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
+ */
+
+public class Client {
+
+    public static void main(String[] args) {
+        //先要组装责任链
+        Handler h1 = new GeneralManager();
+        Handler h2 = new DeptManager();
+        Handler h3 = new ProjectManager();
+        h3.setSuccessor(h2);
+        h2.setSuccessor(h1);
+
+        //开始测试
+        String test1 = h3.handleFeeRequest("张三", 300);
+        System.out.println("test1 = " + test1);
+        String test2 = h3.handleFeeRequest("李四", 300);
+        System.out.println("test2 = " + test2);
+        System.out.println("---------------------------------------");
+
+        String test3 = h3.handleFeeRequest("张三", 700);
+        System.out.println("test3 = " + test3);
+        String test4 = h3.handleFeeRequest("李四", 700);
+        System.out.println("test4 = " + test4);
+        System.out.println("---------------------------------------");
+
+        String test5 = h3.handleFeeRequest("张三", 1500);
+        System.out.println("test5 = " + test5);
+        String test6 = h3.handleFeeRequest("李四", 1500);
+        System.out.println("test6 = " + test6);
+    }
+
+}
diff --git a/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/DeptManager.java b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/DeptManager.java
new file mode 100644
index 000000000..d051b7f37
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/DeptManager.java
@@ -0,0 +1,35 @@
+package com.coderising.myknowledgepoint.myResponseChain;
+
+/**
+ * Created by thomas_young on 10/8/2017.
+ */
+public class DeptManager extends Handler {
+
+    @Override
+    public String handleFeeRequest(String user, double fee) {
+
+        String str = "";
+        //部门经理的权限只能在1000以内
+        if(fee < 1000)
+        {
+            //为了测试，简单点，只同意张三的请求
+            if("张三".equals(user))
+            {
+                str = "成功：部门经理同意【" + user + "】的聚餐费用，金额为" + fee + "元";
+            }else
+            {
+                //其他人一律不同意
+                str = "失败：部门经理不同意【" + user + "】的聚餐费用，金额为" + fee + "元";
+            }
+        }else
+        {
+            //超过1000，继续传递给级别更高的人处理
+            if(getSuccessor() != null)
+            {
+                return getSuccessor().handleFeeRequest(user, fee);
+            }
+        }
+        return str;
+    }
+
+}
diff --git a/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/GeneralManager.java b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/GeneralManager.java
new file mode 100644
index 000000000..2d601604c
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/GeneralManager.java
@@ -0,0 +1,34 @@
+package com.coderising.myknowledgepoint.myResponseChain;
+
+/**
+ * Created by thomas_young on 10/8/2017.
+ */
+public class GeneralManager extends Handler {
+
+    @Override
+    public String handleFeeRequest(String user, double fee) {
+
+        String str = "";
+        //总经理的权限很大，只要请求到了这里，他都可以处理
+        if(fee >= 1000)
+        {
+            //为了测试，简单点，只同意张三的请求
+            if("张三".equals(user))
+            {
+                str = "成功：总经理同意【" + user + "】的聚餐费用，金额为" + fee + "元";
+            }else
+            {
+                //其他人一律不同意
+                str = "失败：总经理不同意【" + user + "】的聚餐费用，金额为" + fee + "元";
+            }
+        }else {
+            //如果还有后继的处理对象，继续传递
+            if(getSuccessor() != null)
+            {
+                return getSuccessor().handleFeeRequest(user, fee);
+            }
+        }
+        return str;
+    }
+
+}
diff --git a/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/Handler.java b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/Handler.java
new file mode 100644
index 000000000..a032475bd
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/Handler.java
@@ -0,0 +1,30 @@
+package com.coderising.myknowledgepoint.myResponseChain;
+
+/**
+ * Created by thomas_young on 10/8/2017.
+ */
+public abstract class Handler {
+    /**
+     * 持有下一个处理请求的对象
+     */
+    protected Handler successor = null;
+    /**
+     * 取值方法
+     */
+    public Handler getSuccessor() {
+        return successor;
+    }
+    /**
+     * 设置下一个处理请求的对象
+     */
+    public void setSuccessor(Handler successor) {
+        this.successor = successor;
+    }
+    /**
+     * 处理聚餐费用的申请
+     * @param user    申请人
+     * @param fee    申请的钱数
+     * @return        成功或失败的具体通知
+     */
+    public abstract String handleFeeRequest(String user , double fee);
+}
\ No newline at end of file
diff --git a/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/ProjectManager.java b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/ProjectManager.java
new file mode 100644
index 000000000..7fa75aa66
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myknowledgepoint/myResponseChain/ProjectManager.java
@@ -0,0 +1,35 @@
+package com.coderising.myknowledgepoint.myResponseChain;
+
+/**
+ * Created by thomas_young on 10/8/2017.
+ */
+public class ProjectManager extends Handler {
+
+    @Override
+    public String handleFeeRequest(String user, double fee) {
+
+        String str = "";
+        //项目经理权限比较小，只能在500以内
+        if(fee < 500)
+        {
+            //为了测试，简单点，只同意张三的请求
+            if("张三".equals(user))
+            {
+                str = "成功：项目经理同意【" + user + "】的聚餐费用，金额为" + fee + "元";
+            }else
+            {
+                //其他人一律不同意
+                str = "失败：项目经理不同意【" + user + "】的聚餐费用，金额为" + fee + "元";
+            }
+        }else
+        {
+            //超过500，继续传递给级别更高的人处理
+            if(getSuccessor() != null)
+            {
+                return getSuccessor().handleFeeRequest(user, fee);
+            }
+        }
+        return str;
+    }
+
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/Assert.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/Assert.java
new file mode 100644
index 000000000..d54221364
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/Assert.java
@@ -0,0 +1,225 @@
+package com.coderising.myood.litejunit.liuxinv1;
+
+/**
+ * A set of assert methods.
+ */
+
+public class Assert {
+	/**
+	 * Protect constructor since it is a static only class
+	 */
+	protected Assert() {
+	}
+	
+	/**
+	 * Asserts that a condition is true. If it isn't it throws
+	 * an AssertionFailedError with the given message.
+	 */
+	static public void assertTrue(String message, boolean condition) {
+		if (!condition)
+			fail(message);
+	}
+	/**
+	 * Asserts that a condition is true. If it isn't it throws
+	 * an AssertionFailedError.
+	 */
+	static public void assertTrue(boolean condition) {
+		assertTrue(null, condition);
+	}
+	/**
+	 * Fails a test with the given message. 
+	 */
+	static public void fail(String message) {
+		throw new AssertionFailedError(message);
+	}
+	/**
+	 * Fails a test with no message. 
+	 */
+	static public void fail() {
+		fail(null);
+	}
+	/**
+	 * Asserts that two objects are equal. If they are not
+	 * an AssertionFailedError is thrown.
+	 */
+	static public void assertEquals(String message, Object expected, Object actual) {
+		if (expected == null && actual == null)
+			return;
+		if (expected != null && expected.equals(actual))
+			return;
+		failNotEquals(message, expected, actual);
+	}
+	/**
+	 * Asserts that two objects are equal. If they are not
+	 * an AssertionFailedError is thrown.
+	 */
+	static public void assertEquals(Object expected, Object actual) {
+	    assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two doubles are equal concerning a delta. If the expected
+	 * value is infinity then the delta value is ignored.
+	 */
+	static public void assertEquals(String message, double expected, double actual, double delta) {
+		// handle infinity specially since subtracting to infinite values gives NaN and the
+		// the following test fails
+		if (Double.isInfinite(expected)) {
+			if (!(expected == actual))
+				failNotEquals(message, new Double(expected), new Double(actual));
+		} else if (!(Math.abs(expected-actual) <= delta)) // Because comparison with NaN always returns false
+			failNotEquals(message, new Double(expected), new Double(actual));
+	}
+	/**
+	 * Asserts that two doubles are equal concerning a delta. If the expected
+	 * value is infinity then the delta value is ignored.
+	 */
+	static public void assertEquals(double expected, double actual, double delta) {
+	    assertEquals(null, expected, actual, delta);
+	}
+	/**
+	 * Asserts that two floats are equal concerning a delta. If the expected
+	 * value is infinity then the delta value is ignored.
+	 */
+	static public void assertEquals(String message, float expected, float actual, float delta) {
+ 		// handle infinity specially since subtracting to infinite values gives NaN and the
+		// the following test fails
+		if (Float.isInfinite(expected)) {
+			if (!(expected == actual))
+				failNotEquals(message, new Float(expected), new Float(actual));
+		} else if (!(Math.abs(expected-actual) <= delta))
+      		failNotEquals(message, new Float(expected), new Float(actual));
+	}
+	/**
+	 * Asserts that two floats are equal concerning a delta. If the expected
+	 * value is infinity then the delta value is ignored.
+	 */
+	static public void assertEquals(float expected, float actual, float delta) {
+		assertEquals(null, expected, actual, delta);
+	}
+	/**
+	 * Asserts that two longs are equal.
+	 */
+	static public void assertEquals(String message, long expected, long actual) {
+	    assertEquals(message, new Long(expected), new Long(actual));
+	}
+	/**
+	 * Asserts that two longs are equal.
+	 */
+	static public void assertEquals(long expected, long actual) {
+	    assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two booleans are equal.
+	 */
+	static public void assertEquals(String message, boolean expected, boolean actual) {
+    		assertEquals(message, new Boolean(expected), new Boolean(actual));
+  	}
+	/**
+	 * Asserts that two booleans are equal.
+ 	 */
+	static public void assertEquals(boolean expected, boolean actual) {
+		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two bytes are equal.
+	 */
+  	static public void assertEquals(String message, byte expected, byte actual) {
+		assertEquals(message, new Byte(expected), new Byte(actual));
+	}
+	/**
+   	 * Asserts that two bytes are equal.
+	 */
+	static public void assertEquals(byte expected, byte actual) {
+		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two chars are equal.
+	 */
+  	static public void assertEquals(String message, char expected, char actual) {
+    		assertEquals(message, new Character(expected), new Character(actual));
+  	}
+	/**
+	 * Asserts that two chars are equal.
+	 */
+  	static public void assertEquals(char expected, char actual) {
+		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two shorts are equal.
+	 */
+	static public void assertEquals(String message, short expected, short actual) {
+    		assertEquals(message, new Short(expected), new Short(actual));
+	}
+  	/**
+	 * Asserts that two shorts are equal.
+	 */
+	static public void assertEquals(short expected, short actual) {
+		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two ints are equal.
+	 */
+  	static public void assertEquals(String message, int expected, int actual) {
+		assertEquals(message, new Integer(expected), new Integer(actual));
+  	}
+  	/**
+   	 * Asserts that two ints are equal.
+	 */
+  	static public void assertEquals(int expected, int actual) {
+  		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that an object isn't null.
+	 */
+	static public void assertNotNull(Object object) {
+		assertNotNull(null, object);
+	}
+	/**
+	 * Asserts that an object isn't null.
+	 */
+	static public void assertNotNull(String message, Object object) {
+		assertTrue(message, object != null); 
+	}
+	/**
+	 * Asserts that an object is null.
+	 */
+	static public void assertNull(Object object) {
+		assertNull(null, object);
+	}
+	/**
+	 * Asserts that an object is null.
+	 */
+	static public void assertNull(String message, Object object) {
+		assertTrue(message, object == null); 
+	}
+	/**
+	 * Asserts that two objects refer to the same object. If they are not
+	 * an AssertionFailedError is thrown.
+	 */
+	static public void assertSame(String message, Object expected, Object actual) {
+		if (expected == actual)
+			return;
+		failNotSame(message, expected, actual);
+	}
+	/**
+	 * Asserts that two objects refer to the same object. If they are not
+	 * the same an AssertionFailedError is thrown.
+	 */
+	static public void assertSame(Object expected, Object actual) {
+	    assertSame(null, expected, actual);
+	}
+	
+	static private void failNotEquals(String message, Object expected, Object actual) {
+		String formatted= "";
+		if (message != null)
+			formatted= message+" ";
+		fail(formatted+"expected:<"+expected+"> but was:<"+actual+">");
+	}
+	
+	static private void failNotSame(String message, Object expected, Object actual) {
+		String formatted= "";
+		if (message != null)
+			formatted= message+" ";
+		fail(formatted+"expected same");
+	}
+}
\ No newline at end of file
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/AssertionFailedError.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/AssertionFailedError.java
new file mode 100644
index 000000000..9724d5bd9
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/AssertionFailedError.java
@@ -0,0 +1,13 @@
+package com.coderising.myood.litejunit.liuxinv1;
+
+/**
+ * Thrown when an assertion failed.
+ */
+public class AssertionFailedError extends Error {
+
+	public AssertionFailedError () {
+	}
+	public AssertionFailedError (String message) {
+		super (message);
+	}
+}
\ No newline at end of file
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/Calculator.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/Calculator.java
new file mode 100644
index 000000000..7ff741ee8
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/Calculator.java
@@ -0,0 +1,22 @@
+package com.coderising.myood.litejunit.liuxinv1;
+
+public class Calculator {
+	
+	private int result = 0;
+	public  void add(int x){
+		result += x;
+	}
+	public void subtract(int x){
+		result -=x;
+	}
+	
+	public int getResult(){
+		return this.result;
+	}
+	public static void main(String[] args){
+		Calculator calculator = new Calculator();
+		calculator.add(10);
+		calculator.subtract(5);		
+		System.out.println(calculator.getResult());
+	}
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/CalculatorTest.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/CalculatorTest.java
new file mode 100644
index 000000000..cb2d8cd2c
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/CalculatorTest.java
@@ -0,0 +1,77 @@
+package com.coderising.myood.litejunit.liuxinv1;
+
+
+public class CalculatorTest extends TestCase {
+	public CalculatorTest(String name) {
+		super(name);
+
+	}
+	Calculator calculator =null;
+	public void setUp(){
+		calculator = new Calculator();
+	}
+	public void tearDown(){
+		calculator = null;
+	}
+	public void testAdd(){
+		
+		calculator.add(10);
+		assertEquals(10,calculator.getResult());
+	}	
+	public void testSubtract(){
+		calculator.add(10);
+		calculator.subtract(5);
+		assertEquals(4,calculator.getResult());
+	}
+
+	private void testXX() {
+
+    }
+	
+	public static void main(String[] args){
+		TestSuite ts = new TestSuite(CalculatorTest.class);
+		TestResult tr = new TestResult();
+		ts.run(tr);
+		System.out.println(tr.wasSuccessful());
+		for(TestFailure failure : tr.failures){
+			System.err.println(failure);
+		}
+        /*
+        Iterator<TestFailure> iterator = tr.failures();
+		while(iterator.hasNext()) {
+		    System.err.println(iterator.next());
+        }
+        */
+//        TestSuite ts2 = new TestSuite();
+//		ts2.addTest(ts);
+//        ts2.run(tr);
+        /*{
+		TestCase tc1 = new CalculatorTest("testAdd"){
+			protected void runTest() {
+				testAdd();
+			}
+		};
+		
+		TestCase tc2 = new CalculatorTest("testSubtract"){
+			protected void runTest() {
+				testSubtract();
+			}
+		};
+		tc1.run();
+		tc2.run();
+		}
+		
+		
+		TestSuite ts = new TestSuite();
+		ts.addTest(new CalculatorTest("testAdd"));
+		ts.addTest(new CalculatorTest("testSubtract"));
+		
+		
+		{
+			TestCase tc1 = new CalculatorTest("test1");
+			TestCase tc2 = new CalculatorTest("test2");
+			tc1.run();
+			tc2.run();
+		}*/
+	}
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/Test.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/Test.java
new file mode 100644
index 000000000..c2e390382
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/Test.java
@@ -0,0 +1,6 @@
+package com.coderising.myood.litejunit.liuxinv1;
+
+public interface Test {
+	public abstract int countTestCases();  // command模式，一个测试用例是一个command
+	public void run(TestResult tr);  // 分离测试用例和测试结果，收集参数模式
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestCase.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestCase.java
new file mode 100644
index 000000000..1a0887f2a
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestCase.java
@@ -0,0 +1,63 @@
+package com.coderising.myood.litejunit.liuxinv1;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+
+
+public abstract class TestCase extends Assert implements Test {
+	private String name;
+	
+	TestCase() {}
+	public TestCase(String name) {
+		this.name = name;
+	}
+	
+	public int countTestCases() {
+		return 1;
+	}
+
+	protected void runTest() throws Throwable {
+		Method runMethod= null;
+		try {			
+			runMethod= getClass().getMethod(name, null);
+		} catch (NoSuchMethodException e) {
+			fail("Method \""+name+"\" not found");
+		}
+		if (!Modifier.isPublic(runMethod.getModifiers())) {
+			fail("Method \""+name+"\" should be public");
+		}
+
+		try {
+			runMethod.invoke(this, new Class[0]);
+		}
+		catch (InvocationTargetException e) {
+			e.fillInStackTrace();
+			throw e.getTargetException();
+		}
+		catch (IllegalAccessException e) {
+			e.fillInStackTrace();
+			throw e;
+		}
+	}
+
+	protected void setUp() {
+	}
+
+	protected void tearDown() {
+	}
+	
+	public void run(TestResult tr) {
+		tr.run(this);
+	}
+	public void doRun() throws Throwable{
+		setUp();
+		try{
+			runTest();
+		} 
+		finally{
+			tearDown();
+		}		
+	}
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestFailure.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestFailure.java
new file mode 100644
index 000000000..08d75a5e9
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestFailure.java
@@ -0,0 +1,39 @@
+package com.coderising.myood.litejunit.liuxinv1;
+
+/**
+ * A <code>TestFailure</code> collects a failed test together with
+ * the caught exception.
+ * @see TestResult
+ */
+public class TestFailure {
+	protected Test failedTest;
+	protected Throwable thrownException;
+
+	/**
+	 * Constructs a TestFailure with the given test and exception.
+	 */
+	public TestFailure(Test failedTest, Throwable thrownException) {
+		this.failedTest= failedTest;
+		this.thrownException= thrownException;
+	}
+	/**
+	 * Gets the failed test.
+	 */
+	public Test failedTest() {
+	    return failedTest;
+	}
+	/**
+	 * Gets the thrown exception.
+	 */
+	public Throwable thrownException() {
+	    return thrownException;
+	}
+	/**
+	 * Returns a short description of the failure.
+	 */
+	public String toString() {
+	    StringBuffer buffer= new StringBuffer();
+	    buffer.append(failedTest+": "+thrownException.getMessage());
+	    return buffer.toString();
+	}
+}
\ No newline at end of file
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestResult.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestResult.java
new file mode 100644
index 000000000..69b09b892
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestResult.java
@@ -0,0 +1,92 @@
+package com.coderising.myood.litejunit.liuxinv1;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class TestResult extends Object {
+	protected List<TestFailure> failures;  // 存储assert失败
+	protected List<TestFailure> errors;  // 存储业务代码异常，比如空指针
+	
+	protected int testCount;
+	private boolean stop;
+	
+	public TestResult() {
+		failures= new ArrayList<>();
+		errors= new ArrayList<>();	
+		
+		testCount= 0;
+		stop= false;
+	}
+	
+	public  void addError(Test test, Throwable t) {
+		errors.add(new TestFailure(test, t));		
+	}
+	
+	public  void addFailure(Test test, AssertionFailedError t) {
+		failures.add(new TestFailure(test, t));		
+	}
+	
+	public void startTest(Test test) {
+		int count= test.countTestCases();
+		testCount+= count;		
+	}
+	public void endTest(Test test) {		
+	}
+	
+	/**
+	 * Runs a TestCase.
+	 */
+	protected void run(final TestCase test) {
+		startTest(test);		
+		try {
+			test.doRun();
+		} 
+		catch (AssertionFailedError e) {
+			addFailure(test, e);
+		}
+		catch (Throwable e) {
+			addError(test, e);
+		}
+
+		endTest(test);
+	}
+	/**
+	 * Gets the number of run tests.
+	 */
+	public  int runCount() {
+		return testCount;
+	}
+	
+	
+	public  boolean shouldStop() {
+		return stop;
+	}
+	
+	public  void stop() {
+		stop= true;
+	}
+	
+	public  int errorCount() {
+		return errors.size();
+	}
+	
+	public  Iterator errors() {
+		return errors.iterator();
+	}
+	
+	public  int failureCount() {
+		return failures.size();
+	}
+	
+	public  Iterator<TestFailure> failures() {
+		return failures.iterator();
+	}
+	/**
+	 * Returns whether the entire test was successful or not.
+	 */
+	public  boolean wasSuccessful() {
+		return this.failureCount() == 0 && this.errorCount() == 0;
+	}
+}
\ No newline at end of file
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestSuite.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestSuite.java
new file mode 100644
index 000000000..32ff05d93
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/liuxinv1/TestSuite.java
@@ -0,0 +1,130 @@
+package com.coderising.myood.litejunit.liuxinv1;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+
+
+
+public class TestSuite extends Assert implements Test {	
+	private List<Test> tests= new ArrayList<>(10);  // 组合模式，可以放TestSuite,也可以放TestCase
+	private String name;
+	public TestSuite(){
+		
+	}
+	public TestSuite(final Class<?> theClass) {
+		this.name= theClass.getName();
+		Constructor<?> constructor= null;
+		try {	
+			constructor= getConstructor(theClass);
+		} catch (NoSuchMethodException e) {
+			addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name)"));
+			return;
+		}
+
+		if (!Modifier.isPublic(theClass.getModifiers())) {
+			addTest(warning("Class "+theClass.getName()+" is not public"));
+			return;
+		}
+
+		Vector<String> names= new Vector<>();
+		Method[] methods= theClass.getDeclaredMethods();
+		for (int i= 0; i < methods.length; i++) {
+			addTestMethod(methods[i], names, constructor);  // 该方法挺重要的
+		}		
+		
+		if (tests.size() == 0)
+			addTest(warning("No tests found in "+theClass.getName()));
+	}
+	
+	private Constructor<?> getConstructor(Class<?> theClass) throws NoSuchMethodException {
+		Class<?>[] args= { String.class };
+		return theClass.getConstructor(args);
+	}
+	private void addTestMethod(Method m, Vector<String> names, Constructor<?> constructor) {
+		String name= m.getName();
+		if (names.contains(name)) 
+			return;
+		if (isPublicTestMethod(m)) {
+			names.addElement(name);
+
+			Object[] args= new Object[]{name};
+			try {
+				addTest((Test)constructor.newInstance(args));
+			} catch (InstantiationException e) {
+				addTest(warning("Cannot instantiate test case: "+name+" ("+exceptionToString(e)+")"));
+			} catch (InvocationTargetException e) {
+				addTest(warning("Exception in constructor: "+name+" ("+exceptionToString(e.getTargetException())+")"));
+			} catch (IllegalAccessException e) {
+				addTest(warning("Cannot access test case: "+name+" ("+exceptionToString(e)+")"));
+			}
+
+		} else { // almost a test method
+			if (isTestMethod(m)) 
+				addTest(warning("Test method isn't public: "+m.getName()));
+		}
+	}
+	private boolean isPublicTestMethod(Method m) {
+		return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
+	}
+	private boolean isTestMethod(Method m) {
+		String name= m.getName();
+		Class<?>[] parameters= m.getParameterTypes();
+		Class<?> returnType= m.getReturnType();
+		return parameters.length == 0 && name.startsWith("test") && returnType.equals(Void.TYPE);
+	}
+	public void addTest(Test test) {
+		tests.add(test);
+	}
+	
+	private Test warning(final String message) {
+		return new TestCase("warning") {
+			public void doRun() {
+				fail(message);
+			}
+		};		
+	}
+	private String exceptionToString(Throwable t) {
+		StringWriter stringWriter= new StringWriter();
+		PrintWriter writer= new PrintWriter(stringWriter);
+		t.printStackTrace(writer);
+		return stringWriter.toString();
+		
+	}
+	
+	
+	
+	@Override
+	public void run(TestResult result) {
+		for (Iterator<Test> e= tests(); e.hasNext(); ) {
+	  		if (result.shouldStop() ){
+	  			break;
+	  		}
+			Test test= e.next();
+			test.run(result);
+		}
+
+	}
+	
+	public int countTestCases() {
+		int count= 0;
+		
+		for (Iterator<Test> e= tests(); e.hasNext(); ) {
+			Test test= e.next();
+			count= count + test.countTestCases();
+		}
+		return count;
+	}
+	public Iterator<Test> tests() {
+		return tests.iterator();
+	}
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/Assert.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/Assert.java
new file mode 100644
index 000000000..8afbd1567
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/Assert.java
@@ -0,0 +1,226 @@
+package com.coderising.myood.litejunit.v1;
+
+
+/**
+ * A set of assert methods.
+ */
+
+public class Assert {
+	/**
+	 * Protect constructor since it is a static only class
+	 */
+	protected Assert() {
+	}
+	
+	/**
+	 * Asserts that a condition is true. If it isn't it throws
+	 * an AssertionFailedError with the given message.
+	 */
+	static public void assertTrue(String message, boolean condition) {
+		if (!condition)
+			fail(message);
+	}
+	/**
+	 * Asserts that a condition is true. If it isn't it throws
+	 * an AssertionFailedError.
+	 */
+	static public void assertTrue(boolean condition) {
+		assertTrue(null, condition);
+	}
+	/**
+	 * Fails a test with the given message. 
+	 */
+	static public void fail(String message) {
+		throw new AssertionFailedError(message);
+	}
+	/**
+	 * Fails a test with no message. 
+	 */
+	static public void fail() {
+		fail(null);
+	}
+	/**
+	 * Asserts that two objects are equal. If they are not
+	 * an AssertionFailedError is thrown.
+	 */
+	static public void assertEquals(String message, Object expected, Object actual) {
+		if (expected == null && actual == null)
+			return;
+		if (expected != null && expected.equals(actual))
+			return;
+		failNotEquals(message, expected, actual);
+	}
+	/**
+	 * Asserts that two objects are equal. If they are not
+	 * an AssertionFailedError is thrown.
+	 */
+	static public void assertEquals(Object expected, Object actual) {
+	    assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two doubles are equal concerning a delta. If the expected
+	 * value is infinity then the delta value is ignored.
+	 */
+	static public void assertEquals(String message, double expected, double actual, double delta) {
+		// handle infinity specially since subtracting to infinite values gives NaN and the
+		// the following test fails
+		if (Double.isInfinite(expected)) {
+			if (!(expected == actual))
+				failNotEquals(message, new Double(expected), new Double(actual));
+		} else if (!(Math.abs(expected-actual) <= delta)) // Because comparison with NaN always returns false
+			failNotEquals(message, new Double(expected), new Double(actual));
+	}
+	/**
+	 * Asserts that two doubles are equal concerning a delta. If the expected
+	 * value is infinity then the delta value is ignored.
+	 */
+	static public void assertEquals(double expected, double actual, double delta) {
+	    assertEquals(null, expected, actual, delta);
+	}
+	/**
+	 * Asserts that two floats are equal concerning a delta. If the expected
+	 * value is infinity then the delta value is ignored.
+	 */
+	static public void assertEquals(String message, float expected, float actual, float delta) {
+ 		// handle infinity specially since subtracting to infinite values gives NaN and the
+		// the following test fails
+		if (Float.isInfinite(expected)) {
+			if (!(expected == actual))
+				failNotEquals(message, new Float(expected), new Float(actual));
+		} else if (!(Math.abs(expected-actual) <= delta))
+      		failNotEquals(message, new Float(expected), new Float(actual));
+	}
+	/**
+	 * Asserts that two floats are equal concerning a delta. If the expected
+	 * value is infinity then the delta value is ignored.
+	 */
+	static public void assertEquals(float expected, float actual, float delta) {
+		assertEquals(null, expected, actual, delta);
+	}
+	/**
+	 * Asserts that two longs are equal.
+	 */
+	static public void assertEquals(String message, long expected, long actual) {
+	    assertEquals(message, new Long(expected), new Long(actual));
+	}
+	/**
+	 * Asserts that two longs are equal.
+	 */
+	static public void assertEquals(long expected, long actual) {
+	    assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two booleans are equal.
+	 */
+	static public void assertEquals(String message, boolean expected, boolean actual) {
+    		assertEquals(message, new Boolean(expected), new Boolean(actual));
+  	}
+	/**
+	 * Asserts that two booleans are equal.
+ 	 */
+	static public void assertEquals(boolean expected, boolean actual) {
+		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two bytes are equal.
+	 */
+  	static public void assertEquals(String message, byte expected, byte actual) {
+		assertEquals(message, new Byte(expected), new Byte(actual));
+	}
+	/**
+   	 * Asserts that two bytes are equal.
+	 */
+	static public void assertEquals(byte expected, byte actual) {
+		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two chars are equal.
+	 */
+  	static public void assertEquals(String message, char expected, char actual) {
+    		assertEquals(message, new Character(expected), new Character(actual));
+  	}
+	/**
+	 * Asserts that two chars are equal.
+	 */
+  	static public void assertEquals(char expected, char actual) {
+		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two shorts are equal.
+	 */
+	static public void assertEquals(String message, short expected, short actual) {
+    		assertEquals(message, new Short(expected), new Short(actual));
+	}
+  	/**
+	 * Asserts that two shorts are equal.
+	 */
+	static public void assertEquals(short expected, short actual) {
+		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that two ints are equal.
+	 */
+  	static public void assertEquals(String message, int expected, int actual) {
+		assertEquals(message, new Integer(expected), new Integer(actual));
+  	}
+  	/**
+   	 * Asserts that two ints are equal.
+	 */
+  	static public void assertEquals(int expected, int actual) {
+  		assertEquals(null, expected, actual);
+	}
+	/**
+	 * Asserts that an object isn't null.
+	 */
+	static public void assertNotNull(Object object) {
+		assertNotNull(null, object);
+	}
+	/**
+	 * Asserts that an object isn't null.
+	 */
+	static public void assertNotNull(String message, Object object) {
+		assertTrue(message, object != null); 
+	}
+	/**
+	 * Asserts that an object is null.
+	 */
+	static public void assertNull(Object object) {
+		assertNull(null, object);
+	}
+	/**
+	 * Asserts that an object is null.
+	 */
+	static public void assertNull(String message, Object object) {
+		assertTrue(message, object == null); 
+	}
+	/**
+	 * Asserts that two objects refer to the same object. If they are not
+	 * an AssertionFailedError is thrown.
+	 */
+	static public void assertSame(String message, Object expected, Object actual) {
+		if (expected == actual)
+			return;
+		failNotSame(message, expected, actual);
+	}
+	/**
+	 * Asserts that two objects refer to the same object. If they are not
+	 * the same an AssertionFailedError is thrown.
+	 */
+	static public void assertSame(Object expected, Object actual) {
+	    assertSame(null, expected, actual);
+	}
+	
+	static private void failNotEquals(String message, Object expected, Object actual) {
+		String formatted= "";
+		if (message != null)
+			formatted= message+" ";
+		fail(formatted+"expected:<"+expected+"> but was:<"+actual+">");
+	}
+	
+	static private void failNotSame(String message, Object expected, Object actual) {
+		String formatted= "";
+		if (message != null)
+			formatted= message+" ";
+		fail(formatted+"expected same");
+	}
+}
\ No newline at end of file
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/AssertionFailedError.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/AssertionFailedError.java
new file mode 100644
index 000000000..3de657c3b
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/AssertionFailedError.java
@@ -0,0 +1,13 @@
+package com.coderising.myood.litejunit.v1;
+
+/**
+ * Thrown when an assertion failed.
+ */
+public class AssertionFailedError extends Error {
+
+	public AssertionFailedError() {
+	}
+	public AssertionFailedError(String message) {
+		super (message);
+	}
+}
\ No newline at end of file
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/Calculator.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/Calculator.java
new file mode 100644
index 000000000..fba48eb1e
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/Calculator.java
@@ -0,0 +1,22 @@
+package com.coderising.myood.litejunit.v1;
+
+public class Calculator {
+	
+	private int result = 0;
+	public  void add(int x){
+		result += x;
+	}
+	public void subtract(int x){
+		result -=x;
+	}
+	
+	public int getResult(){
+		return this.result;
+	}
+	public static void main(String[] args){
+		Calculator calculator = new Calculator();
+		calculator.add(10);
+		calculator.subtract(5);		
+		System.out.println(calculator.getResult());
+	}
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/CalculatorTest.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/CalculatorTest.java
new file mode 100644
index 000000000..5cf83e318
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/CalculatorTest.java
@@ -0,0 +1,37 @@
+package com.coderising.myood.litejunit.v1;
+
+
+public class CalculatorTest extends TestCase {
+	public CalculatorTest(String name) {
+		super(name);
+
+	}
+	Calculator calculator =null;
+	public void setUp(){
+		System.out.println("init a calculator instance");
+		calculator = new Calculator();
+	}
+	public void tearDown(){
+		System.out.println("destroy a calculator instance");
+		calculator = null;
+	}
+	public void testAdd(){
+
+		calculator.add(10);
+		assertEquals(10,calculator.getResult());
+	}
+	public void testSubtract(){
+		calculator.add(10);
+		calculator.subtract(5);
+		assertEquals(4,calculator.getResult());
+	}
+
+	public void haha() {
+        System.out.println("haha is not test case");
+    }
+
+	private void testXX() {
+
+    }
+
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/ClientToTest.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/ClientToTest.java
new file mode 100644
index 000000000..fc321f1ce
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/ClientToTest.java
@@ -0,0 +1,34 @@
+package com.coderising.myood.litejunit.v1;
+
+
+/**
+ * Created by thomas_young on 21/8/2017.
+ */
+public class ClientToTest {
+
+    public static void main(String[] args) {
+        TestResult tr = new TestResult();
+
+//        Test cs1 = new CalculatorTest("testAdd");
+//        tryTest(cs1, tr);
+//        Test cs2 = new CalculatorTest("testSubtract");
+//        tryTest(cs2, tr);
+
+        System.out.println("---------------------------------");
+        tr.clearResult();
+        Test ts = new TestSuite("AllTest");
+        ((TestSuite)ts).addTest(new CalculatorTest("haha"));
+        ((TestSuite)ts).addTest(new TestSuite(CalculatorTest.class));
+        tryTest(ts, tr);
+
+    }
+
+    private static void tryTest(Test test, TestResult tr) {
+        test.run(tr);
+        System.out.println(tr.wasSuccessful());
+        for (TestFailure failure: tr.failures) {
+            System.err.println(failure);
+        }
+        System.out.println("runCount=" + tr.runCount());
+    }
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/Test.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/Test.java
new file mode 100644
index 000000000..07c74cce4
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/Test.java
@@ -0,0 +1,7 @@
+package com.coderising.myood.litejunit.v1;
+
+
+public interface Test {
+	int countTestCases();  // command模式，一个测试用例是一个command
+	void run(TestResult tr);  // 分离测试用例和测试结果，收集参数模式
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestCase.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestCase.java
new file mode 100644
index 000000000..5c6ba60b8
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestCase.java
@@ -0,0 +1,69 @@
+package com.coderising.myood.litejunit.v1;
+
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Created by thomas_young on 21/8/2017.
+ */
+public abstract class TestCase extends Assert implements Test {
+    private String name;
+    protected TestCase(String name) {
+        this.name = name;
+    }
+    @Override
+    public int countTestCases() {
+        return 1;
+    }
+
+    @Override
+    public void run(TestResult tr) {
+        tr.run(this);
+    }
+
+    public void doRun() throws Throwable {
+        setUp();
+        try{
+            runTest();
+        }
+        finally{
+            tearDown();
+        }
+    }
+
+    private void runTest() throws Throwable {
+        Method method = null;
+        try {
+            method = getClass().getMethod(name, null);
+        } catch (NoSuchMethodException e) {
+            fail("Method \""+name+"\" not found");
+        }
+        if (!Modifier.isPublic(method.getModifiers())) {
+            fail("Method \""+name+"\" should be public");
+        }
+        try {
+            method.invoke(this, null);
+        } catch (IllegalAccessException e) {
+            e.fillInStackTrace();
+            throw e;
+        } catch (InvocationTargetException e) {
+            e.fillInStackTrace();
+            throw e.getTargetException();
+        }
+    }
+
+    protected void setUp() {
+    }
+
+    protected void tearDown() {
+    }
+
+    @Override
+    public String toString() {
+        return "TestCase{" +
+                "name='" + getClass().getName() + "." + name + '\'' +
+                '}';
+    }
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestFailure.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestFailure.java
new file mode 100644
index 000000000..9f4455f43
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestFailure.java
@@ -0,0 +1,40 @@
+package com.coderising.myood.litejunit.v1;
+
+
+/**
+ * A <code>TestFailure</code> collects a failed test together with
+ * the caught exception.
+ * @see TestResult
+ */
+public class TestFailure {
+	protected Test failedTest;
+	protected Throwable thrownException;
+
+	/**
+	 * Constructs a TestFailure with the given test and exception.
+	 */
+	public TestFailure(Test failedTest, Throwable thrownException) {
+		this.failedTest= failedTest;
+		this.thrownException= thrownException;
+	}
+	/**
+	 * Gets the failed test.
+	 */
+	public Test failedTest() {
+	    return failedTest;
+	}
+	/**
+	 * Gets the thrown exception.
+	 */
+	public Throwable thrownException() {
+	    return thrownException;
+	}
+	/**
+	 * Returns a short description of the failure.
+	 */
+	public String toString() {
+	    StringBuffer buffer= new StringBuffer();
+	    buffer.append(failedTest+": "+thrownException.getMessage());
+	    return buffer.toString();
+	}
+}
\ No newline at end of file
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestResult.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestResult.java
new file mode 100644
index 000000000..0a6d96740
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestResult.java
@@ -0,0 +1,88 @@
+package com.coderising.myood.litejunit.v1;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Created by thomas_young on 21/8/2017.
+ */
+public class TestResult {
+    protected List<TestFailure> failures;  // 存储assert失败
+    protected List<TestFailure> errors;  // 存储业务代码异常，比如空指针
+    private int testCount;
+    private boolean stop;
+
+    public TestResult() {
+        failures= new ArrayList<>();
+        errors= new ArrayList<>();
+
+        testCount= 0;
+        stop= false;
+    }
+
+    public void run(TestCase testCase) {
+        startTest(testCase);
+        try {
+            testCase.doRun();
+        } catch (AssertionFailedError e) {
+            failures.add(new TestFailure(testCase, e));
+        } catch (Throwable e) {
+            errors.add(new TestFailure(testCase, e));
+        }
+        endTest(testCase);
+    }
+
+    private void startTest(TestCase testCase) {
+        int count= testCase.countTestCases();
+        testCount+= count;
+    }
+
+    private void endTest(TestCase testCase) {
+    }
+    /**
+     * Gets the number of run tests.
+     */
+    public  int runCount() {
+        return testCount;
+    }
+
+
+    public  boolean shouldStop() {
+        return stop;
+    }
+
+    public  void stop() {
+        stop= true;
+    }
+
+    public  int errorCount() {
+        return errors.size();
+    }
+
+    public Iterator errors() {
+        return errors.iterator();
+    }
+
+    public  int failureCount() {
+        return failures.size();
+    }
+
+    public  Iterator<TestFailure> failures() {
+        return failures.iterator();
+    }
+    /**
+     * Returns whether the entire test was successful or not.
+     */
+    public  boolean wasSuccessful() {
+        return this.failureCount() == 0 && this.errorCount() == 0;
+    }
+
+    public void clearResult() {
+        failures.clear();
+        errors.clear();
+        testCount = 0;
+        stop= false;
+    }
+
+}
diff --git a/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestSuite.java b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestSuite.java
new file mode 100644
index 000000000..19ee4caf1
--- /dev/null
+++ b/students/812350401/src/main/java/com/coderising/myood/litejunit/v1/TestSuite.java
@@ -0,0 +1,127 @@
+package com.coderising.myood.litejunit.v1;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+/**
+ * Created by thomas_young on 21/8/2017.
+ */
+public class TestSuite implements Test {
+    private String name;
+    private List<Test> tests = new ArrayList<>(10);
+
+    @Override
+    public int countTestCases() {
+        int totalCount = 0;
+        for (Test test: tests) {
+            totalCount += test.countTestCases();
+        }
+        return totalCount;
+    }
+
+    public TestSuite(String name) {
+        this.name = name;
+    }
+
+    // 把某个测试类中的所有pulic的test方法构造成对象，塞入tests
+    public TestSuite(final Class<?> theClass) {
+        this.name = theClass.getName();
+        Constructor<?> constructor = null;
+        try {
+            constructor = getConstructor(theClass);
+        } catch (NoSuchMethodException e) {
+            addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name)"));
+        }
+
+        if (!Modifier.isPublic(theClass.getModifiers())) {
+            addTest(warning("Class "+theClass.getName()+" is not public"));
+            return;
+        }
+
+        Method[] methods = theClass.getDeclaredMethods();
+        Set<String> names = new TreeSet<>();
+        for (Method method: methods) {
+            addTestInstance(method, names, constructor);
+        }
+
+        if (tests.size() == 0)
+            addTest(warning("No tests found in "+theClass.getName()));
+    }
+
+    private Constructor<?> getConstructor(Class<?> theClass) throws NoSuchMethodException {
+        Class<?>[] args = {String.class};
+        return theClass.getConstructor(args);
+    }
+
+    @Override
+    public void run(TestResult tr) {
+        for (Test test: tests) {
+            if (tr.shouldStop()) break;
+            test.run(tr);
+        }
+    }
+
+    public void addTest(Test test) {
+        tests.add(test);
+    }
+
+    public Iterator<Test> tests() {
+        return tests.iterator();
+    }
+
+    // --------------------- private ---------------------------
+    private void addTestInstance(Method method, Set<String> names, Constructor<?> constructor) {
+        String name = method.getName();
+        if (names.contains(name)) {
+            return;
+        }
+        if (!isTestMethod(method)) {
+            return;
+        }
+        if (!Modifier.isPublic(method.getModifiers())) {
+            addTest(warning("Test method isn't public: "+name));
+            return;
+        }
+
+        names.add(name);
+        Object[] args= new Object[]{name};
+        try {
+            addTest((Test)constructor.newInstance(args));
+        } catch (InstantiationException e) {
+            addTest(warning("Cannot instantiate test case: "+name+" ("+exceptionToString(e)+")"));
+        } catch (InvocationTargetException e) {
+            addTest(warning("Exception in constructor: "+name+" ("+exceptionToString(e.getTargetException())+")"));
+        } catch (IllegalAccessException e) {
+            addTest(warning("Cannot access test case: "+name+" ("+exceptionToString(e)+")"));
+        }
+    }
+
+    private boolean isTestMethod(Method method) {
+        String methodName = method.getName();
+        int paraCount = method.getParameterCount();
+        Class<?> returnType = method.getReturnType();
+        return paraCount == 0 && returnType.equals(Void.TYPE) && methodName.startsWith("test");
+    }
+
+    private Test warning(final String message) {
+        return new TestCase("warning") {
+            public void doRun() {
+                fail(message);
+            }
+        };
+    }
+
+    private String exceptionToString(Throwable t) {
+        StringWriter stringWriter= new StringWriter();
+        PrintWriter writer= new PrintWriter(stringWriter);
+        t.printStackTrace(writer);
+        return stringWriter.toString();
+
+    }
+
+}
diff --git a/students/812350401/src/test/com/coderising/mydp/bridge/CircleTest.java b/students/812350401/src/test/com/coderising/mydp/bridge/CircleTest.java
new file mode 100644
index 000000000..f7dc93464
--- /dev/null
+++ b/students/812350401/src/test/com/coderising/mydp/bridge/CircleTest.java
@@ -0,0 +1,21 @@
+package com.coderising.mydp.bridge;
+
+import junit.framework.TestCase;
+
+/**
+ * Created by thomas_young on 6/8/2017.
+ */
+public class CircleTest extends TestCase {
+    public void testDraw() throws Exception {
+
+    }
+
+    public void testSetDrawing() throws Exception {
+
+    }
+
+    public void testMain() throws Exception {
+
+    }
+
+}
\ No newline at end of file
