docs: function (schema, models, modelsToIgnore, modelPropertyMacro) {
      // Resolve the schema (Handle nested schemas)
      schema = resolveSchema(schema);
  
      if(typeof modelPropertyMacro !== 'function') {
        modelPropertyMacro = function(prop){
          return (prop || {}).default;
        };
      }
  
      modelsToIgnore= modelsToIgnore || {};
  
      var type = schema.type || 'object';
      var format = schema.format;
      var model;
      var output;
  
      if (!_.isUndefined(schema.example)) {
        output = schema.example;
      } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {
        output = schema.enum[0];
      }
  
      if (_.isUndefined(output)) {
        if (schema.$ref) {
          model = models[simpleRef(schema.$ref)];
  
          if (!_.isUndefined(model)) {
            if (_.isUndefined(modelsToIgnore[model.name])) {
              modelsToIgnore[model.name] = model;
              output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);
              delete modelsToIgnore[model.name];
            } else {
              if (model.type === 'array') {
                output = [];
              } else {
                output = {};
              }
            }
          }
        } else if (!_.isUndefined(schema.default)) {
          output = schema.default;
        } else if (type === 'string') {
          if (format === 'date-time') {
            output = new Date().toISOString();
          } else if (format === 'date') {
            output = new Date().toISOString().split('T')[0];
          } else {
            output = 'string';
          }
        } else if (type === 'integer') {
          output = 0;
        } else if (type === 'number') {
          output = 0.0;
        } else if (type === 'boolean') {
          output = true;
        } else if (type === 'object') {
          output = {};
  
          _.forEach(schema.properties, function (property, name) {
            var cProperty = _.cloneDeep(property);
  
            // Allow macro to set the default value
            cProperty.default = modelPropertyMacro(property);
  
            output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);
          });
        } else if (type === 'array') {
          output = [];
  
          if (_.isArray(schema.items)) {
            _.forEach(schema.items, function (item) {
              output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));
            });
          } else if (_.isPlainObject(schema.items)) {
            output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));
          } else if (_.isUndefined(schema.items)) {
            output.push({});
          } else {
            console.log('Array type\'s \'items\' property is not an array or an object, cannot process');
          }
        }
      }
  
      return output;
    }