/// <summary>
 /// Determines whether a <see cref="ParameterInfo"/> is by-reference, output or a return value.
 /// </summary>
 /// <param name="parameterInfo">
 /// The parameter information.
 /// </param>
 /// <returns>
 /// <c>true</c>if <paramref name="parameterInfo"/> is by-reference, output or a return value; otherwise <c>false</c>.
 /// </returns>
 public static bool IsByRefOutOrReturnValue(this ParameterInfo parameterInfo)
 {
     return(parameterInfo.IsByRefOrOut() || parameterInfo.IsReturnValue());
 }
 /// <summary>
 /// Determines whether a <see cref="ParameterInfo"/> is input or by-reference.
 /// </summary>
 /// <param name="parameterInfo">
 /// The parameter information.
 /// </param>
 /// <returns>
 /// <c>true</c>if <paramref name="parameterInfo"/> is input or by-reference; otherwise <c>false</c>.
 /// </returns>
 public static bool IsInOrByRef(this ParameterInfo parameterInfo)
 {
     return(!parameterInfo.IsOut && !parameterInfo.IsReturnValue());
 }
            /// <summary>
            /// Appends a parameter to the buffer.
            /// </summary>
            /// <param name="parameter">
            /// Information about the parameter to append.
            /// </param>
            /// <param name="argument">
            /// The argument that was passed to the parameter.
            /// </param>
            private void AppendParameter(ParameterInfo parameter, object argument)
            {
                bool sensitive = this.sensitiveMethod || parameter.IsDefined(typeof(SensitiveDataAttribute), false);

                try
                {
                    if (!parameter.IsReturnValue())
                    {
                        this.buffer.Append(parameter.Name);
                    }

                    this.buffer.Append('=');

                    if (argument == null)
                    {
                        this.buffer.Append("<null>");
                        return;
                    }

#if DEBUG

                    // in debug builds sensitive data may be traced with the appropriate switch; in release builds it may not
                    if (sensitive && !StyleCopTrace.Switch.TraceSensitiveData)
#else
                    if (sensitive) 
#endif
                    {
                        this.buffer.Append("<obscured>");
                        return;
                    }

                    // if the argument is a string then print it with quotes
                    if (argument is string)
                    {
                        this.buffer.Append("\"" + argument + "\"");
                        return;
                    }

                    // if the argument is a type then print it as a typeof
                    if (argument is Type)
                    {
                        this.buffer.Append("typeof(" + ((Type)argument).Name + ")");
                        return;
                    }

                    // if the argument is a primitive (or pseudo-primitive) type then print it 'as is'
                    Type argumentType = argument.GetType();
                    if (argumentType.IsPrimitive || argumentType == typeof(decimal))
                    {
                        this.buffer.Append(argument);
                        return;
                    }

                    // if it has an overridden ToString method print it in curly brackets
                    MethodInfo stringMethod = argumentType.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);
                    if (stringMethod.GetBaseDefinition().DeclaringType != stringMethod.DeclaringType)
                    {
                        this.buffer.Append("{" + argument + "}");
                        return;
                    }

                    // if the argument type has a DebuggerDisplayAttribute then format and print in square brackets
                    DebuggerDisplayAttribute displayAttribute =
                        (DebuggerDisplayAttribute)argumentType.GetCustomAttributes(typeof(DebuggerDisplayAttribute), true).FirstOrDefault();
                    if (displayAttribute != null)
                    {
                        MatchEvaluator evaluator = match =>
                            {
                                string memberName = match.Value.Replace("{", null).Replace("}", null);
                                PropertyInfo propertyInfo = argumentType.GetProperty(
                                    memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
                                if (propertyInfo != null)
                                {
                                    return Convert.ToString(propertyInfo.GetValue(argument, null), CultureInfo.InvariantCulture);
                                }

                                FieldInfo fieldInfo;
                                Type typeToInspect = argumentType;
                                do
                                {
                                    fieldInfo = typeToInspect.GetField(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                                    typeToInspect = typeToInspect.BaseType;
                                }
                                while (fieldInfo == null && typeToInspect != typeof(object));
                                return fieldInfo != null ? Convert.ToString(fieldInfo.GetValue(argument), CultureInfo.InvariantCulture) : "?";
                            };

                        string displayString = DebuggerDisplayFormatRegex.Replace(displayAttribute.Value, evaluator);
                        this.buffer.Append('[');
                        this.AppendTypeName(argumentType);
                        this.buffer.Append(": ").Append(displayString).Append(']');
                        return;
                    }

                    // did somebody forget to supply the parameter?
                    if (argument == Missing.Value)
                    {
                        this.buffer.Append("<missing>");
                        return;
                    }

                    // catch all - just display the type name
                    this.buffer.Append('[');
                    this.AppendTypeName(argumentType);
                    this.buffer.Append(']');
                }
                catch
                {
                    this.buffer.Append("<error>");
                }
            }