You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2023/01/01 14:32:45 UTC

[commons-compress] 02/07: Sort members

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git

commit 95541c966ba97cc1428e2c5d223f83105145b550
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Jan 1 09:18:51 2023 -0500

    Sort members
---
 .../archivers/zip/X5455_ExtendedTimestamp.java     | 140 +++---
 .../compress/archivers/zip/ZipArchiveEntry.java    | 480 ++++++++++-----------
 .../commons/compress/archivers/zip/ZipUtil.java    |  82 ++--
 .../archivers/zip/ZipArchiveEntryTest.java         | 184 ++++----
 .../compress/archivers/zip/ZipUtilTest.java        |  66 +--
 .../harmony/pack200/tests/ArchiveTest.java         |  18 +-
 .../harmony/pack200/tests/BHSDCodecTest.java       |   8 +-
 .../harmony/pack200/tests/CodecEncodingTest.java   |  66 +--
 .../compress/harmony/pack200/tests/CodecTest.java  |  84 ++--
 .../harmony/pack200/tests/PopulationCodecTest.java |  16 +-
 .../harmony/pack200/tests/RunCodecTest.java        |  18 +-
 .../unpack200/tests/AttributeLayoutTest.java       |  36 +-
 .../harmony/unpack200/tests/ICTupleTest.java       |  18 +-
 .../harmony/unpack200/tests/SegmentUtilsTest.java  |  12 +-
 .../commons/compress/utils/TimeUtilsTest.java      |  62 +--
 15 files changed, 645 insertions(+), 645 deletions(-)

diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestamp.java b/src/main/java/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestamp.java
index 1e030268..12d8ab91 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestamp.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/X5455_ExtendedTimestamp.java
@@ -141,6 +141,12 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
         return time == null ? null : unixTimeToZipLong(TimeUtils.toUnixTime(time));
     }
 
+    private static FileTime unixTimeToFileTime(final ZipLong unixTime) {
+        return unixTime != null ? TimeUtils.unixTimeToFileTime(unixTime.getIntValue()) : null;
+    }
+    // The 3 boolean fields (below) come from this flags byte.  The remaining 5 bits
+    // are ignored according to the current version of the spec (December 2012).
+
     private static ZipLong unixTimeToZipLong(final long unixTime) {
         if (!TimeUtils.isUnixTime(unixTime)) {
             throw new IllegalArgumentException("X5455 timestamps must fit in a signed 32 bit integer: " + unixTime);
@@ -152,12 +158,6 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
         return unixTime != null ? new Date(unixTime.getIntValue() * 1000L) : null;
     }
 
-    private static FileTime unixTimeToFileTime(final ZipLong unixTime) {
-        return unixTime != null ? TimeUtils.unixTimeToFileTime(unixTime.getIntValue()) : null;
-    }
-    // The 3 boolean fields (below) come from this flags byte.  The remaining 5 bits
-    // are ignored according to the current version of the spec (December 2012).
-
     private byte flags;
     // Note: even if bit1 and bit2 are set, the Central data will still not contain
     // access/create fields:  only local data ever holds those!  This causes
@@ -200,28 +200,28 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
     }
 
     /**
-     * Gets the access time as a java.util.Date
+     * Gets the access time as a {@link FileTime}
      * of this zip entry, or null if no such timestamp exists in the zip entry.
      * The milliseconds are always zeroed out, since the underlying data
      * offers only per-second precision.
      *
-     * @return access time as java.util.Date or null.
+     * @return modify time as {@link FileTime} or null.
+     * @since 1.23
      */
-    public Date getAccessJavaTime() {
-        return zipLongToDate(accessTime);
+    public FileTime getAccessFileTime() {
+        return unixTimeToFileTime(accessTime);
     }
 
     /**
-     * Gets the access time as a {@link FileTime}
+     * Gets the access time as a java.util.Date
      * of this zip entry, or null if no such timestamp exists in the zip entry.
      * The milliseconds are always zeroed out, since the underlying data
      * offers only per-second precision.
      *
-     * @return modify time as {@link FileTime} or null.
-     * @since 1.23
+     * @return access time as java.util.Date or null.
      */
-    public FileTime getAccessFileTime() {
-        return unixTimeToFileTime(accessTime);
+    public Date getAccessJavaTime() {
+        return zipLongToDate(accessTime);
     }
 
     /**
@@ -263,6 +263,19 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
         return new ZipShort(1 + (bit0_modifyTimePresent ? 4 : 0));
     }
 
+    /**
+     * Gets the create time as a {@link FileTime}
+     * of this zip entry, or null if no such timestamp exists in the zip entry.
+     * The milliseconds are always zeroed out, since the underlying data
+     * offers only per-second precision.
+     *
+     * @return modify time as {@link FileTime} or null.
+     * @since 1.23
+     */
+    public FileTime getCreateFileTime() {
+        return unixTimeToFileTime(createTime);
+    }
+
     /**
      * <p>
      * Gets the create time as a a java.util.Date
@@ -283,19 +296,6 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
         return zipLongToDate(createTime);
     }
 
-    /**
-     * Gets the create time as a {@link FileTime}
-     * of this zip entry, or null if no such timestamp exists in the zip entry.
-     * The milliseconds are always zeroed out, since the underlying data
-     * offers only per-second precision.
-     *
-     * @return modify time as {@link FileTime} or null.
-     * @since 1.23
-     */
-    public FileTime getCreateFileTime() {
-        return unixTimeToFileTime(createTime);
-    }
-
     /**
      * <p>
      * Gets the create time (seconds since epoch) of this zip entry
@@ -386,28 +386,28 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
     }
 
     /**
-     * Gets the modify time as a java.util.Date
+     * Gets the modify time as a {@link FileTime}
      * of this zip entry, or null if no such timestamp exists in the zip entry.
      * The milliseconds are always zeroed out, since the underlying data
      * offers only per-second precision.
      *
-     * @return modify time as java.util.Date or null.
+     * @return modify time as {@link FileTime} or null.
+     * @since 1.23
      */
-    public Date getModifyJavaTime() {
-        return zipLongToDate(modifyTime);
+    public FileTime getModifyFileTime() {
+        return unixTimeToFileTime(modifyTime);
     }
 
     /**
-     * Gets the modify time as a {@link FileTime}
+     * Gets the modify time as a java.util.Date
      * of this zip entry, or null if no such timestamp exists in the zip entry.
      * The milliseconds are always zeroed out, since the underlying data
      * offers only per-second precision.
      *
-     * @return modify time as {@link FileTime} or null.
-     * @since 1.23
+     * @return modify time as java.util.Date or null.
      */
-    public FileTime getModifyFileTime() {
-        return unixTimeToFileTime(modifyTime);
+    public Date getModifyJavaTime() {
+        return zipLongToDate(modifyTime);
     }
 
     /**
@@ -528,8 +528,8 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
 
     /**
      * <p>
-     * Sets the access time as a java.util.Date
-     * of this zip entry.  Supplied value is truncated to per-second
+     * Sets the acccess time as a {@link FileTime}
+     * of this zip entry. Supplied value is truncated to per-second
      * precision (milliseconds zeroed-out).
      * </p><p>
      * Note: the setters for flags and timestamps are decoupled.
@@ -537,16 +537,17 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
      * out if the corresponding bit in the flags is also set.
      * </p>
      *
-     * @param d access time as java.util.Date
+     * @param time access time as {@link FileTime}
+     * @since 1.23
      */
-    public void setAccessJavaTime(final Date d) {
-        setAccessTime(dateToZipLong(d));
+    public void setAccessFileTime(final FileTime time) {
+        setAccessTime(fileTimeToZipLong(time));
     }
 
     /**
      * <p>
-     * Sets the acccess time as a {@link FileTime}
-     * of this zip entry. Supplied value is truncated to per-second
+     * Sets the access time as a java.util.Date
+     * of this zip entry.  Supplied value is truncated to per-second
      * precision (milliseconds zeroed-out).
      * </p><p>
      * Note: the setters for flags and timestamps are decoupled.
@@ -554,11 +555,10 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
      * out if the corresponding bit in the flags is also set.
      * </p>
      *
-     * @param time access time as {@link FileTime}
-     * @since 1.23
+     * @param d access time as java.util.Date
      */
-    public void setAccessFileTime(final FileTime time) {
-        setAccessTime(fileTimeToZipLong(time));
+    public void setAccessJavaTime(final Date d) {
+        setAccessTime(dateToZipLong(d));
     }
 
     /**
@@ -581,8 +581,8 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
 
     /**
      * <p>
-     * Sets the create time as a java.util.Date
-     * of this zip entry.  Supplied value is truncated to per-second
+     * Sets the create time as a {@link FileTime}
+     * of this zip entry. Supplied value is truncated to per-second
      * precision (milliseconds zeroed-out).
      * </p><p>
      * Note: the setters for flags and timestamps are decoupled.
@@ -590,14 +590,17 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
      * out if the corresponding bit in the flags is also set.
      * </p>
      *
-     * @param d create time as java.util.Date
+     * @param time create time as {@link FileTime}
+     * @since 1.23
      */
-    public void setCreateJavaTime(final Date d) { setCreateTime(dateToZipLong(d)); }
+    public void setCreateFileTime(final FileTime time) {
+        setCreateTime(fileTimeToZipLong(time));
+    }
 
     /**
      * <p>
-     * Sets the create time as a {@link FileTime}
-     * of this zip entry. Supplied value is truncated to per-second
+     * Sets the create time as a java.util.Date
+     * of this zip entry.  Supplied value is truncated to per-second
      * precision (milliseconds zeroed-out).
      * </p><p>
      * Note: the setters for flags and timestamps are decoupled.
@@ -605,12 +608,9 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
      * out if the corresponding bit in the flags is also set.
      * </p>
      *
-     * @param time create time as {@link FileTime}
-     * @since 1.23
+     * @param d create time as java.util.Date
      */
-    public void setCreateFileTime(final FileTime time) {
-        setCreateTime(fileTimeToZipLong(time));
-    }
+    public void setCreateJavaTime(final Date d) { setCreateTime(dateToZipLong(d)); }
 
     /**
      * <p>
@@ -653,8 +653,8 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
 
     /**
      * <p>
-     * Sets the modify time as a java.util.Date
-     * of this zip entry.  Supplied value is truncated to per-second
+     * Sets the modify time as a {@link FileTime}
+     * of this zip entry. Supplied value is truncated to per-second
      * precision (milliseconds zeroed-out).
      * </p><p>
      * Note: the setters for flags and timestamps are decoupled.
@@ -662,16 +662,17 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
      * out if the corresponding bit in the flags is also set.
      * </p>
      *
-     * @param d modify time as java.util.Date
+     * @param time modify time as {@link FileTime}
+     * @since 1.23
      */
-    public void setModifyJavaTime(final Date d) {
-        setModifyTime(dateToZipLong(d));
+    public void setModifyFileTime(final FileTime time) {
+        setModifyTime(fileTimeToZipLong(time));
     }
 
     /**
      * <p>
-     * Sets the modify time as a {@link FileTime}
-     * of this zip entry. Supplied value is truncated to per-second
+     * Sets the modify time as a java.util.Date
+     * of this zip entry.  Supplied value is truncated to per-second
      * precision (milliseconds zeroed-out).
      * </p><p>
      * Note: the setters for flags and timestamps are decoupled.
@@ -679,11 +680,10 @@ public class X5455_ExtendedTimestamp implements ZipExtraField, Cloneable, Serial
      * out if the corresponding bit in the flags is also set.
      * </p>
      *
-     * @param time modify time as {@link FileTime}
-     * @since 1.23
+     * @param d modify time as java.util.Date
      */
-    public void setModifyFileTime(final FileTime time) {
-        setModifyTime(fileTimeToZipLong(time));
+    public void setModifyJavaTime(final Date d) {
+        setModifyTime(dateToZipLong(d));
     }
 
     /**
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java
index bf233b12..d75d2fcb 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java
@@ -236,6 +236,15 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
 
     private static final int SHORT_SHIFT = 16;
 
+    private static boolean canConvertToInfoZipExtendedTimestamp(
+            final FileTime lastModifiedTime,
+            final FileTime lastAccessTime,
+            final FileTime creationTime) {
+        return TimeUtils.isUnixTime(lastModifiedTime)
+                && TimeUtils.isUnixTime(lastAccessTime)
+                && TimeUtils.isUnixTime(creationTime);
+    }
+
     /**
      * The {@link java.util.zip.ZipEntry} base class only supports
      * the compression methods STORED and DEFLATED. We override the
@@ -247,7 +256,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
      *        >COMPRESS-93</a>
      */
     private int method = ZipMethod.UNKNOWN_CODE;
-
     /**
      * The {@link java.util.zip.ZipEntry#setSize} method in the base
      * class throws an IllegalArgumentException if the size is bigger
@@ -274,6 +282,7 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
     private long dataOffset = OFFSET_UNKNOWN;
     private boolean isStreamContiguous;
     private NameSource nameSource = NameSource.NAME;
+
     private CommentSource commentSource = CommentSource.COMMENT;
 
     private long diskNumberStart;
@@ -355,17 +364,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         setAttributes(inputPath, options);
     }
 
-    private void setAttributes(final Path inputPath, final LinkOption... options) throws IOException {
-        final BasicFileAttributes attributes = Files.readAttributes(inputPath, BasicFileAttributes.class, options);
-        if (attributes.isRegularFile()) {
-            setSize(attributes.size());
-        }
-        super.setLastModifiedTime(attributes.lastModifiedTime());
-        super.setCreationTime(attributes.creationTime());
-        super.setLastAccessTime(attributes.lastAccessTime());
-        setExtraTimeFields();
-    }
-
     /**
      * Creates a new zip entry with the specified name.
      *
@@ -437,19 +435,38 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         setExtra();
     }
 
-    private void internalAddExtraField(final ZipExtraField ze) {
-        if (ze instanceof UnparseableExtraFieldData) {
-            unparseableExtra = (UnparseableExtraFieldData) ze;
-        } else if (extraFields == null) {
-            extraFields = new ZipExtraField[]{ze};
-        } else {
-            if (getExtraField(ze.getHeaderId()) != null) {
-                internalRemoveExtraField(ze.getHeaderId());
-            }
-            final ZipExtraField[] zipExtraFields = copyOf(extraFields, extraFields.length + 1);
-            zipExtraFields[zipExtraFields.length - 1] = ze;
-            extraFields = zipExtraFields;
+    private void addInfoZipExtendedTimestamp(
+            final FileTime lastModifiedTime,
+            final FileTime lastAccessTime,
+            final FileTime creationTime) {
+        final X5455_ExtendedTimestamp infoZipTimestamp = new X5455_ExtendedTimestamp();
+        if (lastModifiedTime != null) {
+            infoZipTimestamp.setModifyFileTime(lastModifiedTime);
+        }
+        if (lastAccessTime != null) {
+            infoZipTimestamp.setAccessFileTime(lastAccessTime);
+        }
+        if (creationTime != null) {
+            infoZipTimestamp.setCreateFileTime(creationTime);
+        }
+        internalAddExtraField(infoZipTimestamp);
+    }
+
+    private void addNTFSTimestamp(
+            final FileTime lastModifiedTime,
+            final FileTime lastAccessTime,
+            final FileTime creationTime) {
+        final X000A_NTFS ntfsTimestamp = new X000A_NTFS();
+        if (lastModifiedTime != null) {
+            ntfsTimestamp.setModifyFileTime(lastModifiedTime);
+        }
+        if (lastAccessTime != null) {
+            ntfsTimestamp.setAccessFileTime(lastAccessTime);
+        }
+        if (creationTime != null) {
+            ntfsTimestamp.setCreateFileTime(creationTime);
         }
+        internalAddExtraField(ntfsTimestamp);
     }
 
     /**
@@ -472,79 +489,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         return cpy;
     }
 
-    /**
-     * {@inheritDoc}
-     *
-     * <p>Override to work around bug <a href="https://bugs.openjdk.org/browse/JDK-8130914">JDK-8130914</a></p>
-     *
-     * @return  The last modification time of the entry in milliseconds
-     *          since the epoch, or -1 if not specified
-     *
-     * @see #setTime(long)
-     * @see #setLastModifiedTime(FileTime)
-     */
-    @Override
-    public long getTime() {
-        if (lastModifiedDateSet) {
-            return getLastModifiedTime().toMillis();
-        }
-        return time != -1 ? time : super.getTime();
-    }
-
-    /**
-     *
-     * {@inheritDoc}
-     *
-     * <p>Override to work around bug <a href="https://bugs.openjdk.org/browse/JDK-8130914">JDK-8130914</a></p>
-     *
-     * @param time
-     *         The last modification time of the entry in milliseconds
-     *         since the epoch
-     * @see #getTime()
-     * @see #getLastModifiedTime()
-     */
-    @Override
-    public void setTime(final long time) {
-        if (ZipUtil.isDosTime(time)) {
-            super.setTime(time);
-            this.time = time;
-            lastModifiedDateSet = false;
-            setExtraTimeFields();
-        } else {
-            setLastModifiedTime(FileTime.fromMillis(time));
-        }
-    }
-
-    @Override
-    public ZipEntry setLastModifiedTime(final FileTime time) {
-        internalSetLastModifiedTime(time);
-        setExtraTimeFields();
-        return this;
-    }
-
-    private void internalSetLastModifiedTime(final FileTime time) {
-        super.setLastModifiedTime(time);
-        this.time = time.toMillis();
-        lastModifiedDateSet = true;
-    }
-
-    @Override
-    public ZipEntry setLastAccessTime(final FileTime time) {
-        super.setLastAccessTime(time);
-        setExtraTimeFields();
-        return this;
-    }
-
-    @Override
-    public ZipEntry setCreationTime(final FileTime time) {
-        super.setCreationTime(time);
-        setExtraTimeFields();
-        return this;
-    }
-    /* (non-Javadoc)
-     * @see Object#equals(Object)
-     */
-
     @Override
     public boolean equals(final Object obj) {
         if (this == obj) {
@@ -911,6 +855,25 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         return size;
     }
 
+    /**
+     * {@inheritDoc}
+     *
+     * <p>Override to work around bug <a href="https://bugs.openjdk.org/browse/JDK-8130914">JDK-8130914</a></p>
+     *
+     * @return  The last modification time of the entry in milliseconds
+     *          since the epoch, or -1 if not specified
+     *
+     * @see #setTime(long)
+     * @see #setLastModifiedTime(FileTime)
+     */
+    @Override
+    public long getTime() {
+        if (lastModifiedDateSet) {
+            return getLastModifiedTime().toMillis();
+        }
+        return time != -1 ? time : super.getTime();
+    }
+
     /**
      * Unix permission.
      * @return the unix permissions
@@ -967,6 +930,43 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         return getName().hashCode();
     }
 
+    private void internalAddExtraField(final ZipExtraField ze) {
+        if (ze instanceof UnparseableExtraFieldData) {
+            unparseableExtra = (UnparseableExtraFieldData) ze;
+        } else if (extraFields == null) {
+            extraFields = new ZipExtraField[]{ze};
+        } else {
+            if (getExtraField(ze.getHeaderId()) != null) {
+                internalRemoveExtraField(ze.getHeaderId());
+            }
+            final ZipExtraField[] zipExtraFields = copyOf(extraFields, extraFields.length + 1);
+            zipExtraFields[zipExtraFields.length - 1] = ze;
+            extraFields = zipExtraFields;
+        }
+    }
+
+    private void internalRemoveExtraField(final ZipShort type) {
+        if (extraFields == null) {
+            return;
+        }
+        final List<ZipExtraField> newResult = new ArrayList<>();
+        for (final ZipExtraField extraField : extraFields) {
+            if (!type.equals(extraField.getHeaderId())) {
+                newResult.add(extraField);
+            }
+        }
+        if (extraFields.length == newResult.size()) {
+            return;
+        }
+        extraFields = newResult.toArray(ExtraFieldUtils.EMPTY_ZIP_EXTRA_FIELD_ARRAY);
+    }
+
+    private void internalSetLastModifiedTime(final FileTime time) {
+        super.setLastModifiedTime(time);
+        this.time = time.toMillis();
+        lastModifiedDateSet = true;
+    }
+
     /**
      * Is this entry a directory?
      * @return true if the entry is a directory
@@ -1055,22 +1055,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         setExtra();
     }
 
-    private void internalRemoveExtraField(final ZipShort type) {
-        if (extraFields == null) {
-            return;
-        }
-        final List<ZipExtraField> newResult = new ArrayList<>();
-        for (final ZipExtraField extraField : extraFields) {
-            if (!type.equals(extraField.getHeaderId())) {
-                newResult.add(extraField);
-            }
-        }
-        if (extraFields.length == newResult.size()) {
-            return;
-        }
-        extraFields = newResult.toArray(ExtraFieldUtils.EMPTY_ZIP_EXTRA_FIELD_ARRAY);
-    }
-
     /**
      * Removes unparseable extra field data.
      *
@@ -1084,6 +1068,13 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         setExtra();
     }
 
+    private boolean requiresExtraTimeFields() {
+        if (getLastAccessTime() != null || getCreationTime() != null) {
+            return true;
+        }
+        return lastModifiedDateSet;
+    }
+
     /**
      * Sets alignment for this entry.
      *
@@ -1099,73 +1090,15 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         this.alignment = alignment;
     }
 
-    private void setExtraTimeFields() {
-        if (getExtraField(X5455_ExtendedTimestamp.HEADER_ID) != null) {
-            internalRemoveExtraField(X5455_ExtendedTimestamp.HEADER_ID);
-        }
-        if (getExtraField(X000A_NTFS.HEADER_ID) != null) {
-            internalRemoveExtraField(X000A_NTFS.HEADER_ID);
-        }
-        if (requiresExtraTimeFields()) {
-            final FileTime lastModifiedTime = getLastModifiedTime();
-            final FileTime lastAccessTime = getLastAccessTime();
-            final FileTime creationTime = getCreationTime();
-            if (canConvertToInfoZipExtendedTimestamp(lastModifiedTime, lastAccessTime, creationTime)) {
-                addInfoZipExtendedTimestamp(lastModifiedTime, lastAccessTime, creationTime);
-            }
-            addNTFSTimestamp(lastModifiedTime, lastAccessTime, creationTime);
-        }
-        setExtra();
-    }
-
-    private void addInfoZipExtendedTimestamp(
-            final FileTime lastModifiedTime,
-            final FileTime lastAccessTime,
-            final FileTime creationTime) {
-        final X5455_ExtendedTimestamp infoZipTimestamp = new X5455_ExtendedTimestamp();
-        if (lastModifiedTime != null) {
-            infoZipTimestamp.setModifyFileTime(lastModifiedTime);
-        }
-        if (lastAccessTime != null) {
-            infoZipTimestamp.setAccessFileTime(lastAccessTime);
-        }
-        if (creationTime != null) {
-            infoZipTimestamp.setCreateFileTime(creationTime);
-        }
-        internalAddExtraField(infoZipTimestamp);
-    }
-
-    private boolean requiresExtraTimeFields() {
-        if (getLastAccessTime() != null || getCreationTime() != null) {
-            return true;
-        }
-        return lastModifiedDateSet;
-    }
-
-    private void addNTFSTimestamp(
-            final FileTime lastModifiedTime,
-            final FileTime lastAccessTime,
-            final FileTime creationTime) {
-        final X000A_NTFS ntfsTimestamp = new X000A_NTFS();
-        if (lastModifiedTime != null) {
-            ntfsTimestamp.setModifyFileTime(lastModifiedTime);
-        }
-        if (lastAccessTime != null) {
-            ntfsTimestamp.setAccessFileTime(lastAccessTime);
-        }
-        if (creationTime != null) {
-            ntfsTimestamp.setCreateFileTime(creationTime);
+    private void setAttributes(final Path inputPath, final LinkOption... options) throws IOException {
+        final BasicFileAttributes attributes = Files.readAttributes(inputPath, BasicFileAttributes.class, options);
+        if (attributes.isRegularFile()) {
+            setSize(attributes.size());
         }
-        internalAddExtraField(ntfsTimestamp);
-    }
-
-    private static boolean canConvertToInfoZipExtendedTimestamp(
-            final FileTime lastModifiedTime,
-            final FileTime lastAccessTime,
-            final FileTime creationTime) {
-        return TimeUtils.isUnixTime(lastModifiedTime)
-                && TimeUtils.isUnixTime(lastAccessTime)
-                && TimeUtils.isUnixTime(creationTime);
+        super.setLastModifiedTime(attributes.lastModifiedTime());
+        super.setCreationTime(attributes.creationTime());
+        super.setLastAccessTime(attributes.lastAccessTime());
+        setExtraTimeFields();
     }
 
     /**
@@ -1190,6 +1123,16 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         this.commentSource = commentSource;
     }
 
+    @Override
+    public ZipEntry setCreationTime(final FileTime time) {
+        super.setCreationTime(time);
+        setExtraTimeFields();
+        return this;
+    }
+    /* (non-Javadoc)
+     * @see Object#equals(Object)
+     */
+
     /**
      * Sets the data offset.
      *
@@ -1230,67 +1173,6 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         updateTimeFieldsFromExtraFields();
     }
 
-    private void updateTimeFieldsFromExtraFields() {
-        // Update times from X5455_ExtendedTimestamp field
-        updateTimeFromExtendedTimestampField();
-        // Update times from X000A_NTFS field, overriding X5455_ExtendedTimestamp if both are present
-        updateTimeFromNtfsField();
-    }
-
-    /**
-     * Workaround for the fact that, as of Java 17, {@link java.util.zip.ZipEntry} does not properly modify
-     * the entry's {@code xdostime} field, only setting {@code mtime}. While this is not strictly necessary,
-     * it's better to maintain the same behavior between this and the NTFS field.
-     */
-    private void updateTimeFromExtendedTimestampField() {
-        final ZipExtraField extraField = getExtraField(X5455_ExtendedTimestamp.HEADER_ID);
-        if (extraField instanceof X5455_ExtendedTimestamp) {
-            final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) extraField;
-            if (extendedTimestamp.isBit0_modifyTimePresent()) {
-                final FileTime modifyTime = extendedTimestamp.getModifyFileTime();
-                if (modifyTime != null) {
-                    internalSetLastModifiedTime(modifyTime);
-                }
-            }
-            if (extendedTimestamp.isBit1_accessTimePresent()) {
-                final FileTime accessTime = extendedTimestamp.getAccessFileTime();
-                if (accessTime != null) {
-                    super.setLastAccessTime(accessTime);
-                }
-            }
-            if (extendedTimestamp.isBit2_createTimePresent()) {
-                final FileTime creationTime = extendedTimestamp.getCreateFileTime();
-                if (creationTime != null) {
-                    super.setCreationTime(creationTime);
-                }
-            }
-        }
-    }
-
-    /**
-     * Workaround for the fact that, as of Java 17, {@link java.util.zip.ZipEntry} parses NTFS
-     * timestamps with a maximum precision of microseconds, which is lower than the 100ns precision
-     * provided by this extra field.
-     */
-    private void updateTimeFromNtfsField() {
-        final ZipExtraField extraField = getExtraField(X000A_NTFS.HEADER_ID);
-        if (extraField instanceof X000A_NTFS) {
-            final X000A_NTFS ntfsTimestamp = (X000A_NTFS) extraField;
-            final FileTime modifyTime = ntfsTimestamp.getModifyFileTime();
-            if (modifyTime != null) {
-                internalSetLastModifiedTime(modifyTime);
-            }
-            final FileTime accessTime = ntfsTimestamp.getAccessFileTime();
-            if (accessTime != null) {
-                super.setLastAccessTime(accessTime);
-            }
-            final FileTime creationTime = ntfsTimestamp.getCreateFileTime();
-            if (creationTime != null) {
-                super.setCreationTime(creationTime);
-            }
-        }
-    }
-
     /**
      * Parses the given bytes as extra field data and consumes any
      * unparseable data as an {@link UnparseableExtraFieldData}
@@ -1330,6 +1212,25 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         setExtra();
     }
 
+    private void setExtraTimeFields() {
+        if (getExtraField(X5455_ExtendedTimestamp.HEADER_ID) != null) {
+            internalRemoveExtraField(X5455_ExtendedTimestamp.HEADER_ID);
+        }
+        if (getExtraField(X000A_NTFS.HEADER_ID) != null) {
+            internalRemoveExtraField(X000A_NTFS.HEADER_ID);
+        }
+        if (requiresExtraTimeFields()) {
+            final FileTime lastModifiedTime = getLastModifiedTime();
+            final FileTime lastAccessTime = getLastAccessTime();
+            final FileTime creationTime = getCreationTime();
+            if (canConvertToInfoZipExtendedTimestamp(lastModifiedTime, lastAccessTime, creationTime)) {
+                addInfoZipExtendedTimestamp(lastModifiedTime, lastAccessTime, creationTime);
+            }
+            addNTFSTimestamp(lastModifiedTime, lastAccessTime, creationTime);
+        }
+        setExtra();
+    }
+
     /**
      * The "general purpose bit" field.
      * @param b the general purpose bit
@@ -1347,6 +1248,20 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         internalAttributes = value;
     }
 
+    @Override
+    public ZipEntry setLastAccessTime(final FileTime time) {
+        super.setLastAccessTime(time);
+        setExtraTimeFields();
+        return this;
+    }
+
+    @Override
+    public ZipEntry setLastModifiedTime(final FileTime time) {
+        internalSetLastModifiedTime(time);
+        setExtraTimeFields();
+        return this;
+    }
+
     protected void setLocalHeaderOffset(final long localHeaderOffset) {
         this.localHeaderOffset = localHeaderOffset;
     }
@@ -1446,6 +1361,30 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
         setTime(fileTime.toMillis());
     }
 
+    /**
+     *
+     * {@inheritDoc}
+     *
+     * <p>Override to work around bug <a href="https://bugs.openjdk.org/browse/JDK-8130914">JDK-8130914</a></p>
+     *
+     * @param time
+     *         The last modification time of the entry in milliseconds
+     *         since the epoch
+     * @see #getTime()
+     * @see #getLastModifiedTime()
+     */
+    @Override
+    public void setTime(final long time) {
+        if (ZipUtil.isDosTime(time)) {
+            super.setTime(time);
+            this.time = time;
+            lastModifiedDateSet = false;
+            setExtraTimeFields();
+        } else {
+            setLastModifiedTime(FileTime.fromMillis(time));
+        }
+    }
+
     /**
      * Sets Unix permissions in a way that is understood by Info-Zip's
      * unzip command.
@@ -1479,4 +1418,65 @@ public class ZipArchiveEntry extends java.util.zip.ZipEntry implements ArchiveEn
     public void setVersionRequired(final int versionRequired) {
         this.versionRequired = versionRequired;
     }
+
+    private void updateTimeFieldsFromExtraFields() {
+        // Update times from X5455_ExtendedTimestamp field
+        updateTimeFromExtendedTimestampField();
+        // Update times from X000A_NTFS field, overriding X5455_ExtendedTimestamp if both are present
+        updateTimeFromNtfsField();
+    }
+
+    /**
+     * Workaround for the fact that, as of Java 17, {@link java.util.zip.ZipEntry} does not properly modify
+     * the entry's {@code xdostime} field, only setting {@code mtime}. While this is not strictly necessary,
+     * it's better to maintain the same behavior between this and the NTFS field.
+     */
+    private void updateTimeFromExtendedTimestampField() {
+        final ZipExtraField extraField = getExtraField(X5455_ExtendedTimestamp.HEADER_ID);
+        if (extraField instanceof X5455_ExtendedTimestamp) {
+            final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) extraField;
+            if (extendedTimestamp.isBit0_modifyTimePresent()) {
+                final FileTime modifyTime = extendedTimestamp.getModifyFileTime();
+                if (modifyTime != null) {
+                    internalSetLastModifiedTime(modifyTime);
+                }
+            }
+            if (extendedTimestamp.isBit1_accessTimePresent()) {
+                final FileTime accessTime = extendedTimestamp.getAccessFileTime();
+                if (accessTime != null) {
+                    super.setLastAccessTime(accessTime);
+                }
+            }
+            if (extendedTimestamp.isBit2_createTimePresent()) {
+                final FileTime creationTime = extendedTimestamp.getCreateFileTime();
+                if (creationTime != null) {
+                    super.setCreationTime(creationTime);
+                }
+            }
+        }
+    }
+
+    /**
+     * Workaround for the fact that, as of Java 17, {@link java.util.zip.ZipEntry} parses NTFS
+     * timestamps with a maximum precision of microseconds, which is lower than the 100ns precision
+     * provided by this extra field.
+     */
+    private void updateTimeFromNtfsField() {
+        final ZipExtraField extraField = getExtraField(X000A_NTFS.HEADER_ID);
+        if (extraField instanceof X000A_NTFS) {
+            final X000A_NTFS ntfsTimestamp = (X000A_NTFS) extraField;
+            final FileTime modifyTime = ntfsTimestamp.getModifyFileTime();
+            if (modifyTime != null) {
+                internalSetLastModifiedTime(modifyTime);
+            }
+            final FileTime accessTime = ntfsTimestamp.getAccessFileTime();
+            if (accessTime != null) {
+                super.setLastAccessTime(accessTime);
+            }
+            final FileTime creationTime = ntfsTimestamp.getCreateFileTime();
+            if (creationTime != null) {
+                super.setCreationTime(creationTime);
+            }
+        }
+    }
 }
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java
index 12f46ea2..28a6354b 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java
@@ -102,17 +102,6 @@ public abstract class ZipUtil {
      */
     private static final long UPPER_DOSTIME_BOUND = 128L * 365 * 24 * 60 * 60 * 1000;
 
-    /**
-     * Tests whether a given time (in milliseconds since Epoch) can be safely represented as DOS time
-     *
-     * @param time time in milliseconds since epoch
-     * @return true if the time can be safely represented as DOS time, false otherwise
-     * @since 1.23
-     */
-    public static boolean isDosTime(final long time) {
-        return time <= UPPER_DOSTIME_BOUND && javaToDosTime(time) != DOSTIME_BEFORE_1980;
-    }
-
     /**
      * Assumes a negative integer really is a positive integer that
      * has wrapped around and re-creates the original value.
@@ -170,7 +159,6 @@ public abstract class ZipUtil {
         }
     }
 
-
     /**
      * Create a copy of the given array - or return null if the
      * argument is null.
@@ -182,22 +170,13 @@ public abstract class ZipUtil {
         return null;
     }
 
+
     static void copy(final byte[] from, final byte[] to, final int offset) {
         if (from != null) {
             System.arraycopy(from, 0, to, offset, from.length);
         }
     }
 
-    /**
-     * Converts DOS time to Java time (number of milliseconds since
-     * epoch).
-     * @param dosTime time to convert
-     * @return converted time
-     */
-    public static long dosToJavaTime(final long dosTime) {
-        return dosToJavaDate(dosTime).getTime();
-    }
-
     private static Date dosToJavaDate(final long dosTime) {
         final Calendar cal = Calendar.getInstance();
         // CheckStyle:MagicNumberCheck OFF - no point
@@ -212,6 +191,16 @@ public abstract class ZipUtil {
         return cal.getTime();
     }
 
+    /**
+     * Converts DOS time to Java time (number of milliseconds since
+     * epoch).
+     * @param dosTime time to convert
+     * @return converted time
+     */
+    public static long dosToJavaTime(final long dosTime) {
+        return dosToJavaDate(dosTime).getTime();
+    }
+
     /**
      * Convert a DOS date/time field to a Date object.
      *
@@ -252,6 +241,36 @@ public abstract class ZipUtil {
         return null;
     }
 
+    /**
+     * Tests whether a given time (in milliseconds since Epoch) can be safely represented as DOS time
+     *
+     * @param time time in milliseconds since epoch
+     * @return true if the time can be safely represented as DOS time, false otherwise
+     * @since 1.23
+     */
+    public static boolean isDosTime(final long time) {
+        return time <= UPPER_DOSTIME_BOUND && javaToDosTime(time) != DOSTIME_BEFORE_1980;
+    }
+
+    private static LocalDateTime javaEpochToLocalDateTime(final long time) {
+        final Instant instant = Instant.ofEpochMilli(time);
+        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+    }
+
+    // version with integer overflow fixed - see https://bugs.openjdk.org/browse/JDK-8130914
+    private static long javaToDosTime(final long t) {
+        final LocalDateTime ldt = javaEpochToLocalDateTime(t);
+        if (ldt.getYear() < 1980) {
+            return DOSTIME_BEFORE_1980;
+        }
+        return ((ldt.getYear() - 1980) << 25
+                | ldt.getMonthValue() << 21
+                | ldt.getDayOfMonth() << 16
+                | ldt.getHour() << 11
+                | ldt.getMinute() << 5
+                | ldt.getSecond() >> 1) & 0xffffffffL;
+    }
+
     /**
      * <p>
      * Converts a long into a BigInteger.  Negative numbers between -1 and
@@ -367,25 +386,6 @@ public abstract class ZipUtil {
             || entry.getMethod() == ZipMethod.BZIP2.getCode();
     }
 
-    // version with integer overflow fixed - see https://bugs.openjdk.org/browse/JDK-8130914
-    private static long javaToDosTime(final long t) {
-        final LocalDateTime ldt = javaEpochToLocalDateTime(t);
-        if (ldt.getYear() < 1980) {
-            return DOSTIME_BEFORE_1980;
-        }
-        return ((ldt.getYear() - 1980) << 25
-                | ldt.getMonthValue() << 21
-                | ldt.getDayOfMonth() << 16
-                | ldt.getHour() << 11
-                | ldt.getMinute() << 5
-                | ldt.getSecond() >> 1) & 0xffffffffL;
-    }
-
-    private static LocalDateTime javaEpochToLocalDateTime(final long time) {
-        final Instant instant = Instant.ofEpochMilli(time);
-        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
-    }
-
 
     /**
      * Convert a Date object to a DOS date/time field.
diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java
index a64e8734..a999f39f 100644
--- a/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java
@@ -337,46 +337,6 @@ public class ZipArchiveEntryTest {
         assertNotEquals(entry2, entry3);
     }
 
-    @Test
-    public void testUnixMode() {
-        ZipArchiveEntry ze = new ZipArchiveEntry("foo");
-        assertEquals(0, ze.getPlatform());
-        ze.setUnixMode(0755);
-        assertEquals(3, ze.getPlatform());
-        assertEquals(0755,
-                     (ze.getExternalAttributes() >> 16) & 0xFFFF);
-        assertEquals(0, ze.getExternalAttributes()  & 0xFFFF);
-
-        ze.setUnixMode(0444);
-        assertEquals(3, ze.getPlatform());
-        assertEquals(0444,
-                     (ze.getExternalAttributes() >> 16) & 0xFFFF);
-        assertEquals(1, ze.getExternalAttributes()  & 0xFFFF);
-
-        ze = new ZipArchiveEntry("foo/");
-        assertEquals(0, ze.getPlatform());
-        ze.setUnixMode(0777);
-        assertEquals(3, ze.getPlatform());
-        assertEquals(0777,
-                     (ze.getExternalAttributes() >> 16) & 0xFFFF);
-        assertEquals(0x10, ze.getExternalAttributes()  & 0xFFFF);
-
-        ze.setUnixMode(0577);
-        assertEquals(3, ze.getPlatform());
-        assertEquals(0577,
-                     (ze.getExternalAttributes() >> 16) & 0xFFFF);
-        assertEquals(0x11, ze.getExternalAttributes()  & 0xFFFF);
-    }
-
-    @Test
-    public void testZipArchiveClone() throws Exception {
-        try (ZipFile zf = new ZipFile(getFile("COMPRESS-479.zip"))) {
-            final ZipArchiveEntry ze = zf.getEntry("%U20AC_for_Dollar.txt");
-            final ZipArchiveEntry clonedZe = (ZipArchiveEntry) ze.clone();
-            assertEquals(ze, clonedZe);
-        }
-    }
-
     @Test
     public void testShouldNotSetExtraDateFieldsIfDateFitsInDosDates() {
         final ZipArchiveEntry ze = new ZipArchiveEntry();
@@ -393,23 +353,23 @@ public class ZipArchiveEntryTest {
     }
 
     @Test
-    public void testShouldSetExtraDateFieldsIfDateExceedsDosDate() {
+    public void testShouldNotSetInfoZipFieldIfAnyDatesExceedUnixTime() {
         final ZipArchiveEntry ze = new ZipArchiveEntry();
-        final FileTime time = FileTime.from(ZipUtilTest.toLocalInstant("1975-11-27T00:00:00"));
-        ze.setTime(time.toMillis());
+        final FileTime accessTime = FileTime.from(Instant.parse("2022-12-29T21:40:34.1234567Z"));
+        final FileTime creationTime = FileTime.from(Instant.parse("2038-12-28T20:39:33.1234567Z"));
+        final long time = Instant.parse("2020-03-04T12:34:56.1234567Z").toEpochMilli();
+        ze.setTime(time);
+        ze.setLastAccessTime(accessTime);
+        ze.setCreationTime(creationTime);
 
-        assertEquals(time.toMillis(), ze.getTime());
-        assertEquals(time, ze.getLastModifiedTime());
-        final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID);
-        assertNotNull(extendedTimestamp);
-        assertEquals(TimeUtils.toUnixTime(time), extendedTimestamp.getModifyTime().getValue());
-        assertNull(extendedTimestamp.getAccessTime());
-        assertNull(extendedTimestamp.getCreateTime());
+        assertEquals(time, ze.getTime());
+        assertEquals(time, ze.getLastModifiedTime().toMillis());
+        assertNull(ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID));
         final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID);
         assertNotNull(ntfs);
         assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue());
-        assertEquals(0L, ntfs.getAccessTime().getLongValue());
-        assertEquals(0L, ntfs.getCreateTime().getLongValue());
+        assertEquals(TimeUtils.toNtfsTime(accessTime), ntfs.getAccessTime().getLongValue());
+        assertEquals(TimeUtils.toNtfsTime(creationTime), ntfs.getCreateTime().getLongValue());
     }
 
     @Test
@@ -428,26 +388,6 @@ public class ZipArchiveEntryTest {
         assertEquals(0L, ntfs.getCreateTime().getLongValue());
     }
 
-    @Test
-    public void testShouldSetExtraDateFieldsIfModifyDateIsExplicitlySet() {
-        final ZipArchiveEntry ze = new ZipArchiveEntry();
-        final FileTime time = FileTime.from(Instant.parse("2022-12-28T20:39:33.1234567Z"));
-        ze.setLastModifiedTime(time);
-
-        assertEquals(time.toMillis(), ze.getTime());
-        assertEquals(time, ze.getLastModifiedTime());
-        final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID);
-        assertNotNull(extendedTimestamp);
-        assertEquals(TimeUtils.toUnixTime(time), extendedTimestamp.getModifyTime().getValue());
-        assertNull(extendedTimestamp.getAccessTime());
-        assertNull(extendedTimestamp.getCreateTime());
-        final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID);
-        assertNotNull(ntfs);
-        assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue());
-        assertEquals(0L, ntfs.getAccessTime().getLongValue());
-        assertEquals(0L, ntfs.getCreateTime().getLongValue());
-    }
-
     @Test
     public void testShouldSetExtraDateFieldsIfAccessDateIsSet() {
         final ZipArchiveEntry ze = new ZipArchiveEntry();
@@ -470,66 +410,126 @@ public class ZipArchiveEntryTest {
     }
 
     @Test
-    public void testShouldSetExtraDateFieldsIfCreationDateIsSet() {
+    public void testShouldSetExtraDateFieldsIfAllDatesAreSet() {
         final ZipArchiveEntry ze = new ZipArchiveEntry();
+        final FileTime accessTime = FileTime.from(Instant.parse("2022-12-29T21:40:34.1234567Z"));
         final FileTime creationTime = FileTime.from(Instant.parse("2022-12-28T20:39:33.1234567Z"));
         final long time = Instant.parse("2020-03-04T12:34:56.1234567Z").toEpochMilli();
         ze.setTime(time);
+        ze.setLastAccessTime(accessTime);
         ze.setCreationTime(creationTime);
 
         assertEquals(time, ze.getTime());
         assertEquals(time, ze.getLastModifiedTime().toMillis());
         final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID);
         assertNotNull(extendedTimestamp);
-        assertNull(extendedTimestamp.getAccessTime());
+        assertEquals(TimeUtils.toUnixTime(accessTime), extendedTimestamp.getAccessTime().getValue());
         assertEquals(TimeUtils.toUnixTime(creationTime), extendedTimestamp.getCreateTime().getValue());
         final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID);
         assertNotNull(ntfs);
         assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue());
-        assertEquals(0L, ntfs.getAccessTime().getLongValue());
+        assertEquals(TimeUtils.toNtfsTime(accessTime), ntfs.getAccessTime().getLongValue());
         assertEquals(TimeUtils.toNtfsTime(creationTime), ntfs.getCreateTime().getLongValue());
     }
 
     @Test
-    public void testShouldSetExtraDateFieldsIfAllDatesAreSet() {
+    public void testShouldSetExtraDateFieldsIfCreationDateIsSet() {
         final ZipArchiveEntry ze = new ZipArchiveEntry();
-        final FileTime accessTime = FileTime.from(Instant.parse("2022-12-29T21:40:34.1234567Z"));
         final FileTime creationTime = FileTime.from(Instant.parse("2022-12-28T20:39:33.1234567Z"));
         final long time = Instant.parse("2020-03-04T12:34:56.1234567Z").toEpochMilli();
         ze.setTime(time);
-        ze.setLastAccessTime(accessTime);
         ze.setCreationTime(creationTime);
 
         assertEquals(time, ze.getTime());
         assertEquals(time, ze.getLastModifiedTime().toMillis());
         final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID);
         assertNotNull(extendedTimestamp);
-        assertEquals(TimeUtils.toUnixTime(accessTime), extendedTimestamp.getAccessTime().getValue());
+        assertNull(extendedTimestamp.getAccessTime());
         assertEquals(TimeUtils.toUnixTime(creationTime), extendedTimestamp.getCreateTime().getValue());
         final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID);
         assertNotNull(ntfs);
         assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue());
-        assertEquals(TimeUtils.toNtfsTime(accessTime), ntfs.getAccessTime().getLongValue());
+        assertEquals(0L, ntfs.getAccessTime().getLongValue());
         assertEquals(TimeUtils.toNtfsTime(creationTime), ntfs.getCreateTime().getLongValue());
     }
 
     @Test
-    public void testShouldNotSetInfoZipFieldIfAnyDatesExceedUnixTime() {
+    public void testShouldSetExtraDateFieldsIfDateExceedsDosDate() {
         final ZipArchiveEntry ze = new ZipArchiveEntry();
-        final FileTime accessTime = FileTime.from(Instant.parse("2022-12-29T21:40:34.1234567Z"));
-        final FileTime creationTime = FileTime.from(Instant.parse("2038-12-28T20:39:33.1234567Z"));
-        final long time = Instant.parse("2020-03-04T12:34:56.1234567Z").toEpochMilli();
-        ze.setTime(time);
-        ze.setLastAccessTime(accessTime);
-        ze.setCreationTime(creationTime);
+        final FileTime time = FileTime.from(ZipUtilTest.toLocalInstant("1975-11-27T00:00:00"));
+        ze.setTime(time.toMillis());
 
-        assertEquals(time, ze.getTime());
-        assertEquals(time, ze.getLastModifiedTime().toMillis());
-        assertNull(ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID));
+        assertEquals(time.toMillis(), ze.getTime());
+        assertEquals(time, ze.getLastModifiedTime());
+        final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID);
+        assertNotNull(extendedTimestamp);
+        assertEquals(TimeUtils.toUnixTime(time), extendedTimestamp.getModifyTime().getValue());
+        assertNull(extendedTimestamp.getAccessTime());
+        assertNull(extendedTimestamp.getCreateTime());
         final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID);
         assertNotNull(ntfs);
         assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue());
-        assertEquals(TimeUtils.toNtfsTime(accessTime), ntfs.getAccessTime().getLongValue());
-        assertEquals(TimeUtils.toNtfsTime(creationTime), ntfs.getCreateTime().getLongValue());
+        assertEquals(0L, ntfs.getAccessTime().getLongValue());
+        assertEquals(0L, ntfs.getCreateTime().getLongValue());
+    }
+
+    @Test
+    public void testShouldSetExtraDateFieldsIfModifyDateIsExplicitlySet() {
+        final ZipArchiveEntry ze = new ZipArchiveEntry();
+        final FileTime time = FileTime.from(Instant.parse("2022-12-28T20:39:33.1234567Z"));
+        ze.setLastModifiedTime(time);
+
+        assertEquals(time.toMillis(), ze.getTime());
+        assertEquals(time, ze.getLastModifiedTime());
+        final X5455_ExtendedTimestamp extendedTimestamp = (X5455_ExtendedTimestamp) ze.getExtraField(X5455_ExtendedTimestamp.HEADER_ID);
+        assertNotNull(extendedTimestamp);
+        assertEquals(TimeUtils.toUnixTime(time), extendedTimestamp.getModifyTime().getValue());
+        assertNull(extendedTimestamp.getAccessTime());
+        assertNull(extendedTimestamp.getCreateTime());
+        final X000A_NTFS ntfs = (X000A_NTFS) ze.getExtraField(X000A_NTFS.HEADER_ID);
+        assertNotNull(ntfs);
+        assertEquals(TimeUtils.toNtfsTime(time), ntfs.getModifyTime().getLongValue());
+        assertEquals(0L, ntfs.getAccessTime().getLongValue());
+        assertEquals(0L, ntfs.getCreateTime().getLongValue());
+    }
+
+    @Test
+    public void testUnixMode() {
+        ZipArchiveEntry ze = new ZipArchiveEntry("foo");
+        assertEquals(0, ze.getPlatform());
+        ze.setUnixMode(0755);
+        assertEquals(3, ze.getPlatform());
+        assertEquals(0755,
+                     (ze.getExternalAttributes() >> 16) & 0xFFFF);
+        assertEquals(0, ze.getExternalAttributes()  & 0xFFFF);
+
+        ze.setUnixMode(0444);
+        assertEquals(3, ze.getPlatform());
+        assertEquals(0444,
+                     (ze.getExternalAttributes() >> 16) & 0xFFFF);
+        assertEquals(1, ze.getExternalAttributes()  & 0xFFFF);
+
+        ze = new ZipArchiveEntry("foo/");
+        assertEquals(0, ze.getPlatform());
+        ze.setUnixMode(0777);
+        assertEquals(3, ze.getPlatform());
+        assertEquals(0777,
+                     (ze.getExternalAttributes() >> 16) & 0xFFFF);
+        assertEquals(0x10, ze.getExternalAttributes()  & 0xFFFF);
+
+        ze.setUnixMode(0577);
+        assertEquals(3, ze.getPlatform());
+        assertEquals(0577,
+                     (ze.getExternalAttributes() >> 16) & 0xFFFF);
+        assertEquals(0x11, ze.getExternalAttributes()  & 0xFFFF);
+    }
+
+    @Test
+    public void testZipArchiveClone() throws Exception {
+        try (ZipFile zf = new ZipFile(getFile("COMPRESS-479.zip"))) {
+            final ZipArchiveEntry ze = zf.getEntry("%U20AC_for_Dollar.txt");
+            final ZipArchiveEntry clonedZe = (ZipArchiveEntry) ze.clone();
+            assertEquals(ze, clonedZe);
+        }
     }
 }
diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/ZipUtilTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/ZipUtilTest.java
index f0cc3dd2..eaed76e6 100644
--- a/src/test/java/org/apache/commons/compress/archivers/zip/ZipUtilTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/zip/ZipUtilTest.java
@@ -37,7 +37,28 @@ import org.junit.jupiter.api.Test;
 
 public class ZipUtilTest {
 
+    static void assertDosDate(
+            final long value,
+            final int year,
+            final int month,
+            final int day,
+            final int hour,
+            final int minute,
+            final int second) {
+        int pos = 0;
+        assertEquals((year - 1980), ((int) (value << pos)) >>> (32 - 7));
+        assertEquals(month, ((int) (value << (pos += 7))) >>> (32 - 4));
+        assertEquals(day, ((int) (value << (pos += 4))) >>> (32 - 5));
+        assertEquals(hour, ((int) (value << (pos += 5))) >>> (32 - 5));
+        assertEquals(minute, ((int) (value << (pos += 5))) >>> (32 - 6));
+        assertEquals(second, ((int) (value << (pos + 6))) >>> (32 - 5) << 1); // DOS dates only store even seconds
+    }
+    static Instant toLocalInstant(final String date) {
+        return LocalDateTime.parse(date).atZone(ZoneId.systemDefault()).toInstant();
+    }
+
     private Date time;
+
     private ZipLong zl;
 
     @BeforeEach
@@ -122,6 +143,12 @@ public class ZipUtilTest {
         assertEquals(65, b1[2]);
         assertEquals(10, b1[3]);
     }
+    @Test
+    public void testInsideCalendar_bigValue(){
+        final long date = toLocalInstant("2097-11-27T23:59:59").toEpochMilli();
+        final long value = ZipLong.getValue(ZipUtil.toDosTime(date));
+        assertDosDate(value, 2097, 11, 27, 23, 59, 58); // DOS dates only store even seconds
+    }
 
     @Test
     public void testInsideCalendar_long(){
@@ -136,11 +163,13 @@ public class ZipUtilTest {
         final long value = ZipLong.getValue(ZipUtil.toDosTime(date));
         assertDosDate(value, 2022, 12, 27, 16, 18, 22); // DOS dates only store even seconds
     }
+
     @Test
-    public void testInsideCalendar_bigValue(){
-        final long date = toLocalInstant("2097-11-27T23:59:59").toEpochMilli();
-        final long value = ZipLong.getValue(ZipUtil.toDosTime(date));
-        assertDosDate(value, 2097, 11, 27, 23, 59, 58); // DOS dates only store even seconds
+    public void testIsDosTime(){
+        assertFalse(ZipUtil.isDosTime(toLocalInstant("1975-01-31T23:00:00").toEpochMilli()));
+        assertTrue(ZipUtil.isDosTime(toLocalInstant("1980-01-03T00:00:00").toEpochMilli()));
+        assertTrue(ZipUtil.isDosTime(toLocalInstant("2097-11-27T00:00:00").toEpochMilli()));
+        assertFalse(ZipUtil.isDosTime(toLocalInstant("2099-01-01T00:00:00").toEpochMilli()));
     }
 
     @Test
@@ -194,35 +223,6 @@ public class ZipUtilTest {
         assertDosDate(value, 1980, 1, 1, 0, 0, 0);
     }
 
-    @Test
-    public void testIsDosTime(){
-        assertFalse(ZipUtil.isDosTime(toLocalInstant("1975-01-31T23:00:00").toEpochMilli()));
-        assertTrue(ZipUtil.isDosTime(toLocalInstant("1980-01-03T00:00:00").toEpochMilli()));
-        assertTrue(ZipUtil.isDosTime(toLocalInstant("2097-11-27T00:00:00").toEpochMilli()));
-        assertFalse(ZipUtil.isDosTime(toLocalInstant("2099-01-01T00:00:00").toEpochMilli()));
-    }
-
-    static void assertDosDate(
-            final long value,
-            final int year,
-            final int month,
-            final int day,
-            final int hour,
-            final int minute,
-            final int second) {
-        int pos = 0;
-        assertEquals((year - 1980), ((int) (value << pos)) >>> (32 - 7));
-        assertEquals(month, ((int) (value << (pos += 7))) >>> (32 - 4));
-        assertEquals(day, ((int) (value << (pos += 4))) >>> (32 - 5));
-        assertEquals(hour, ((int) (value << (pos += 5))) >>> (32 - 5));
-        assertEquals(minute, ((int) (value << (pos += 5))) >>> (32 - 6));
-        assertEquals(second, ((int) (value << (pos + 6))) >>> (32 - 5) << 1); // DOS dates only store even seconds
-    }
-
-    static Instant toLocalInstant(final String date) {
-        return LocalDateTime.parse(date).atZone(ZoneId.systemDefault()).toInstant();
-    }
-
     @Test
     public void testReverse() {
         final byte[][] bTest = new byte[6][];
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java
index 3c003fa5..1187dc82 100755
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java
@@ -49,8 +49,17 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 public class ArchiveTest {
 
+    static Stream<Arguments> loadMultipleJars() throws URISyntaxException, IOException {
+        return Files.list(Paths.get(Archive.class.getResource("/pack200/jars").toURI()))
+                .filter(child -> {
+                    final String fileName = child.getFileName().toString();
+                    return fileName.endsWith(".jar") && !fileName.endsWith("Unpacked.jar");
+                })
+                .map(Arguments::of);
+    }
     JarFile in;
     OutputStream out;
+
     File file;
 
     private void compareFiles(final JarFile jarFile, final JarFile jarFile2)
@@ -294,15 +303,6 @@ public class ArchiveTest {
         compareFiles(jarFile, jarFile2);
     }
 
-    static Stream<Arguments> loadMultipleJars() throws URISyntaxException, IOException {
-        return Files.list(Paths.get(Archive.class.getResource("/pack200/jars").toURI()))
-                .filter(child -> {
-                    final String fileName = child.getFileName().toString();
-                    return fileName.endsWith(".jar") && !fileName.endsWith("Unpacked.jar");
-                })
-                .map(Arguments::of);
-    }
-
     @ParameterizedTest
     @MethodSource("loadMultipleJars")
     public void testMultipleJars(final Path path) throws URISyntaxException, IOException, Pack200Exception {
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/BHSDCodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/BHSDCodecTest.java
index 71d1ff5d..42a57db2 100644
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/BHSDCodecTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/BHSDCodecTest.java
@@ -39,6 +39,10 @@ import org.junit.jupiter.params.provider.MethodSource;
  */
 public class BHSDCodecTest {
 
+    static Stream<Arguments> encodeDecodeRange() {
+        return IntStream.range(1, 116).mapToObj(Arguments::of);
+    }
+
     @Test
     public void testDeltaEncodings() throws IOException, Pack200Exception {
         final Codec c = Codec.UDELTA5;
@@ -50,10 +54,6 @@ public class BHSDCodecTest {
         }
     }
 
-    static Stream<Arguments> encodeDecodeRange() {
-        return IntStream.range(1, 116).mapToObj(Arguments::of);
-    }
-
     @ParameterizedTest
     @MethodSource("encodeDecodeRange")
     public void testEncodeDecode(final int i) throws IOException, Pack200Exception {
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java
index d3ebe43c..ea2ba4ab 100644
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java
@@ -49,18 +49,6 @@ public class CodecEncodingTest {
         );
     }
 
-    @ParameterizedTest
-    @MethodSource("arbitraryCodec")
-    public void testArbitraryCodec(final String expected, final byte[] bytes) throws IOException, Pack200Exception {
-        assertEquals(expected, CodecEncoding.getCodec(116, new ByteArrayInputStream(bytes), null).toString());
-    }
-
-    @Test
-    public void testDefaultCodec() throws Pack200Exception, IOException {
-        final Codec defaultCodec = new BHSDCodec(2, 16, 0, 0);
-        assertEquals(defaultCodec, CodecEncoding.getCodec(0, null, defaultCodec));
-    }
-
     // These are the canonical encodings specified by the Pack200 spec
     static Stream<Arguments> canonicalEncodings() {
         return Stream.of(
@@ -182,12 +170,45 @@ public class CodecEncodingTest {
         );
     }
 
+    // Test canonical codecs
+    static Stream<Arguments> canonicalGetSpecifier() {
+        return IntStream.range(1, 115).mapToObj(Arguments::of);
+    }
+
+    static Stream<Arguments> specifier() {
+        return Stream.of(
+                Arguments.of(new BHSDCodec(2, 125, 0, 1)),
+                Arguments.of(new BHSDCodec(3, 125, 2, 1)),
+                Arguments.of(new BHSDCodec(4, 125)),
+                Arguments.of(new BHSDCodec(5, 125, 2, 0)),
+                Arguments.of(new BHSDCodec(3, 5, 2, 1))
+        );
+    }
+
+    @ParameterizedTest
+    @MethodSource("arbitraryCodec")
+    public void testArbitraryCodec(final String expected, final byte[] bytes) throws IOException, Pack200Exception {
+        assertEquals(expected, CodecEncoding.getCodec(116, new ByteArrayInputStream(bytes), null).toString());
+    }
+
     @ParameterizedTest
     @MethodSource("canonicalEncodings")
     void testCanonicalEncodings(final int i, final String expectedCodec) throws IOException, Pack200Exception {
         assertEquals(expectedCodec, CodecEncoding.getCodec(i, null, null).toString());
     }
 
+    @ParameterizedTest
+    @MethodSource("canonicalGetSpecifier")
+    public void testCanonicalGetSpecifier(final int i) throws Pack200Exception, IOException {
+        assertEquals(i, CodecEncoding.getSpecifier(CodecEncoding.getCodec(i, null, null), null)[0]);
+    }
+
+    @Test
+    public void testDefaultCodec() throws Pack200Exception, IOException {
+        final Codec defaultCodec = new BHSDCodec(2, 16, 0, 0);
+        assertEquals(defaultCodec, CodecEncoding.getCodec(0, null, defaultCodec));
+    }
+
     @Test
     public void testGetSpeciferForPopulationCodec() throws IOException, Pack200Exception {
         final PopulationCodec pCodec = new PopulationCodec(Codec.BYTE1, Codec.CHAR3, Codec.UNSIGNED5);
@@ -275,27 +296,6 @@ public class CodecEncodingTest {
         assertEquals(bCodec.getBCodec(), bCodec2.getBCodec());
     }
 
-    // Test canonical codecs
-    static Stream<Arguments> canonicalGetSpecifier() {
-        return IntStream.range(1, 115).mapToObj(Arguments::of);
-    }
-
-    @ParameterizedTest
-    @MethodSource("canonicalGetSpecifier")
-    public void testCanonicalGetSpecifier(final int i) throws Pack200Exception, IOException {
-        assertEquals(i, CodecEncoding.getSpecifier(CodecEncoding.getCodec(i, null, null), null)[0]);
-    }
-
-    static Stream<Arguments> specifier() {
-        return Stream.of(
-                Arguments.of(new BHSDCodec(2, 125, 0, 1)),
-                Arguments.of(new BHSDCodec(3, 125, 2, 1)),
-                Arguments.of(new BHSDCodec(4, 125)),
-                Arguments.of(new BHSDCodec(5, 125, 2, 0)),
-                Arguments.of(new BHSDCodec(3, 5, 2, 1))
-        );
-    }
-
     @ParameterizedTest
     @MethodSource("specifier")
     void testGetSpecifier(final Codec c1) throws IOException, Pack200Exception {
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecTest.java
index bdb06288..eb1d6f3d 100644
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecTest.java
@@ -43,6 +43,38 @@ import org.junit.jupiter.params.provider.MethodSource;
  */
 public class CodecTest {
 
+    static Stream<Arguments> bCodings(){
+        return IntStream.rangeClosed(1, 5).mapToObj(Arguments::of);
+    }
+
+    static Stream<Arguments> codecFamily() {
+        return Stream.of(
+                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs1),
+                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs2),
+                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs3),
+                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs4),
+                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs5),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs1),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs2),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs3),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs4),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs5),
+                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs1),
+                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs2),
+                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaDoubleSignedCodecs1),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs1),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs2),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs3),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs4),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs5),
+                Arguments.of((Object) CanonicalCodecFamilies.deltaDoubleSignedCodecs1)
+        );
+    }
+
+    static Stream<Arguments> hCodings() {
+        return IntStream.range(0, 256).mapToObj(Arguments::of);
+    }
+
     private long decode(final Codec codec, final byte[] data, final long value,
             final long last) throws IOException, Pack200Exception {
         final ByteArrayInputStream in = new ByteArrayInputStream(data);
@@ -56,6 +88,16 @@ public class CodecTest {
         assertThrowsExactly(EOFException.class, () -> decode(codec, data, 0, 0), "Should have detected an EOFException");
     }
 
+    @ParameterizedTest
+    @MethodSource("bCodings")
+    public void testBCodings(final int i) {
+        if (i == 5) {
+            assertThrows(IllegalArgumentException.class, () -> new BHSDCodec(i, 256));
+        } else {
+            assertDoesNotThrow(() -> new BHSDCodec(i, 256));
+        }
+    }
+
     @Test
     public void testByte1() throws Exception {
         for (int i = 0; i < 255; i++) {
@@ -154,30 +196,6 @@ public class CodecTest {
         assertFalse(byte2s.encodes(256));
     }
 
-    static Stream<Arguments> codecFamily() {
-        return Stream.of(
-                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs1),
-                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs2),
-                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs3),
-                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs4),
-                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaUnsignedCodecs5),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs1),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs2),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs3),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs4),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaUnsignedCodecs5),
-                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs1),
-                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaSignedCodecs2),
-                Arguments.of((Object) CanonicalCodecFamilies.nonDeltaDoubleSignedCodecs1),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs1),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs2),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs3),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs4),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaSignedCodecs5),
-                Arguments.of((Object) CanonicalCodecFamilies.deltaDoubleSignedCodecs1)
-        );
-    }
-
     @ParameterizedTest
     @MethodSource("codecFamily")
     public void testCodecFamilies(final BHSDCodec[] family) {
@@ -206,30 +224,12 @@ public class CodecTest {
         assertEquals("(5,64,2,1)", Codec.MDELTA5.toString());
     }
 
-    static Stream<Arguments> hCodings() {
-        return IntStream.range(0, 256).mapToObj(Arguments::of);
-    }
-
     @ParameterizedTest
     @MethodSource("hCodings")
     public void testInvalidHCodings(final int i) {
         assertThrows(IllegalArgumentException.class, () -> new BHSDCodec(1, i), "b=1 -> h=256");
     }
 
-    static Stream<Arguments> bCodings(){
-        return IntStream.rangeClosed(1, 5).mapToObj(Arguments::of);
-    }
-
-    @ParameterizedTest
-    @MethodSource("bCodings")
-    public void testBCodings(final int i) {
-        if (i == 5) {
-            assertThrows(IllegalArgumentException.class, () -> new BHSDCodec(i, 256));
-        } else {
-            assertDoesNotThrow(() -> new BHSDCodec(i, 256));
-        }
-    }
-
     @Test
     public void testUnsigned5() throws Exception {
         decode(Codec.UNSIGNED5, new byte[] { 1 }, 1, 0);
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java
index d3edd889..1a0d65f8 100644
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java
@@ -34,14 +34,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 public class PopulationCodecTest {
 
-    @Test
-    public void testEncodeSingleValue() {
-        assertThrows(Pack200Exception.class, () -> new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5),
-                "Should not allow a single value to be encoded as we don't know which codec to use");
-        assertThrows(Pack200Exception.class, () -> new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5, 8),
-                "Should not allow a single value to be encoded as we don't know which codec to use");
-    }
-
     static Stream<Arguments> populationCodec() {
         return Stream.of(
                 Arguments.of(new byte[] { 4, 5, 6, 4, 2, 1, 3, 0, 7 }, new long[] { 5, 4, 6, 7 }, Codec.BYTE1),
@@ -60,6 +52,14 @@ public class PopulationCodecTest {
         );
     }
 
+    @Test
+    public void testEncodeSingleValue() {
+        assertThrows(Pack200Exception.class, () -> new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5),
+                "Should not allow a single value to be encoded as we don't know which codec to use");
+        assertThrows(Pack200Exception.class, () -> new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5, 8),
+                "Should not allow a single value to be encoded as we don't know which codec to use");
+    }
+
     @ParameterizedTest
     @MethodSource("populationCodec")
     public void testPopulationCodec(final byte[] data, final long[] expectedResult, final Codec codec) throws IOException, Pack200Exception {
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java
index da37b2fb..504f79fd 100644
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java
@@ -36,6 +36,15 @@ import org.junit.jupiter.params.provider.MethodSource;
  */
 public class RunCodecTest {
 
+    static Stream<Arguments> runCodec() {
+        return Stream.of(
+                Arguments.of(0, Codec.SIGNED5, Codec.UDELTA5, "Should not allow a k value of 0"),
+                Arguments.of(10, null, Codec.UDELTA5, "Should not allow a null codec"),
+                Arguments.of(10, Codec.UDELTA5, null, "Should not allow a null codec"),
+                Arguments.of(10, null, null, "Should not allow a null codec")
+        );
+    }
+
     @Test
     public void testDecode() throws Exception {
         RunCodec runCodec = new RunCodec(1, Codec.UNSIGNED5, Codec.BYTE1);
@@ -131,15 +140,6 @@ public class RunCodecTest {
         }
     }
 
-    static Stream<Arguments> runCodec() {
-        return Stream.of(
-                Arguments.of(0, Codec.SIGNED5, Codec.UDELTA5, "Should not allow a k value of 0"),
-                Arguments.of(10, null, Codec.UDELTA5, "Should not allow a null codec"),
-                Arguments.of(10, Codec.UDELTA5, null, "Should not allow a null codec"),
-                Arguments.of(10, null, null, "Should not allow a null codec")
-        );
-    }
-
     @ParameterizedTest
     @MethodSource("runCodec")
     public void testRunCodec(final int k, final Codec aCodec, final Codec bCodec, final String failureMessage) {
diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/AttributeLayoutTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/AttributeLayoutTest.java
index e2b4d05c..72a66512 100644
--- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/AttributeLayoutTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/AttributeLayoutTest.java
@@ -84,10 +84,15 @@ public class AttributeLayoutTest {
         );
     }
 
-    @ParameterizedTest
-    @MethodSource("badData")
-    public void testBadData(final String name, final int context, final String layout) {
-        assertThrows(Pack200Exception.class, () -> new AttributeLayout(name, context, layout, -1));
+    static Stream<Arguments> codec() {
+        return Stream.of(
+                Arguments.of("O", AttributeLayout.CONTEXT_CLASS, "HOBS", Codec.BRANCH5),
+                Arguments.of("P", AttributeLayout.CONTEXT_METHOD, "PIN", Codec.BCI5),
+                Arguments.of("S", AttributeLayout.CONTEXT_FIELD, "HS", Codec.SIGNED5),
+                Arguments.of("RS", AttributeLayout.CONTEXT_CODE, "RRRS", Codec.UNSIGNED5),
+                Arguments.of("KS", AttributeLayout.CONTEXT_CLASS, "RKS", Codec.UNSIGNED5),
+                Arguments.of("B", AttributeLayout.CONTEXT_CLASS, "TRKSB", Codec.BYTE1)
+        );
     }
 
     static Stream<Arguments> okData() {
@@ -100,20 +105,9 @@ public class AttributeLayoutTest {
     }
 
     @ParameterizedTest
-    @MethodSource("okData")
-    public void testOkData(final String name, final int context, final String layout) {
-        assertDoesNotThrow(() -> new AttributeLayout(name, context, layout, -1));
-    }
-
-    static Stream<Arguments> codec() {
-        return Stream.of(
-                Arguments.of("O", AttributeLayout.CONTEXT_CLASS, "HOBS", Codec.BRANCH5),
-                Arguments.of("P", AttributeLayout.CONTEXT_METHOD, "PIN", Codec.BCI5),
-                Arguments.of("S", AttributeLayout.CONTEXT_FIELD, "HS", Codec.SIGNED5),
-                Arguments.of("RS", AttributeLayout.CONTEXT_CODE, "RRRS", Codec.UNSIGNED5),
-                Arguments.of("KS", AttributeLayout.CONTEXT_CLASS, "RKS", Codec.UNSIGNED5),
-                Arguments.of("B", AttributeLayout.CONTEXT_CLASS, "TRKSB", Codec.BYTE1)
-        );
+    @MethodSource("badData")
+    public void testBadData(final String name, final int context, final String layout) {
+        assertThrows(Pack200Exception.class, () -> new AttributeLayout(name, context, layout, -1));
     }
 
     @ParameterizedTest
@@ -162,4 +156,10 @@ public class AttributeLayoutTest {
         assertEquals("Zero", ((CPUTF8)layout.getValue(1, segment.getConstantPool())).underlyingString());
         assertEquals("One", ((CPUTF8)layout.getValue(2, segment.getConstantPool())).underlyingString());
     }
+
+    @ParameterizedTest
+    @MethodSource("okData")
+    public void testOkData(final String name, final int context, final String layout) {
+        assertDoesNotThrow(() -> new AttributeLayout(name, context, layout, -1));
+    }
 }
diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ICTupleTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ICTupleTest.java
index cd63c2fd..bb7547fc 100644
--- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ICTupleTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ICTupleTest.java
@@ -36,6 +36,15 @@ public class ICTupleTest {
         );
     }
 
+    static Stream<Arguments> predicted() {
+        return Stream.of(
+                Arguments.of("orw/SimpleHelloWorld$SimpleHelloWorldInner", "SimpleHelloWorldInner", "orw/SimpleHelloWorld"),
+                Arguments.of("java/util/AbstractList$2$Local", "Local", "java/util/AbstractList$2"),
+                Arguments.of("java/util/AbstractList#2#Local", "Local", "java/util/AbstractList$2"),
+                Arguments.of("java/util/AbstractList$1", "1", "java/util/AbstractList")
+        );
+    }
+
     @ParameterizedTest
     @MethodSource("explicit")
     public void testExplicitClassTupleParsing(final String c, final String c2, final String n, final String expectedSimpleClassName, final String expectedOuterClass) {
@@ -46,15 +55,6 @@ public class ICTupleTest {
         );
     }
 
-    static Stream<Arguments> predicted() {
-        return Stream.of(
-                Arguments.of("orw/SimpleHelloWorld$SimpleHelloWorldInner", "SimpleHelloWorldInner", "orw/SimpleHelloWorld"),
-                Arguments.of("java/util/AbstractList$2$Local", "Local", "java/util/AbstractList$2"),
-                Arguments.of("java/util/AbstractList#2#Local", "Local", "java/util/AbstractList$2"),
-                Arguments.of("java/util/AbstractList$1", "1", "java/util/AbstractList")
-        );
-    }
-
     @ParameterizedTest
     @MethodSource("predicted")
     public void testPredictedClassTupleParsing(final String c, final String expectedSimpleClass, final String expectedOuterClass) {
diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentUtilsTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentUtilsTest.java
index 1eeca2ab..1eecb6d2 100644
--- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentUtilsTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentUtilsTest.java
@@ -60,12 +60,6 @@ public class SegmentUtilsTest {
         );
     }
 
-    @ParameterizedTest
-    @MethodSource("countArgs")
-    public void testCountArgs(final String descriptor, final int expectedArgsCount) {
-        assertEquals(expectedArgsCount, SegmentUtils.countArgs(descriptor));
-    }
-
     static Stream<Arguments> countInvokeInterfaceArgs() {
         return Stream.of(
                 Arguments.of("(Z)V", 1),
@@ -80,6 +74,12 @@ public class SegmentUtilsTest {
         );
     }
 
+    @ParameterizedTest
+    @MethodSource("countArgs")
+    public void testCountArgs(final String descriptor, final int expectedArgsCount) {
+        assertEquals(expectedArgsCount, SegmentUtils.countArgs(descriptor));
+    }
+
     @ParameterizedTest
     @MethodSource("countInvokeInterfaceArgs")
     public void testCountInvokeInterfaceArgs(final String descriptor, final int expectedCountInvokeInterfaceArgs) {
diff --git a/src/test/java/org/apache/commons/compress/utils/TimeUtilsTest.java b/src/test/java/org/apache/commons/compress/utils/TimeUtilsTest.java
index 9aff262f..1c7de4da 100644
--- a/src/test/java/org/apache/commons/compress/utils/TimeUtilsTest.java
+++ b/src/test/java/org/apache/commons/compress/utils/TimeUtilsTest.java
@@ -80,6 +80,14 @@ public class TimeUtilsTest {
         );
     }
 
+    public static Stream<Arguments> fileTimeToUnixTimeArguments() {
+        return Stream.of(
+                Arguments.of(0L, "1970-01-01T00:00:00Z"),
+                Arguments.of(1672141989L, "2022-12-27T11:53:09Z"),
+                Arguments.of(Integer.MAX_VALUE, "2038-01-19T03:14:07Z")
+        );
+    }
+
     public static Stream<Arguments> truncateFileTimeProvider() {
         return Stream.of(
                 Arguments.of(
@@ -117,6 +125,17 @@ public class TimeUtilsTest {
         );
     }
 
+    @Test
+    public void shouldCheckWhetherTimeCanBeRepresentedAsUnixTime() {
+        assertTrue(TimeUtils.isUnixTime(null));
+        assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2022-12-27T12:45:22Z"))));
+        assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:07Z"))));
+        assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T23:14:08Z"))));
+        assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T03:14:08Z"))));
+        assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:08Z"))));
+        assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2099-06-30T12:31:42Z"))));
+    }
+
     @ParameterizedTest
     @MethodSource("dateToNtfsProvider")
     public void shouldConvertDateToFileTime(final String instant, final long ignored) {
@@ -153,6 +172,12 @@ public class TimeUtilsTest {
         assertEquals(ntfsTime, toNtfsTime(parsed));
     }
 
+    @ParameterizedTest
+    @MethodSource("fileTimeToUnixTimeArguments")
+    public void shouldConvertFileTimeToUnixTime(final long expectedUnixTime, final String instant) {
+        assertEquals(expectedUnixTime, TimeUtils.toUnixTime(FileTime.from(Instant.parse(instant))));
+    }
+
     @ParameterizedTest
     @MethodSource("dateToNtfsProvider")
     public void shouldConvertNtfsTimeToDate(final String instant, final long ntfsTime) {
@@ -179,6 +204,12 @@ public class TimeUtilsTest {
         assertNull(toDate(null));
     }
 
+    @ParameterizedTest
+    @MethodSource("fileTimeToUnixTimeArguments")
+    public void shouldConvertUnixTimeToFileTime(final long unixTime, final String expectedInstant) {
+        assertEquals(Instant.parse(expectedInstant), TimeUtils.unixTimeToFileTime(unixTime).toInstant());
+    }
+
     @ParameterizedTest
     @MethodSource("truncateFileTimeProvider")
     public void shouldTruncateFileTimeToHundredNanos(final String original, final String truncated) {
@@ -186,35 +217,4 @@ public class TimeUtilsTest {
         final FileTime truncatedTime = FileTime.from(Instant.parse(truncated));
         assertEquals(truncatedTime, TimeUtils.truncateToHundredNanos(originalTime));
     }
-
-    @Test
-    public void shouldCheckWhetherTimeCanBeRepresentedAsUnixTime() {
-        assertTrue(TimeUtils.isUnixTime(null));
-        assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2022-12-27T12:45:22Z"))));
-        assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:07Z"))));
-        assertTrue(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T23:14:08Z"))));
-        assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("1901-12-13T03:14:08Z"))));
-        assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2038-01-19T03:14:08Z"))));
-        assertFalse(TimeUtils.isUnixTime(FileTime.from(Instant.parse("2099-06-30T12:31:42Z"))));
-    }
-
-    public static Stream<Arguments> fileTimeToUnixTimeArguments() {
-        return Stream.of(
-                Arguments.of(0L, "1970-01-01T00:00:00Z"),
-                Arguments.of(1672141989L, "2022-12-27T11:53:09Z"),
-                Arguments.of(Integer.MAX_VALUE, "2038-01-19T03:14:07Z")
-        );
-    }
-
-    @ParameterizedTest
-    @MethodSource("fileTimeToUnixTimeArguments")
-    public void shouldConvertFileTimeToUnixTime(final long expectedUnixTime, final String instant) {
-        assertEquals(expectedUnixTime, TimeUtils.toUnixTime(FileTime.from(Instant.parse(instant))));
-    }
-
-    @ParameterizedTest
-    @MethodSource("fileTimeToUnixTimeArguments")
-    public void shouldConvertUnixTimeToFileTime(final long unixTime, final String expectedInstant) {
-        assertEquals(Instant.parse(expectedInstant), TimeUtils.unixTimeToFileTime(unixTime).toInstant());
-    }
 }