Object createMock(IMockMaker.IMockCreationSettings settings) {
    final Class<?> type = settings.getMockType();
    TypeCache.SimpleKey key = new TypeCache.SimpleKey(type, settings.getAdditionalInterface());
    ClassLoader classLoader = settings.getClassLoader();

    Class<?> enhancedType = CACHE.findOrInsert(classLoader,
      key,
      () -> {
        String typeName = type.getName();
        Class<?> targetClass = type;
        if (shouldLoadIntoCodegenPackage(type)) {
          typeName = CODEGEN_PACKAGE + "." + type.getSimpleName();
          targetClass = CODEGEN_TARGET_CLASS;
        }
        int randomNumber = Math.abs(ThreadLocalRandom.current().nextInt());
        String name = String.format("%s$%s$%d", typeName, "SpockMock", randomNumber);
        ClassLoadingStrategy<ClassLoader> strategy = determineBestClassLoadingStrategy(targetClass, settings);
        //noinspection resource
        return new ByteBuddy()
          .with(TypeValidation.DISABLED) // https://github.com/spockframework/spock/issues/776
          .ignore(none())
          .subclass(type)
          .name(name)
          .implement(settings.getAdditionalInterface())
          .implement(ISpockMockObject.class)
          .method(m -> isGroovyMOPMethod(type, m))
          .intercept(mockInterceptor())
          .transform(mockTransformer())
          .annotateMethod(INTERNAL_ANNOTATION) //Annotate the Groovy MOP methods with @Internal
          .method(m -> !isGroovyMOPMethod(type, m))
          .intercept(mockInterceptor())
          .transform(mockTransformer())
          .method(m -> m.represents(MOCK_INTERACTION_VALIDATOR_METHOD))
          // Implement the $spock_mockInteractionValidation() method which returns the static field below, so we have a validation instance for every mock class
          .intercept(FixedValue.reference(new ByteBuddyMockInteractionValidator(), SpockNames.SPOCK_MOCK_INTERATION_VALIDATOR))
          .transform(validateMockInteractionTransformer())
          .implement(ByteBuddyInterceptorAdapter.InterceptorAccess.class)
          .intercept(FieldAccessor.ofField("$spock_interceptor"))
          .defineField("$spock_interceptor", IProxyBasedMockInterceptor.class, Visibility.PRIVATE, SyntheticState.SYNTHETIC)
          .make()
          .load(classLoader, strategy)
          .getLoaded();
      }, getCacheLockForKey(key));

    Object proxy = MockInstantiator.instantiate(type, enhancedType, settings.getConstructorArgs(), settings.isUseObjenesis());
    ((ByteBuddyInterceptorAdapter.InterceptorAccess) proxy).$spock_set(settings.getMockInterceptor());
    return proxy;
  }
Returns {@code true}, if the mock is considered local
<p>
A mock is considered local, if all additional interfaces of the mock (including {@link ISpockMockObject}) are
loadable by the target class' classloader.

@param targetClass The to-be-mocked class
@param additionalInterfaces Additional interfaces of the to-be-mocked type
@return true, if this is a local mock. Otherwise false
spock-core/src/main/java/org/spockframework/mock/runtime/ByteBuddyMockFactory.java