function safeSchemaFaker (context, oldSchema, resolveFor, parameterSourceOption, components,
  schemaFormat, schemaCache) {
  let prop, key, resolvedSchema, fakedSchema,
    schemaFakerCache = _.get(schemaCache, 'schemaFakerCache', {}),
    concreteUtils = context.concreteUtils;

  const options = context.computedOptions,
    resolveTo = _.get(options, 'parametersResolution', 'example'),
    indentCharacter = options.indentCharacter;

  /**
   * Schema is cloned here as resolveSchema() when called for CONVERSION use cases, will mutate schema in certain way.
   * i.e. For array it'll add maxItems = 2. This should be avoided as we'll again be needing non-mutated schema
   * in further VALIDATION use cases as needed.
   */
  resolvedSchema = resolveSchema(context, _.cloneDeep(oldSchema), {
    resolveFor: _.toLower(PROCESSING_TYPE.CONVERSION),
    isResponseSchema: parameterSourceOption === PARAMETER_SOURCE.RESPONSE
  });

  resolvedSchema = concreteUtils.fixExamplesByVersion(resolvedSchema);
  key = JSON.stringify(resolvedSchema);

  if (resolveTo === 'schema') {
    key = 'resolveToSchema ' + key;
    schemaFaker.option({
      useExamplesValue: false,
      useDefaultValue: true
    });
  }
  else if (resolveTo === 'example') {
    key = 'resolveToExample ' + key;
    schemaFaker.option({
      useExamplesValue: true
    });
  }

  if (resolveFor === PROCESSING_TYPE.VALIDATION) {
    schemaFaker.option({
      avoidExampleItemsLength: false
    });
  }

  if (schemaFormat === 'xml') {
    key += ' schemaFormatXML';
  }
  else {
    key += ' schemaFormatDEFAULT';
  }

  key = hash(key);
  if (schemaFakerCache[key]) {
    return schemaFakerCache[key];
  }

  if (resolvedSchema.properties) {
    // If any property exists with format:binary (and type: string) schemaFaker crashes
    // we just delete based on format=binary
    for (prop in resolvedSchema.properties) {
      if (resolvedSchema.properties.hasOwnProperty(prop)) {
        if (resolvedSchema.properties[prop].format === 'binary') {
          delete resolvedSchema.properties[prop].format;
        }
      }
    }
  }

  try {
    if (schemaFormat === SCHEMA_FORMATS.XML) {
      fakedSchema = xmlFaker(null, resolvedSchema, indentCharacter);
      schemaFakerCache[key] = fakedSchema;
      return fakedSchema;
    }
    // for JSON, the indentCharacter will be applied in the JSON.stringify step later on
    fakedSchema = schemaFaker(resolvedSchema, null, _.get(schemaCache, 'schemaValidationCache'));
    schemaFakerCache[key] = fakedSchema;
    return fakedSchema;
  }
  catch (e) {
    console.warn(
      'Error faking a schema. Not faking this schema. Schema:', resolvedSchema,
      'Error', e
    );
    return null;
  }
}
Safe wrapper for schemaFaker that resolves references and
removes things that might make schemaFaker crash
@param {Object} context - Required context from related SchemaPack function
@param {*} oldSchema the schema to fake
generate a fake object, example: use specified examples as-is). Default: schema
@param {*} resolveFor - resolve refs for flow validation/conversion (value to be one of VALIDATION/CONVERSION)
@param {string} parameterSourceOption Specifies whether the schema being faked is from a request or response.
@param {*} components list of predefined components (with schemas)
@param {string} schemaFormat default or xml
@param {object} schemaCache - object storing schemaFaker and schemaResolution caches
@returns {object} fakedObject