private function generateMethods(ClassMetadata $class)
    {
        $methods           = '';
        $methodNames       = [];
        $reflectionMethods = $class->getReflectionClass()->getMethods(\ReflectionMethod::IS_PUBLIC);
        $skippedMethods    = [
            '__sleep'   => true,
            '__clone'   => true,
            '__wakeup'  => true,
            '__get'     => true,
            '__set'     => true,
            '__isset'   => true,
        ];

        foreach ($reflectionMethods as $method) {
            $name = $method->getName();

            if ($method->isConstructor() ||
                isset($skippedMethods[strtolower($name)]) ||
                isset($methodNames[$name]) ||
                $method->isFinal() ||
                $method->isStatic() ||
                ( ! $method->isPublic())
            ) {
                continue;
            }

            $methodNames[$name] = true;
            $methods           .= "\n    /**\n"
                . "     * {@inheritDoc}\n"
                . "     */\n"
                . '    public function ';

            if ($method->returnsReference()) {
                $methods .= '&';
            }

            $methods .= $name . '(' . $this->buildParametersString($method->getParameters()) . ')';
            $methods .= $this->getMethodReturnType($method);
            $methods .= "\n" . '    {' . "\n";

            if ($this->isShortIdentifierGetter($method, $class)) {
                $identifier = lcfirst(substr($name, 3));
                $fieldType  = $class->getTypeOfField($identifier);
                $cast       = in_array($fieldType, ['integer', 'smallint']) ? '(int) ' : '';

                $methods .= '        if ($this->__isInitialized__ === false) {' . "\n";
                $methods .= '            ';
                $methods .= $this->shouldProxiedMethodReturn($method) ? 'return ' : '';
                $methods .= $cast . ' parent::' . $method->getName() . "();\n";
                $methods .= '        }' . "\n\n";
            }

            $invokeParamsString = implode(', ', $this->getParameterNamesForInvoke($method->getParameters()));
            $callParamsString   = implode(', ', $this->getParameterNamesForParentCall($method->getParameters()));

            $methods .= "\n        \$this->__initializer__ "
                . "&& \$this->__initializer__->__invoke(\$this, " . var_export($name, true)
                . ", [" . $invokeParamsString . "]);"
                . "\n\n        "
                . ($this->shouldProxiedMethodReturn($method) ? 'return ' : '')
                . "parent::" . $name . '(' . $callParamsString . ');'
                . "\n" . '    }' . "\n";
        }

        return $methods;
    }