content: package com.annimon.stream.test.hamcrest;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Modifier;
  import org.hamcrest.BaseMatcher;
  import org.hamcrest.Description;
  import org.hamcrest.Matcher;
  import org.hamcrest.StringDescription;
  import org.hamcrest.TypeSafeDiagnosingMatcher;
  
  public class CommonMatcher {
  
      private CommonMatcher() { }
  
      public static Matcher<Class<?>> hasOnlyPrivateConstructors() {
          return new PrivateConstructorsMatcher();
      }
  
      public static Matcher<Matcher> description(Matcher<String> matcher) {
          return new DescriptionMatcher(matcher);
      }
  
      public static class PrivateConstructorsMatcher extends BaseMatcher<Class<?>> {
  
          @SuppressWarnings("deprecation")
          @Override
          public boolean matches(Object item) {
              final Class<?> clazz = (Class<?>) item;
              for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
                  if (!Modifier.isPrivate(constructor.getModifiers())) {
                      return false;
                  }
  
                  // isAccessible deprecated since Java 9. For Java 6 this warning can be ignored.
                  boolean isAccessible = constructor.isAccessible();
                  try {
                      constructor.setAccessible(true);
                      constructor.newInstance();
                  } catch (InstantiationException ex) {
                  } catch (IllegalAccessException ex) {
                  } catch (IllegalArgumentException ex) {
                  } catch (InvocationTargetException ex) {
                  } finally {
                      constructor.setAccessible(isAccessible);
                  }
              }
              return true;
          }
  
          @Override
          public void describeTo(Description description) {
              description.appendText("has only private constructors");
          }
      }
  
      public static class DescriptionMatcher extends TypeSafeDiagnosingMatcher<Matcher> {
  
          private final Matcher<String> matcher;
  
          public DescriptionMatcher(Matcher<String> matcher) {
              this.matcher = matcher;
          }
  
          @Override
          protected boolean matchesSafely(Matcher m, Description mismatchDescription) {
              StringDescription stringDescription = new StringDescription();
              m.describeTo(stringDescription);
              final String description = stringDescription.toString();
  
              if (!matcher.matches(description)) {
                  mismatchDescription.appendText("description ");
                  matcher.describeMismatch(description, mismatchDescription);
                  return false;
              }
              return true;
          }
  
          @Override
          public void describeTo(Description description) {
              description.appendText("description ").appendDescriptionOf(matcher);
          }
      }
  }
  