private static function createMethods(\ReflectionClass $class): string
    {
        $code    = '';
        $methods = [];
        $params  = [];
        $voidMethods = [];
        foreach (self::methodsOf($class) as $method) {
            $return = true;
            $returnType = determineReturnTypeOf($method);
            if ($returnType === ': void') {
                $voidMethods[$method->getName()] = $method->getName();
                $return = false;
            }

            $param = paramsOf($method);
            /* @var $method \ReflectionMethod */
            $code .= sprintf(
                    "    %s function %s(%s)%s {\n"
                  . "        %s\$this->handleMethodCall('%s', func_get_args(), %s);\n"
                  . "    }\n",
                    ($method->isPublic() ? 'public' : 'protected'),
                    $method->getName(),
                    $param['string'],
                    $returnType,
                    $return ? 'return ' : '',
                    $method->getName(),
                    self::shouldReturnSelf($class, $method) ? 'true' : 'false'
            );
            $methods[] = "'" . $method->getName() . "' => '" . $method->getName() . "'";
            $params[$method->getName()] = $param['names'];
        }

        return $code . sprintf(
                "\n    private \$_allowedMethods = [%s];\n",
                join(', ', $methods)
        ) . sprintf(
                "\n    private \$_methodParams = %s;\n",
                var_export($params, true)
        ) . sprintf(
                "\n    private \$_voidMethods = %s;\n",
                var_export($voidMethods, true)
        );
    }