private SimplePropertyInfo CreateSimpleProperty(PropertyInfo property, SimplePropertyInfo parent)
        {
            var propertyTypeName = GetValidTypeName(property.PropertyType);
            var simpleProperty   = new SimplePropertyInfo(property, parent, propertyTypeName, AssemblyDocumentation);

            return(simpleProperty);
        }
        /// <summary>
        /// This ctor should be used by anything that emits code. Emit limiters are always emitted
        /// as int types regardless of the wire type and as such a check will be made for the
        /// parameter being bound before use. The check for all other parameters is done based on
        /// whether they could be a nullable value type.
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="parent"></param>
        /// <param name="propertyTypeName"></param>
        /// <param name="documentationSource"></param>
        /// <param name="collectionType"></param>
        /// <param name="genericCollectionTypes"></param>
        public SimplePropertyInfo(PropertyInfo propertyInfo,
                                  SimplePropertyInfo parent,
                                  string propertyTypeName,
                                  XmlDocument documentationSource,
                                  PropertyCollectionType collectionType,
                                  Type[] genericCollectionTypes)
        {
            BaseProperty       = propertyInfo;
            Name               = propertyInfo.Name;
            PropertyType       = propertyInfo.PropertyType;
            PropertyTypeName   = propertyTypeName;
            DeclaringType      = propertyInfo.DeclaringType;
            DeprecationMessage = propertyInfo.GetCustomAttributes(typeof(ObsoleteAttribute), false).Cast <ObsoleteAttribute>().FirstOrDefault()?.Message;

            dynamic awsPropertyAttribute = propertyInfo.GetCustomAttributes().Where(attribute => attribute.GetType().FullName == "Amazon.Runtime.Internal.AWSPropertyAttribute").SingleOrDefault();

            if (awsPropertyAttribute != null)
            {
                IsRequired = awsPropertyAttribute?.Required;
                MinValue   = awsPropertyAttribute.IsMinSet ? awsPropertyAttribute.Min : null;
                MaxValue   = awsPropertyAttribute.IsMaxSet ? awsPropertyAttribute.Max : null;
            }

            CollectionType         = collectionType;
            GenericCollectionTypes = genericCollectionTypes;

            Parent              = parent;
            Children            = new List <SimplePropertyInfo>();
            IsReadWrite         = propertyInfo.CanRead && propertyInfo.CanWrite;
            DocumentationSource = documentationSource;
            IsMemoryStreamType  = typeof(System.IO.MemoryStream).IsAssignableFrom(PropertyType);
            IsStreamType        = typeof(System.IO.Stream).IsAssignableFrom(PropertyType);
            IsDocumentType      = PropertyType.FullName == "Amazon.Runtime.Documents.Document";

            UseParameterValueOnlyIfBound = IsNullableValueType(propertyInfo.PropertyType);

            // if analysing properties on a cmdlet for help purposes, extract
            // the Parameter, AWSRequiredParameter and Alias attributes info
            PsParameterAttribute
                = propertyInfo.GetCustomAttributes(typeof(ParameterAttribute), false) as ParameterAttribute[];
            PsAliasAttribute
                = propertyInfo.GetCustomAttributes(typeof(AliasAttribute), false).SingleOrDefault() as AliasAttribute;
            IsRequiredForParameterSets = GetRequiredHelpDescription(propertyInfo);

            IsConstrainedToSet = PropertyType.BaseType != null && PropertyType.BaseType.FullName.Equals(ConstantClassBaseTypeName, StringComparison.Ordinal);
        }
        protected static void InspectParameter(SimplePropertyInfo property, out HashSet <string> isRequiredForParameterSets,
                                               out string pipelineInput, out string position, out string[] aliases)
        {
            pipelineInput = "False";
            position      = "Named";
            aliases       = new string[0];

            // 'Required? true | false'
            isRequiredForParameterSets = property.IsRequiredForParameterSets;

            if (property.PsParameterAttribute == null)
            {
                return;
            }

            // 'Accept pipeline input?       true ([ByValue,] [ByPropertyName]) | false'
            var markedValueFromPipeline     = IsMarkedValueFromPipeline(property.PsParameterAttribute);
            var markedValueFromPropertyName = IsMarkedValueFromPipelineByName(property.PsParameterAttribute);

            if (markedValueFromPipeline | markedValueFromPropertyName)
            {
                pipelineInput = string.Format("True ({0}{1}{2})",
                                              markedValueFromPipeline ? "ByValue" : "",
                                              markedValueFromPipeline && markedValueFromPropertyName ? ", " : "",
                                              markedValueFromPropertyName ? "ByPropertyName" : "");
            }

            // 'Position named | ordinal'. Shell convention is to start indexing at 1, but we
            // start at 0 internally.
            var pos = HasPositionalData(property.PsParameterAttribute);

            if (pos >= 0)
            {
                position = (pos + 1).ToString(CultureInfo.InvariantCulture);
            }

            if (property.PsAliasAttribute != null)
            {
                aliases = property.PsAliasAttribute.AliasNames.ToArray();
            }
        }
 /// <summary>
 /// This ctor is used by the help generator. At this point we don't care about collection type/contents or
 /// emit limiter status as the type data has already been determined.
 /// </summary>
 /// <param name="propertyInfo"></param>
 /// <param name="parent"></param>
 /// <param name="propertyTypeName"></param>
 /// <param name="documentationSource"></param>
 public SimplePropertyInfo(PropertyInfo propertyInfo, SimplePropertyInfo parent, string propertyTypeName, XmlDocument documentationSource)
     : this(propertyInfo, parent, propertyTypeName, documentationSource, PropertyCollectionType.NoCollection, null)
 {
 }