docs: private void write(FieldInfos fieldInfos, Fields fields) {
      IndexOutput outField;
      IndexOutput outDoc;
      IndexOutput outIndexDocId;
      IndexOutput outIndexObjectId;
      IndexOutput outIndexObjectPosition;
      IndexOutput outIndexObjectParent;
      IndexOutput outTerm;
      IndexOutput outObject;
      IndexOutput outPrefix;
      IndexOutput outTmpDoc;
      IndexOutput outTmpField;
      HashSet<Closeable> closeables = new HashSet<>();
      // prefix stats
      intersectingPrefixes = new HashMap<>();
      singlePositionPrefix = new HashMap<>();
      multiplePositionPrefix = new HashMap<>();
      setPositionPrefix = new HashMap<>();
      prefixReferenceIndex = new HashMap<>();
      prefixIdIndex = new HashMap<>();
      // temporary temporary index in memory for doc
      SortedMap<Integer, Long> memoryIndexTemporaryObject = new TreeMap<>();
      // create (backwards) chained new temporary index docs
      SortedMap<Integer, Long> memoryTmpDocChainList = new TreeMap<>();
      // list of objectIds and references to objects
      SortedMap<Integer, Long> memoryIndexDocList = new TreeMap<>();
  
      try {
        // create file tmpDoc
        closeables.add(outTmpDoc = state.directory
            .createOutput(mtasTmpDocFileName, state.context));
        // create file tmpField
        closeables.add(outTmpField = state.directory
            .createOutput(mtasTmpFieldFileName, state.context));
        // create file indexDoc
        closeables.add(outDoc = state.directory.createOutput(mtasDocFileName,
            state.context));
        CodecUtil.writeIndexHeader(outDoc, name,
            MtasCodecPostingsFormat.VERSION_CURRENT, state.segmentInfo.getId(),
            state.segmentSuffix);
        outDoc.writeString(delegatePostingsFormatName);
        // create file indexDocId
        closeables.add(outIndexDocId = state.directory
            .createOutput(mtasIndexDocIdFileName, state.context));
        CodecUtil.writeIndexHeader(outIndexDocId, name,
            MtasCodecPostingsFormat.VERSION_CURRENT, state.segmentInfo.getId(),
            state.segmentSuffix);
        outIndexDocId.writeString(delegatePostingsFormatName);
        // create file indexObjectId
        closeables.add(outIndexObjectId = state.directory
            .createOutput(mtasIndexObjectIdFileName, state.context));
        CodecUtil.writeIndexHeader(outIndexObjectId, name,
            MtasCodecPostingsFormat.VERSION_CURRENT, state.segmentInfo.getId(),
            state.segmentSuffix);
        outIndexObjectId.writeString(delegatePostingsFormatName);
        // create file indexObjectPosition
        closeables.add(outIndexObjectPosition = state.directory
            .createOutput(mtasIndexObjectPositionFileName, state.context));
        CodecUtil.writeIndexHeader(outIndexObjectPosition, name,
            MtasCodecPostingsFormat.VERSION_CURRENT, state.segmentInfo.getId(),
            state.segmentSuffix);
        outIndexObjectPosition.writeString(delegatePostingsFormatName);
        // create file indexObjectParent
        closeables.add(outIndexObjectParent = state.directory
            .createOutput(mtasIndexObjectParentFileName, state.context));
        CodecUtil.writeIndexHeader(outIndexObjectParent, name,
            MtasCodecPostingsFormat.VERSION_CURRENT, state.segmentInfo.getId(),
            state.segmentSuffix);
        outIndexObjectParent.writeString(delegatePostingsFormatName);
        // create file term
        closeables.add(outTerm = state.directory.createOutput(mtasTermFileName,
            state.context));
        CodecUtil.writeIndexHeader(outTerm, name,
            MtasCodecPostingsFormat.VERSION_CURRENT, state.segmentInfo.getId(),
            state.segmentSuffix);
        outTerm.writeString(delegatePostingsFormatName);
        // create file prefix
        closeables.add(outPrefix = state.directory
            .createOutput(mtasPrefixFileName, state.context));
        CodecUtil.writeIndexHeader(outPrefix, name,
            MtasCodecPostingsFormat.VERSION_CURRENT, state.segmentInfo.getId(),
            state.segmentSuffix);
        outPrefix.writeString(delegatePostingsFormatName);
        // create file object
        closeables.add(outObject = state.directory
            .createOutput(mtasObjectFileName, state.context));
        CodecUtil.writeIndexHeader(outObject, name,
            MtasCodecPostingsFormat.VERSION_CURRENT, state.segmentInfo.getId(),
            state.segmentSuffix);
        outObject.writeString(delegatePostingsFormatName);
        // For each field
        for (String field : fields) {
          Terms terms = fields.terms(field);
          if (terms == null) {
            continue;
          } else {
            // new temporary object storage for this field
            IndexOutput outTmpObject = state.directory
                .createOutput(mtasTmpObjectFileName, state.context);
            closeables.add(outTmpObject);
            // new temporary index docs for this field
            IndexOutput outTmpDocs = state.directory
                .createOutput(mtasTmpDocsFileName, state.context);
            closeables.add(outTmpDocs);
            // get fieldInfo
            FieldInfo fieldInfo = fieldInfos.fieldInfo(field);
            // get properties terms
            boolean hasPositions = terms.hasPositions();
            boolean hasFreqs = terms.hasFreqs();
            boolean hasPayloads = fieldInfo.hasPayloads();
            boolean hasOffsets = terms.hasOffsets();
            // register references
            Long smallestTermFilepointer = outTerm.getFilePointer();
            Long smallestPrefixFilepointer = outPrefix.getFilePointer();
            int termCounter = 0;
            // only if freqs, positions and payload available
            if (hasFreqs && hasPositions && hasPayloads) {
              // compute flags
              int flags = PostingsEnum.POSITIONS | PostingsEnum.PAYLOADS;
              if (hasOffsets) {
                flags = flags | PostingsEnum.OFFSETS;
              }
              // get terms
              TermsEnum termsEnum = terms.iterator();
              PostingsEnum postingsEnum = null;
              // for each term in field
              while (true) {
                BytesRef term = termsEnum.next();
                if (term == null) {
                  break;
                }
                // store term and get ref
                Long termRef = outTerm.getFilePointer();
                outTerm.writeString(term.utf8ToString());
                termCounter++;
                // get postings
                postingsEnum = termsEnum.postings(postingsEnum, flags);
                // for each doc in field+term
                while (true) {
                  Integer docId = postingsEnum.nextDoc();
                  if (docId.equals(DocIdSetIterator.NO_MORE_DOCS)) {
                    break;
                  }
                  int freq = postingsEnum.freq();
                  // temporary storage objects and temporary index in memory for
                  // doc
                  memoryIndexTemporaryObject.clear();
                  Long offsetFilePointerTmpObject = outTmpObject.getFilePointer();
                  for (int i = 0; i < freq; i++) {
                    Long currentFilePointerTmpObject = outTmpObject
                        .getFilePointer();
                    Integer mtasId;
                    int position = postingsEnum.nextPosition();
                    BytesRef payload = postingsEnum.getPayload();
                    if (hasOffsets) {
                      mtasId = createObjectAndRegisterPrefix(field, outTmpObject,
                          term, termRef, position, payload,
                          postingsEnum.startOffset(), postingsEnum.endOffset(),
                          outPrefix);
                    } else {
                      mtasId = createObjectAndRegisterPrefix(field, outTmpObject,
                          term, termRef, position, payload, outPrefix);
                    }
                    if (mtasId != null) {
                      assert !memoryIndexTemporaryObject.containsKey(
                          mtasId) : "mtasId should be unique in this selection";
                      memoryIndexTemporaryObject.put(mtasId,
                          currentFilePointerTmpObject);
                    }
                  } // end loop positions
                  // store temporary index for this doc
                  if (memoryIndexTemporaryObject.size() > 0) {
                    // docId for this part
                    outTmpDocs.writeVInt(docId);
                    // number of objects/tokens in this part
                    outTmpDocs.writeVInt(memoryIndexTemporaryObject.size());
                    // offset to be used for references
                    outTmpDocs.writeVLong(offsetFilePointerTmpObject);
                    // loop over tokens
                    for (Entry<Integer, Long> entry : memoryIndexTemporaryObject
                        .entrySet()) {
                      // mtasId object
                      outTmpDocs.writeVInt(entry.getKey());
                      // reference object
                      outTmpDocs.writeVLong(
                          (entry.getValue() - offsetFilePointerTmpObject));
                    }
                  }
                  // clean up
                  memoryIndexTemporaryObject.clear();
                } // end loop docs
              } // end loop terms
              // set fieldInfo
              fieldInfos.fieldInfo(field).putAttribute(
                  MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SINGLE_POSITION,
                  getPrefixStatsSinglePositionPrefixAttribute(field));
              fieldInfos.fieldInfo(field).putAttribute(
                  MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_MULTIPLE_POSITION,
                  getPrefixStatsMultiplePositionPrefixAttribute(field));
              fieldInfos.fieldInfo(field).putAttribute(
                  MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SET_POSITION,
                  getPrefixStatsSetPositionPrefixAttribute(field));
            } // end processing field with freqs, positions and payload
            // close temporary object storage and index docs
            outTmpObject.close();
            closeables.remove(outTmpObject);
            outTmpDocs.close();
            closeables.remove(outTmpDocs);
  
            // create (backwards) chained new temporary index docs
            IndexInput inTmpDocs = state.directory.openInput(mtasTmpDocsFileName,
                state.context);
            closeables.add(inTmpDocs);
            IndexOutput outTmpDocsChained = state.directory
                .createOutput(mtasTmpDocsChainedFileName, state.context);
            closeables.add(outTmpDocsChained);
            memoryTmpDocChainList.clear();
            while (true) {
              try {
                Long currentFilepointer = outTmpDocsChained.getFilePointer();
                // copy docId
                int docId = inTmpDocs.readVInt();
                outTmpDocsChained.writeVInt(docId);
                // copy size
                int size = inTmpDocs.readVInt();
                outTmpDocsChained.writeVInt(size);
                // offset references
                outTmpDocsChained.writeVLong(inTmpDocs.readVLong());
                for (int t = 0; t < size; t++) {
                  outTmpDocsChained.writeVInt(inTmpDocs.readVInt());
                  outTmpDocsChained.writeVLong(inTmpDocs.readVLong());
                }
                // set back reference to part with same docId
                if (memoryTmpDocChainList.containsKey(docId)) {
                  // reference to previous
                  outTmpDocsChained.writeVLong(memoryTmpDocChainList.get(docId));
                } else {
                  // self reference indicates end of chain
                  outTmpDocsChained.writeVLong(currentFilepointer);
                }
                // update temporary index in memory
                memoryTmpDocChainList.put(docId, currentFilepointer);
              } catch (IOException ex) {
                log.debug(ex);
                break;
              }
            }
            outTmpDocsChained.close();
            closeables.remove(outTmpDocsChained);
            inTmpDocs.close();
            closeables.remove(inTmpDocs);
            state.directory.deleteFile(mtasTmpDocsFileName);
  
            // set reference to tmpDoc in Field
            if (memoryTmpDocChainList.size() > 0) {
              outTmpField.writeString(field);
              outTmpField.writeVLong(outTmpDoc.getFilePointer());
              outTmpField.writeVInt(memoryTmpDocChainList.size());
              outTmpField.writeVLong(smallestTermFilepointer);
              outTmpField.writeVInt(termCounter);
              outTmpField.writeVLong(smallestPrefixFilepointer);
              outTmpField.writeVInt(prefixReferenceIndex.get(field).size());
              // fill indexDoc
              IndexInput inTmpDocsChained = state.directory
                  .openInput(mtasTmpDocsChainedFileName, state.context);
              closeables.add(inTmpDocsChained);
              IndexInput inTmpObject = state.directory
                  .openInput(mtasTmpObjectFileName, state.context);
              closeables.add(inTmpObject);
              for (Entry<Integer, Long> entry : memoryTmpDocChainList
                  .entrySet()) {
                Integer docId = entry.getKey();
                Long currentFilePointer;
                Long newFilePointer;
                // list of objectIds and references to objects
                memoryIndexDocList.clear();
                // construct final object + indexObjectId for docId
                currentFilePointer = entry.getValue();
                // collect objects for document
                tokenStatsMinPos = null;
                tokenStatsMaxPos = null;
                tokenStatsNumber = 0;
                while (true) {
                  inTmpDocsChained.seek(currentFilePointer);
                  Integer docIdPart = inTmpDocsChained.readVInt();
                  assert docIdPart.equals(
                      docId) : "conflicting docId in reference to temporaryIndexDocsChained";
                  // number of objects/tokens in part
                  int size = inTmpDocsChained.readVInt();
                  long offsetFilePointerTmpObject = inTmpDocsChained.readVLong();
                  assert size > 0 : "number of objects/tokens in part cannot be "
                      + size;
                  for (int t = 0; t < size; t++) {
                    int mtasId = inTmpDocsChained.readVInt();
                    Long tmpObjectRef = inTmpDocsChained.readVLong()
                        + offsetFilePointerTmpObject;
                    assert !memoryIndexDocList.containsKey(
                        mtasId) : "mtasId should be unique in this selection";
                    // initially, store ref to tmpObject
                    memoryIndexDocList.put(mtasId, tmpObjectRef);
                  }
                  // reference to next part
                  newFilePointer = inTmpDocsChained.readVLong();
                  if (newFilePointer.equals(currentFilePointer)) {
                    break; // end of chained parts
                  } else {
                    currentFilePointer = newFilePointer;
                  }
                }
                // now create new objects, sorted by mtasId
                Long smallestObjectFilepointer = outObject.getFilePointer();
                for (Entry<Integer, Long> objectEntry : memoryIndexDocList
                    .entrySet()) {
                  int mtasId = objectEntry.getKey();
                  Long tmpObjectRef = objectEntry.getValue();
                  Long objectRef = outObject.getFilePointer();
                  copyObjectAndUpdateStats(mtasId, inTmpObject, tmpObjectRef,
                      outObject);
                  // update with new ref
                  memoryIndexDocList.put(mtasId, objectRef);
                }
                // check mtasIds properties
                assert memoryIndexDocList.firstKey()
                    .equals(0) : "first mtasId should not be "
                        + memoryIndexDocList.firstKey();
                assert (1 + memoryIndexDocList.lastKey()
                    - memoryIndexDocList.firstKey()) == memoryIndexDocList
                        .size() : "missing mtasId";
                assert tokenStatsNumber.equals(memoryIndexDocList
                    .size()) : "incorrect number of items in tokenStats";
  
                // store item in tmpDoc
                outTmpDoc.writeVInt(docId);
                outTmpDoc.writeVLong(outIndexObjectId.getFilePointer());
  
                int mtasId = 0;
                // compute linear approximation (least squares method, integer
                // constants)
                long tmpN = memoryIndexDocList.size();
                long tmpSumY = 0;
                long tmpSumXY = 0;
                long tmpSumX = 0;
                long tmpSumXX = 0;
                for (Entry<Integer, Long> objectEntry : memoryIndexDocList
                    .entrySet()) {
                  assert objectEntry.getKey()
                      .equals(mtasId) : "unexpected mtasId";
                  tmpSumY += objectEntry.getValue();
                  tmpSumX += mtasId;
                  tmpSumXY += mtasId * objectEntry.getValue();
                  tmpSumXX += mtasId * mtasId;
                  mtasId++;
                }
                int objectRefApproxQuotient;
                if(tmpN>1) {
                  objectRefApproxQuotient= (int) (((tmpN * tmpSumXY)              
                    - (tmpSumX * tmpSumY))
                    / ((tmpN * tmpSumXX) - (tmpSumX * tmpSumX)));
                } else {
                  objectRefApproxQuotient = 0;
                }
                long objectRefApproxOffset = (tmpSumY
                    - objectRefApproxQuotient * tmpSumX) / tmpN;
                Long objectRefApproxCorrection;
                long maxAbsObjectRefApproxCorrection = 0;
                // compute maximum correction
                mtasId = 0;
                for (Entry<Integer, Long> objectEntry : memoryIndexDocList
                    .entrySet()) {
                  objectRefApproxCorrection = (objectEntry.getValue()
                      - (objectRefApproxOffset
                          + (mtasId * objectRefApproxQuotient)));
                  maxAbsObjectRefApproxCorrection = Math.max(
                      maxAbsObjectRefApproxCorrection,
                      Math.abs(objectRefApproxCorrection));
                  mtasId++;
                }
                byte storageFlags;
                if (maxAbsObjectRefApproxCorrection <= Long
                    .valueOf(Byte.MAX_VALUE)) {
                  storageFlags = MtasCodecPostingsFormat.MTAS_STORAGE_BYTE;
                } else if (maxAbsObjectRefApproxCorrection <= Long
                    .valueOf(Short.MAX_VALUE)) {
                  storageFlags = MtasCodecPostingsFormat.MTAS_STORAGE_SHORT;
                } else if (maxAbsObjectRefApproxCorrection <= Long
                    .valueOf(Integer.MAX_VALUE)) {
                  storageFlags = MtasCodecPostingsFormat.MTAS_STORAGE_INTEGER;
                } else {
                  storageFlags = MtasCodecPostingsFormat.MTAS_STORAGE_LONG;
                }
                // update indexObjectId with correction on approximated ref
                // (assume
                // can be stored as int)
                mtasId = 0;
                for (Entry<Integer, Long> objectEntry : memoryIndexDocList
                    .entrySet()) {
                  objectRefApproxCorrection = (objectEntry.getValue()
                      - (objectRefApproxOffset
                          + (mtasId * objectRefApproxQuotient)));
                  if (storageFlags == MtasCodecPostingsFormat.MTAS_STORAGE_BYTE) {
                    outIndexObjectId
                        .writeByte(objectRefApproxCorrection.byteValue());
                  } else if (storageFlags == MtasCodecPostingsFormat.MTAS_STORAGE_SHORT) {
                    outIndexObjectId
                        .writeShort(objectRefApproxCorrection.shortValue());
                  } else if (storageFlags == MtasCodecPostingsFormat.MTAS_STORAGE_INTEGER) {
                    outIndexObjectId
                        .writeInt(objectRefApproxCorrection.intValue());
                  } else {
                    outIndexObjectId.writeLong(objectRefApproxCorrection);
                  }
                  mtasId++;
                }
                outTmpDoc.writeVLong(smallestObjectFilepointer);
                outTmpDoc.writeVInt(objectRefApproxQuotient);
                outTmpDoc.writeZLong(objectRefApproxOffset);
                outTmpDoc.writeByte(storageFlags);
                outTmpDoc.writeVInt(tokenStatsNumber);
                outTmpDoc.writeVInt(tokenStatsMinPos);
                outTmpDoc.writeVInt(tokenStatsMaxPos);
                // clean up
                memoryIndexDocList.clear();
              } // end loop over docs
              inTmpDocsChained.close();
              closeables.remove(inTmpDocsChained);
              inTmpObject.close();
              closeables.remove(inTmpObject);
            }
            // clean up
            memoryTmpDocChainList.clear();
            // remove temporary files
            state.directory.deleteFile(mtasTmpObjectFileName);
            state.directory.deleteFile(mtasTmpDocsChainedFileName);
            // store references for field
  
          } // end processing field
        } // end loop fields
        // close temporary index doc
        outTmpDoc.close();
        closeables.remove(outTmpDoc);
        // close indexField, indexObjectId and object
        CodecUtil.writeFooter(outTmpField);
        outTmpField.close();
        closeables.remove(outTmpField);
        CodecUtil.writeFooter(outIndexObjectId);
        outIndexObjectId.close();
        closeables.remove(outIndexObjectId);
        CodecUtil.writeFooter(outObject);
        outObject.close();
        closeables.remove(outObject);
        CodecUtil.writeFooter(outTerm);
        outTerm.close();
        closeables.remove(outTerm);
        CodecUtil.writeFooter(outPrefix);
        outPrefix.close();
        closeables.remove(outPrefix);
  
        // create final doc, fill indexObjectPosition, indexObjectParent and
        // indexTermPrefixPosition, create final field
        IndexInput inTmpField = state.directory.openInput(mtasTmpFieldFileName,
            state.context);
        closeables.add(inTmpField);
        IndexInput inTmpDoc = state.directory.openInput(mtasTmpDocFileName,
            state.context);
        closeables.add(inTmpDoc);
        IndexInput inObjectId = state.directory
            .openInput(mtasIndexObjectIdFileName, state.context);
        closeables.add(inObjectId);
        IndexInput inObject = state.directory.openInput(mtasObjectFileName,
            state.context);
        closeables.add(inObject);
        IndexInput inTerm = state.directory.openInput(mtasTermFileName,
            state.context);
        closeables.add(inTerm);
        closeables.add(outField = state.directory
            .createOutput(mtasIndexFieldFileName, state.context));
        CodecUtil.writeIndexHeader(outField, name,
            MtasCodecPostingsFormat.VERSION_CURRENT, state.segmentInfo.getId(),
            state.segmentSuffix);
        outField.writeString(delegatePostingsFormatName);
        boolean doWrite = true;
        do {
          try {
            // read from tmpField
            String field = inTmpField.readString();
            long fpTmpDoc = inTmpField.readVLong();
            int numberDocs = inTmpField.readVInt();
            long fpTerm = inTmpField.readVLong();
            int numberTerms = inTmpField.readVInt();
            long fpPrefix = inTmpField.readVLong();
            int numberPrefixes = inTmpField.readVInt();
            inTmpDoc.seek(fpTmpDoc);
            long fpFirstDoc = outDoc.getFilePointer();
            // get prefixId index
            HashMap<String, Integer> prefixIdIndexField = prefixIdIndex
                .get(field);
            // construct MtasRBTree for indexDocId
            MtasRBTree mtasDocIdTree = new MtasRBTree(true, false);
            for (int docCounter = 0; docCounter < numberDocs; docCounter++) {
              // get info from tmpDoc
              int docId = inTmpDoc.readVInt();
              // filePointer indexObjectId
              Long fpIndexObjectId = inTmpDoc.readVLong();
              // filePointer indexObjectPosition (unknown)
              Long fpIndexObjectPosition;
              // filePointer indexObjectParent (unknown)
              Long fpIndexObjectParent;
              // constants for approximation object references for this document
              long smallestObjectFilepointer = inTmpDoc.readVLong();
              int objectRefApproxQuotient = inTmpDoc.readVInt();
              long objectRefApproxOffset = inTmpDoc.readZLong();
              byte storageFlags = inTmpDoc.readByte();
              // number objects/tokens
              int size = inTmpDoc.readVInt();
              // construct MtasRBTree
              MtasRBTree mtasPositionTree = new MtasRBTree(false, true);
              MtasRBTree mtasParentTree = new MtasRBTree(false, true);
              inObjectId.seek(fpIndexObjectId);
              long refCorrection;
              long ref;
              HashMap<String, HashSet<Integer>> docFieldAdministration = new HashMap<>();
              for (int mtasId = 0; mtasId < size; mtasId++) {
                if (storageFlags == MtasCodecPostingsFormat.MTAS_STORAGE_BYTE) {
                  refCorrection = inObjectId.readByte();
                } else if (storageFlags == MtasCodecPostingsFormat.MTAS_STORAGE_SHORT) {
                  refCorrection = inObjectId.readShort();
                } else if (storageFlags == MtasCodecPostingsFormat.MTAS_STORAGE_INTEGER) {
                  refCorrection = inObjectId.readInt();
                } else {
                  refCorrection = inObjectId.readLong();
                }
                ref = objectRefApproxOffset + mtasId * objectRefApproxQuotient
                    + refCorrection;
                MtasTokenString token = MtasCodecPostingsFormat.getToken(inObject,
                    inTerm, ref);
                String prefix = token.getPrefix();
                registerPrefixIntersection(field, prefix,
                    token.getPositionStart(), token.getPositionEnd(),
                    docFieldAdministration);
                int prefixId = prefixIdIndexField.containsKey(prefix)
                    ? prefixIdIndexField.get(prefix) : 0;
                token.setPrefixId(prefixId);
                assert token.getId().equals(mtasId) : "unexpected mtasId "
                    + mtasId;
                mtasPositionTree.addPositionAndObjectFromToken(token);
                mtasParentTree.addParentFromToken(token);
              }
              // store mtasPositionTree and mtasParentTree
              fpIndexObjectPosition = storeTree(mtasPositionTree,
                  outIndexObjectPosition, smallestObjectFilepointer);
              fpIndexObjectParent = storeTree(mtasParentTree,
                  outIndexObjectParent, smallestObjectFilepointer);
              long fpDoc = outDoc.getFilePointer();
              // create indexDoc with updated fpIndexObjectPosition from tmpDoc
              outDoc.writeVInt(docId); // docId
              // reference indexObjectId
              outDoc.writeVLong(fpIndexObjectId);
              // reference indexObjectPosition
              outDoc.writeVLong(fpIndexObjectPosition);
              // reference indexObjectParent
              outDoc.writeVLong(fpIndexObjectParent);
              // variables approximation and storage references object
              outDoc.writeVLong(smallestObjectFilepointer);
              outDoc.writeVInt(objectRefApproxQuotient);
              outDoc.writeZLong(objectRefApproxOffset);
              outDoc.writeByte(storageFlags);
              // number of objects
              outDoc.writeVInt(size);
              // minPosition
              outDoc.writeVInt(inTmpDoc.readVInt());
              // maxPosition
              outDoc.writeVInt(inTmpDoc.readVInt());
              // add to tree for indexDocId
              mtasDocIdTree.addIdFromDoc(docId, fpDoc);
            }
            long fpIndexDocId = storeTree(mtasDocIdTree, outIndexDocId,
                fpFirstDoc);
  
            // store in indexField
            outField.writeString(field);
            outField.writeVLong(fpFirstDoc);
            outField.writeVLong(fpIndexDocId);
            outField.writeVInt(numberDocs);
            outField.writeVLong(fpTerm);
            outField.writeVInt(numberTerms);
            outField.writeVLong(fpPrefix);
            outField.writeVInt(numberPrefixes);
            // register intersection
            fieldInfos.fieldInfo(field).putAttribute(
                MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_INTERSECTION,
                getPrefixStatsIntersectionPrefixAttribute(field));
          } catch (EOFException e) {
            log.debug(e);
            doWrite = false;
          }
          // end loop over fields
        } while (doWrite);
        inTerm.close();
        closeables.remove(inTerm);
        inObject.close();
        closeables.remove(inObject);
        inObjectId.close();
        closeables.remove(inObjectId);
        inTmpDoc.close();
        closeables.remove(inTmpDoc);
        inTmpField.close();
        closeables.remove(inTmpField);
  
        // remove temporary files
        state.directory.deleteFile(mtasTmpDocFileName);
        state.directory.deleteFile(mtasTmpFieldFileName);
        // close indexDoc, indexObjectPosition and indexObjectParent
        CodecUtil.writeFooter(outDoc);
        outDoc.close();
        closeables.remove(outDoc);
        CodecUtil.writeFooter(outIndexObjectPosition);
        outIndexObjectPosition.close();
        closeables.remove(outIndexObjectPosition);
        CodecUtil.writeFooter(outIndexObjectParent);
        outIndexObjectParent.close();
        closeables.remove(outIndexObjectParent);
        CodecUtil.writeFooter(outIndexDocId);
        outIndexDocId.close();
        closeables.remove(outIndexDocId);
        CodecUtil.writeFooter(outField);
        outField.close();
        closeables.remove(outField);
      } catch (IOException e) {
        // ignore, can happen when merging segment already written by
        // delegateFieldsConsumer
        log.error(e);
      } finally {
        IOUtils.closeWhileHandlingException(closeables);
        try {
          state.directory.deleteFile(mtasTmpDocsFileName);
        } catch (IOException e) {
          log.debug(e);
        }
        try {
          state.directory.deleteFile(mtasTmpDocFileName);
        } catch (IOException e) {
          log.debug(e);
        }
        try {
          state.directory.deleteFile(mtasTmpFieldFileName);
        } catch (IOException e) {
          log.debug(e);
        }
      }
    }