GroupMatcherCategoryFilter(GroupMatcher included, GroupMatcher excluded) {
    GroupMatcher invertedExclude = excluded == null ? null : new InverseGroupMatcher(excluded);
    if (included != null || invertedExclude != null) {
      matcher = new AndGroupMatcher();
      if (included != null) {
        matcher.addMatcher(included);
      }

      if (invertedExclude != null) {
        matcher.addMatcher(invertedExclude);
      }
    } else {
      matcher = null;
    }
  }
  private boolean shouldRun(Description description, Description parent, Class<?> parentClass) {
    if (matcher == null) {
      return true;
    } else {
      Set<Class<?>> cats = new HashSet<Class<?>>();
      Category cat = description.getAnnotation(Category.class);
      if (cat != null) {
        addAll(cats, cat.value());
      }

      if (parent != null) {
        cat = parent.getAnnotation(Category.class);
        if (cat != null) {
          addAll(cats, cat.value());
        }
      }

      if (parentClass != null) {
        findSuperclassCategories(cats, parentClass);
      }

      Class<?> testClass = description.getTestClass();
      if (testClass != null) {
        cat = testClass.getAnnotation(Category.class);
        if (cat != null) {
          addAll(cats, cat.value());
        }
      }

      cats.remove(null);

      boolean result = matcher.enabled(cats.toArray(new Class<?>[cats.size()]));

      if (!result) {
        ArrayList<Description> children = description.getChildren();
        if (children != null) {
          for (Description child : children) {
            if (shouldRun(child, description, null)) {
              result = true;
              break;
            }
          }
        }
      }

      return result;
    }
  }
 @Override
 public String describe() {
   return matcher == null ? "ANY" : matcher.toString();
 }