docs: private Pair<ResourcePackage, PackageHeader> readPackage(PackageHeader packageHeader) {
          Pair<ResourcePackage, PackageHeader> pair = new Pair<>();
          //read packageHeader
          ResourcePackage resourcePackage = new ResourcePackage(packageHeader);
          pair.setLeft(resourcePackage);
  
          long beginPos = buffer.position();
          // read type string pool
          if (packageHeader.getTypeStrings() > 0) {
              Buffers.position(buffer, beginPos + packageHeader.getTypeStrings() - packageHeader.getHeaderSize());
              resourcePackage.setTypeStringPool(ParseUtils.readStringPool(buffer,
                      (StringPoolHeader) readChunkHeader()));
          }
  
          //read key string pool
          if (packageHeader.getKeyStrings() > 0) {
              Buffers.position(buffer, beginPos + packageHeader.getKeyStrings() - packageHeader.getHeaderSize());
              resourcePackage.setKeyStringPool(ParseUtils.readStringPool(buffer,
                      (StringPoolHeader) readChunkHeader()));
          }
  
  
          outer:
          while (buffer.hasRemaining()) {
              ChunkHeader chunkHeader = readChunkHeader();
              long chunkBegin = buffer.position();
              switch (chunkHeader.getChunkType()) {
                  case ChunkType.TABLE_TYPE_SPEC:
                      TypeSpecHeader typeSpecHeader = (TypeSpecHeader) chunkHeader;
                      long[] entryFlags = new long[(int) typeSpecHeader.getEntryCount()];
                      for (int i = 0; i < typeSpecHeader.getEntryCount(); i++) {
                          entryFlags[i] = Buffers.readUInt(buffer);
                      }
  
                      TypeSpec typeSpec = new TypeSpec(typeSpecHeader);
  
  
                      typeSpec.setEntryFlags(entryFlags);
                      //id start from 1
                      typeSpec.setName(resourcePackage.getTypeStringPool()
                              .get(typeSpecHeader.getId() - 1));
  
                      resourcePackage.addTypeSpec(typeSpec);
                      Buffers.position(buffer, chunkBegin + typeSpecHeader.getBodySize());
                      break;
                  case ChunkType.TABLE_TYPE:
                      TypeHeader typeHeader = (TypeHeader) chunkHeader;
                      // read offsets table
                      long[] offsets = new long[(int) typeHeader.getEntryCount()];
                      for (int i = 0; i < typeHeader.getEntryCount(); i++) {
                          offsets[i] = Buffers.readUInt(buffer);
                      }
  
                      Type type = new Type(typeHeader);
                      type.setName(resourcePackage.getTypeStringPool().get(typeHeader.getId() - 1));
                      long entryPos = chunkBegin + typeHeader.getEntriesStart() - typeHeader.getHeaderSize();
                      Buffers.position(buffer, entryPos);
                      ByteBuffer b = buffer.slice();
                      b.order(byteOrder);
                      type.setBuffer(b);
                      type.setKeyStringPool(resourcePackage.getKeyStringPool());
                      type.setOffsets(offsets);
                      type.setStringPool(stringPool);
                      resourcePackage.addType(type);
                      locales.add(type.getLocale());
                      Buffers.position(buffer, chunkBegin + typeHeader.getBodySize());
                      break;
                  case ChunkType.TABLE_PACKAGE:
                      // another package. we should read next package here
                      pair.setRight((PackageHeader) chunkHeader);
                      break outer;
                  case ChunkType.TABLE_LIBRARY:
                      // read entries
                      LibraryHeader libraryHeader = (LibraryHeader) chunkHeader;
                      for (long i = 0; i < libraryHeader.getCount(); i++) {
                          int packageId = buffer.getInt();
                          String name = Buffers.readZeroTerminatedString(buffer, 128);
                          LibraryEntry entry = new LibraryEntry(packageId, name);
                          //TODO: now just skip it..
                      }
                      Buffers.position(buffer, chunkBegin + chunkHeader.getBodySize());
                      break;
                  case ChunkType.NULL:
  //                    Buffers.position(buffer, chunkBegin + chunkHeader.getBodySize());
                      Buffers.position(buffer, buffer.position() + buffer.remaining());
                      break;
                  default:
                      throw new ParserException("unexpected chunk type: 0x" + chunkHeader.getChunkType());
              }
          }
  
          return pair;
  
      }