/**
  * If there are no extra fields, use the given fields as new extra data - otherwise merge the
  * fields assuming the existing fields and the new fields stem from different locations inside the
  * archive.
  *
  * @param f the extra fields to merge
  * @param local whether the new fields originate from local data
  */
 private void mergeExtraFields(ZipExtraField[] f, boolean local) throws ZipException {
   if (extraFields == null) {
     setExtraFields(f);
   } else {
     for (ZipExtraField element : f) {
       ZipExtraField existing;
       if (element instanceof UnparseableExtraFieldData) {
         existing = unparseableExtra;
       } else {
         existing = getExtraField(element.getHeaderId());
       }
       if (existing == null) {
         addExtraField(element);
       } else {
         if (local) {
           byte[] b = element.getLocalFileDataData();
           existing.parseFromLocalFileData(b, 0, b.length);
         } else {
           byte[] b = element.getCentralDirectoryData();
           existing.parseFromCentralDirectoryData(b, 0, b.length);
         }
       }
     }
     setExtra();
   }
 }
  /**
   * Adds UnicodeExtra fields for name and file comment if mode is ALWAYS or the data cannot be
   * encoded using the configured encoding.
   */
  private void addUnicodeExtraFields(ZipArchiveEntry ze, boolean encodable, ByteBuffer name)
      throws IOException {
    if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS || !encodable) {
      ze.addExtraField(
          new UnicodePathExtraField(
              ze.getName(), name.array(), name.arrayOffset(), name.limit() - name.position()));
    }

    String comm = ze.getComment();
    if (comm != null && !"".equals(comm)) {

      boolean commentEncodable = zipEncoding.canEncode(comm);

      if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS || !commentEncodable) {
        ByteBuffer commentB = getEntryEncoding(ze).encode(comm);
        ze.addExtraField(
            new UnicodeCommentExtraField(
                comm,
                commentB.array(),
                commentB.arrayOffset(),
                commentB.limit() - commentB.position()));
      }
    }
  }