protected virtual IEnumerable<MigrationStatement> Generate(ProcedureOperation operation, string action)
        {
            // we might add support for [LANGUAGE SQL | LANGUAGE JAVA ] via AnonymousArguments

            using (var writer = SqlWriter())
            {
                writer.Write(action);
                writer.Write(" PROCEDURE ");
                writer.Write(Quote(operation.Name));
                writer.Write(" (");
                if (operation.Parameters.Any())
                {
                    writer.WriteLine();
                    writer.Indent++;
                    WriteColumns(writer, operation.Parameters.Select(Generate), true);
                    writer.Indent--;
                    writer.WriteLine();
                }
                writer.Write(")");
                writer.WriteLine();
                writer.Write("AS");
                writer.WriteLine();
                writer.Write(operation.BodySql);
                writer.WriteLine();
                writer.Write("END_PROCEDURE");
                yield return Statement(writer);
            }
        }
        private void Generate(ProcedureOperation procedureOperation, string modifier)
        {
            DebugCheck.NotNull(procedureOperation);
            DebugCheck.NotEmpty(modifier);

            using (var writer = Writer())
            {
                writer.Write(modifier);
                writer.WriteLine(" PROCEDURE " + Name(procedureOperation.Name));
                writer.Indent++;

                procedureOperation.Parameters.Each(
                    (p, i) =>
                    {
                        Generate(p, writer);
                        writer.WriteLine(
                            i < procedureOperation.Parameters.Count - 1
                                ? ","
                                : string.Empty);
                    });

                writer.Indent--;
                writer.WriteLine("AS");
                writer.WriteLine("BEGIN");
                writer.Indent++;

                writer.WriteLine(
                    !string.IsNullOrWhiteSpace(procedureOperation.BodySql)
                        ? Indent(procedureOperation.BodySql, writer.CurrentIndentation())
                        : "RETURN");

                writer.Indent--;
                writer.Write("END");

                Statement(writer, batchTerminator: BatchTerminator);
            }
        }
        private void Generate(ProcedureOperation procedureOperation, string methodName, IndentedTextWriter writer)
        {
            DebugCheck.NotNull(procedureOperation);
            DebugCheck.NotEmpty(methodName);
            DebugCheck.NotNull(writer);

            writer.Write(methodName);
            writer.WriteLine("(");
            writer.Indent++;
            writer.Write(Quote(procedureOperation.Name));
            writer.WriteLine(",");

            if (procedureOperation.Parameters.Any())
            {
                writer.WriteLine("Function(p) New With");
                writer.Indent++;
                writer.WriteLine("{");
                writer.Indent++;

                procedureOperation.Parameters.Each(
                    (p, i) =>
                    {
                        var scrubbedName = ScrubName(p.Name);

                        writer.Write(".");
                        writer.Write(scrubbedName);
                        writer.Write(" =");
                        Generate(p, writer, !string.Equals(p.Name, scrubbedName, StringComparison.Ordinal));

                        if (i < procedureOperation.Parameters.Count - 1)
                        {
                            writer.Write(",");
                        }

                        writer.WriteLine();
                    });

                writer.Indent--;
                writer.WriteLine("},");
                writer.Indent--;
            }

            writer.Write("body :=");

            if (!string.IsNullOrWhiteSpace(procedureOperation.BodySql))
            {
                writer.WriteLine();
                writer.Indent++;

                var indentString
                    = "\" & vbCrLf & _"
                      + writer.NewLine
                      + writer.CurrentIndentation()
                      + "\"";

                writer.WriteLine(
                    Generate(
                        procedureOperation
                            .BodySql
                            .Replace(Environment.NewLine, indentString)));

                writer.Indent--;
            }
            else
            {
                writer.WriteLine(" \"\"");
            }

            writer.Indent--;
            writer.WriteLine(")");
            writer.WriteLine();
        }
		protected virtual IEnumerable<MigrationStatement> Generate(ProcedureOperation operation, string action)
		{
			using (var writer = SqlWriter())
			{
				var inputParameters = operation.Parameters.Where(x => !x.IsOutParameter).ToArray();
				var outputParameters = operation.Parameters.Where(x => x.IsOutParameter).ToArray();

				writer.Write(action);
				writer.Write(" PROCEDURE ");
				writer.Write(Quote(ExtractName(operation.Name)));
				if (inputParameters.Any())
				{
					writer.Write(" (");
					writer.WriteLine();
					writer.Indent++;
					WriteColumns(writer, inputParameters.Select(Generate), true);
					writer.Indent--;
					writer.WriteLine();
					writer.Write(")");
				}
				if (outputParameters.Any())
				{
					writer.WriteLine();
					writer.Write("RETURNS (");
					writer.WriteLine();
					writer.Indent++;
					WriteColumns(writer, outputParameters.Select(Generate), true);
					writer.Indent--;
					writer.WriteLine();
					writer.Write(")");
				}
				writer.WriteLine();
				writer.WriteLine("AS");
				writer.WriteLine("BEGIN");
				writer.Write(operation.BodySql);
				writer.WriteLine();
				writer.Write("END");
				yield return Statement(writer);
			}
		}