@SuppressWarnings("unchecked")
  private void invokeAfter(Class<?> clazz, Object instance) throws Exception {
    for (Method m : clazz.getMethods()) {
      if (Annotations.isAnnotationPresent(
          m, (Class<? extends Annotation>) clazz.getClassLoader().loadClass("org.junit.After"))) {
        m.invoke(instance);
      }
    }

    if (clazz.getSuperclass() != null && !Object.class.equals(clazz.getSuperclass()))
      invokeAfter(clazz.getSuperclass(), instance);
  }
  public AbstractRuleProvider() {
    /*
     * In the case of a proxy, the no-args constructor will be called. This is the case even if the provider
     * itself would normally have a metadata param passed in.
     *
     * Once completed, the getMetadata() method will be proxied correctly, so this is ok. Just allow it to pass
     * in this case.
     */
    if (Proxies.isForgeProxy(this)
        && !Annotations.isAnnotationPresent(getClass(), RuleMetadata.class)) return;

    if (!Annotations.isAnnotationPresent(getClass(), RuleMetadata.class)) {
      throw new IllegalStateException(
          getClass().getName()
              + " must either "
              + "be abstract, or specify @"
              + RuleMetadata.class.getName()
              + ", or call a super() constructor and provide "
              + RuleProviderMetadata.class.getName());
    }
    this.metadata = MetadataBuilder.forProvider(getClass());
  }