//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public java.util.List<org.neo4j.internal.kernel.api.procs.FieldSignature> signatureFor(Method method) throws org.neo4j.internal.kernel.api.exceptions.ProcedureException
        public virtual IList <FieldSignature> SignatureFor(System.Reflection.MethodInfo method)
        {
            Parameter[]            @params   = method.Parameters;
            Type[]                 types     = method.GenericParameterTypes;
            IList <FieldSignature> signature = new List <FieldSignature>(@params.Length);
            bool seenDefault = false;

            for (int i = 0; i < @params.Length; i++)
            {
                Parameter param = @params[i];
                Type      type  = types[i];

                if (!param.isAnnotationPresent(typeof(Name)))
                {
                    throw new ProcedureException(Org.Neo4j.Kernel.Api.Exceptions.Status_Procedure.ProcedureRegistrationFailed, "Argument at position %d in method `%s` is missing an `@%s` annotation.%n" + "Please add the annotation, recompile the class and try again.", i, method.Name, typeof(Name).Name);
                }
                Name   parameter = param.getAnnotation(typeof(Name));
                string name      = parameter.value();

                if (name.Trim().Length == 0)
                {
                    throw new ProcedureException(Org.Neo4j.Kernel.Api.Exceptions.Status_Procedure.ProcedureRegistrationFailed, "Argument at position %d in method `%s` is annotated with a name,%n" + "but the name is empty, please provide a non-empty name for the argument.", i, method.Name);
                }

                try
                {
                    DefaultValueConverter            valueConverter = _typeMappers.converterFor(type);
                    Optional <DefaultParameterValue> defaultValue   = valueConverter.DefaultValue(parameter);
                    //it is not allowed to have holes in default values
                    if (seenDefault && !defaultValue.Present)
                    {
                        throw new ProcedureException(Org.Neo4j.Kernel.Api.Exceptions.Status_Procedure.ProcedureRegistrationFailed, "Non-default argument at position %d with name %s in method %s follows default argument. " + "Add a default value or rearrange arguments so that the non-default values comes first.", i, parameter.value(), method.Name);
                    }

                    seenDefault = defaultValue.Present;

                    // Currently only byte[] is not supported as a Cypher type, so we have specific conversion here.
                    // Should we add more unsupported types we should generalize this.
                    if (type == typeof(sbyte[]))
                    {
                        FieldSignature.InputMapper mapper = new ByteArrayConverter();
                        signature.Add(defaultValue.map(neo4jValue => inputField(name, valueConverter.Type(), neo4jValue, mapper)).orElseGet(() => inputField(name, valueConverter.Type(), mapper)));
                    }
                    else
                    {
                        signature.Add(defaultValue.map(neo4jValue => inputField(name, valueConverter.Type(), neo4jValue)).orElseGet(() => inputField(name, valueConverter.Type())));
                    }
                }
                catch (ProcedureException e)
                {
                    throw new ProcedureException(e.Status(), "Argument `%s` at position %d in `%s` with%n" + "type `%s` cannot be converted to a Neo4j type: %s", name, i, method.Name, param.Type.SimpleName, e.Message);
                }
            }

            return(signature);
        }