public function createMockClass(
        MockDefinition $definition,
        bool $createNew = false
    ): ReflectionClass {
        $signature = $definition->signature();

        if (!$createNew) {
            foreach ($this->definitions as $tuple) {
                if ($signature === $tuple[0]) {
                    return $tuple[1];
                }
            }
        }

        $className = $this->generator->generateClassName($definition);

        if (class_exists($className, false)) {
            throw new ClassExistsException($className);
        }

        $source = $this->generator->generate($definition, $className);
        $reporting = error_reporting(E_ERROR | E_COMPILE_ERROR);

        try {
            eval($source);
        } catch (ParseError $e) {
            throw new MockGenerationFailedException(
                $className,
                $definition,
                $source,
                error_get_last(),
                $e
            );
        } finally {
            error_reporting($reporting);
        }

        if (!class_exists($className, false)) {
            // @codeCoverageIgnoreStart
            throw new MockGenerationFailedException(
                $className,
                $definition,
                $source,
                error_get_last()
            );
            // @codeCoverageIgnoreEnd
        }

        $class = new ReflectionClass($className);
        $customMethods = [];

        foreach ($definition->customStaticMethods() as $methodName => $method) {
            $customMethods[strtolower($methodName)] = $method[0];
        }
        foreach ($definition->customMethods() as $methodName => $method) {
            $customMethods[strtolower($methodName)] = $method[0];
        }

        $customMethodsProperty = $class->getProperty('_customMethods');
        $customMethodsProperty->setAccessible(true);
        $customMethodsProperty->setValue(null, $customMethods);

        $this->handleFactory->staticHandle($class);

        $this->definitions[] = [$signature, $class];

        return $class;
    }