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

cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-indexer.git


The following commit(s) were added to refs/heads/master by this push:
     new 45d5438  [MINDEXER-152] Simplify/rework IndexReader API (#254)
45d5438 is described below

commit 45d543886ede172878898c8cc3894633092bb0e4
Author: Tamas Cservenak <[email protected]>
AuthorDate: Fri Oct 14 22:01:37 2022 +0200

    [MINDEXER-152] Simplify/rework IndexReader API (#254)
    
    For now remove the not-so-helpful generic that was bad, update Javadoc...
    Let's see for more later. Also remove uused Guava.
    
    Biggest change: no "resource" is auto closed, it is all responsibility of 
code using reader.
    
    ---
    
    https://issues.apache.org/jira/browse/MINDEXER-152
---
 indexer-reader/pom.xml                             |   5 -
 .../org/apache/maven/index/reader/ChunkReader.java |  30 ++-
 .../org/apache/maven/index/reader/ChunkWriter.java |  27 +-
 .../org/apache/maven/index/reader/IndexReader.java |  89 ++++---
 .../org/apache/maven/index/reader/IndexWriter.java |  57 ++--
 .../java/org/apache/maven/index/reader/Record.java | 170 ++++++++----
 .../apache/maven/index/reader/RecordCompactor.java |  76 +++---
 .../apache/maven/index/reader/RecordExpander.java  |   4 +-
 .../apache/maven/index/reader/ResourceHandler.java |  24 +-
 .../java/org/apache/maven/index/reader/Utils.java  |  62 ++---
 .../index/reader/WritableResourceHandler.java      |  15 +-
 .../index/reader/resource/BufferedResource.java    |  11 +-
 .../reader/resource/BufferedResourceHandler.java   |   5 +-
 .../resource/BufferedWritableResourceHandler.java  |   5 +-
 .../reader/resource/PathWritableResource.java      |   5 +-
 .../resource/PathWritableResourceHandler.java      |  11 +-
 .../index/reader/resource/UriResourceHandler.java  |  10 +-
 .../maven/index/reader/CachingResourceHandler.java |   1 -
 .../apache/maven/index/reader/ChunkReaderTest.java |  65 ++---
 .../index/reader/DirectoryResourceHandler.java     |  85 +++---
 .../maven/index/reader/HttpResourceHandler.java    |  80 +++---
 .../apache/maven/index/reader/IndexReaderTest.java | 287 ++++++++++-----------
 .../apache/maven/index/reader/IndexWriterTest.java | 101 +++-----
 .../org/apache/maven/index/reader/TestSupport.java |  73 ++----
 .../org/apache/maven/index/reader/TestUtils.java   | 118 +++++----
 .../apache/maven/index/reader/TransformTest.java   | 117 +++++----
 pom.xml                                            |   6 -
 27 files changed, 789 insertions(+), 750 deletions(-)

diff --git a/indexer-reader/pom.xml b/indexer-reader/pom.xml
index fb7875b..9535ec1 100644
--- a/indexer-reader/pom.xml
+++ b/indexer-reader/pom.xml
@@ -58,11 +58,6 @@ under the License.
       <artifactId>jmock</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
   <build>
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkReader.java 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkReader.java
index c42c4ea..d344bb5 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkReader.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkReader.java
@@ -34,12 +34,14 @@ import java.util.NoSuchElementException;
 import java.util.zip.GZIPInputStream;
 
 /**
- * Maven 2 Index published binary chunk reader, it reads raw Maven Indexer 
records from the transport binary format.
+ * Maven Index published binary chunk reader, it reads raw Maven Indexer 
records from the transport binary format.
+ * Instances of this class MUST BE handled as resources (have them closed once 
done with them), it is user
+ * responsibility to close them, ideally in try-with-resource block.
  *
  * @since 5.1.2
  */
 public class ChunkReader
-    implements Closeable, Iterable<Map<String, String>>
+        implements Closeable, Iterable<Map<String, String>>
 {
     private final String chunkName;
 
@@ -49,8 +51,9 @@ public class ChunkReader
 
     private final Date timestamp;
 
-    public ChunkReader( final String chunkName, final InputStream inputStream )
-        throws IOException
+    public ChunkReader( final String chunkName,
+                        final InputStream inputStream )
+            throws IOException
     {
         this.chunkName = chunkName.trim();
         this.dataInputStream = new DataInputStream( new GZIPInputStream( 
inputStream, 2 * 1024 ) );
@@ -85,6 +88,7 @@ public class ChunkReader
     /**
      * Returns the {@link Record} iterator.
      */
+    @Override
     public Iterator<Map<String, String>> iterator()
     {
         try
@@ -100,8 +104,9 @@ public class ChunkReader
     /**
      * Closes this reader and it's underlying input.
      */
+    @Override
     public void close()
-        throws IOException
+            throws IOException
     {
         dataInputStream.close();
     }
@@ -110,24 +115,26 @@ public class ChunkReader
      * Low memory footprint index iterator that incrementally parses the 
underlying stream.
      */
     private static class IndexIterator
-        implements Iterator<Map<String, String>>
+            implements Iterator<Map<String, String>>
     {
         private final DataInputStream dataInputStream;
 
         private Map<String, String> nextRecord;
 
         private IndexIterator( final DataInputStream dataInputStream )
-            throws IOException
+                throws IOException
         {
             this.dataInputStream = dataInputStream;
             this.nextRecord = nextRecord();
         }
 
+        @Override
         public boolean hasNext()
         {
             return nextRecord != null;
         }
 
+        @Override
         public Map<String, String> next()
         {
             if ( nextRecord == null )
@@ -139,6 +146,7 @@ public class ChunkReader
             return result;
         }
 
+        @Override
         public void remove()
         {
             throw new UnsupportedOperationException( "remove" );
@@ -161,7 +169,7 @@ public class ChunkReader
      * Reads and returns next record from the underlying stream, or {@code 
null} if no more records.
      */
     private static Map<String, String> readRecord( final DataInput dataInput )
-        throws IOException
+            throws IOException
     {
         int fieldCount;
         try
@@ -182,7 +190,7 @@ public class ChunkReader
     }
 
     private static void readField( final Map<String, String> record, final 
DataInput dataInput )
-        throws IOException
+            throws IOException
     {
         dataInput.readByte(); // flags: neglect them
         String name = dataInput.readUTF();
@@ -191,7 +199,7 @@ public class ChunkReader
     }
 
     private static String readUTF( final DataInput dataInput )
-        throws IOException
+            throws IOException
     {
         int utflen = dataInput.readInt();
 
@@ -273,7 +281,7 @@ public class ChunkReader
                         throw new UTFDataFormatException( "malformed input 
around byte " + ( count - 1 ) );
                     }
                     chararr[chararrCount++] =
-                        (char) ( ( ( c & 0x0F ) << 12 ) | ( ( char2 & 0x3F ) 
<< 6 ) | ( char3 & 0x3F ) );
+                            (char) ( ( ( c & 0x0F ) << 12 ) | ( ( char2 & 0x3F 
) << 6 ) | ( char3 & 0x3F ) );
                     break;
 
                 default:
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkWriter.java 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkWriter.java
index c3c8e18..3261c3b 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkWriter.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/ChunkWriter.java
@@ -30,12 +30,14 @@ import java.util.Map;
 import java.util.zip.GZIPOutputStream;
 
 /**
- * Maven 2 Index published binary chunk writer, it writes raw Maven Indexer 
records to the transport binary format.
+ * Maven Index published binary chunk writer, it writes raw Maven Indexer 
records to the transport binary format.
+ * Instances of this class MUST BE handled as resources (have them closed once 
done with them), it is user
+ * responsibility to close them, ideally in try-with-resource block.
  *
  * @since 5.1.2
  */
 public class ChunkWriter
-    implements Closeable
+        implements Closeable
 {
     private static final int F_INDEXED = 1;
 
@@ -51,9 +53,11 @@ public class ChunkWriter
 
     private final Date timestamp;
 
-    public ChunkWriter( final String chunkName, final OutputStream 
outputStream, final int version,
+    public ChunkWriter( final String chunkName,
+                        final OutputStream outputStream,
+                        final int version,
                         final Date timestamp )
-        throws IOException
+            throws IOException
     {
         this.chunkName = chunkName.trim();
         this.dataOutputStream = new DataOutputStream( new GZIPOutputStream( 
outputStream, 2 * 1024 ) );
@@ -92,7 +96,7 @@ public class ChunkWriter
      * Writes out the record iterator and returns the written record count.
      */
     public int writeChunk( final Iterator<Map<String, String>> iterator )
-        throws IOException
+            throws IOException
     {
         int written = 0;
         while ( iterator.hasNext() )
@@ -106,14 +110,15 @@ public class ChunkWriter
     /**
      * Closes this reader and it's underlying input.
      */
+    @Override
     public void close()
-        throws IOException
+            throws IOException
     {
         dataOutputStream.close();
     }
 
     private static void writeRecord( final Map<String, String> record, final 
DataOutput dataOutput )
-        throws IOException
+            throws IOException
     {
         dataOutput.writeInt( record.size() );
         for ( Map.Entry<String, String> entry : record.entrySet() )
@@ -123,12 +128,12 @@ public class ChunkWriter
     }
 
     private static void writeField( final String fieldName, final String 
fieldValue, final DataOutput dataOutput )
-        throws IOException
+            throws IOException
     {
         boolean isIndexed = !( fieldName.equals( "i" ) || fieldName.equals( 
"m" ) );
         boolean isTokenized =
-            !( fieldName.equals( "i" ) || fieldName.equals( "m" ) || 
fieldName.equals( "1" ) || fieldName.equals(
-                "px" ) );
+                !( fieldName.equals( "i" ) || fieldName.equals( "m" ) || 
fieldName.equals( "1" ) || fieldName.equals(
+                        "px" ) );
         int flags = ( isIndexed ? F_INDEXED : 0 ) + ( isTokenized ? 
F_TOKENIZED : 0 ) + F_STORED;
         dataOutput.writeByte( flags );
         dataOutput.writeUTF( fieldName );
@@ -136,7 +141,7 @@ public class ChunkWriter
     }
 
     private static void writeUTF( final String str, final DataOutput 
dataOutput )
-        throws IOException
+            throws IOException
     {
         int strlen = str.length();
         int utflen = 0;
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexReader.java 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexReader.java
index 6b34b36..702608f 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexReader.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexReader.java
@@ -19,31 +19,39 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import org.apache.maven.index.reader.ResourceHandler.Resource;
-
 import java.io.Closeable;
 import java.io.IOException;
+import java.io.UncheckedIOException;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Objects;
 import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.maven.index.reader.ResourceHandler.Resource;
 
+import static java.util.Objects.requireNonNull;
 import static org.apache.maven.index.reader.Utils.loadProperties;
 import static org.apache.maven.index.reader.Utils.storeProperties;
 
 /**
- * Maven 2 Index reader that handles incremental updates if possible and 
provides one or more {@link ChunkReader}s, to
- * read all the required records.
+ * Maven Index reader that handles incremental updates, if possible, and 
provides one or more {@link ChunkReader}s, to
+ * read all the required records. Instances of this class MUST BE handled as 
resources (have them closed once done with
+ * them), it is user responsibility to close them, ideally in 
try-with-resource block.
+ * <p>
+ * Every involved instance, this {@link IndexReader}, provided {@link 
ChunkReader}, and used  {@link ResourceHandler}s
+ * are {@link Closeable}, and all have to be explicitly closed, best in 
try-with-resource.
  *
  * @since 5.1.2
  */
 public class IndexReader
-    implements Iterable<ChunkReader>, Closeable
+        implements Iterable<ChunkReader>, Closeable
 {
+    private final AtomicBoolean closed;
+
     private final WritableResourceHandler local;
 
     private final ResourceHandler remote;
@@ -60,10 +68,12 @@ public class IndexReader
 
     private final List<String> chunkNames;
 
-    public IndexReader( final WritableResourceHandler local, final 
ResourceHandler remote )
-        throws IOException
+    public IndexReader( final WritableResourceHandler local,
+                        final ResourceHandler remote )
+            throws IOException
     {
-        Objects.requireNonNull( remote, "remote resource handler null" );
+        requireNonNull( remote, "remote resource handler null" );
+        this.closed = new AtomicBoolean( false );
         this.local = local;
         this.remote = remote;
         remoteIndexProperties = loadProperties( remote.locate( 
Utils.INDEX_FILE_PREFIX + ".properties" ) );
@@ -85,8 +95,8 @@ public class IndexReader
                     if ( remoteIndexId == null || !remoteIndexId.equals( 
localIndexId ) )
                     {
                         throw new IllegalArgumentException(
-                            "local and remote index IDs does not match or is 
null: " + localIndexId + ", "
-                                + remoteIndexId );
+                                "local and remote index IDs does not match or 
is null: " + localIndexId + ", "
+                                        + remoteIndexId );
                     }
                     this.indexId = localIndexId;
                     this.incremental = canRetrieveAllChunks();
@@ -105,7 +115,7 @@ public class IndexReader
                 this.incremental = false;
             }
             this.publishedTimestamp =
-                Utils.INDEX_DATE_FORMAT.parse( 
remoteIndexProperties.getProperty( "nexus.index.timestamp" ) );
+                    Utils.INDEX_DATE_FORMAT.parse( 
remoteIndexProperties.getProperty( "nexus.index.timestamp" ) );
             this.chunkNames = calculateChunkNames();
         }
         catch ( ParseException e )
@@ -157,19 +167,23 @@ public class IndexReader
      * method should NOT be invoked, but rather the {@link ResourceHandler}s 
that caller provided in constructor of
      * this class should be closed manually.
      */
+    @Override
     public void close()
-        throws IOException
+            throws IOException
     {
-        remote.close();
-        if ( local != null )
+        if ( closed.compareAndSet( false, true ) )
         {
-            try
-            {
-                syncLocalWithRemote();
-            }
-            finally
+            remote.close();
+            if ( local != null )
             {
-                local.close();
+                try
+                {
+                    syncLocalWithRemote();
+                }
+                finally
+                {
+                    local.close();
+                }
             }
         }
     }
@@ -179,6 +193,8 @@ public class IndexReader
      * updates from the index. It is caller responsibility to either consume 
fully this iterator, or to close current
      * {@link ChunkReader} if aborting.
      */
+
+    @Override
     public Iterator<ChunkReader> iterator()
     {
         return new ChunkReaderIterator( remote, chunkNames.iterator() );
@@ -189,7 +205,7 @@ public class IndexReader
      * for future incremental updates.
      */
     private void syncLocalWithRemote()
-        throws IOException
+            throws IOException
     {
         storeProperties( local.locate( Utils.INDEX_FILE_PREFIX + ".properties" 
), remoteIndexProperties );
     }
@@ -234,7 +250,7 @@ public class IndexReader
         try
         {
             int localLastIncremental =
-                Integer.parseInt( localIndexProperties.getProperty( 
"nexus.index.last-incremental" ) );
+                    Integer.parseInt( localIndexProperties.getProperty( 
"nexus.index.last-incremental" ) );
             String currentLocalCounter = String.valueOf( localLastIncremental 
);
             String nextLocalCounter = String.valueOf( localLastIncremental + 1 
);
             // check remote props for existence of current or next chunk after 
local
@@ -263,52 +279,41 @@ public class IndexReader
      * is being consumed.
      */
     private static class ChunkReaderIterator
-        implements Iterator<ChunkReader>
+            implements Iterator<ChunkReader>
     {
         private final ResourceHandler resourceHandler;
 
         private final Iterator<String> chunkNamesIterator;
 
-        private ChunkReader currentChunkReader;
-
-        private ChunkReaderIterator( final ResourceHandler resourceHandler, 
final Iterator<String> chunkNamesIterator )
+        private ChunkReaderIterator( final ResourceHandler resourceHandler,
+                                     final Iterator<String> chunkNamesIterator 
)
         {
             this.resourceHandler = resourceHandler;
             this.chunkNamesIterator = chunkNamesIterator;
-            this.currentChunkReader = null;
         }
 
+        @Override
         public boolean hasNext()
         {
-            try
-            {
-                if ( currentChunkReader != null )
-                {
-                    currentChunkReader.close();
-                }
-            }
-            catch ( IOException e )
-            {
-                throw new RuntimeException( "IO problem while closing chunk 
readers", e );
-            }
             return chunkNamesIterator.hasNext();
         }
 
+        @Override
         public ChunkReader next()
         {
             String chunkName = chunkNamesIterator.next();
             try
             {
                 Resource currentResource = resourceHandler.locate( chunkName );
-                currentChunkReader = new ChunkReader( chunkName, 
currentResource.read() );
-                return currentChunkReader;
+                return new ChunkReader( chunkName, currentResource.read() );
             }
             catch ( IOException e )
             {
-                throw new RuntimeException( "IO problem while opening chunk 
readers", e );
+                throw new UncheckedIOException( "IO problem while opening 
chunk readers", e );
             }
         }
 
+        @Override
         public void remove()
         {
             throw new UnsupportedOperationException( "remove" );
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexWriter.java 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexWriter.java
index c470411..03aeeb7 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexWriter.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/IndexWriter.java
@@ -19,34 +19,39 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import org.apache.maven.index.reader.WritableResourceHandler.WritableResource;
-
 import java.io.Closeable;
 import java.io.IOException;
 import java.text.ParseException;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Properties;
 import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.maven.index.reader.WritableResourceHandler.WritableResource;
 
+import static java.util.Objects.requireNonNull;
 import static org.apache.maven.index.reader.Utils.loadProperties;
 import static org.apache.maven.index.reader.Utils.storeProperties;
 
 /**
- * Maven 2 Index writer that writes chunk and maintains published property 
file.
+ * Maven Index writer that writes chunk and maintains published property file. 
Instances of this class MUST BE handled
+ * as resources (have them closed once done with them), it is user 
responsibility to close them, ideally in
+ * try-with-resource block.
  * <p/>
- * <strong>Currently no incremental update is supported, as the deleteion 
states should be maintained by
+ * <strong>Currently no incremental update is supported, as the deletion 
states should be maintained by
  * caller</strong>. Hence, this writer will always produce the "main" chunk 
only.
  *
  * @since 5.1.2
  */
 public class IndexWriter
-    implements Closeable
+        implements Closeable
 {
     private static final int INDEX_V1 = 1;
 
+    private final AtomicBoolean closed;
+
     private final WritableResourceHandler local;
 
     private final Properties localIndexProperties;
@@ -57,11 +62,14 @@ public class IndexWriter
 
     private final String nextChunkName;
 
-    public IndexWriter( final WritableResourceHandler local, final String 
indexId, final boolean incrementalSupported )
-        throws IOException
+    public IndexWriter( final WritableResourceHandler local,
+                        final String indexId,
+                        final boolean incrementalSupported )
+            throws IOException
     {
-        Objects.requireNonNull( local, "local resource handler null" );
-        Objects.requireNonNull( indexId, "indexId null" );
+        requireNonNull( local, "local resource handler null" );
+        requireNonNull( indexId, "indexId null" );
+        this.closed = new AtomicBoolean( false );
         this.local = local;
         Properties indexProperties = loadProperties( local.locate( 
Utils.INDEX_FILE_PREFIX + ".properties" ) );
         if ( incrementalSupported && indexProperties != null )
@@ -72,7 +80,7 @@ public class IndexWriter
             if ( localIndexId == null || !localIndexId.equals( indexId ) )
             {
                 throw new IllegalArgumentException(
-                    "index already exists and indexId mismatch or unreadable: 
" + localIndexId + ", " + indexId );
+                        "index already exists and indexId mismatch or 
unreadable: " + localIndexId + ", " + indexId );
             }
             this.incremental = true;
             this.nextChunkCounter = calculateNextChunkCounter();
@@ -149,7 +157,7 @@ public class IndexWriter
      * Writes out the record iterator and returns the written record count.
      */
     public int writeChunk( final Iterator<Map<String, String>> iterator )
-        throws IOException
+            throws IOException
     {
         int written;
 
@@ -174,21 +182,26 @@ public class IndexWriter
      * method should NOT be invoked, but rather the {@link ResourceHandler} 
that caller provided in constructor of
      * this class should be closed manually.
      */
+    @Override
     public void close()
-        throws IOException
+            throws IOException
     {
-        try
+        if ( closed.compareAndSet( false, true ) )
         {
-            if ( incremental )
+            try
             {
-                localIndexProperties.setProperty( 
"nexus.index.last-incremental", nextChunkCounter );
+                if ( incremental )
+                {
+                    localIndexProperties.setProperty( 
"nexus.index.last-incremental", nextChunkCounter );
+                }
+                localIndexProperties.setProperty( "nexus.index.timestamp",
+                        Utils.INDEX_DATE_FORMAT.format( new Date() ) );
+                storeProperties( local.locate( Utils.INDEX_FILE_PREFIX + 
".properties" ), localIndexProperties );
+            }
+            finally
+            {
+                local.close();
             }
-            localIndexProperties.setProperty( "nexus.index.timestamp", 
Utils.INDEX_DATE_FORMAT.format( new Date() ) );
-            storeProperties( local.locate( Utils.INDEX_FILE_PREFIX + 
".properties" ), localIndexProperties );
-        }
-        finally
-        {
-            local.close();
         }
     }
 
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/Record.java 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/Record.java
index c87bc0c..571cc79 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/Record.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/Record.java
@@ -22,8 +22,10 @@ package org.apache.maven.index.reader;
 import java.util.Map;
 import java.util.Objects;
 
+import static java.util.Objects.requireNonNull;
+
 /**
- * Maven 2 Index record.
+ * Maven Index record.
  *
  * @since 5.1.2
  */
@@ -31,31 +33,29 @@ public final class Record
 {
     /**
      * Entry key is field key with some metadata.
-     *
-     * @param <T> The type of the value belonging to this key instance.
      */
-    public static final class EntryKey<T>
+    public static final class EntryKey
     {
         private final String name;
 
-        private final Class<T> proto;
+        private final Class<?> proto;
 
-        public EntryKey( final String name, final Class<T> proto )
+        public EntryKey( final String name, final Class<?> proto )
         {
-            Objects.requireNonNull( name, "name is null" );
-            Objects.requireNonNull( proto, "proto is null" );
+            requireNonNull( name, "name is null" );
+            requireNonNull( proto, "proto is null" );
             this.name = name;
             this.proto = proto;
         }
 
-        public T coerce( final Object object )
+        public String getName()
         {
-            return proto.cast( object );
+            return name;
         }
 
-        public String getName()
+        public Class<?> getProto()
         {
-            return name;
+            return proto;
         }
 
         @Override
@@ -69,7 +69,7 @@ public final class Record
             {
                 return false;
             }
-            EntryKey<?> entryKey = (EntryKey<?>) o;
+            EntryKey entryKey = (EntryKey) o;
             return Objects.equals( name, entryKey.name );
         }
 
@@ -89,203 +89,203 @@ public final class Record
     /**
      * Key of repository ID entry, that contains {@link String}.
      */
-    public static final EntryKey<String> REPOSITORY_ID = new EntryKey<>( 
"repositoryId", String.class );
+    public static final EntryKey REPOSITORY_ID = new EntryKey( "repositoryId", 
String.class );
 
     /**
      * Key of all groups list entry, that contains {@link 
java.util.List<String>}.
      */
-    public static final EntryKey<String[]> ALL_GROUPS = new EntryKey<>( 
"allGroups", String[].class );
+    public static final EntryKey ALL_GROUPS = new EntryKey( "allGroups", 
String[].class );
 
     /**
      * Key of root groups list entry, that contains {@link 
java.util.List<String>}.
      */
-    public static final EntryKey<String[]> ROOT_GROUPS = new EntryKey<>( 
"rootGroups", String[].class );
+    public static final EntryKey ROOT_GROUPS = new EntryKey( "rootGroups", 
String[].class );
 
     /**
      * Key of index record modification (added to index or removed from index) 
timestamp entry, that contains {@link
      * Long}.
      */
-    public static final EntryKey<Long> REC_MODIFIED = new EntryKey<>( 
"recordModified", Long.class );
+    public static final EntryKey REC_MODIFIED = new EntryKey( 
"recordModified", Long.class );
 
     /**
      * Key of artifact groupId entry, that contains {@link String}.
      */
-    public static final EntryKey<String> GROUP_ID = new EntryKey<>( "groupId", 
String.class );
+    public static final EntryKey GROUP_ID = new EntryKey( "groupId", 
String.class );
 
     /**
      * Key of artifact artifactId entry, that contains {@link String}.
      */
-    public static final EntryKey<String> ARTIFACT_ID = new EntryKey<>( 
"artifactId", String.class );
+    public static final EntryKey ARTIFACT_ID = new EntryKey( "artifactId", 
String.class );
 
     /**
      * Key of artifact version entry, that contains {@link String}.
      */
-    public static final EntryKey<String> VERSION = new EntryKey<>( "version", 
String.class );
+    public static final EntryKey VERSION = new EntryKey( "version", 
String.class );
 
     /**
      * Key of artifact classifier entry, that contains {@link String}.
      */
-    public static final EntryKey<String> CLASSIFIER = new EntryKey<>( 
"classifier", String.class );
+    public static final EntryKey CLASSIFIER = new EntryKey( "classifier", 
String.class );
 
     /**
      * Key of artifact packaging entry, that contains {@link String}.
      */
-    public static final EntryKey<String> PACKAGING = new EntryKey<>( 
"packaging", String.class );
+    public static final EntryKey PACKAGING = new EntryKey( "packaging", 
String.class );
 
     /**
      * Key of artifact file extension, that contains {@link String}.
      */
-    public static final EntryKey<String> FILE_EXTENSION = new EntryKey<>( 
"fileExtension", String.class );
+    public static final EntryKey FILE_EXTENSION = new EntryKey( 
"fileExtension", String.class );
 
     /**
      * Key of artifact file last modified timestamp, that contains {@link 
Long}.
      */
-    public static final EntryKey<Long> FILE_MODIFIED = new EntryKey<>( 
"fileModified", Long.class );
+    public static final EntryKey FILE_MODIFIED = new EntryKey( "fileModified", 
Long.class );
 
     /**
      * Key of artifact file size in bytes, that contains {@link Long}.
      */
-    public static final EntryKey<Long> FILE_SIZE = new EntryKey<>( "fileSize", 
Long.class );
+    public static final EntryKey FILE_SIZE = new EntryKey( "fileSize", 
Long.class );
 
     /**
      * Key of artifact Sources presence flag, that contains {@link Boolean}.
      */
-    public static final EntryKey<Boolean> HAS_SOURCES = new EntryKey<>( 
"hasSources", Boolean.class );
+    public static final EntryKey HAS_SOURCES = new EntryKey( "hasSources", 
Boolean.class );
 
     /**
      * Key of artifact Javadoc presence flag, that contains {@link Boolean}.
      */
-    public static final EntryKey<Boolean> HAS_JAVADOC = new EntryKey<>( 
"hasJavadoc", Boolean.class );
+    public static final EntryKey HAS_JAVADOC = new EntryKey( "hasJavadoc", 
Boolean.class );
 
     /**
      * Key of artifact signature presence flag, that contains {@link Boolean}.
      */
-    public static final EntryKey<Boolean> HAS_SIGNATURE = new EntryKey<>( 
"hasSignature", Boolean.class );
+    public static final EntryKey HAS_SIGNATURE = new EntryKey( "hasSignature", 
Boolean.class );
 
     /**
      * Key of artifact name (as set in POM), that contains {@link String}.
      */
-    public static final EntryKey<String> NAME = new EntryKey<>( "name", 
String.class );
+    public static final EntryKey NAME = new EntryKey( "name", String.class );
 
     /**
      * Key of artifact description (as set in POM), that contains {@link 
String}.
      */
-    public static final EntryKey<String> DESCRIPTION = new EntryKey<>( 
"description", String.class );
+    public static final EntryKey DESCRIPTION = new EntryKey( "description", 
String.class );
 
     /**
      * Key of artifact SHA1 digest, that contains {@link String}.
      */
-    public static final EntryKey<String> SHA1 = new EntryKey<>( "sha1", 
String.class );
+    public static final EntryKey SHA1 = new EntryKey( "sha1", String.class );
 
     /**
      * Key of artifact contained class names, that contains {@link 
java.util.List<String>}. Extracted by {@code
      * JarFileContentsIndexCreator}.
      */
-    public static final EntryKey<String[]> CLASSNAMES = new EntryKey<>( 
"classNames", String[].class );
+    public static final EntryKey CLASSNAMES = new EntryKey( "classNames", 
String[].class );
 
     /**
      * Key of plugin artifact prefix, that contains {@link String}. Extracted 
by {@code
      * MavenPluginArtifactInfoIndexCreator}.
      */
-    public static final EntryKey<String> PLUGIN_PREFIX = new EntryKey<>( 
"pluginPrefix", String.class );
+    public static final EntryKey PLUGIN_PREFIX = new EntryKey( "pluginPrefix", 
String.class );
 
     /**
      * Key of plugin artifact goals, that contains {@link 
java.util.List<String>}. Extracted by {@code
      * MavenPluginArtifactInfoIndexCreator}.
      */
-    public static final EntryKey<String[]> PLUGIN_GOALS = new EntryKey<>( 
"pluginGoals", String[].class );
+    public static final EntryKey PLUGIN_GOALS = new EntryKey( "pluginGoals", 
String[].class );
 
     /**
      * Key of OSGi "Bundle-SymbolicName" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_BUNDLE_SYMBOLIC_NAME = new 
EntryKey<>( "Bundle-SymbolicName",
+    public static final EntryKey OSGI_BUNDLE_SYMBOLIC_NAME = new EntryKey( 
"Bundle-SymbolicName",
             String.class );
 
     /**
      * Key of OSGi "Bundle-Version" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_BUNDLE_VERSION = new EntryKey<>( 
"Bundle-Version", String.class );
+    public static final EntryKey OSGI_BUNDLE_VERSION = new EntryKey( 
"Bundle-Version", String.class );
 
     /**
      * Key of OSGi "Export-Package" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_EXPORT_PACKAGE = new EntryKey<>( 
"Export-Package", String.class );
+    public static final EntryKey OSGI_EXPORT_PACKAGE = new EntryKey( 
"Export-Package", String.class );
 
     /**
      * Key of OSGi "Export-Service" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_EXPORT_SERVICE = new EntryKey<>( 
"Export-Service", String.class );
+    public static final EntryKey OSGI_EXPORT_SERVICE = new EntryKey( 
"Export-Service", String.class );
 
     /**
      * Key of OSGi "Bundle-Description" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_BUNDLE_DESCRIPTION = new 
EntryKey<>( "Bundle-Description", String.class );
+    public static final EntryKey OSGI_BUNDLE_DESCRIPTION = new EntryKey( 
"Bundle-Description", String.class );
 
     /**
      * Key of OSGi "Bundle-Name" manifest entry, that contains {@link String}. 
Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_BUNDLE_NAME = new EntryKey<>( 
"Bundle-Name", String.class );
+    public static final EntryKey OSGI_BUNDLE_NAME = new EntryKey( 
"Bundle-Name", String.class );
 
     /**
      * Key of OSGi "Bundle-License" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_BUNDLE_LICENSE = new EntryKey<>( 
"Bundle-License", String.class );
+    public static final EntryKey OSGI_BUNDLE_LICENSE = new EntryKey( 
"Bundle-License", String.class );
 
     /**
      * Key of OSGi "Bundle-DocURL" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_EXPORT_DOCURL = new EntryKey<>( 
"Bundle-DocURL", String.class );
+    public static final EntryKey OSGI_EXPORT_DOCURL = new EntryKey( 
"Bundle-DocURL", String.class );
 
     /**
      * Key of OSGi "Import-Package" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_IMPORT_PACKAGE = new EntryKey<>( 
"Import-Package", String.class );
+    public static final EntryKey OSGI_IMPORT_PACKAGE = new EntryKey( 
"Import-Package", String.class );
 
     /**
      * Key of OSGi "Require-Bundle" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_REQUIRE_BUNDLE = new EntryKey<>( 
"Require-Bundle", String.class );
+    public static final EntryKey OSGI_REQUIRE_BUNDLE = new EntryKey( 
"Require-Bundle", String.class );
 
     /**
      * Key of OSGi "Provide-Capability" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_PROVIDE_CAPABILITY = new 
EntryKey<>( "Provide-Capability", String.class );
+    public static final EntryKey OSGI_PROVIDE_CAPABILITY = new EntryKey( 
"Provide-Capability", String.class );
 
     /**
      * Key of OSGi "Require-Capability" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_REQUIRE_CAPABILITY = new 
EntryKey<>( "Require-Capability", String.class );
+    public static final EntryKey OSGI_REQUIRE_CAPABILITY = new EntryKey( 
"Require-Capability", String.class );
 
     /**
      * Key of OSGi "Fragment-Host" manifest entry, that contains {@link 
String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_FRAGMENT_HOST = new EntryKey<>( 
"Fragment-Host", String.class );
+    public static final EntryKey OSGI_FRAGMENT_HOST = new EntryKey( 
"Fragment-Host", String.class );
 
     /**
      * Key of deprecated OSGi "Bundle-RequiredExecutionEnvironment" manifest 
entry, that contains {@link String}.
      * Extracted by {@code OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> OSGI_BREE = new EntryKey<>( 
"Bundle-RequiredExecutionEnvironment",
+    public static final EntryKey OSGI_BREE = new EntryKey( 
"Bundle-RequiredExecutionEnvironment",
             String.class );
 
     /**
      * Key for SHA-256 checksum  needed for OSGI content capability that 
contains {@link String}. Extracted by {@code
      * OsgiArtifactIndexCreator}.
      */
-    public static final EntryKey<String> SHA_256 = new EntryKey<>( "sha256", 
String.class );
+    public static final EntryKey SHA_256 = new EntryKey( "sha256", 
String.class );
 
 
     /**
@@ -395,7 +395,7 @@ public final class Record
     /**
      * Returns {@code true} if this record contains given {@link EntryKey}.
      */
-    boolean containsKey( final EntryKey<?> entryKey )
+    boolean containsKey( final EntryKey entryKey )
     {
         return expanded.containsKey( entryKey );
     }
@@ -403,19 +403,79 @@ public final class Record
     /**
      * Type safe handy method to get value from expanded map.
      */
-    public <T> T get( final EntryKey<T> entryKey )
+    public Object get( final EntryKey entryKey )
+    {
+        return expanded.get( entryKey );
+    }
+
+    /**
+     * Type safe handy method to get string value from expanded map.
+     *
+     * @since TBD
+     */
+    public String getString( final EntryKey entryKey )
+    {
+        if ( !String.class.isAssignableFrom( entryKey.proto ) )
+        {
+            throw new IllegalArgumentException( "Key " + entryKey
+                    + " does not hold type compatible to java.lang.String" );
+        }
+        return (String) expanded.get( entryKey );
+    }
+
+    /**
+     * Type safe handy method to get String[] value from expanded map.
+     *
+     * @since TBD
+     */
+    public String[] getStringArray( final EntryKey entryKey )
+    {
+        if ( !String[].class.isAssignableFrom( entryKey.proto ) )
+        {
+            throw new IllegalArgumentException( "Key " + entryKey
+                    + " does not hold type compatible to java.lang.String[]" );
+        }
+        return (String[]) expanded.get( entryKey );
+    }
+
+    /**
+     * Type safe handy method to get Long value from expanded map.
+     *
+     * @since TBD
+     */
+    public Long getLong( final EntryKey entryKey )
     {
-        return entryKey.coerce( expanded.get( entryKey ) );
+        if ( !Long.class.isAssignableFrom( entryKey.proto ) )
+        {
+            throw new IllegalArgumentException( "Key " + entryKey
+                    + " does not hold type compatible to java.lang.Long" );
+        }
+        return (Long) expanded.get( entryKey );
+    }
+
+    /**
+     * Type safe handy method to get Boolean value from expanded map.
+     *
+     * @since TBD
+     */
+    public Boolean getBoolean( final EntryKey entryKey )
+    {
+        if ( !Boolean.class.isAssignableFrom( entryKey.proto ) )
+        {
+            throw new IllegalArgumentException( "Key " + entryKey
+                    + " does not hold type compatible to java.lang.Boolean" );
+        }
+        return (Boolean) expanded.get( entryKey );
     }
 
     /**
      * Type safe handy method to put value to expanded map. Accepts {@code 
null} values, that removes the mapping.
      */
-    public <T> T put( final EntryKey<T> entryKey, final T value )
+    public Object put( final EntryKey entryKey, final Object value )
     {
         if ( value == null )
         {
-            return entryKey.coerce( expanded.remove( entryKey ) );
+            return expanded.remove( entryKey );
         }
         else
         {
@@ -423,7 +483,7 @@ public final class Record
             {
                 throw new IllegalArgumentException( "Key " + entryKey + " does 
not accepts value " + value );
             }
-            return entryKey.coerce( expanded.put( entryKey, value ) );
+            return expanded.put( entryKey, value );
         }
     }
 
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordCompactor.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordCompactor.java
index 7e8f221..d07166c 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordCompactor.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordCompactor.java
@@ -31,7 +31,7 @@ import static org.apache.maven.index.reader.Utils.UINFO;
 import static org.apache.maven.index.reader.Utils.nvl;
 
 /**
- * Maven 2 Index record transformer, that transforms {@link Record}s into 
"native" Maven Indexer records.
+ * Maven Index record transformer, that transforms {@link Record}s into 
"native" Maven Indexer records.
  *
  * @since 5.1.2
  */
@@ -75,7 +75,7 @@ public class RecordCompactor
     {
         final Map<String, String> result = new HashMap<>();
         result.put( "DESCRIPTOR", "NexusIndex" );
-        result.put( "IDXINFO", "1.0|" + record.get( Record.REPOSITORY_ID ) );
+        result.put( "IDXINFO", "1.0|" + record.getString( Record.REPOSITORY_ID 
) );
         return result;
     }
 
@@ -83,7 +83,7 @@ public class RecordCompactor
     {
         final Map<String, String> result = new HashMap<>();
         result.put( "allGroups", "allGroups" );
-        putIfNotNullAsStringArray( record.get( Record.ALL_GROUPS ), result, 
"allGroupsList" );
+        putIfNotNullAsStringArray( record.getStringArray( Record.ALL_GROUPS ), 
result, "allGroupsList" );
         return result;
     }
 
@@ -91,14 +91,14 @@ public class RecordCompactor
     {
         final Map<String, String> result = new HashMap<>();
         result.put( "rootGroups", "allGroups" );
-        putIfNotNullAsStringArray( record.get( Record.ROOT_GROUPS ), result, 
"rootGroupsList" );
+        putIfNotNullAsStringArray( record.getStringArray( Record.ROOT_GROUPS 
), result, "rootGroupsList" );
         return result;
     }
 
     private static Map<String, String> compactDeletedArtifact( final Record 
record )
     {
         final Map<String, String> result = new HashMap<>();
-        putIfNotNullTS( record.get( Record.REC_MODIFIED ), result, "m" );
+        putIfNotNullTS( record.getLong( Record.REC_MODIFIED ), result, "m" );
         result.put( "del", compactUinfo( record ) );
         return result;
     }
@@ -113,42 +113,43 @@ public class RecordCompactor
         // Minimal
         result.put( UINFO, compactUinfo( record ) );
 
-        String info = nvl( record.get( Record.PACKAGING ) ) + FIELD_SEPARATOR 
+ record.get(
-                Record.FILE_MODIFIED ) + FIELD_SEPARATOR + record.get(
-                Record.FILE_SIZE ) + FIELD_SEPARATOR + ( record.get(
-                Record.HAS_SOURCES ) ? "1" : "0" ) + FIELD_SEPARATOR + ( 
record.get(
-                Record.HAS_JAVADOC ) ? "1" : "0" ) + FIELD_SEPARATOR + ( 
record.get(
-                Record.HAS_SIGNATURE ) ? "1" : "0" ) + FIELD_SEPARATOR + nvl( 
record.get( Record.FILE_EXTENSION ) );
+        String info = nvl( record.getString( Record.PACKAGING ) ) + 
FIELD_SEPARATOR
+                + record.getLong( Record.FILE_MODIFIED ) + FIELD_SEPARATOR
+                + record.getLong( Record.FILE_SIZE ) + FIELD_SEPARATOR
+                + ( record.getBoolean( Record.HAS_SOURCES ) ? "1" : "0" ) + 
FIELD_SEPARATOR
+                + ( record.getBoolean( Record.HAS_JAVADOC ) ? "1" : "0" ) + 
FIELD_SEPARATOR
+                + ( record.getBoolean( Record.HAS_SIGNATURE ) ? "1" : "0" ) + 
FIELD_SEPARATOR
+                + nvl( record.getString( Record.FILE_EXTENSION ) );
         result.put( INFO, info );
 
-        putIfNotNullTS( record.get( Record.REC_MODIFIED ), result, "m" );
-        putIfNotNull( record.get( Record.NAME ), result, "n" );
-        putIfNotNull( record.get( Record.DESCRIPTION ), result, "d" );
-        putIfNotNull( record.get( Record.SHA1 ), result, "1" );
+        putIfNotNullTS( record.getLong( Record.REC_MODIFIED ), result, "m" );
+        putIfNotNull( record.getString( Record.NAME ), result, "n" );
+        putIfNotNull( record.getString( Record.DESCRIPTION ), result, "d" );
+        putIfNotNull( record.getString( Record.SHA1 ), result, "1" );
 
         // Jar file contents (optional)
-        putIfNotNullAsStringArray( record.get( Record.CLASSNAMES ), result, 
"classnames" );
+        putIfNotNullAsStringArray( record.getStringArray( Record.CLASSNAMES ), 
result, "classnames" );
 
         // Maven Plugin (optional)
-        putIfNotNull( record.get( Record.PLUGIN_PREFIX ), result, "px" );
-        putIfNotNullAsStringArray( record.get( Record.PLUGIN_GOALS ), result, 
"gx" );
+        putIfNotNull( record.getString( Record.PLUGIN_PREFIX ), result, "px" );
+        putIfNotNullAsStringArray( record.getStringArray( Record.PLUGIN_GOALS 
), result, "gx" );
 
         // OSGi (optional)
-        putIfNotNull( record.get( Record.OSGI_BUNDLE_SYMBOLIC_NAME ), result, 
"Bundle-SymbolicName" );
-        putIfNotNull( record.get( Record.OSGI_BUNDLE_VERSION ), result, 
"Bundle-Version" );
-        putIfNotNull( record.get( Record.OSGI_EXPORT_PACKAGE ), result, 
"Export-Package" );
-        putIfNotNull( record.get( Record.OSGI_EXPORT_SERVICE ), result, 
"Export-Service" );
-        putIfNotNull( record.get( Record.OSGI_BUNDLE_DESCRIPTION ), result, 
"Bundle-Description" );
-        putIfNotNull( record.get( Record.OSGI_BUNDLE_NAME ), result, 
"Bundle-Name" );
-        putIfNotNull( record.get( Record.OSGI_BUNDLE_LICENSE ), result, 
"Bundle-License" );
-        putIfNotNull( record.get( Record.OSGI_EXPORT_DOCURL ), result, 
"Bundle-DocURL" );
-        putIfNotNull( record.get( Record.OSGI_IMPORT_PACKAGE ), result, 
"Import-Package" );
-        putIfNotNull( record.get( Record.OSGI_REQUIRE_BUNDLE ), result, 
"Require-Bundle" );
-        putIfNotNull( record.get( Record.OSGI_PROVIDE_CAPABILITY ), result, 
"Provide-Capability" );
-        putIfNotNull( record.get( Record.OSGI_REQUIRE_CAPABILITY ), result, 
"Require-Capability" );
-        putIfNotNull( record.get( Record.OSGI_FRAGMENT_HOST ), result, 
"Fragment-Host" );
-        putIfNotNull( record.get( Record.OSGI_BREE ), result, 
"Bundle-RequiredExecutionEnvironment" );
-        putIfNotNull( record.get( Record.SHA_256 ), result, "sha256" );
+        putIfNotNull( record.getString( Record.OSGI_BUNDLE_SYMBOLIC_NAME ), 
result, "Bundle-SymbolicName" );
+        putIfNotNull( record.getString( Record.OSGI_BUNDLE_VERSION ), result, 
"Bundle-Version" );
+        putIfNotNull( record.getString( Record.OSGI_EXPORT_PACKAGE ), result, 
"Export-Package" );
+        putIfNotNull( record.getString( Record.OSGI_EXPORT_SERVICE ), result, 
"Export-Service" );
+        putIfNotNull( record.getString( Record.OSGI_BUNDLE_DESCRIPTION ), 
result, "Bundle-Description" );
+        putIfNotNull( record.getString( Record.OSGI_BUNDLE_NAME ), result, 
"Bundle-Name" );
+        putIfNotNull( record.getString( Record.OSGI_BUNDLE_LICENSE ), result, 
"Bundle-License" );
+        putIfNotNull( record.getString( Record.OSGI_EXPORT_DOCURL ), result, 
"Bundle-DocURL" );
+        putIfNotNull( record.getString( Record.OSGI_IMPORT_PACKAGE ), result, 
"Import-Package" );
+        putIfNotNull( record.getString( Record.OSGI_REQUIRE_BUNDLE ), result, 
"Require-Bundle" );
+        putIfNotNull( record.getString( Record.OSGI_PROVIDE_CAPABILITY ), 
result, "Provide-Capability" );
+        putIfNotNull( record.getString( Record.OSGI_REQUIRE_CAPABILITY ), 
result, "Require-Capability" );
+        putIfNotNull( record.getString( Record.OSGI_FRAGMENT_HOST ), result, 
"Fragment-Host" );
+        putIfNotNull( record.getString( Record.OSGI_BREE ), result, 
"Bundle-RequiredExecutionEnvironment" );
+        putIfNotNull( record.getString( Record.SHA_256 ), result, "sha256" );
 
         return result;
     }
@@ -158,11 +159,10 @@ public class RecordCompactor
      */
     private static String compactUinfo( final Record record )
     {
-        final String classifier = record.get( Record.CLASSIFIER );
-        StringBuilder sb = new StringBuilder();
-        sb.append( record.get( Record.GROUP_ID ) ).append( FIELD_SEPARATOR 
).append(
-            record.get( Record.ARTIFACT_ID ) ).append( FIELD_SEPARATOR 
).append( record.get( Record.VERSION ) ).append(
-            FIELD_SEPARATOR ).append( nvl( classifier ) );
+        final String classifier = record.getString( Record.CLASSIFIER );
+        StringBuilder sb = new StringBuilder().append( record.getString( 
Record.GROUP_ID ) ).append( FIELD_SEPARATOR )
+                .append( record.getString( Record.ARTIFACT_ID ) ).append( 
FIELD_SEPARATOR )
+                .append( record.getString( Record.VERSION ) ).append( 
FIELD_SEPARATOR ).append( nvl( classifier ) );
         if ( classifier != null )
         {
             sb.append( FIELD_SEPARATOR ).append( record.get( 
Record.FILE_EXTENSION ) );
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordExpander.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordExpander.java
index 809f5b4..e0b0b84 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordExpander.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/RecordExpander.java
@@ -35,7 +35,7 @@ import static org.apache.maven.index.reader.Utils.renvl;
 
 
 /**
- * Maven 2 Index record transformer, that transforms "native" Maven Indexer 
records into {@link Record}s.
+ * Maven Index record transformer, that transforms "native" Maven Indexer 
records into {@link Record}s.
  *
  * @since 5.1.2
  */
@@ -143,7 +143,7 @@ public class RecordExpander
             }
             else
             {
-                final String packaging = Record.PACKAGING.coerce( result.get( 
Record.PACKAGING ) );
+                final String packaging = result.getString( Record.PACKAGING );
                 if ( result.containsKey( Record.CLASSIFIER ) || "pom".equals( 
packaging ) || "war".equals( packaging )
                     || "ear".equals( packaging ) )
                 {
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/ResourceHandler.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/ResourceHandler.java
index 111e872..1b6ec3d 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/ResourceHandler.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/ResourceHandler.java
@@ -24,7 +24,7 @@ import java.io.IOException;
 import java.io.InputStream;
 
 /**
- * Maven 2 Index resource abstraction, that should be handled as a resource 
(is {@link Closeable}. That means, that
+ * Maven Index resource abstraction, that should be handled as a resource (is 
{@link Closeable}. That means, that
  * implementations could perform any extra activity as FS locking or so (if 
uses FS as backing store). Is used by single
  * thread only.
  *
@@ -37,6 +37,7 @@ public interface ResourceHandler
      * Handle of content.
      */
     interface Resource
+        extends Closeable
     {
         /**
          * Returns the {@link InputStream} stream of the resource, if exists, 
{@code null} otherwise. The stream should
@@ -44,6 +45,15 @@ public interface ResourceHandler
          */
         InputStream read()
             throws IOException;
+
+        /**
+         * Default close method is no-op, override if implementation requires.
+         */
+        @Override
+        default void close() throws IOException
+        {
+            // nothing
+        }
     }
 
     /**
@@ -51,6 +61,14 @@ public interface ResourceHandler
      *
      * @param name Resource name, guaranteed to be non-{@code null} and is FS 
and URL safe string.
      */
-    Resource locate( String name )
-        throws IOException;
+    Resource locate( String name ) throws IOException;
+
+    /**
+     * Default close method is no-op, override if implementation requires.
+     */
+    @Override
+    default void close() throws IOException
+    {
+        // nothing
+    }
 }
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/Utils.java 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/Utils.java
index e6a9afc..855e26e 100644
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/Utils.java
+++ b/indexer-reader/src/main/java/org/apache/maven/index/reader/Utils.java
@@ -67,24 +67,6 @@ public final class Utils
 
     public static final Pattern FS_PATTERN = Pattern.compile( Pattern.quote( 
FIELD_SEPARATOR ) );
 
-    /**
-     * Creates and loads {@link Properties} from provided {@link InputStream} 
and closes the stream.
-     */
-    public static Properties loadProperties( final InputStream inputStream )
-        throws IOException
-    {
-        try
-        {
-            final Properties properties = new Properties();
-            properties.load( inputStream );
-            return properties;
-        }
-        finally
-        {
-            inputStream.close();
-        }
-    }
-
     /**
      * Creates and loads {@link Properties} from provided {@link Resource} if 
exists, and closes the resource. If not
      * exists, returns {@code null}.
@@ -92,44 +74,30 @@ public final class Utils
     public static Properties loadProperties( final Resource resource )
         throws IOException
     {
-        final InputStream inputStream = resource.read();
-        if ( inputStream == null )
+        try ( InputStream inputStream = resource.read() )
         {
-            return null;
-        }
-        return loadProperties( inputStream );
-    }
-
-    /**
-     * Saves {@link Properties} to provided {@link OutputStream} and closes 
the stream.
-     */
-    public static void storeProperties( final OutputStream outputStream, final 
Properties properties )
-        throws IOException
-    {
-        try
-        {
-            properties.store( outputStream, "Maven Indexer Writer" );
-        }
-        finally
-        {
-            outputStream.close();
+            if ( inputStream == null )
+            {
+                return null;
+            }
+            final Properties properties = new Properties();
+            properties.load( inputStream );
+            return properties;
         }
     }
 
-
     /**
      * Saves {@link Properties} to provided {@link WritableResource} and 
closes the resource.
      */
     public static void storeProperties( final WritableResource 
writableResource, final Properties properties )
         throws IOException
     {
-        try
-        {
-            storeProperties( writableResource.write(), properties );
-        }
-        finally
+        try ( writableResource )
         {
-            writableResource.close();
+            try ( OutputStream outputStream = writableResource.write() )
+            {
+                properties.store( outputStream, "Maven Indexer Writer" );
+            }
         }
     }
 
@@ -149,7 +117,7 @@ public final class Utils
     public static Record allGroups( final Collection<String> allGroups )
     {
         HashMap<EntryKey, Object> entries = new HashMap<>();
-        entries.put( Record.ALL_GROUPS, allGroups.toArray( new 
String[allGroups.size()] ) );
+        entries.put( Record.ALL_GROUPS, allGroups.toArray( new String[0] ) );
         return new Record( Type.ALL_GROUPS, entries );
     }
 
@@ -159,7 +127,7 @@ public final class Utils
     public static Record rootGroups( final Collection<String> rootGroups )
     {
         HashMap<EntryKey, Object> entries = new HashMap<>();
-        entries.put( Record.ROOT_GROUPS, rootGroups.toArray( new 
String[rootGroups.size()] ) );
+        entries.put( Record.ROOT_GROUPS, rootGroups.toArray( new String[0] ) );
         return new Record( Type.ROOT_GROUPS, entries );
     }
 
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/WritableResourceHandler.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/WritableResourceHandler.java
index 207b076..ed79239 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/WritableResourceHandler.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/WritableResourceHandler.java
@@ -19,12 +19,11 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.io.OutputStream;
 
 /**
- * Maven 2 Index writable {@link ResourceHandler}, is capable of saving 
resources too. Needed only if incremental index
+ * Maven Index writable {@link ResourceHandler}, is capable of saving 
resources too. Needed only if incremental index
  * updates are wanted, to store the index state locally, and be able to 
calculate incremental diffs on next {@link
  * IndexReader} invocation. Is used by single thread only.
  *
@@ -32,13 +31,13 @@ import java.io.OutputStream;
  * @since 5.1.2
  */
 public interface WritableResourceHandler
-    extends ResourceHandler
+        extends ResourceHandler
 {
     /**
      * Resource that is writable.
      */
     interface WritableResource
-        extends Resource, Closeable
+            extends Resource
     {
         /**
          * Returns the {@link OutputStream} stream of the resource, if exists, 
it will replace the existing content, or
@@ -48,16 +47,14 @@ public interface WritableResourceHandler
          * Implementation does not have to be "read consistent", in a way to 
worry what subsequent {@link #read()}
          * method will return, as mixed calls will not happen on same instance 
of resource.
          */
-        OutputStream write()
-            throws IOException;
+        OutputStream write() throws IOException;
     }
 
     /**
      * Returns the {@link WritableResource} with {@code name}. Returned 
locator should be handled as
-     * resource, is {@link Closeable}.
+     * resource.
      *
      * @param name Resource name, guaranteed to be non-{@code null} and is FS 
and URL safe string.
      */
-    WritableResource locate( String name )
-        throws IOException;
+    WritableResource locate( String name ) throws IOException;
 }
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedResource.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedResource.java
index bf3b60a..07899e6 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedResource.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedResource.java
@@ -22,10 +22,11 @@ package org.apache.maven.index.reader.resource;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Objects;
 
 import org.apache.maven.index.reader.ResourceHandler.Resource;
 
+import static java.util.Objects.requireNonNull;
+
 /**
  * Wraps {@link Resource}s so that they return {@link BufferedInputStream}s.
  */
@@ -35,7 +36,7 @@ public class BufferedResource implements Resource
 
     public BufferedResource( Resource resource )
     {
-        Objects.requireNonNull( resource, "resource cannot be null" );
+        requireNonNull( resource, "resource cannot be null" );
         this.resource = resource;
     }
 
@@ -49,4 +50,10 @@ public class BufferedResource implements Resource
         }
         return new BufferedInputStream( in );
     }
+
+    @Override
+    public void close() throws IOException
+    {
+        resource.close();
+    }
 }
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedResourceHandler.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedResourceHandler.java
index 3b065d6..9b86cde 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedResourceHandler.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedResourceHandler.java
@@ -21,10 +21,11 @@ package org.apache.maven.index.reader.resource;
 
 import java.io.BufferedInputStream;
 import java.io.IOException;
-import java.util.Objects;
 
 import org.apache.maven.index.reader.ResourceHandler;
 
+import static java.util.Objects.requireNonNull;
+
 /**
  * Wraps {@link ResourceHandler}s so that they return {@link Resource}s that 
return {@link
  * BufferedInputStream}s.
@@ -35,7 +36,7 @@ public class BufferedResourceHandler implements 
ResourceHandler
 
     public BufferedResourceHandler( ResourceHandler resourceHandler )
     {
-        Objects.requireNonNull( resourceHandler, "resourceHandler cannot be 
null" );
+        requireNonNull( resourceHandler, "resourceHandler cannot be null" );
         this.resourceHandler = resourceHandler;
     }
 
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedWritableResourceHandler.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedWritableResourceHandler.java
index 762b239..f9cc2b4 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedWritableResourceHandler.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/BufferedWritableResourceHandler.java
@@ -22,10 +22,11 @@ package org.apache.maven.index.reader.resource;
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.IOException;
-import java.util.Objects;
 
 import org.apache.maven.index.reader.WritableResourceHandler;
 
+import static java.util.Objects.requireNonNull;
+
 /**
  * Wraps {@link WritableResourceHandler}s so that they return {@link 
WritableResource}s that return
  * {@link BufferedInputStream}s and {@link BufferedOutputStream}s.
@@ -36,7 +37,7 @@ public class BufferedWritableResourceHandler implements 
WritableResourceHandler
 
     public BufferedWritableResourceHandler( WritableResourceHandler 
writableResourceHandler )
     {
-        Objects.requireNonNull( writableResourceHandler, 
"writableResourceHandler cannot be null" );
+        requireNonNull( writableResourceHandler, "writableResourceHandler 
cannot be null" );
         this.writableResourceHandler = writableResourceHandler;
     }
 
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/PathWritableResource.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/PathWritableResource.java
index 70dd59d..35cff82 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/PathWritableResource.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/PathWritableResource.java
@@ -25,10 +25,11 @@ import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
-import java.util.Objects;
 
 import org.apache.maven.index.reader.WritableResourceHandler.WritableResource;
 
+import static java.util.Objects.requireNonNull;
+
 /**
  * A {@link WritableResource} that represents a {@link Path}.
  */
@@ -38,7 +39,7 @@ public class PathWritableResource implements WritableResource
 
     public PathWritableResource( Path path )
     {
-        Objects.requireNonNull( path, "path cannot be null" );
+        requireNonNull( path, "path cannot be null" );
         this.path = path;
     }
 
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/PathWritableResourceHandler.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/PathWritableResourceHandler.java
index 9799831..f40f57b 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/PathWritableResourceHandler.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/PathWritableResourceHandler.java
@@ -19,12 +19,12 @@ package org.apache.maven.index.reader.resource;
  * under the License.
  */
 
-import java.io.IOException;
 import java.nio.file.Path;
-import java.util.Objects;
 
 import org.apache.maven.index.reader.WritableResourceHandler;
 
+import static java.util.Objects.requireNonNull;
+
 /**
  * A {@link WritableResourceHandler} that represents the base of a {@link 
Path} hierarchy.
  */
@@ -34,7 +34,7 @@ public class PathWritableResourceHandler implements 
WritableResourceHandler
 
     public PathWritableResourceHandler( Path path )
     {
-        Objects.requireNonNull( path, "path cannot be null" );
+        requireNonNull( path, "path cannot be null" );
         this.path = path;
     }
 
@@ -43,9 +43,4 @@ public class PathWritableResourceHandler implements 
WritableResourceHandler
     {
         return new PathWritableResource( path.resolve( name ) );
     }
-
-    @Override
-    public void close() throws IOException
-    {
-    }
 }
diff --git 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/UriResourceHandler.java
 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/UriResourceHandler.java
index ecff872..7e10638 100644
--- 
a/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/UriResourceHandler.java
+++ 
b/indexer-reader/src/main/java/org/apache/maven/index/reader/resource/UriResourceHandler.java
@@ -21,10 +21,11 @@ package org.apache.maven.index.reader.resource;
 
 import java.io.IOException;
 import java.net.URI;
-import java.util.Objects;
 
 import org.apache.maven.index.reader.ResourceHandler;
 
+import static java.util.Objects.requireNonNull;
+
 /**
  * A {@link ResourceHandler} that represents the base of a {@link URI} 
hierarchy.
  */
@@ -34,7 +35,7 @@ public class UriResourceHandler implements ResourceHandler
 
     public UriResourceHandler( URI uri )
     {
-        Objects.requireNonNull( uri, "uri cannot be null" );
+        requireNonNull( uri, "uri cannot be null" );
         this.uri = uri;
     }
 
@@ -43,9 +44,4 @@ public class UriResourceHandler implements ResourceHandler
     {
         return new UrlResource( uri.resolve( name ).toURL() );
     }
-
-    @Override
-    public void close() throws IOException
-    {
-    }
 }
diff --git 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/CachingResourceHandler.java
 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/CachingResourceHandler.java
index 5e2dd32..dace48e 100644
--- 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/CachingResourceHandler.java
+++ 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/CachingResourceHandler.java
@@ -53,7 +53,6 @@ public class CachingResourceHandler
     }
 
     public Resource locate( final String name )
-        throws IOException
     {
         if ( notFoundResources.contains( name ) )
         {
diff --git 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/ChunkReaderTest.java
 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/ChunkReaderTest.java
index 1d701bf..b2ea645 100644
--- 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/ChunkReaderTest.java
+++ 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/ChunkReaderTest.java
@@ -19,10 +19,6 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import org.apache.maven.index.reader.Record.Type;
-import org.apache.maven.index.reader.ResourceHandler.Resource;
-import org.junit.Test;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -31,6 +27,9 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.maven.index.reader.Record.Type;
+import org.junit.Test;
+
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsEqual.equalTo;
@@ -39,51 +38,53 @@ import static org.hamcrest.core.IsEqual.equalTo;
  * UT for {@link ChunkReader}
  */
 public class ChunkReaderTest
-    extends TestSupport
+        extends TestSupport
 {
     @Test
     public void simple()
-        throws IOException
+            throws IOException
     {
-        final ChunkReader chunkReader = new ChunkReader( "full", 
testResourceHandler( "simple" ) //
-            .locate( "nexus-maven-repository-index.gz" ).read() );
-        final Map<Type, List<Record>> recordTypes = loadRecordsByType( 
chunkReader );
-        assertThat( recordTypes.get( Type.DESCRIPTOR ).size(), equalTo( 1 ) );
-        assertThat( recordTypes.get( Type.ROOT_GROUPS ).size(), equalTo( 1 ) );
-        assertThat( recordTypes.get( Type.ALL_GROUPS ).size(), equalTo( 1 ) );
-        assertThat( recordTypes.get( Type.ARTIFACT_ADD ).size(), equalTo( 2 ) 
);
-        assertThat( recordTypes.get( Type.ARTIFACT_REMOVE ), nullValue() );
+        try ( WritableResourceHandler handler = testResourceHandler( "simple" 
);
+              ChunkReader chunkReader = new ChunkReader( "full",
+                      handler.locate( "nexus-maven-repository-index.gz" 
).read() ) )
+        {
+            final Map<Type, List<Record>> recordTypes = loadRecordsByType( 
chunkReader );
+            assertThat( recordTypes.get( Type.DESCRIPTOR ).size(), equalTo( 1 
) );
+            assertThat( recordTypes.get( Type.ROOT_GROUPS ).size(), equalTo( 1 
) );
+            assertThat( recordTypes.get( Type.ALL_GROUPS ).size(), equalTo( 1 
) );
+            assertThat( recordTypes.get( Type.ARTIFACT_ADD ).size(), equalTo( 
2 ) );
+            assertThat( recordTypes.get( Type.ARTIFACT_REMOVE ), nullValue() );
+        }
     }
 
     @Test
     public void roundtrip()
-        throws IOException
+            throws IOException
     {
         final Date published;
         File tempChunkFile = createTempFile( "nexus-maven-repository-index.gz" 
);
         {
-            final Resource resource = testResourceHandler( "simple" ) //
-                .locate( "nexus-maven-repository-index.gz" );
-
-            try (ChunkReader chunkReader = new ChunkReader( "full",
-                                                            resource.read() ); 
ChunkWriter chunkWriter = new ChunkWriter(
-                chunkReader.getName(), //
-                new FileOutputStream( tempChunkFile ), 1, new Date() ))
+            try ( WritableResourceHandler resource = testResourceHandler( 
"simple" );
+                  ChunkReader chunkReader = new ChunkReader( "full",
+                          resource.locate( "nexus-maven-repository-index.gz" 
).read() );
+                  ChunkWriter chunkWriter = new ChunkWriter( 
chunkReader.getName(),
+                          new FileOutputStream( tempChunkFile ), 1, new Date() 
) )
             {
                 chunkWriter.writeChunk( chunkReader.iterator() );
                 published = chunkWriter.getTimestamp();
             }
-
         }
 
-        final ChunkReader chunkReader = new ChunkReader( "full", new 
FileInputStream( tempChunkFile ) );
-        assertThat( chunkReader.getVersion(), equalTo( 1 ) );
-        assertThat( chunkReader.getTimestamp().getTime(), equalTo( 
published.getTime() ) );
-        final Map<Type, List<Record>> recordTypes = loadRecordsByType( 
chunkReader );
-        assertThat( recordTypes.get( Type.DESCRIPTOR ).size(), equalTo( 1 ) );
-        assertThat( recordTypes.get( Type.ROOT_GROUPS ).size(), equalTo( 1 ) );
-        assertThat( recordTypes.get( Type.ALL_GROUPS ).size(), equalTo( 1 ) );
-        assertThat( recordTypes.get( Type.ARTIFACT_ADD ).size(), equalTo( 2 ) 
);
-        assertThat( recordTypes.get( Type.ARTIFACT_REMOVE ), nullValue() );
+        try ( ChunkReader chunkReader = new ChunkReader( "full", new 
FileInputStream( tempChunkFile ) ) )
+        {
+            assertThat( chunkReader.getVersion(), equalTo( 1 ) );
+            assertThat( chunkReader.getTimestamp().getTime(), equalTo( 
published.getTime() ) );
+            final Map<Type, List<Record>> recordTypes = loadRecordsByType( 
chunkReader );
+            assertThat( recordTypes.get( Type.DESCRIPTOR ).size(), equalTo( 1 
) );
+            assertThat( recordTypes.get( Type.ROOT_GROUPS ).size(), equalTo( 1 
) );
+            assertThat( recordTypes.get( Type.ALL_GROUPS ).size(), equalTo( 1 
) );
+            assertThat( recordTypes.get( Type.ARTIFACT_ADD ).size(), equalTo( 
2 ) );
+            assertThat( recordTypes.get( Type.ARTIFACT_REMOVE ), nullValue() );
+        }
     }
 }
diff --git 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/DirectoryResourceHandler.java
 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/DirectoryResourceHandler.java
index eaa49e8..3a1eb52 100644
--- 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/DirectoryResourceHandler.java
+++ 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/DirectoryResourceHandler.java
@@ -34,56 +34,59 @@ import java.io.OutputStream;
  * by name from specified existing directory.
  */
 public class DirectoryResourceHandler
-    implements WritableResourceHandler
+        implements WritableResourceHandler
 {
-  private final File rootDirectory;
+    private final File rootDirectory;
 
-  public DirectoryResourceHandler(final File rootDirectory) {
-    if (rootDirectory == null) {
-      throw new NullPointerException("null rootDirectory");
+    public DirectoryResourceHandler( final File rootDirectory )
+    {
+        if ( rootDirectory == null )
+        {
+            throw new NullPointerException( "null rootDirectory" );
+        }
+        if ( !rootDirectory.isDirectory() )
+        {
+            throw new IllegalArgumentException( "rootDirectory exists and is 
not a directory" );
+        }
+        this.rootDirectory = rootDirectory;
     }
-    if (!rootDirectory.isDirectory()) {
-      throw new IllegalArgumentException("rootDirectory exists and is not a 
directory");
-    }
-    this.rootDirectory = rootDirectory;
-  }
-
-  public File getRootDirectory() {
-    return rootDirectory;
-  }
-
-  public WritableResource locate(final String name) throws IOException {
-    return new FileResource( new File( rootDirectory, name ) );
-  }
-
-  public void close() throws IOException {
-    // nop
-  }
 
-  private static class FileResource
-      implements WritableResource
-  {
-    private final File file;
-
-    private FileResource(final File file) {
-      this.file = file;
+    public File getRootDirectory()
+    {
+        return rootDirectory;
     }
 
-    public InputStream read() throws IOException {
-      try {
-        return new BufferedInputStream(new FileInputStream(file));
-      } catch (FileNotFoundException e) {
-        return null;
-      }
+    public WritableResource locate( final String name )
+    {
+        return new FileResource( new File( rootDirectory, name ) );
     }
 
-    public OutputStream write() throws IOException {
-      return new BufferedOutputStream(new FileOutputStream(file));
-    }
+    private static class FileResource
+            implements WritableResource
+    {
+        private final File file;
+
+        private FileResource( final File file )
+        {
+            this.file = file;
+        }
+
+        public InputStream read() throws IOException
+        {
+            try
+            {
+                return new BufferedInputStream( new FileInputStream( file ) );
+            }
+            catch ( FileNotFoundException e )
+            {
+                return null;
+            }
+        }
 
-    public void close() throws IOException {
-      // nop
+        public OutputStream write() throws IOException
+        {
+            return new BufferedOutputStream( new FileOutputStream( file ) );
+        }
     }
-  }
 
 }
diff --git 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/HttpResourceHandler.java
 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/HttpResourceHandler.java
index e19d949..b792346 100644
--- 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/HttpResourceHandler.java
+++ 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/HttpResourceHandler.java
@@ -19,53 +19,69 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+
+import static java.util.Objects.requireNonNull;
 
 /**
- * A trivial HTTP {@link ResourceHandler} that uses {@link URL} to fetch 
remote content. This implementation does not
+ * A trivial HTTP {@link ResourceHandler} that uses {@link URI} to fetch 
remote content. This implementation does not
  * handle any advanced cases, like redirects, authentication, etc.
  */
 public class HttpResourceHandler
-    implements ResourceHandler
+        implements ResourceHandler
 {
-  private final URI root;
+    private final HttpClient client = HttpClient.newBuilder().followRedirects( 
HttpClient.Redirect.NEVER ).build();
+    private final URI root;
 
-  public HttpResourceHandler(final URL root) throws URISyntaxException {
-    if (root == null) {
-      throw new NullPointerException("root URL null");
+    public HttpResourceHandler( final URI root )
+    {
+        this.root = requireNonNull( root );
     }
-    this.root = root.toURI();
-  }
 
-  public Resource locate(final String name) throws IOException {
-    return new HttpResource(name);
-  }
+    public Resource locate( final String name )
+    {
+        return new HttpResource( name );
+    }
 
-  private class HttpResource
-      implements Resource
-  {
-    private final String name;
+    private class HttpResource
+            implements Resource
+    {
+        private final String name;
 
-    private HttpResource(final String name) {
-      this.name = name;
-    }
+        private HttpResource( final String name )
+        {
+            this.name = name;
+        }
 
-    public InputStream read() throws IOException {
-      URL target = root.resolve(name).toURL();
-      HttpURLConnection conn = (HttpURLConnection) target.openConnection();
-      conn.setRequestMethod("GET");
-      conn.setRequestProperty("User-Agent", "ASF Maven-Indexer-Reader/1.0");
-      return new BufferedInputStream(conn.getInputStream());
+        public InputStream read() throws IOException
+        {
+            HttpRequest request = HttpRequest.newBuilder()
+                    .uri( root.resolve( name ) )
+                    .GET()
+                    .build();
+            try
+            {
+                HttpResponse<InputStream> response = client.send( request, 
HttpResponse.BodyHandlers.ofInputStream() );
+                if ( response.statusCode() == HttpURLConnection.HTTP_OK )
+                {
+                    return response.body();
+                }
+                else
+                {
+                    throw new IOException( "Unexpected response: " + response 
);
+                }
+            }
+            catch ( InterruptedException e )
+            {
+                Thread.currentThread().interrupt();
+                throw new IOException( e );
+            }
+        }
     }
-  }
-
-  public void close() throws IOException {
-    // nop
-  }
 }
diff --git 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexReaderTest.java
 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexReaderTest.java
index c300613..065afb3 100644
--- 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexReaderTest.java
+++ 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexReaderTest.java
@@ -19,20 +19,19 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import org.apache.maven.index.reader.Record.Type;
-import org.junit.Ignore;
-import org.junit.Test;
-
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.net.URL;
-import java.util.Arrays;
+import java.net.URI;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 
+import org.apache.maven.index.reader.Record.Type;
+import org.junit.Ignore;
+import org.junit.Test;
+
 import static org.apache.maven.index.reader.TestUtils.expandFunction;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsEqual.equalTo;
@@ -43,162 +42,162 @@ import static org.hamcrest.core.IsNull.nullValue;
  * UT for {@link IndexReader}
  */
 public class IndexReaderTest
-    extends TestSupport
+        extends TestSupport
 {
-  @Test
-  public void simple() throws IOException {
-    try ( IndexReader indexReader = new IndexReader( null, 
testResourceHandler( "simple" ) ) )
+    @Test
+    public void simple() throws IOException
     {
-      assertThat( indexReader.getIndexId(), equalTo( "apache-snapshots-local" 
) );
-      assertThat( indexReader.getPublishedTimestamp().getTime(), equalTo( 
1243533418015L ) );
-      assertThat( indexReader.isIncremental(), equalTo( false ) );
-      assertThat( indexReader.getChunkNames(), equalTo( Arrays.asList( 
"nexus-maven-repository-index.gz" ) ) );
-      int chunks = 0;
-      int records = 0;
-      for ( ChunkReader chunkReader : indexReader )
-      {
-        chunks++;
-        assertThat( chunkReader.getName(), equalTo( 
"nexus-maven-repository-index.gz" ) );
-        assertThat( chunkReader.getVersion(), equalTo( 1 ) );
-        assertThat( chunkReader.getTimestamp().getTime(), equalTo( 
1243533418015L ) );
-        for ( Record ignored : StreamSupport.stream( 
chunkReader.spliterator(), false )
-          .map( expandFunction )
-          .collect( Collectors.toList() ) )
+        try ( IndexReader indexReader = new IndexReader( null, 
testResourceHandler( "simple" ) ) )
         {
-          records++;
-        }
-      }
+            assertThat( indexReader.getIndexId(), equalTo( 
"apache-snapshots-local" ) );
+            assertThat( indexReader.getPublishedTimestamp().getTime(), 
equalTo( 1243533418015L ) );
+            assertThat( indexReader.isIncremental(), equalTo( false ) );
+            assertThat( indexReader.getChunkNames(), equalTo( List.of( 
"nexus-maven-repository-index.gz" ) ) );
+            int chunks = 0;
+            int records = 0;
+            for ( ChunkReader chunkReader : indexReader )
+            {
+                try ( chunkReader )
+                {
+                    chunks++;
+                    assertThat( chunkReader.getName(), equalTo( 
"nexus-maven-repository-index.gz" ) );
+                    assertThat( chunkReader.getVersion(), equalTo( 1 ) );
+                    assertThat( chunkReader.getTimestamp().getTime(), equalTo( 
1243533418015L ) );
+                    records = (int) StreamSupport.stream( 
chunkReader.spliterator(), false )
+                            .map( expandFunction ).count();
+                }
+            }
 
-      assertThat( chunks, equalTo( 1 ) );
-      assertThat( records, equalTo( 5 ) );
+            assertThat( chunks, equalTo( 1 ) );
+            assertThat( records, equalTo( 5 ) );
+        }
     }
-  }
 
-  @Test
-  public void simpleWithLocal() throws IOException {
-    WritableResourceHandler writableResourceHandler = 
createWritableResourceHandler();
-    try ( IndexReader indexReader = new IndexReader( writableResourceHandler, 
testResourceHandler( "simple" ) ) )
+    @Test
+    public void simpleWithLocal() throws IOException
     {
-      assertThat( indexReader.getIndexId(), equalTo( "apache-snapshots-local" 
) );
-      assertThat( indexReader.getPublishedTimestamp().getTime(), equalTo( 
1243533418015L ) );
-      assertThat( indexReader.isIncremental(), equalTo( false ) );
-      assertThat( indexReader.getChunkNames(), equalTo( Arrays.asList( 
"nexus-maven-repository-index.gz" ) ) );
-      int chunks = 0;
-      int records = 0;
-      for ( ChunkReader chunkReader : indexReader )
-      {
-        chunks++;
-        assertThat( chunkReader.getName(), equalTo( 
"nexus-maven-repository-index.gz" ) );
-        assertThat( chunkReader.getVersion(), equalTo( 1 ) );
-        assertThat( chunkReader.getTimestamp().getTime(), equalTo( 
1243533418015L ) );
-        for ( Record ignored : StreamSupport.stream( 
chunkReader.spliterator(), false )
-            .map( expandFunction )
-            .collect( Collectors.toList() ) )
+        try ( WritableResourceHandler writableResourceHandler = 
createWritableResourceHandler() )
         {
-          records++;
-        }
-      }
+            try ( IndexReader indexReader = new IndexReader( 
writableResourceHandler,
+                    testResourceHandler( "simple" ) ) )
+            {
+                assertThat( indexReader.getIndexId(), equalTo( 
"apache-snapshots-local" ) );
+                assertThat( indexReader.getPublishedTimestamp().getTime(), 
equalTo( 1243533418015L ) );
+                assertThat( indexReader.isIncremental(), equalTo( false ) );
+                assertThat( indexReader.getChunkNames(), equalTo( List.of( 
"nexus-maven-repository-index.gz" ) ) );
+                int chunks = 0;
+                int records = 0;
+                for ( ChunkReader chunkReader : indexReader )
+                {
+                    try ( chunkReader )
+                    {
+                        chunks++;
+                        assertThat( chunkReader.getName(), equalTo( 
"nexus-maven-repository-index.gz" ) );
+                        assertThat( chunkReader.getVersion(), equalTo( 1 ) );
+                        assertThat( chunkReader.getTimestamp().getTime(), 
equalTo( 1243533418015L ) );
+                        records = (int) StreamSupport.stream( 
chunkReader.spliterator(), false )
+                                .map( expandFunction ).count();
+                    }
+                }
 
-      assertThat( chunks, equalTo( 1 ) );
-      assertThat( records, equalTo( 5 ) );
-    }
-
-    
assertThat(writableResourceHandler.locate("nexus-maven-repository-index.properties").read(),
 not(nullValue()));
-  }
+                assertThat( chunks, equalTo( 1 ) );
+                assertThat( records, equalTo( 5 ) );
+            }
 
-  @Test
-  public void roundtrip() throws IOException {
-    WritableResourceHandler writableResourceHandler = 
createWritableResourceHandler();
-    Date published;
-    {
-      final IndexReader indexReader = new IndexReader(
-          null,
-          testResourceHandler("simple")
-      );
-      final IndexWriter indexWriter = new IndexWriter(
-          writableResourceHandler,
-          indexReader.getIndexId(),
-          false
-      );
-      try {
-        for (ChunkReader chunkReader : indexReader) {
-          indexWriter.writeChunk(chunkReader.iterator());
+            assertThat( writableResourceHandler.locate( 
"nexus-maven-repository-index.properties" ).read(),
+                    not( nullValue() ) );
         }
-      }
-      finally {
-        indexWriter.close();
-        published = indexWriter.getPublishedTimestamp();
-        indexReader.close();
-      }
     }
 
-    try ( IndexReader indexReader = new IndexReader( null, 
writableResourceHandler ) )
+    @Test
+    public void roundtrip() throws IOException
     {
-      assertThat( indexReader.getIndexId(), equalTo( "apache-snapshots-local" 
) );
-      assertThat( indexReader.getPublishedTimestamp().getTime(), equalTo( 
published.getTime() ) );
-      assertThat( indexReader.isIncremental(), equalTo( false ) );
-      assertThat( indexReader.getChunkNames(), equalTo( Arrays.asList( 
"nexus-maven-repository-index.gz" ) ) );
-      int chunks = 0;
-      int records = 0;
-      for ( ChunkReader chunkReader : indexReader )
-      {
-        chunks++;
-        assertThat( chunkReader.getName(), equalTo( 
"nexus-maven-repository-index.gz" ) );
-        assertThat( chunkReader.getVersion(), equalTo( 1 ) );
-        // assertThat(chunkReader.getTimestamp().getTime(), 
equalTo(1243533418015L));
-        for ( Record record : StreamSupport.stream( chunkReader.spliterator(), 
false )
-            .map( expandFunction )
-            .collect( Collectors.toList() ) )
+        try ( WritableResourceHandler writableResourceHandler = 
createWritableResourceHandler() )
         {
-          records++;
-        }
-      }
+            Date published;
+            IndexWriter iw; // TODO: fix this, IW close will set timestamp but 
ref to it is lost from try-with-res
+            {
+                try ( IndexReader indexReader = new IndexReader( null, 
testResourceHandler( "simple" ) );
+                      IndexWriter indexWriter = iw = new IndexWriter( 
writableResourceHandler,
+                              indexReader.getIndexId(), false ) )
+                {
+                    for ( ChunkReader chunkReader : indexReader )
+                    {
+                        try ( chunkReader )
+                        {
+                            indexWriter.writeChunk( chunkReader.iterator() );
+                        }
+                    }
+                }
+                published = iw.getPublishedTimestamp();
+            }
+
+            try ( IndexReader indexReader = new IndexReader( null, 
writableResourceHandler ) )
+            {
+                assertThat( indexReader.getIndexId(), equalTo( 
"apache-snapshots-local" ) );
+                assertThat( indexReader.getPublishedTimestamp().getTime(), 
equalTo( published.getTime() ) );
+                assertThat( indexReader.isIncremental(), equalTo( false ) );
+                assertThat( indexReader.getChunkNames(),
+                        equalTo( List.of( "nexus-maven-repository-index.gz" ) 
) );
+                int chunks = 0;
+                int records = 0;
+                for ( ChunkReader chunkReader : indexReader )
+                {
+                    try ( chunkReader )
+                    {
+                        chunks++;
+                        assertThat( chunkReader.getName(), equalTo( 
"nexus-maven-repository-index.gz" ) );
+                        assertThat( chunkReader.getVersion(), equalTo( 1 ) );
+                        // assertThat(chunkReader.getTimestamp().getTime(), 
equalTo(1243533418015L));
+                        records = (int) StreamSupport.stream( 
chunkReader.spliterator(), false )
+                                .map( expandFunction ).count();
+                    }
+                }
 
-      assertThat( chunks, equalTo( 1 ) );
-      assertThat( records, equalTo( 5 ) );
+                assertThat( chunks, equalTo( 1 ) );
+                assertThat( records, equalTo( 5 ) );
+            }
+        }
     }
-  }
 
-  /**
-   * This UT is here for demonstration purposes only. Bashing Central is not 
something you want to do, and risk your
-   * IP address being banned. You were warned!
-   */
-  @Test
-  @Ignore("For eyes only")
-  public void central() throws Exception {
-    // local index location, against which we perform incremental updates
-    final File indexDir = createTempDirectory();
-    // cache of remote, to not rely on HTTP transport possible failures, or, 
to detect them early
-    final File cacheDir = createTempDirectory();
+    /**
+     * This UT is here for demonstration purposes only. Bashing Central is not 
something you want to do, and risk your
+     * IP address being banned. You were warned!
+     */
+    @Test
+    @Ignore( "For eyes only" )
+    public void central() throws Exception
+    {
+        // local index location, against which we perform incremental updates
+        final File indexDir = createTempDirectory();
+        // cache of remote, to not rely on HTTP transport possible failures, 
or, to detect them early
+        final File cacheDir = createTempDirectory();
+
+        final PrintWriter writer = new PrintWriter( System.out, true );
 
-    final PrintWriter writer = new PrintWriter(System.out, true);
-    final WritableResourceHandler local = new 
DirectoryResourceHandler(indexDir);
-    final CachingResourceHandler remote = new CachingResourceHandler(
-        new DirectoryResourceHandler(cacheDir),
-        new HttpResourceHandler(new 
URL("http://repo1.maven.org/maven2/.index/";))
-    );
-    final IndexReader indexReader = new IndexReader(local, remote);
-    try {
-      writer.println("indexRepoId=" + indexReader.getIndexId());
-      writer.println("indexLastPublished=" + 
indexReader.getPublishedTimestamp());
-      writer.println("isIncremental=" + indexReader.isIncremental());
-      writer.println("indexRequiredChunkNames=" + indexReader.getChunkNames());
-      for (ChunkReader chunkReader : indexReader) {
-        writer.println("chunkName=" + chunkReader.getName());
-        writer.println("chunkVersion=" + chunkReader.getVersion());
-        writer.println("chunkPublished=" + chunkReader.getTimestamp());
-        writer.println("Chunk stats:");
-        Map<Type, Integer> stats = countRecordsByType(chunkReader);
-        for (Map.Entry<Type, Integer> entry : stats.entrySet()) {
-          writer.println(entry.getKey() + " = " + entry.getValue());
+        try ( WritableResourceHandler local = new DirectoryResourceHandler( 
indexDir );
+              CachingResourceHandler remote = new CachingResourceHandler(
+                new DirectoryResourceHandler( cacheDir ),
+                new HttpResourceHandler( URI.create( 
"https://repo1.maven.org/maven2/.index/"; ) ) );
+              IndexReader indexReader = new IndexReader( local, remote ) )
+        {
+            writer.println( "indexRepoId=" + indexReader.getIndexId() );
+            writer.println( "indexLastPublished=" + 
indexReader.getPublishedTimestamp() );
+            writer.println( "isIncremental=" + indexReader.isIncremental() );
+            writer.println( "indexRequiredChunkNames=" + 
indexReader.getChunkNames() );
+            for ( ChunkReader chunkReader : indexReader )
+            {
+                writer.println( "chunkName=" + chunkReader.getName() );
+                writer.println( "chunkVersion=" + chunkReader.getVersion() );
+                writer.println( "chunkPublished=" + chunkReader.getTimestamp() 
);
+                writer.println( "Chunk stats:" );
+                Map<Type, Integer> stats = countRecordsByType( chunkReader );
+                for ( Map.Entry<Type, Integer> entry : stats.entrySet() )
+                {
+                    writer.println( entry.getKey() + " = " + entry.getValue() 
);
+                }
+                writer.println( "= = = = = =" );
+            }
         }
-        writer.println("= = = = = =");
-      }
-    }
-    finally {
-      indexReader.close();
-      remote.close();
-      local.close();
     }
-  }
 }
diff --git 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexWriterTest.java
 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexWriterTest.java
index 46acfd4..67ad807 100644
--- 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexWriterTest.java
+++ 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/IndexWriterTest.java
@@ -19,13 +19,12 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import org.junit.Test;
-
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.stream.Collectors;
+import java.util.List;
 import java.util.stream.StreamSupport;
 
+import org.junit.Test;
+
 import static org.apache.maven.index.reader.TestUtils.expandFunction;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsEqual.equalTo;
@@ -34,63 +33,49 @@ import static org.hamcrest.core.IsEqual.equalTo;
  * UT for {@link IndexWriter}
  */
 public class IndexWriterTest
-    extends TestSupport
+        extends TestSupport
 {
-  @Test
-  public void roundtrip() throws IOException {
-    IndexReader indexReader;
-    IndexWriter indexWriter;
-    WritableResourceHandler writableResourceHandler = 
createWritableResourceHandler();
+    @Test
+    public void roundtrip() throws IOException
+    {
+        try ( WritableResourceHandler writableResourceHandler = 
createWritableResourceHandler() )
+        {
+            try ( IndexReader indexReader = new IndexReader( null, 
testResourceHandler( "simple" ) );
+                  IndexWriter indexWriter = new IndexWriter( 
writableResourceHandler,
+                          indexReader.getIndexId(), false ) )
+            {
+                for ( ChunkReader chunkReader : indexReader )
+                {
+                    try ( chunkReader )
+                    {
+                        indexWriter.writeChunk( chunkReader.iterator() );
+                    }
+                }
+            }
 
-    // write it once
-    indexReader = new IndexReader(
-        null,
-        testResourceHandler("simple")
-    );
-    indexWriter = new IndexWriter(
-        writableResourceHandler,
-        indexReader.getIndexId(),
-        false
-    );
-    try {
-      for (ChunkReader chunkReader : indexReader) {
-        indexWriter.writeChunk(chunkReader.iterator());
-      }
-    }
-    finally {
-      indexWriter.close();
-      indexReader.close();
-    }
+            // read what we wrote out
+            try ( IndexReader indexReader = new IndexReader( null, 
writableResourceHandler ) )
+            {
+                assertThat( indexReader.getIndexId(), equalTo( 
"apache-snapshots-local" ) );
+                // assertThat(indexReader.getPublishedTimestamp().getTime(), 
equalTo(published.getTime()));
+                assertThat( indexReader.isIncremental(), equalTo( false ) );
+                assertThat( indexReader.getChunkNames(),
+                        equalTo( List.of( "nexus-maven-repository-index.gz" ) 
) );
+                int chunks = 0;
+                int records = 0;
+                for ( ChunkReader chunkReader : indexReader )
+                {
+                    chunks++;
+                    assertThat( chunkReader.getName(), equalTo( 
"nexus-maven-repository-index.gz" ) );
+                    assertThat( chunkReader.getVersion(), equalTo( 1 ) );
+                    // assertThat(chunkReader.getTimestamp().getTime(), 
equalTo(1243533418015L));
+                    records = (int) StreamSupport.stream( 
chunkReader.spliterator(), false )
+                            .map( expandFunction ).count();
+                }
 
-    // read what we wrote out
-    indexReader = new IndexReader(
-        null,
-        writableResourceHandler
-    );
-    try {
-      assertThat(indexReader.getIndexId(), equalTo("apache-snapshots-local"));
-      // assertThat(indexReader.getPublishedTimestamp().getTime(), 
equalTo(published.getTime()));
-      assertThat(indexReader.isIncremental(), equalTo(false));
-      assertThat(indexReader.getChunkNames(), 
equalTo(Arrays.asList("nexus-maven-repository-index.gz")));
-      int chunks = 0;
-      int records = 0;
-      for (ChunkReader chunkReader : indexReader) {
-        chunks++;
-        assertThat(chunkReader.getName(), 
equalTo("nexus-maven-repository-index.gz"));
-        assertThat(chunkReader.getVersion(), equalTo(1));
-        // assertThat(chunkReader.getTimestamp().getTime(), 
equalTo(1243533418015L));
-        for (Record record : StreamSupport.stream( chunkReader.spliterator(), 
false )
-            .map( expandFunction )
-            .collect( Collectors.toList() ) ) {
-          records++;
+                assertThat( chunks, equalTo( 1 ) );
+                assertThat( records, equalTo( 5 ) );
+            }
         }
-      }
-
-      assertThat(chunks, equalTo(1));
-      assertThat(records, equalTo(5));
-    }
-    finally {
-      indexReader.close();
     }
-  }
 }
diff --git 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/TestSupport.java 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/TestSupport.java
index 0b6055a..0e7f237 100644
--- 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/TestSupport.java
+++ 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/TestSupport.java
@@ -19,12 +19,6 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import org.apache.maven.index.reader.Record.Type;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.rules.TestName;
-
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
@@ -33,6 +27,12 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.maven.index.reader.Record.Type;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 
@@ -53,7 +53,7 @@ public class TestSupport
      */
     @Before
     public void setup()
-        throws IOException
+            throws IOException
     {
         this.tempDir = Files.createTempDirectory( getClass().getSimpleName() + 
".temp" ).toFile();
         this.directoryResourceHandlers = new ArrayList<>();
@@ -64,7 +64,7 @@ public class TestSupport
      */
     @After
     public void cleanup()
-        throws IOException
+            throws IOException
     {
         for ( DirectoryResourceHandler directoryResourceHandler : 
directoryResourceHandlers )
         {
@@ -77,7 +77,7 @@ public class TestSupport
      * Creates a temp file within {@link #tempDir} with given name.
      */
     protected File createTempFile( final String name )
-        throws IOException
+            throws IOException
     {
         File file = new File( tempDir, name );
         file.deleteOnExit();
@@ -88,7 +88,7 @@ public class TestSupport
      * Creates a temp directory within {@link #tempDir}.
      */
     protected File createTempDirectory()
-        throws IOException
+            throws IOException
     {
         return Files.createTempDirectory( tempDir.toPath(), 
testName.getMethodName() + "-dir" ).toFile();
     }
@@ -97,7 +97,7 @@ public class TestSupport
      * Creates an empty {@link DirectoryResourceHandler}.
      */
     protected WritableResourceHandler createWritableResourceHandler()
-        throws IOException
+            throws IOException
     {
         DirectoryResourceHandler result = new DirectoryResourceHandler( 
createTempDirectory() );
         directoryResourceHandlers.add( result );
@@ -108,8 +108,8 @@ public class TestSupport
      * Creates a "test" {@link ResourceHandler} that contains predefined 
files, is mapped to test resources under given
      * name.
      */
-    protected ResourceHandler testResourceHandler( final String name )
-        throws IOException
+    protected DirectoryResourceHandler testResourceHandler( final String name )
+            throws IOException
     {
         DirectoryResourceHandler result = new DirectoryResourceHandler( new 
File( "src/test/resources/" + name ) );
         directoryResourceHandlers.add( result );
@@ -120,10 +120,10 @@ public class TestSupport
      * Consumes {@link ChunkReader} and creates a map "by type" with records.
      */
     protected Map<Type, List<Record>> loadRecordsByType( final ChunkReader 
chunkReader )
-        throws IOException
+            throws IOException
     {
         HashMap<Type, List<Record>> stat = new HashMap<>();
-        try
+        try ( chunkReader )
         {
             assertThat( chunkReader.getVersion(), equalTo( 1 ) );
             final RecordExpander recordExpander = new RecordExpander();
@@ -137,10 +137,6 @@ public class TestSupport
                 stat.get( record.getType() ).add( record );
             }
         }
-        finally
-        {
-            chunkReader.close();
-        }
         return stat;
     }
 
@@ -149,10 +145,10 @@ public class TestSupport
      * Consumes {@link ChunkReader} and creates a map "by type" with record 
type counts.
      */
     protected Map<Type, Integer> countRecordsByType( final ChunkReader 
chunkReader )
-        throws IOException
+            throws IOException
     {
         HashMap<Type, Integer> stat = new HashMap<>();
-        try
+        try ( chunkReader )
         {
             assertThat( chunkReader.getVersion(), equalTo( 1 ) );
             final RecordExpander recordExpander = new RecordExpander();
@@ -166,41 +162,6 @@ public class TestSupport
                 stat.put( record.getType(), stat.get( record.getType() ) + 1 );
             }
         }
-        finally
-        {
-            chunkReader.close();
-        }
         return stat;
     }
-
-    /**
-     * Delete recursively.
-     */
-    private static boolean delete( final File file )
-    {
-        if ( file == null )
-        {
-            return false;
-        }
-        if ( !file.exists() )
-        {
-            return true;
-        }
-        if ( file.isDirectory() )
-        {
-            String[] list = file.list();
-            if ( list != null )
-            {
-                for ( String s : list )
-                {
-                    File entry = new File( file, s );
-                    if ( !delete( entry ) )
-                    {
-                        return false;
-                    }
-                }
-            }
-        }
-        return file.delete();
-    }
 }
diff --git 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/TestUtils.java 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/TestUtils.java
index 54c26b7..5676b86 100644
--- a/indexer-reader/src/test/java/org/apache/maven/index/reader/TestUtils.java
+++ b/indexer-reader/src/test/java/org/apache/maven/index/reader/TestUtils.java
@@ -19,8 +19,6 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import org.apache.maven.index.reader.Record.Type;
-
 import java.util.Map;
 import java.util.TreeSet;
 import java.util.function.Function;
@@ -28,72 +26,78 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
-import static org.apache.maven.index.reader.Utils.*;
+import org.apache.maven.index.reader.Record.Type;
+
+import static org.apache.maven.index.reader.Utils.allGroups;
+import static org.apache.maven.index.reader.Utils.descriptor;
+import static org.apache.maven.index.reader.Utils.rootGroup;
+import static org.apache.maven.index.reader.Utils.rootGroups;
 
 /**
  * Helpers to transform records from one to another representation, and, some 
helpers for publishing using Guava.
  */
 public final class TestUtils
 {
-  private TestUtils() {
-    // nothing
-  }
+    private TestUtils()
+    {
+        // nothing
+    }
 
-  private static final RecordCompactor RECORD_COMPACTOR = new 
RecordCompactor();
+    private static final RecordCompactor RECORD_COMPACTOR = new 
RecordCompactor();
 
-  private static final RecordExpander RECORD_EXPANDER = new RecordExpander();
+    private static final RecordExpander RECORD_EXPANDER = new RecordExpander();
 
-  public static Function<Record, Map<String, String>> compactFunction = 
RECORD_COMPACTOR::apply;
+    public static Function<Record, Map<String, String>> compactFunction = 
RECORD_COMPACTOR;
 
-  public static Function<Map<String, String>, Record> expandFunction = 
RECORD_EXPANDER::apply;
+    public static Function<Map<String, String>, Record> expandFunction = 
RECORD_EXPANDER;
 
-  /**
-   * Helper method, that "decorates" the stream of records to be written out 
with "special" Maven Indexer records, so
-   * all the caller is needed to provide {@link Iterable} or {@link Record}s 
<strong>to be</strong> on the index, with
-   * record type {@link Type#ARTIFACT_ADD}. This method will create the output 
as "proper" Maven Indexer record
-   * stream, by adding the {@link Type#DESCRIPTOR}, {@link Type#ROOT_GROUPS} 
and {@link Type#ALL_GROUPS} special
-   * records.
-   */
-  public static Iterable<Record> decorate(final Iterable<Record> iterable,
-                                          final String repoId)
-  {
-    final TreeSet<String> allGroupsSet = new TreeSet<>();
-    final TreeSet<String> rootGroupsSet = new TreeSet<>();
-    return Stream.concat(
-            Stream.of( descriptor( repoId ) ),
-            Stream.concat(
-                    StreamSupport.stream( iterable.spliterator(), false ),
-                    Stream.concat(
-                            Stream.of( allGroups( allGroupsSet ) ),
-                            // placeholder, will be recreated at the end with 
proper content
-                            Stream.of( rootGroups( rootGroupsSet ) )
-                    )
-            )
-            // placeholder, will be recreated at the end with proper content
-    ).map( rec ->
+    /**
+     * Helper method, that "decorates" the stream of records to be written out 
with "special" Maven Indexer records, so
+     * all the caller is needed to provide {@link Iterable} or {@link Record}s 
<strong>to be</strong> on the index, with
+     * record type {@link Type#ARTIFACT_ADD}. This method will create the 
output as "proper" Maven Indexer record
+     * stream, by adding the {@link Type#DESCRIPTOR}, {@link Type#ROOT_GROUPS} 
and {@link Type#ALL_GROUPS} special
+     * records.
+     */
+    public static Iterable<Record> decorate( final Iterable<Record> iterable,
+                                             final String repoId )
     {
-      if ( Type.DESCRIPTOR == rec.getType() )
-      {
-        return rec;
-      }
-      else if ( Type.ALL_GROUPS == rec.getType() )
-      {
-        return allGroups( allGroupsSet );
-      }
-      else if ( Type.ROOT_GROUPS == rec.getType() )
-      {
-        return rootGroups( rootGroupsSet );
-      }
-      else
-      {
-        final String groupId = rec.get( Record.GROUP_ID );
-        if ( groupId != null )
+        final TreeSet<String> allGroupsSet = new TreeSet<>();
+        final TreeSet<String> rootGroupsSet = new TreeSet<>();
+        return Stream.concat(
+                Stream.of( descriptor( repoId ) ),
+                Stream.concat(
+                        StreamSupport.stream( iterable.spliterator(), false ),
+                        Stream.concat(
+                                Stream.of( allGroups( allGroupsSet ) ),
+                                // placeholder, will be recreated at the end 
with proper content
+                                Stream.of( rootGroups( rootGroupsSet ) )
+                        )
+                )
+                // placeholder, will be recreated at the end with proper 
content
+        ).map( rec ->
         {
-          allGroupsSet.add( groupId );
-          rootGroupsSet.add( rootGroup( groupId ) );
-        }
-        return rec;
-      }
-    } ).collect( Collectors.toList() );
-  }
+            if ( Type.DESCRIPTOR == rec.getType() )
+            {
+                return rec;
+            }
+            else if ( Type.ALL_GROUPS == rec.getType() )
+            {
+                return allGroups( allGroupsSet );
+            }
+            else if ( Type.ROOT_GROUPS == rec.getType() )
+            {
+                return rootGroups( rootGroupsSet );
+            }
+            else
+            {
+                final String groupId = rec.getString( Record.GROUP_ID );
+                if ( groupId != null )
+                {
+                    allGroupsSet.add( groupId );
+                    rootGroupsSet.add( rootGroup( groupId ) );
+                }
+                return rec;
+            }
+        } ).collect( Collectors.toList() );
+    }
 }
diff --git 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/TransformTest.java 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/TransformTest.java
index 7cf6bc5..37b580f 100644
--- 
a/indexer-reader/src/test/java/org/apache/maven/index/reader/TransformTest.java
+++ 
b/indexer-reader/src/test/java/org/apache/maven/index/reader/TransformTest.java
@@ -19,10 +19,6 @@ package org.apache.maven.index.reader;
  * under the License.
  */
 
-import org.apache.maven.index.reader.Record.EntryKey;
-import org.apache.maven.index.reader.Record.Type;
-import org.junit.Test;
-
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -31,6 +27,10 @@ import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 
+import org.apache.maven.index.reader.Record.EntryKey;
+import org.apache.maven.index.reader.Record.Type;
+import org.junit.Test;
+
 import static org.apache.maven.index.reader.TestUtils.compactFunction;
 import static org.apache.maven.index.reader.TestUtils.decorate;
 import static org.hamcrest.CoreMatchers.nullValue;
@@ -38,63 +38,70 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsEqual.equalTo;
 
 /**
- * UT for {@link RecordCompactor} and {@linl RecordExpander}.
+ * UT for {@link RecordCompactor} and {@link RecordExpander}.
  */
 public class TransformTest
-    extends TestSupport
+        extends TestSupport
 {
-  @Test
-  public void decorateAndTransform() throws IOException {
-    final String indexId = "test";
-    final Record r1 = new Record(Type.ARTIFACT_ADD, artifactMap("org.apache"));
-    final Record r2 = new Record(Type.ARTIFACT_ADD, artifactMap("org.foo"));
-    final Record r3 = new Record(Type.ARTIFACT_ADD, artifactMap("com.bar"));
+    @Test
+    public void decorateAndTransform() throws IOException
+    {
+        final String indexId = "test";
+        final Record r1 = new Record( Type.ARTIFACT_ADD, artifactMap( 
"org.apache" ) );
+        final Record r2 = new Record( Type.ARTIFACT_ADD, artifactMap( 
"org.foo" ) );
+        final Record r3 = new Record( Type.ARTIFACT_ADD, artifactMap( 
"com.bar" ) );
 
-    Iterable<Map<String, String>> iterable = StreamSupport.stream(
-            decorate( Arrays.asList( r1, r2, r3 ), indexId ).spliterator(), 
false )
-            .map( compactFunction )
-            .collect( Collectors.toList() );
+        Iterable<Map<String, String>> iterable = StreamSupport.stream(
+                        decorate( Arrays.asList( r1, r2, r3 ), indexId 
).spliterator(), false )
+                .map( compactFunction )
+                .collect( Collectors.toList() );
 
-    WritableResourceHandler writableResourceHandler = 
createWritableResourceHandler();
-    try {
-      IndexWriter indexWriter = new IndexWriter(
-          writableResourceHandler,
-          indexId,
-          false
-      );
-      indexWriter.writeChunk(iterable.iterator());
-      indexWriter.close();
-    }
-    finally {
-      writableResourceHandler.close();
-    }
+        ;
+        try ( WritableResourceHandler writableResourceHandler = 
createWritableResourceHandler() )
+        {
+            try ( IndexWriter indexWriter = new IndexWriter(
+                    writableResourceHandler,
+                    indexId,
+                    false
+            ) )
+            {
+                indexWriter.writeChunk( iterable.iterator() );
+                indexWriter.close();
+            }
 
-    IndexReader indexReader = new IndexReader(null, writableResourceHandler);
-    assertThat(indexReader.getChunkNames(), 
equalTo(Arrays.asList("nexus-maven-repository-index.gz")));
-    ChunkReader chunkReader = indexReader.iterator().next();
-    final Map<Type, List<Record>> recordTypes = loadRecordsByType(chunkReader);
-    assertThat(recordTypes.get(Type.DESCRIPTOR).size(), equalTo(1));
-    assertThat(recordTypes.get(Type.ROOT_GROUPS).size(), equalTo(1));
-    assertThat(recordTypes.get(Type.ALL_GROUPS).size(), equalTo(1));
-    assertThat(recordTypes.get(Type.ARTIFACT_ADD).size(), equalTo(3));
-    assertThat(recordTypes.get(Type.ARTIFACT_REMOVE), nullValue());
+            try ( IndexReader indexReader = new IndexReader( null, 
writableResourceHandler ) )
+            {
+                assertThat( indexReader.getChunkNames(),
+                        equalTo( List.of( "nexus-maven-repository-index.gz" ) 
) );
+                ChunkReader chunkReader = indexReader.iterator().next();
+                final Map<Type, List<Record>> recordTypes = loadRecordsByType( 
chunkReader );
+                assertThat( recordTypes.get( Type.DESCRIPTOR ).size(), 
equalTo( 1 ) );
+                assertThat( recordTypes.get( Type.ROOT_GROUPS ).size(), 
equalTo( 1 ) );
+                assertThat( recordTypes.get( Type.ALL_GROUPS ).size(), 
equalTo( 1 ) );
+                assertThat( recordTypes.get( Type.ARTIFACT_ADD ).size(), 
equalTo( 3 ) );
+                assertThat( recordTypes.get( Type.ARTIFACT_REMOVE ), 
nullValue() );
 
-    
assertThat(recordTypes.get(Type.ROOT_GROUPS).get(0).get(Record.ROOT_GROUPS), 
equalTo(new String[] {"com","org"}));
-    assertThat(recordTypes.get(Type.ALL_GROUPS).get(0).get(Record.ALL_GROUPS), 
equalTo(new String[] {"com.bar", "org.apache", "org.foo"}));
-  }
+                assertThat( recordTypes.get( Type.ROOT_GROUPS ).get( 0 ).get( 
Record.ROOT_GROUPS ),
+                        equalTo( new String[] {"com", "org"} ) );
+                assertThat( recordTypes.get( Type.ALL_GROUPS ).get( 0 ).get( 
Record.ALL_GROUPS ),
+                        equalTo( new String[] {"com.bar", "org.apache", 
"org.foo"} ) );
+            }
+        }
+    }
 
-  private Map<EntryKey, Object> artifactMap(final String groupId) {
-    final HashMap<EntryKey, Object> result = new HashMap<>();
-    result.put(Record.GROUP_ID, groupId);
-    result.put(Record.ARTIFACT_ID, "artifact");
-    result.put(Record.VERSION, "1.0");
-    result.put(Record.PACKAGING, "jar");
-    result.put(Record.FILE_MODIFIED, System.currentTimeMillis());
-    result.put(Record.FILE_SIZE, 123L);
-    result.put(Record.FILE_EXTENSION, "jar");
-    result.put(Record.HAS_SOURCES, Boolean.FALSE);
-    result.put(Record.HAS_JAVADOC, Boolean.FALSE);
-    result.put(Record.HAS_SIGNATURE, Boolean.FALSE);
-    return result;
-  }
+    private Map<EntryKey, Object> artifactMap( final String groupId )
+    {
+        final HashMap<EntryKey, Object> result = new HashMap<>();
+        result.put( Record.GROUP_ID, groupId );
+        result.put( Record.ARTIFACT_ID, "artifact" );
+        result.put( Record.VERSION, "1.0" );
+        result.put( Record.PACKAGING, "jar" );
+        result.put( Record.FILE_MODIFIED, System.currentTimeMillis() );
+        result.put( Record.FILE_SIZE, 123L );
+        result.put( Record.FILE_EXTENSION, "jar" );
+        result.put( Record.HAS_SOURCES, Boolean.FALSE );
+        result.put( Record.HAS_JAVADOC, Boolean.FALSE );
+        result.put( Record.HAS_SIGNATURE, Boolean.FALSE );
+        return result;
+    }
 }
diff --git a/pom.xml b/pom.xml
index 6630c55..5a3dada 100644
--- a/pom.xml
+++ b/pom.xml
@@ -136,12 +136,6 @@ under the License.
         <optional>true</optional>
       </dependency>
 
-      <dependency>
-        <groupId>com.google.guava</groupId>
-        <artifactId>guava</artifactId>
-        <version>31.1-jre</version>
-      </dependency>
-
       <!-- DI -->
       <dependency>
         <groupId>javax.inject</groupId>

Reply via email to