public ProxyDefinition ParseSwaggerDoc(string document, bool parseOperationIdForProxyName)
        {
            var jObject = JObject.Parse(document);

            var proxyDefinition = new ProxyDefinition();

            var infoToken = jObject["info"];
            proxyDefinition.Title = infoToken["title"].ToString();
            var descriptionToken = infoToken["description"];
            proxyDefinition.Description = descriptionToken != null ? descriptionToken.ToString() : null;

            this.ParsePaths(jObject, proxyDefinition, parseOperationIdForProxyName);
            this.ParseDefinitions(jObject, proxyDefinition);

            return proxyDefinition;
        }
        private void ParsePaths(JObject jObject, ProxyDefinition proxyDefinition, bool parseOperationIdForProxyName)
        {
            foreach (var pathToken in jObject["paths"].Cast<JProperty>())
            {
                var path = pathToken.Name;
                foreach (var operationToken in pathToken.First.Cast<JProperty>())
                {
                    var proxyName = string.Empty;
                    var method = operationToken.Name;
                    var operationId = operationToken.First["operationId"].ToString();

                    if (parseOperationIdForProxyName)
                    {
                        if (operationId.Contains("_"))
                        {
                            var underscoreLocation = operationId.IndexOf("_", StringComparison.OrdinalIgnoreCase);
                            proxyName = operationId.Substring(0, underscoreLocation);
                            operationId = operationId.Substring(underscoreLocation + 1);
                        }
                    }

                    if (string.IsNullOrWhiteSpace(proxyName))
                    {
                        // didn't get the proxy name from the operation id, let's try the tags
                        var tagToken = operationToken.First["tags"];
                        if (tagToken != null)
                        {
                            var tags = tagToken.ToObject<List<string>>();
                            proxyName = tags.First();
                        }
                    }

                    var descriptionToken = operationToken.First["description"];
                    string description = null;
                    if (descriptionToken != null)
                    {
                        description = descriptionToken.ToString();
                    }

                    string returnType;
                    var schema = operationToken.First["responses"]["200"];
                    if (schema != null)
                    {
                        bool dummyNullable;
                        returnType = this.GetTypeName(schema, out dummyNullable);
                        if (returnType != null && returnType.Equals("Void"))
                            returnType = null;
                    }
                    else
                    {
                        returnType = null;
                    }

                    var parameters = new List<Parameter>();
                    var paramTokens = operationToken.First["parameters"];
                    if (paramTokens != null)
                    {
                        foreach (var prop in paramTokens)
                        {
                            var type = ParseType(prop);

                            var isRequired = prop["required"].ToObject<bool>();

                            ParameterIn parameterIn;
                            if (prop["in"].ToString().Equals("path"))
                            {
                                parameterIn = ParameterIn.Path;
                            }
                            else if (prop["in"].ToString().Equals("query"))
                            {
                                parameterIn = ParameterIn.Query;
                            }
                            else if (prop["in"].ToString().Equals("formData"))
                            {
                                parameterIn = ParameterIn.FormData;
                            }
                            else
                            {
                                parameterIn = ParameterIn.Body;
                            }


                            var propDescriptionToken = prop["description"];
                            string propDescription = string.Empty;
                            if (propDescriptionToken != null)
                            {
                                propDescription = propDescriptionToken.ToString();
                            }

                            string collectionFormat = string.Empty;
                            var collectionFormatToken = prop["collectionFormat"];
                            if (collectionFormatToken != null)
                            {
                                collectionFormat = collectionFormatToken.ToString();
                            }

                            parameters.Add(new Parameter(type, parameterIn, isRequired, propDescription, collectionFormat));
                        }
                    }

                    proxyDefinition.Operations.Add(new Operation(returnType, method, path, parameters, operationId, description, proxyName));
                }
            }
        }
        private void ParseDefinitions(JObject jObject, ProxyDefinition proxyDefinition)
        {
            foreach (var definitionToken in jObject["definitions"].Where(i => i.Type == JTokenType.Property).Cast<JProperty>())
            {
                bool addIt = true;
                var classDefinition = new ClassDefinition(definitionToken.Name);
                var allOf = definitionToken.First["allOf"];
                if (allOf != null)
                {
                    foreach (var itemToken in allOf)
                    {
                        var refType = itemToken["$ref"] as JValue;
                        if (refType != null)
                        {
                            classDefinition.Inherits = refType.Value.ToString();
                        }

                        var properties = itemToken["properties"];
                        if (properties != null)
                        {
                            foreach (var prop in properties)
                            {
                                var type = ParseType(prop);
                                classDefinition.Properties.Add(type);
                            }
                        }
                    }
                }
                else
                {
                    var properties = definitionToken.Value["properties"];
                    if (properties != null)
                    {
                        foreach (var prop in properties)
                        {
                            var type = ParseType(prop);
                            classDefinition.Properties.Add(type);
                        }
                    }
                    else
                    {
                        addIt = false;
                    }
                }


                classDefinition.Name = FixGenericName(classDefinition.Name);
                if (classDefinition.Name.Equals("Void", StringComparison.InvariantCulture))
                {
                    addIt = false;
                }

                if (addIt)
                {
                    proxyDefinition.ClassDefinitions.Add(classDefinition);
                }
            }
        }