docs: function objectRefsReviver(key, value) {
      if (value && typeof value === 'object') {
        const chain = [{ key, value }]
  
        //First stage
        while (chains.length) {
          const prevChain = chains[chains.length - 1]
          const prevChainHead = prevChain[0]
  
          if (value[prevChainHead.key] === prevChainHead.value) {// current object is a parent for {prevChain}
            const refId = prevChainHead.value[OBJECTREF_FIELD]
  
            if (refId != null) { //last chain head is an object reference
              refs.push({ parent: value, key: prevChainHead.key, id: refId })
            } else {
              //merge child chain with parent pulling down previously merge siblings
              chain.splice.apply(chain, [1, 0].concat(prevChain))
            }
  
            chains.pop() //remove processed chain
          } else {
  
            //no parents -> stop chains iteration and go to the next object
            break
          }
        }
  
        chains.push(chain)
  
        if (key === '') { //root object
  
          // Second stage
          // We have reached the top most value. At this point the chains array contains just
          // a single root chain, merged with all its children
          // We are ready to replace object references
          refs.forEach(ref => {
            ref.parent[ref.key] = chains[0][ref.id].value
          })
        }
      }
  
      return value
    }