docs: function remap (inventory) {
    // Group & sort all the $ref pointers, so they're in the order that we need to dereference/remap them
    inventory.sort(function (a, b) {
      if (a.file !== b.file) {
        // Group all the $refs that point to the same file
        return a.file < b.file ? -1 : +1;
      }
      else if (a.hash !== b.hash) {
        // Group all the $refs that point to the same part of the file
        return a.hash < b.hash ? -1 : +1;
      }
      else if (a.circular !== b.circular) {
        // If the $ref points to itself, then sort it higher than other $refs that point to this $ref
        return a.circular ? -1 : +1;
      }
      else if (a.extended !== b.extended) {
        // If the $ref extends the resolved value, then sort it lower than other $refs that don't extend the value
        return a.extended ? +1 : -1;
      }
      else if (a.indirections !== b.indirections) {
        // Sort direct references higher than indirect references
        return a.indirections - b.indirections;
      }
      else if (a.depth !== b.depth) {
        // Sort $refs by how close they are to the JSON Schema root
        return a.depth - b.depth;
      }
      else {
        // Determine how far each $ref is from the "definitions" property.
        // Most people will expect references to be bundled into the the "definitions" property if possible.
        var aDefinitionsIndex = a.pathFromRoot.lastIndexOf("/definitions");
        var bDefinitionsIndex = b.pathFromRoot.lastIndexOf("/definitions");
  
        if (aDefinitionsIndex !== bDefinitionsIndex) {
          // Give higher priority to the $ref that's closer to the "definitions" property
          return bDefinitionsIndex - aDefinitionsIndex;
        }
        else {
          // All else is equal, so use the shorter path, which will produce the shortest possible reference
          return a.pathFromRoot.length - b.pathFromRoot.length;
        }
      }
    });
  
    var file, hash, pathFromRoot;
    inventory.forEach(function (entry) {
      // console.log('Re-mapping $ref pointer "%s" at %s', entry.$ref.$ref, entry.pathFromRoot);
  
      if (!entry.external) {
        // This $ref already resolves to the main JSON Schema file
        entry.$ref.$ref = entry.hash;
      }
      else if (entry.file === file && entry.hash === hash) {
        // This $ref points to the same value as the prevous $ref, so remap it to the same path
        entry.$ref.$ref = pathFromRoot;
      }
      else if (entry.file === file && entry.hash.indexOf(hash + "/") === 0) {
        // This $ref points to a sub-value of the prevous $ref, so remap it beneath that path
        entry.$ref.$ref = Pointer.join(pathFromRoot, Pointer.parse(entry.hash.replace(hash, "#")));
      }
      else {
        // We've moved to a new file or new hash
        file = entry.file;
        hash = entry.hash;
        pathFromRoot = entry.pathFromRoot;
  
        // This is the first $ref to point to this value, so dereference the value.
        // Any other $refs that point to the same value will point to this $ref instead
        entry.$ref = entry.parent[entry.key] = $Ref.dereference(entry.$ref, entry.value);
  
        if (entry.circular) {
          // This $ref points to itself
          entry.$ref.$ref = entry.pathFromRoot;
        }
      }
  
      // console.log('    new value: %s', (entry.$ref && entry.$ref.$ref) ? entry.$ref.$ref : '[object Object]');
    });
  }