function generateComponentsObject(documentContext, rootContent,
  refTypeResolver, components, version, remoteRefResolver) {
  let notInLine = Object.entries(documentContext.globalReferences).filter(([, value]) => {
      return value.keyInComponents.length !== 0;
    }),
    circularRefsSet = new Set();
  const { COMPONENTS_KEYS } = getBundleRulesDataByVersion(version);
  notInLine.forEach(([key, value]) => {
    let [nodeRef, partial] = key.split(localPointer);
    if (documentContext.globalReferences[key].refHasContent) {
      setValueInComponents(
        value.keyInComponents,
        components,
        getContentFromTrace(documentContext.nodeContents[nodeRef], partial),
        COMPONENTS_KEYS
      );
    }
  });
  [rootContent, components].forEach((contentData, index) => {
    if (index === 1 && contentData.hasOwnProperty('$ref')) {
      delete contentData.$ref;
    }
    traverseUtility(contentData).forEach(function (property) {
      if (property) {
        let hasReferenceTypeKey;
        hasReferenceTypeKey = Object.keys(property)
          .find(
            (key) => {
              return refTypeResolver(property, key);
            }
          );
        if (hasReferenceTypeKey) {
          let tempRef = property.$ref,
            [nodeRef, local] = tempRef.split(localPointer),
            refData = documentContext.globalReferences[tempRef],
            isMissingNode = documentContext.missing.find((missingNode) => {
              return missingNode.path === nodeRef;
            });

          if (isMissingNode) {
            refData.nodeContent = refData.node;
            refData.local = false;
          }
          else if (!refData) {
            return;
          }
          else if (!isExtRef(property, '$ref') && isExtURLRef(property, '$ref')) {
            let splitPathByHttp = property.$ref.split(httpSeparator),
              prefix = splitPathByHttp
                .slice(0, splitPathByHttp.length - 1).join(httpSeparator) +
                httpSeparator + splitPathByHttp[splitPathByHttp.length - 1]
                .split(localPointer)[0],
              separatedPaths = [prefix, splitPathByHttp[splitPathByHttp.length - 1].split(localPointer)[1]];

            nodeRef = separatedPaths[0];
            local = separatedPaths[1];

            refData.nodeContent = documentContext.nodeContents[nodeRef];

            const isReferenceRemoteURL = stringIsAValidUrl(nodeRef);

            if (isReferenceRemoteURL && _.isFunction(remoteRefResolver)) {
              Object.keys(documentContext.nodeContents).forEach((key) => {
                if (_.startsWith(key, nodeRef) && !key.split(nodeRef)[1].includes(httpSeparator)) {
                  refData.nodeContent = documentContext.nodeContents[key];
                }
              });
            }
          }
          else {
            refData.nodeContent = documentContext.nodeContents[nodeRef];
          }
          if (local) {
            let contentFromTrace = getContentFromTrace(refData.nodeContent, local);
            if (!contentFromTrace) {
              refData.nodeContent = { $ref: `${localPointer + local}` };
            }
            else if (isCircularReference(this, contentFromTrace)) {
              if (refData.inline) {
                refData.nodeContent = { [CIRCULAR_OR_REF_EXT_PROP]: tempRef };
                circularRefsSet.add(tempRef);
              }
              else {
                refData.node = { [CIRCULAR_OR_REF_EXT_PROP]: refData.reference };
                refData.nodeContent = contentFromTrace;
                circularRefsSet.add(refData.reference);
              }
            }
            else {
              refData.nodeContent = contentFromTrace;
            }
          }
          if (refData.inline) {
            let referenceSiblings = _.omit(property, ['$ref']),
              hasSiblings = !_.isEmpty(referenceSiblings);
            refData.node = hasSiblings ?
              _.merge(referenceSiblings, refData.nodeContent) :
              refData.nodeContent;
            documentContext.globalReferences[tempRef].reference =
              resolveJsonPointerInlineNodes(this.parents, this.key);
          }
          else if (refData.refHasContent) {
            setValueInComponents(
              refData.keyInComponents,
              components,
              refData.nodeContent,
              COMPONENTS_KEYS
            );
          }
          this.update(refData.node);
        }
      }
    });
  });
  return {
    resRoot: traverseUtility(rootContent).map(function () {
      handleCircularReference(this, documentContext);
    }),
    newComponents: traverseUtility(components).map(function () {
      handleCircularReference(this, documentContext);
    }),
    circularRefs: [...circularRefsSet]
  };
}
Generates the components object from the documentContext data
@param {object} documentContext The document context from root
@param {object} rootContent - The root's parsed content
@param {function} refTypeResolver - The resolver function to test if node has a reference
@param {object} components - The global components object
@param {string} version - The current version
@param {function} remoteRefResolver - The function that would be called to fetch remote ref contents
@returns {object} The components object related to the file