protected override CreateConstructorDeclarationContext CreateContext()
        {
            var target = GetTarget();

            var psiModule            = myClassLikeDeclaration.GetPsiModule();
            var constructorSignature = CSharpMethodSignatureProvider.CreateFromArguments(
                EmptyArray <ICSharpArgument> .Instance, (IType)null, psiModule);

            return(new CreateConstructorDeclarationContext
            {
                Class = GetTypeElement(),
                AccessRights = AccessRights.NONE,
                ConstructorSignature = constructorSignature,
                Target = target
            });
        }
        public IMethodDeclaration CreateDeclaration([NotNull] CSharpElementFactory factory,
                                                    [NotNull] KnownTypesCache knownTypesCache,
                                                    [NotNull] IClassLikeDeclaration classDeclaration,
                                                    AccessRights accessRights,
                                                    bool makeVirtual   = false,
                                                    bool makeCoroutine = false)
        {
            var    builder = new StringBuilder(128);
            var    args    = new object[1 + Parameters.Length];
            object arg;
            var    argIndex = 0;
            var    module   = classDeclaration.GetPsiModule();

            if (accessRights != AccessRights.NONE)
            {
                builder.Append(CSharpDeclaredElementPresenter.Instance.Format(accessRights));
                builder.Append(" ");
            }

            if (IsStatic)
            {
                builder.Append("static ");
            }

            // Consider this declaration a template, and the final generated code implements (or overrides) this API
            if (makeVirtual)
            {
                builder.Append("virtual ");
            }
            if (makeCoroutine && CanBeCoroutine)
            {
                builder.Append(PredefinedType.IENUMERATOR_FQN.FullName);
            }
            else
            {
                arg = GetTypeObject(ReturnType, knownTypesCache, module);
                if (arg is string)
                {
                    builder.Append(arg);
                    if (ReturnType.IsArray)
                    {
                        builder.Append("[]");
                    }
                }
                else
                {
                    builder.Append("$0");
                    args[argIndex++] = arg;
                }
            }

            builder.Append(" ");
            builder.Append(Name);
            builder.Append("(");

            for (var i = 0; i < Parameters.Length; i++)
            {
                if (i > 0)
                {
                    builder.Append(",");
                }

                var parameter = Parameters[i];
                // TODO: `out` or `ref`?
                // From reflection point of view, it's a "ByRef" Type, and that's all we know...
                // The only place it's currently being used is an out parameter
                if (parameter.IsByRef)
                {
                    builder.Append("out ");
                }

                arg = GetTypeObject(parameter.TypeSpec, knownTypesCache, module);
                if (arg is string)
                {
                    builder.Append(arg);
                    if (parameter.TypeSpec.IsArray)
                    {
                        builder.Append("[]");
                    }
                }
                else
                {
                    builder.Append($"${argIndex}");
                    args[argIndex++] = arg;
                }
                builder.Append(' ');
                builder.Append(parameter.Name);
            }

            builder.Append(");");

            var declaration = (IMethodDeclaration)factory.CreateTypeMemberDeclaration(builder.ToString(), args);

            declaration.SetResolveContextForSandBox(classDeclaration, SandBoxContextType.Child);
            return(declaration);
        }