Add support for skipping tests
diff --git a/lib/test_reflective_loader.dart b/lib/test_reflective_loader.dart
index 25868d9..4312ba5 100644
--- a/lib/test_reflective_loader.dart
+++ b/lib/test_reflective_loader.dart
@@ -27,6 +27,11 @@
 const _ReflectiveTest reflectiveTest = const _ReflectiveTest();
 
 /**
+ * A marker annotation used to annotate test methods that should be skipped.
+ */
+const SkippedTest skippedTest = const SkippedTest();
+
+/**
  * A marker annotation used to annotate "solo" groups and tests.
  */
 const _SoloTest soloTest = const _SoloTest();
@@ -115,14 +120,18 @@
         _hasAnnotationInstance(memberMirror, soloTest);
     // test_
     if (memberName.startsWith('test_')) {
-      group.addTest(isSolo, memberName, memberMirror, () {
-        if (_hasFailingTestAnnotation(memberMirror) ||
-            _isCheckedMode && _hasAssertFailingTestAnnotation(memberMirror)) {
-          return _runFailingTest(classMirror, symbol);
-        } else {
-          return _runTest(classMirror, symbol);
-        }
-      });
+      if (_hasSkippedTestAnnotation(memberMirror)) {
+        group.addSkippedTest(memberName);
+      } else {
+        group.addTest(isSolo, memberName, memberMirror, () {
+          if (_hasFailingTestAnnotation(memberMirror) ||
+              _isCheckedMode && _hasAssertFailingTestAnnotation(memberMirror)) {
+            return _runFailingTest(classMirror, symbol);
+          } else {
+            return _runTest(classMirror, symbol);
+          }
+        });
+      }
       return;
     }
     // solo_test_
@@ -143,6 +152,10 @@
         return _runFailingTest(classMirror, symbol);
       });
     }
+    // skip_test_
+    if (memberName.startsWith('skip_test_')) {
+      group.addSkippedTest(memberName);
+    }
   });
 
   // Support for the case of missing enclosing [defineReflectiveSuite].
@@ -160,7 +173,7 @@
           for (_Test test in group.tests) {
             if (allTests || test.isSolo) {
               test_package.test(test.name, test.function,
-                  timeout: test.timeout);
+                  timeout: test.timeout, skip: test.isSkipped);
             }
           }
         }
@@ -211,6 +224,9 @@
 bool _hasFailingTestAnnotation(MethodMirror method) =>
     _hasAnnotationInstance(method, failingTest);
 
+bool _hasSkippedTestAnnotation(MethodMirror method) =>
+    _hasAnnotationInstance(method, skippedTest);
+
 Future _invokeSymbolIfExists(InstanceMirror instanceMirror, Symbol symbol) {
   var invocationResult = null;
   InstanceMirror closure;
@@ -277,6 +293,19 @@
 }
 
 /**
+ * A marker annotation used to annotate test methods which are skipped.
+ */
+class SkippedTest {
+  /**
+   * Initialize this annotation with the given arguments.
+   *
+   * [issue] is a full URI describing the failure and used for tracking.
+   * [reason] is a free form textual description.
+   */
+  const SkippedTest({String issue, String reason});
+}
+
+/**
  * A marker annotation used to annotate test methods with additional timeout
  * information.
  */
@@ -309,6 +338,11 @@
 
   bool get hasSoloTest => tests.any((test) => test.isSolo);
 
+  void addSkippedTest(String name) {
+    String fullName = _combineNames(this.name, name);
+    tests.add(new _Test.skipped(isSolo, fullName));
+  }
+
   void addTest(bool isSolo, String name, MethodMirror memberMirror,
       _TestFunction function) {
     String fullName = _combineNames(this.name, name);
@@ -341,5 +375,12 @@
   final _TestFunction function;
   final test_package.Timeout timeout;
 
-  _Test(this.isSolo, this.name, this.function, this.timeout);
+  final bool isSkipped;
+
+  _Test(this.isSolo, this.name, this.function, this.timeout)
+      : isSkipped = false;
+  _Test.skipped(this.isSolo, this.name)
+      : isSkipped = true,
+        function = null,
+        timeout = null;
 }
diff --git a/test/test_reflective_loader_test.dart b/test/test_reflective_loader_test.dart
index 952fe0a..a657b04 100644
--- a/test/test_reflective_loader_test.dart
+++ b/test/test_reflective_loader_test.dart
@@ -35,4 +35,14 @@
   Future test_fails_throws_async() {
     return new Future.error('foo');
   }
+
+  @skippedTest
+  void test_fails_but_skipped() {
+    throw 'foo';
+  }
+
+  @skippedTest
+  void test_times_out_but_skipped() {
+    while (true) {}
+  }
 }