private static void GenerateSamples(HelpPageApiModel apiModel, HelpPageSampleGenerator sampleGenerator) {
			try {
				foreach (var item in sampleGenerator.GetSampleRequests(apiModel.ApiDescription)) {
					apiModel.SampleRequests.Add(item.Key, item.Value);
					LogInvalidSampleAsError(apiModel, item.Value);
				}

				foreach (var item in sampleGenerator.GetSampleResponses(apiModel.ApiDescription)) {
					apiModel.SampleResponses.Add(item.Key, item.Value);
					LogInvalidSampleAsError(apiModel, item.Value);
				}
			} catch (Exception e) {
				apiModel.ErrorMessages.Add(String.Format(CultureInfo.CurrentCulture,
					"An exception has occurred while generating the sample. Exception message: {0}",
					HelpPageSampleGenerator.UnwrapException(e).Message));
			}
		}
		private static void LogInvalidSampleAsError(HelpPageApiModel apiModel, object sample) {
			InvalidSample invalidSample = sample as InvalidSample;
			if (invalidSample != null) {
				apiModel.ErrorMessages.Add(invalidSample.ErrorMessage);
			}
		}
		private static void GenerateResourceDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator) {
			ResponseDescription response = apiModel.ApiDescription.ResponseDescription;
			Type responseType = response.ResponseType ?? response.DeclaredType;
			if (responseType != null && responseType != typeof(void)) {
				apiModel.ResourceDescription = modelGenerator.GetOrCreateModelDescription(responseType);
			}
		}
		private static void GenerateRequestModelDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator, HelpPageSampleGenerator sampleGenerator) {
			ApiDescription apiDescription = apiModel.ApiDescription;
			foreach (ApiParameterDescription apiParameter in apiDescription.ParameterDescriptions) {
				if (apiParameter.Source == ApiParameterSource.FromBody) {
					Type parameterType = apiParameter.ParameterDescriptor.ParameterType;
					apiModel.RequestModelDescription = modelGenerator.GetOrCreateModelDescription(parameterType);
					apiModel.RequestDocumentation = apiParameter.Documentation;
				} else if (apiParameter.ParameterDescriptor != null &&
					  apiParameter.ParameterDescriptor.ParameterType == typeof(HttpRequestMessage)) {
					Type parameterType = sampleGenerator.ResolveHttpRequestMessageType(apiDescription);

					if (parameterType != null) {
						apiModel.RequestModelDescription = modelGenerator.GetOrCreateModelDescription(parameterType);
					}
				}
			}
		}
		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;
		}
		private static void GenerateUriParameters(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator) {
			ApiDescription apiDescription = apiModel.ApiDescription;
			foreach (ApiParameterDescription apiParameter in apiDescription.ParameterDescriptions) {
				if (apiParameter.Source == ApiParameterSource.FromUri) {
					HttpParameterDescriptor parameterDescriptor = apiParameter.ParameterDescriptor;
					Type parameterType = null;
					ModelDescription typeDescription = null;
					ComplexTypeModelDescription complexTypeDescription = null;
					if (parameterDescriptor != null) {
						parameterType = parameterDescriptor.ParameterType;
						typeDescription = modelGenerator.GetOrCreateModelDescription(parameterType);
						complexTypeDescription = typeDescription as ComplexTypeModelDescription;
					}

					// Example:
					// [TypeConverter(typeof(PointConverter))]
					// public class Point
					// {
					//     public Point(int x, int y)
					//     {
					//         X = x;
					//         Y = y;
					//     }
					//     public int X { get; set; }
					//     public int Y { get; set; }
					// }
					// Class Point is bindable with a TypeConverter, so Point will be added to UriParameters collection.
					// 
					// public class Point
					// {
					//     public int X { get; set; }
					//     public int Y { get; set; }
					// }
					// Regular complex class Point will have properties X and Y added to UriParameters collection.
					if (complexTypeDescription != null
						&& !IsBindableWithTypeConverter(parameterType)) {
						foreach (ParameterDescription uriParameter in complexTypeDescription.Properties) {
							apiModel.UriParameters.Add(uriParameter);
						}
					} else if (parameterDescriptor != null) {
						ParameterDescription uriParameter =
							AddParameterDescription(apiModel, apiParameter, typeDescription);

						if (!parameterDescriptor.IsOptional) {
							uriParameter.Annotations.Add(new ParameterAnnotation() { Documentation = "Required" });
						}

						object defaultValue = parameterDescriptor.DefaultValue;
						if (defaultValue != null) {
							uriParameter.Annotations.Add(new ParameterAnnotation() { Documentation = "Default value is " + Convert.ToString(defaultValue, CultureInfo.InvariantCulture) });
						}
					} else {
						Debug.Assert(parameterDescriptor == null);

						// If parameterDescriptor is null, this is an undeclared route parameter which only occurs
						// when source is FromUri. Ignored in request model and among resource parameters but listed
						// as a simple string here.
						ModelDescription modelDescription = modelGenerator.GetOrCreateModelDescription(typeof(string));
						AddParameterDescription(apiModel, apiParameter, modelDescription);
					}
				}
			}
		}
		private static HelpPageApiModel GenerateApiModel(ApiDescription apiDescription, HttpConfiguration config) {
			HelpPageApiModel apiModel = new HelpPageApiModel() {
				ApiDescription = apiDescription,
			};

			ModelDescriptionGenerator modelGenerator = config.GetModelDescriptionGenerator();
			HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator();
			GenerateUriParameters(apiModel, modelGenerator);
			GenerateRequestModelDescription(apiModel, modelGenerator, sampleGenerator);
			GenerateResourceDescription(apiModel, modelGenerator);
			GenerateSamples(apiModel, sampleGenerator);

			return apiModel;
		}