Inheritance: System.Attribute
 public ExcelParamsArgumentAttribute(ExcelArgumentAttribute original)
 {
     // Just copy all the fields
     AllowReference = original.AllowReference;
     Description = original.Description;
     Name = original.Name;
 }
        // NOTE: 16 parameter max for Expression.GetDelegateType
        public RegistrationEntry(MethodInfo methodInfo)
        {
            MethodInfo = methodInfo;

            var paramExprs = methodInfo.GetParameters()
                             .Select(pi => Expression.Parameter(pi.ParameterType, pi.Name))
                             .ToArray();
            FunctionLambda = Expression.Lambda(Expression.Call(methodInfo, paramExprs), methodInfo.Name, paramExprs);

            // Need to make sure we have explicit
            FunctionAttribute = methodInfo.GetCustomAttribute<ExcelFunctionAttribute>();
            if (FunctionAttribute == null)
                FunctionAttribute = new ExcelFunctionAttribute { Name = methodInfo.Name };
            else if (string.IsNullOrEmpty(FunctionAttribute.Name))
                FunctionAttribute.Name = methodInfo.Name;

            ArgumentAttributes = new List<ExcelArgumentAttribute>();
            foreach (var pi in methodInfo.GetParameters())
            {
                var argAtt = pi.GetCustomAttribute<ExcelArgumentAttribute>();
                if (argAtt == null)
                    argAtt = new ExcelArgumentAttribute { Name = pi.Name };
                else if (string.IsNullOrEmpty(argAtt.Name))
                    argAtt.Name = pi.Name;

                ArgumentAttributes.Add(argAtt);
            }

            // Special check for final Params argument - transform to an ExcelParamsArgumentAttribute
            // NOTE: This won't work with a custom derived attribute...
            var lastParam = methodInfo.GetParameters().LastOrDefault();
            if (lastParam != null && lastParam.GetCustomAttribute<ParamArrayAttribute>() != null)
            {
                var excelParamsAtt = new ExcelParamsArgumentAttribute(ArgumentAttributes.Last());
                ArgumentAttributes[ArgumentAttributes.Count - 1] = excelParamsAtt;
            }
        }
        /// <summary>
        /// Also craetes attributes from Optional / Default Value
        /// </summary>
        /// <param name="parameterInfo"></param>
        public ExcelParameterRegistration(ParameterInfo parameterInfo)
        {
            CustomAttributes = new List<object>();

            var allParameterAttributes = parameterInfo.GetCustomAttributes(true);
            foreach (var att in allParameterAttributes)
            {
                var argAtt = att as ExcelArgumentAttribute;
                if (argAtt != null)
                {
                    ArgumentAttribute = argAtt;
                    if (string.IsNullOrEmpty(ArgumentAttribute.Name))
                        ArgumentAttribute.Name = parameterInfo.Name;
                }
                else
                {
                    CustomAttributes.Add(att);
                }
            }

            // Check that the ExcelArgumentAttribute has been set
            if (ArgumentAttribute == null)
            {
                ArgumentAttribute = new ExcelArgumentAttribute { Name = parameterInfo.Name };
            }

            // Extra processing for Optional / Default values
            // TODO: Also consider DefaultValueAttribute (which is wrong, but might be used...)
            if (parameterInfo.IsOptional && parameterInfo.DefaultValue != DBNull.Value)
            {
                Debug.Assert(CustomAttributes.OfType<OptionalAttribute>().Any());
                Debug.Assert(!CustomAttributes.OfType<DefaultParameterValueAttribute>().Any());
                CustomAttributes.Add(new DefaultParameterValueAttribute(parameterInfo.DefaultValue));
            }
        }
        public ExcelParameterRegistration(ExcelArgumentAttribute argumentAttribute)
        {
            if (argumentAttribute == null) throw new ArgumentNullException("argumentAttribute");
            ArgumentAttribute = argumentAttribute;

            CustomAttributes = new List<object>();
        }