class TypeInfoImpl<T> implements TypeInfo<T> {
  /** Source object from which memberNames are read. */
  private final T source;
  private final Class<T> type;
  private final InheritingConfiguration configuration;
  private volatile Map<String, Accessor> accessors;
  private volatile Map<String, Mutator> mutators;

  TypeInfoImpl(T source, Class<T> sourceType, InheritingConfiguration configuration) {
    this.source = source;
    this.type = sourceType;
    this.configuration = configuration;
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == this)
      return true;
    if (!(obj instanceof TypeInfo))
      return false;
    TypeInfo<?> typeInfo = (TypeInfo<?>) obj;
    return type.equals(typeInfo.getType()) && configuration.equals(typeInfo.getConfiguration());
  }

  /**
   * Lazily initializes and gets accessors.
   */
  public Map<String, Accessor> getAccessors() {
    if (accessors == null)
      synchronized (this) {
        if (accessors == null)
          accessors = PropertyInfoSetResolver.resolveAccessors(source, type, configuration);
      }

    return accessors;
  }

  public Configuration getConfiguration() {
    return configuration;
  }

  /**
   * Lazily initializes and gets mutators.
   */
  public Map<String, Mutator> getMutators() {<FILL_FUNCTION_BODY>}

  public Class<T> getType() {
    return type;
  }

  @Override
  public int hashCode() {
    return type.hashCode() * 31 + configuration.hashCode();
  }

  @Override
  public String toString() {
    return type.toString();
  }

  Mutator mutatorForAccessorMethod(String accessorMethodName) {
    return getMutators().get(
        configuration.getSourceNameTransformer().transform(accessorMethodName, NameableType.METHOD));
  }
}

    if (mutators == null)
      synchronized (this) {
        if (mutators == null)
          mutators = PropertyInfoSetResolver.resolveMutators(type, configuration);
      }

    return mutators;
  
<no_super_class>