private static function getMethodsTemplate(array $reflectionMethods, string $handlerPropertyName): string
    {
        $template = '';
        foreach ($reflectionMethods as $reflectionMethod) {
            $methodName = $reflectionMethod->getName();

            // not to override method
            if ($reflectionMethod->isConstructor() || $reflectionMethod->isStatic()) {
                continue;
            }
            
            // define override methodBody
            $methodBody = "{
                return \$this->{$handlerPropertyName}->invoke('{$methodName}', func_get_args());
            }
            ";
            
            // the template of parameter
            $template .= " public function $methodName (";
            $template .= self::getParameterTemplate($reflectionMethod);
            $template .= ' ) ';

            // the template of return type
            $reflectionMethodReturn = $reflectionMethod->getReturnType();
            if ($reflectionMethodReturn !== null) {
                $returnType = $reflectionMethodReturn->__toString();
                $returnType = $returnType === 'self' ? $reflectionMethod->getDeclaringClass()->getName() : $returnType;
                $template .= " : $returnType";
                // if returnType is void
                if ($returnType === 'void') {
                    $methodBody = str_replace('return ', '', $methodBody);
                }
            }

            // append methodBody
            $template .= $methodBody;
        }

        return $template;
    }