/**
   * Read and process the PropertiesTable and the FAT / XFAT blocks, so that we're ready to work
   * with the file
   */
  private void readCoreContents() throws IOException {
    // Grab the block size
    bigBlockSize = _header.getBigBlockSize();

    // Each block should only ever be used by one of the
    //  FAT, XFAT or Property Table. Ensure it does
    ChainLoopDetector loopDetector = getChainLoopDetector();

    // Read the FAT blocks
    for (int fatAt : _header.getBATArray()) {
      readBAT(fatAt, loopDetector);
    }

    // Work out how many FAT blocks remain in the XFATs
    int remainingFATs = _header.getBATCount() - _header.getBATArray().length;

    // Now read the XFAT blocks, and the FATs within them
    BATBlock xfat;
    int nextAt = _header.getXBATIndex();
    for (int i = 0; i < _header.getXBATCount(); i++) {
      loopDetector.claim(nextAt);
      ByteBuffer fatData = getBlockAt(nextAt);
      xfat = BATBlock.createBATBlock(bigBlockSize, fatData);
      xfat.setOurBlockIndex(nextAt);
      nextAt = xfat.getValueAt(bigBlockSize.getXBATEntriesPerBlock());
      _xbat_blocks.add(xfat);

      // Process all the (used) FATs from this XFAT
      int xbatFATs = Math.min(remainingFATs, bigBlockSize.getXBATEntriesPerBlock());
      for (int j = 0; j < xbatFATs; j++) {
        int fatAt = xfat.getValueAt(j);
        if (fatAt == POIFSConstants.UNUSED_BLOCK || fatAt == POIFSConstants.END_OF_CHAIN) break;
        readBAT(fatAt, loopDetector);
      }
      remainingFATs -= xbatFATs;
    }

    // We're now able to load steams
    // Use this to read in the properties
    _property_table = new NPropertyTable(_header, this);

    // Finally read the Small Stream FAT (SBAT) blocks
    BATBlock sfat;
    List<BATBlock> sbats = new ArrayList<BATBlock>();
    _mini_store = new NPOIFSMiniStore(this, _property_table.getRoot(), sbats, _header);
    nextAt = _header.getSBATStart();
    for (int i = 0; i < _header.getSBATCount(); i++) {
      loopDetector.claim(nextAt);
      ByteBuffer fatData = getBlockAt(nextAt);
      sfat = BATBlock.createBATBlock(bigBlockSize, fatData);
      sfat.setOurBlockIndex(nextAt);
      sbats.add(sfat);
      nextAt = getNextBlock(nextAt);
    }
  }
 private void readBAT(int batAt, ChainLoopDetector loopDetector) throws IOException {
   loopDetector.claim(batAt);
   ByteBuffer fatData = getBlockAt(batAt);
   BATBlock bat = BATBlock.createBATBlock(bigBlockSize, fatData);
   bat.setOurBlockIndex(batAt);
   _bat_blocks.add(bat);
 }