docs: function (hostId) {
  
          var swaggerDocResult = {};
          var registeredServices = Shared.registeredServices();
          var bodySchemaCounter = 0;
          var bodySchemaModels = [];
          var pathArray = [];
  
          registeredServices = registeredServices.sort(function (a, b) {
              var x = a["name"];
              var y = b["name"];
              return ((x < y) ? -1 : ((x > y) ? 1 : 0));
          });
  
          for (var index in registeredServices) {
              var service = registeredServices[index];
              var responses = service.responses;
              if (service.docs == true && service.hostId == hostId && service.url.match(/^\//)) {
                  var parameters = service.parameters;
                  var responseSchemes = {};
                  if (!_.isEmpty(responses)) {
  
  
                      // Build swagger compatible parameters definition
                      var swaggerParameters = [];
  
                      if (!_.isEmpty(parameters)) {
                          for (var sectionName in parameters) {
                              var section = parameters[sectionName];
                              var parameterName;
                              if (sectionName != "body") {
                                  var swaggerParameter = {};
                                  var parameter;
                                  for (parameterName in section) {
  
                                      parameter = section[parameterName];
  
                                      // Skip parameters which should not be shown in the documentation
                                      if (_.get(parameter, 'docs') === false) continue;
  
                                      var type = parameter.type ? parameter.type.toLowerCase() : "string";
                                      if (type != "string" && type != "number" && type != "boolean" && type != "array") {
                                          type = "string";
                                      }
  
                                      swaggerParameter = {
                                          "in": sectionName,
                                          "name": parameterName,
                                          "type": type,
                                          "description": parameter.desc || "",
                                          "required": parameter.required || false
                                      };
                                      swaggerParameters.push(swaggerParameter);
                                  }
                              } else {
  
                                  var thisHash = "def-" + ObjectHash(parameters[sectionName]);
                                  var subSchemaObject = _createBodySchema(bodySchemaModels, parameters[sectionName]);
                                  bodySchemaModels = subSchemaObject.bodySchemaModels;
  
                                  _registeredSchemaDefs[thisHash] = true;
                                  swaggerParameters.push({
                                      "in": "body",
                                      "name": "body",
                                      schema: {
                                          "$ref": "#/definitions/" + thisHash
                                      }
                                  });
  
                                  bodySchemaCounter++;
                              }
                          }
                      }
  
                      // Build swagger compatible response definition
                      var responseCodes = {};
                      var successHash = null;
                      var errorHash = null;
  
                      if (!_.isEmpty(service.responseSchemes)) {
                          if (service.responseSchemes.success) {
                              successHash = "def-" + ObjectHash(service.responseSchemes.success);
                              var subSchemaObjectSuccess = _createBodySchema(bodySchemaModels, service.responseSchemes.success);
                              bodySchemaModels = subSchemaObjectSuccess.bodySchemaModels;
                          }
                          if (service.responseSchemes.error) {
                              errorHash = "def-" + ObjectHash(service.responseSchemes.error);
                              var subSchemaObjectError = _createBodySchema(bodySchemaModels, service.responseSchemes.error);
                              bodySchemaModels = subSchemaObjectError.bodySchemaModels;
                          }
                      }
  
                      for (var responseCode in responses) {
                          if (parseInt(responseCode) == 204) {
                              responseCodes[responseCode] = {
                                  "description": responses[responseCode].join(', ')
                              }
                          }
                          else {
                              if (parseInt(responseCode) < 300) {
                                  if (successHash) {
                                      _registeredSchemaDefs[successHash] = true;
                                      responseCodes[responseCode] = {
                                          "description": responses[responseCode].join(', '),
                                          "schema": {
                                              "$ref": "#/definitions/" + successHash
                                          }
                                      }
                                  }
                                  else {
                                      responseCodes[responseCode] = {
                                          "description": responses[responseCode].join(', '),
                                          "schema": {
                                              "$ref": "#/definitions/Success"
                                          }
                                      }
                                  }
                              }
                              else {
                                  if (errorHash) {
                                      _registeredSchemaDefs[errorHash] = true;
                                      responseCodes[responseCode] = {
                                          "description": responses[responseCode].join(', '),
                                          "schema": {
                                              "$ref": "#/definitions/" + errorHash
                                          }
                                      }
                                  }
                                  else {
                                      responseCodes[responseCode] = {
                                          "description": responses[responseCode].join(', '),
                                          "schema": {
                                              "$ref": "#/definitions/Error"
                                          }
                                      }
                                  }
                              }
                          }
                      }
  
                      var swaggerDoc = {
                          "description": service.description || "",
                          "responses": responseCodes
                      };
  
                      if (service.deprecated === true) {
                          swaggerDoc.description = "NOTICE: THIS SERVICE IS DEPRECATED\n" + swaggerDoc.description;
                      }
  
                      if (!_.isEmpty(swaggerParameters)) {
                          swaggerDoc.parameters = swaggerParameters;
                      }
  
                      //add swagger docu, if present
                      var swaggerPath = service.url.replace(/:(\w)+/ig, function (match) {
  
                          swaggerDoc.parameters = swaggerDoc.parameters || [];
                          var pathVaribleIsDefined = false;
                          for (var pIndex in swaggerParameters) {
                              if (swaggerParameters[pIndex].in == "path" && swaggerParameters[pIndex].name == match.substring(1)) {
                                  pathVaribleIsDefined = true
                              }
                          }
                          if (pathVaribleIsDefined == false) {
                              swaggerDoc.parameters.push({
                                  "in": "path",
                                  "name": match.substring(1),
                                  "description": match.substring(1),
                                  "required": true,
                                  "type": "string"
                              });
                          }
  
                          return '{' + match.substring(1) + '}';
                      });
  
                      var env = Shared.config("environment");
  
                      if (_.isEmpty(swaggerDocResult)) {
                          swaggerDocResult = {};
                          swaggerDocResult["swagger"] = "2.0";
                          swaggerDocResult["info"] = {
                              "title": env.title || "API",
                              "description": env.description || "API documentation",
                              "version": env.version || "1.0"
                          };
                          //swaggerDocResult["host"] = "localhost:3000";
                          swaggerDocResult["basePath"] = "/";
                          swaggerDocResult["produces"] = ["application/json"];
                          swaggerDocResult["definitions"] = {
                              "ServiceDescriptions": {
                                  "properties": {
                                      "status": {
                                          "type": "number"
                                      },
                                      response: {
                                          "type": "array",
                                          "items": {
                                              "$ref": "#/definitions/ServiceDescription"
                                          }
                                      }
                                  }
                              },
                              "ServiceDescription": {
                                  "properties": {
                                      "modified": {
                                          "type": "string"
                                      },
                                      "url": {
                                          "type": "string"
                                      },
                                      "authorization": {
                                          "type": "boolean"
                                      },
                                      "name": {
                                          "type": "string"
                                      },
                                      "requestMethods": {
                                          "type": "array",
                                          "items": {
                                              "type": "string"
                                          }
                                      }
                                  }
                              },
                              "Error": {
                                  "properties": {
                                      "status": {
                                          type: "number"
                                      },
                                      "errors": {
                                          "type": "array",
                                          "items": {
                                              "$ref": "#/definitions/ErrorDescription"
                                          }
                                      }
                                  }
                              },
                              "ErrorDescription": {
                                  "properties": {
                                      "code": {
                                          "type": "string"
                                      },
                                      "msg": {
                                          "type": "string"
                                      }
                                  }
                              },
                              "Success": {
                                  "properties": {
                                      "status": {
                                          "type": "number"
                                      },
                                      response: {}
  
                                  }
                              }
                          };
                          var env = Shared.config('environment');
                          if (env.swagger) {
                              swaggerDocResult = _.merge(swaggerDocResult, _.cloneDeep(Shared.config('environment.swagger')));
                          }
                      }
  
                      //Register body schema models
                      for (var sIndex in bodySchemaModels) {
                          if (_registeredSchemaDefs[bodySchemaModels[sIndex].name]) {
                              swaggerDocResult.definitions[bodySchemaModels[sIndex].name] = bodySchemaModels[sIndex].schema;
                          }
                      }
  
                      for (var rSIndex in responseSchemes) {
                          //swaggerDocResult.definitions[rSIndex] = responseSchemes[rSIndex];
                      }
  
                      swaggerDocResult.paths = swaggerDocResult.paths || {};
  
                      var data = swaggerDoc;
  
                      if (service.deprecated === true) {
                          data.tags = [service.name + " (deprecated)"];
                      }
                      else {
                          data.tags = [service.name];
                      }
  
                      pathArray.push({
                          name: (service.name + swaggerPath + service.requestMethod.toLowerCase()).replace(/[^a-zA-Z0-9]+/g, ""),
                          requestMethod: service.requestMethod.toLowerCase(),
                          path: swaggerPath,
                          data: data
                      });
                  }
              }
          }
  
  
          if (!_.isEmpty(pathArray)) {
              swaggerDocResult.paths = swaggerDocResult.paths || {};
              pathArray = pathArray.sort(function (a, b) {
                  var x = a["name"];
                  var y = b["name"];
                  return ((x < y) ? -1 : ((x > y) ? 1 : 0));
              });
  
              for (var index in pathArray) {
                  var path = pathArray[index]["path"];
                  swaggerDocResult.paths[path] = swaggerDocResult.paths[path] || {};
                  swaggerDocResult.paths[path][pathArray[index]["requestMethod"]] = pathArray[index]["data"]
              }
          }
  
          return swaggerDocResult;
  
      }