ComposeMatchers { public static <T, U> Matcher<T> hasFeatureValue(Function<T, U> featureFunction, U featureValue) { return hasFeature(featureFunction, equalTo(featureValue)); } private  ComposeMatchers(); @SafeVarargs static ConjunctionMatcher<T> compose(Matcher<? super T>... matchers); @SafeVarargs static ConjunctionMatcher<T> compose(String compositeDescription, Matcher<? super T>... matchers); static ConjunctionMatcher<T> compose(Iterable<Matcher<? super T>> matchers); static ConjunctionMatcher<T> compose(String compositeDescription, Iterable<Matcher<? super T>> matchers); static Matcher<T> hasFeature(Function<T, U> featureFunction, Matcher<? super U> featureMatcher); static Matcher<T> hasFeature(String featureName, Function<T, U> featureFunction,
		Matcher<? super U> featureMatcher); static Matcher<T> hasFeature(String featureDescription, String featureName,
		Function<T, U> featureFunction, Matcher<? super U> featureMatcher); static Matcher<T> hasFeatureValue(Function<T, U> featureFunction, U featureValue); static Matcher<T> hasFeatureValue(String featureName, Function<T, U> featureFunction, U featureValue); static Matcher<T> hasFeatureValue(String featureDescription, String featureName,
		Function<T, U> featureFunction, U featureValue);  }
@Test public void hasFeatureValueReturnsMatcher() { Matcher<String> actual = hasFeatureValue("x", "y", String::length, 1); assertThat(actual.matches("z"), is(true)); }
@Test public void hasFeatureValueWithoutDescriptionReturnsMatcher() { Matcher<String> actual = hasFeatureValue("x", String::length, 1); assertThat(actual.matches("y"), is(true)); }
@Test public void hasFeatureValueWithoutNameReturnsMatcher() { Matcher<String> actual = hasFeatureValue(String::length, 1); assertThat(actual.matches("x"), is(true)); }
@Test(expected = NullPointerException.class) public void hasFeatureValueWithNullFunctionThrowsException() { hasFeatureValue("x", "y", null, anything()); }