package com.googlecode.jslint4java.maven;

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;

import com.google.common.base.Throwables;

/**
 * An hamcrest matcher implementation, which allows matching the root cause of a {@link Throwable}.
 */
class RootCauseMatcher extends BaseMatcher<Class<? extends Throwable>> {
    private final Class<? extends Throwable> expectedRootCause;

    // TODO: should we take a Matcher instead?
    RootCauseMatcher(Class<? extends Throwable> clazz) {
        this.expectedRootCause = clazz;
    }

    public boolean matches(Object obj) {
        if (!(obj instanceof Throwable)) {
            // Not an exception
            return false;
        }
        Throwable e = (Throwable) obj;
        Throwable rootCause = Throwables.getRootCause(e);
        return rootCause.getClass().equals(expectedRootCause);
    }

    public void describeTo(Description desc) {
        desc.appendText("an exception with root cause " + expectedRootCause.getName());
    }

    public static Matcher<Class<? extends Throwable>> rootCause(Class<? extends Throwable> e) {
        return new RootCauseMatcher(e);
    }

}
@@ -56,27 +56,27 @@
 amcrest.
-Bas
+Cor
 eMatcher
 ;%0Aimport
@@ -67,16 +67,17 @@
 eMatcher
+s
 ;%0Aimport
@@ -131,16 +131,53 @@
 Matcher;
+%0Aimport org.hamcrest.TypeSafeMatcher;
 %0A%0Aimport
@@ -278,16 +278,24 @@
 atching 
+against 
 the root
@@ -305,16 +305,19 @@
 use of a
+%0A *
  %7B@link 
@@ -328,16 +328,33 @@
 wable%7D.%0A
+ *%0A * @param %3CT%3E%0A
  */%0Aclas
@@ -371,16 +371,19 @@
 eMatcher
+%3CT%3E
  extends
@@ -387,11 +387,15 @@
 nds 
-Bas
+TypeSaf
 eMat
@@ -399,32 +399,16 @@
 Matcher%3C
-Class%3C? extends 
 Throwabl
@@ -409,17 +409,16 @@
 rowable%3E
-%3E
  %7B%0A    p
@@ -434,380 +434,168 @@
 nal 
-Class%3C? extends Throwable%3E expectedRootCause;%0A%0A    // TODO: should we take a Matcher instead?%0A    RootCauseMatcher(Class%3C? extends Throwable%3E clazz) %7B%0A        this.expectedRootCause = clazz;%0A    %7D%0A%0A    public boolean matches(Object obj) %7B%0A        if (!(obj instanceof Throwable)) %7B%0A            // Not an exception%0A            return false;%0A        %7D%0A        Throwable e = 
+Matcher%3CT%3E matcher;%0A%0A    private RootCauseMatcher(Matcher%3CT%3E matcher) %7B%0A        this.matcher = matcher;%0A    %7D%0A%0A    @Override%0A    protected boolean matchesSafely
 (Thr
@@ -604,14 +604,16 @@
 able
-) obj;
+ item) %7B
 %0A   
@@ -663,17 +663,20 @@
 otCause(
-e
+item
 );%0A     
@@ -689,45 +689,25 @@
 urn 
-rootCause.getClass().equals(expectedR
+matcher.matches(r
 ootC
@@ -826,47 +826,165 @@
 se %22
- + expectedRootC
+)%0A            .appendDescriptionOf(matcher);%0A    %7D%0A%0A    /**%0A     * Return a matcher that verifies the root c
 ause
-.getName());
+ of an exception is an instance of e.
 %0A    
-%7D%0A
+ */
 %0A   
@@ -997,16 +997,20 @@
 c static
+ %3CT%3E
  Matcher
@@ -1010,16 +1010,29 @@
 Matcher%3C
+T%3E rootCause(
 Class%3C? 
@@ -1053,48 +1053,290 @@
 ble%3E
-%3E rootCause(Class%3C? extends Throwable%3E e
+ e) %7B%0A        Matcher%3CT%3E m = CoreMatchers.instanceOf(e);%0A        return rootCause(m);%0A    %7D%0A%0A    /**%0A     * Return a matcher that matches against the root cause of an exception.%0A     */%0A    @SuppressWarnings(%22unchecked%22)%0A    public static %3CT%3E Matcher%3CT%3E rootCause(Matcher%3CT%3E matcher
 ) %7B%0A
@@ -1349,16 +1349,29 @@
   return
+ (Matcher%3CT%3E)
  new Roo
@@ -1383,18 +1383,27 @@
 eMatcher
-(e
+%3CT%3E(matcher
 );%0A    %7D
@@ -1403,10 +1403,9 @@
 ;%0A    %7D%0A
-%0A
 %7D

Allow arbitrary matchers.