@Override
  public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    synchronized (getClassLoadingLock(name)) {
      Class<?> loadedClass = findLoadedClass(name);
      if (loadedClass != null) {
        return loadedClass;
      }
      if (isClosed) {
        throw new ClassNotFoundException("This ClassLoader is closed");
      }
      if (config.shouldAcquire(name)) {
        loadedClass =
            PerfStatsCollector.getInstance()
                .measure("load sandboxed class", () -> maybeInstrumentClass(name));
      } else {
        loadedClass = getParent().loadClass(name);
      }

      if (resolve) {
        resolveClass(loadedClass);
      }

      return loadedClass;
    }
  }
@Test
  @SuppressWarnings("CheckReturnValue")
  public void shouldAlsoInstrumentEqualsAndHashCodeAndToStringWhenDeclared() throws Exception {
    Class<?> theClass = loadClass(AClassWithEqualsHashCodeToString.class);
    Object instance = theClass.getDeclaredConstructor().newInstance();
    assertThat(transcript)
        .containsExactly("methodInvoked:" + " AClassWithEqualsHashCodeToString.__constructor__()");
    transcript.clear();

    instance.toString();
    assertThat(transcript)
        .containsExactly("methodInvoked:" + " AClassWithEqualsHashCodeToString.toString()");
    transcript.clear();

    classHandler.valueToReturn = true;
    //noinspection ResultOfMethodCallIgnored,ObjectEqualsNull
    instance.equals(null);
    assertThat(transcript)
        .containsExactly(
            "methodInvoked:"
                + " AClassWithEqualsHashCodeToString.equals(java.lang.Object"
                + " null)");
    transcript.clear();

    classHandler.valueToReturn = 42;
    //noinspection ResultOfMethodCallIgnored
    instance.hashCode();
    assertThat(transcript)
        .containsExactly("methodInvoked:" + " AClassWithEqualsHashCodeToString.hashCode()");
  }