private void GenerateAnnotations(MemberInfo property, ParameterDescription propertyModel) {
			List<ParameterAnnotation> annotations = new List<ParameterAnnotation>();

			IEnumerable<Attribute> attributes = property.GetCustomAttributes();
			foreach (Attribute attribute in attributes) {
				Func<object, string> textGenerator;
				if (AnnotationTextGenerator.TryGetValue(attribute.GetType(), out textGenerator)) {
					annotations.Add(
						new ParameterAnnotation {
							AnnotationAttribute = attribute,
							Documentation = textGenerator(attribute)
						});
				}
			}

			// Rearrange the annotations
			annotations.Sort((x, y) => {
				// Special-case RequiredAttribute so that it shows up on top
				if (x.AnnotationAttribute is RequiredAttribute) {
					return -1;
				}
				if (y.AnnotationAttribute is RequiredAttribute) {
					return 1;
				}

				// Sort the rest based on alphabetic order of the documentation
				return String.Compare(x.Documentation, y.Documentation, StringComparison.OrdinalIgnoreCase);
			});

			foreach (ParameterAnnotation annotation in annotations) {
				propertyModel.Annotations.Add(annotation);
			}
		}
		private ModelDescription GenerateComplexTypeModelDescription(Type modelType) {
			ComplexTypeModelDescription complexModelDescription = new ComplexTypeModelDescription {
				Name = ModelNameHelper.GetModelName(modelType),
				ModelType = modelType,
				Documentation = CreateDefaultDocumentation(modelType)
			};

			GeneratedModels.Add(complexModelDescription.Name, complexModelDescription);
			bool hasDataContractAttribute = modelType.GetCustomAttribute<DataContractAttribute>() != null;
			PropertyInfo[] properties = modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
			foreach (PropertyInfo property in properties) {
				if (ShouldDisplayMember(property, hasDataContractAttribute)) {
					ParameterDescription propertyModel = new ParameterDescription {
						Name = GetMemberName(property, hasDataContractAttribute)
					};

					if (DocumentationProvider != null) {
						propertyModel.Documentation = DocumentationProvider.GetDocumentation(property);
					}

					GenerateAnnotations(property, propertyModel);
					complexModelDescription.Properties.Add(propertyModel);
					propertyModel.TypeDescription = GetOrCreateModelDescription(property.PropertyType);
				}
			}

			FieldInfo[] fields = modelType.GetFields(BindingFlags.Public | BindingFlags.Instance);
			foreach (FieldInfo field in fields) {
				if (ShouldDisplayMember(field, hasDataContractAttribute)) {
					ParameterDescription propertyModel = new ParameterDescription {
						Name = GetMemberName(field, hasDataContractAttribute)
					};

					if (DocumentationProvider != null) {
						propertyModel.Documentation = DocumentationProvider.GetDocumentation(field);
					}

					complexModelDescription.Properties.Add(propertyModel);
					propertyModel.TypeDescription = GetOrCreateModelDescription(field.FieldType);
				}
			}

			return complexModelDescription;
		}
		private static ParameterDescription AddParameterDescription(HelpPageApiModel apiModel,
			ApiParameterDescription apiParameter, ModelDescription typeDescription) {
			ParameterDescription parameterDescription = new ParameterDescription {
				Name = apiParameter.Name,
				Documentation = apiParameter.Documentation,
				TypeDescription = typeDescription,
			};

			apiModel.UriParameters.Add(parameterDescription);
			return parameterDescription;
		}