Remove Transform, let user use any lib it wants to for iterable manipulation

Also, UTs got new TestUtils based on Guava
diff --git a/indexer-reader/pom.xml b/indexer-reader/pom.xml
index 95d821f..49e4c6c 100644
--- a/indexer-reader/pom.xml
+++ b/indexer-reader/pom.xml
@@ -44,6 +44,12 @@
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>18.0</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
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 47ca80b..76fc1e5 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
@@ -22,7 +22,6 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.maven.index.reader.Transform.Function;
 import org.apache.maven.index.reader.Record.Type;
 
 import static org.apache.maven.index.reader.Utils.FIELD_SEPARATOR;
@@ -36,8 +35,11 @@
  * @since 5.1.2
  */
 public class RecordCompactor
-    implements Function<Record, Map<String, String>>
 {
+  /**
+   * Compacts {@link Record} into low level MI record with all the encoded fields as physically present in MI binary
+   * chunk.
+   */
   public Map<String, String> apply(final Record record) {
     if (Type.DESCRIPTOR == record.getType()) {
       return compactDescriptor(record);
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 1de965f..6d7f4be 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
@@ -22,7 +22,6 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.maven.index.reader.Transform.Function;
 import org.apache.maven.index.reader.Record.EntryKey;
 import org.apache.maven.index.reader.Record.Type;
 
@@ -39,8 +38,10 @@
  * @since 5.1.2
  */
 public class RecordExpander
-    implements Function<Map<String, String>, Record>
 {
+  /**
+   * Expands MI low level record into {@link Record}.
+   */
   public Record apply(final Map<String, String> recordMap) {
     if (recordMap.containsKey("DESCRIPTOR")) {
       return expandDescriptor(recordMap);
diff --git a/indexer-reader/src/main/java/org/apache/maven/index/reader/Transform.java b/indexer-reader/src/main/java/org/apache/maven/index/reader/Transform.java
deleted file mode 100644
index 50821bd..0000000
--- a/indexer-reader/src/main/java/org/apache/maven/index/reader/Transform.java
+++ /dev/null
@@ -1,212 +0,0 @@
-package org.apache.maven.index.reader;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.TreeSet;
-
-import org.apache.maven.index.reader.Record.EntryKey;
-import org.apache.maven.index.reader.Record.Type;
-
-/**
- * Helpers to transform records from one to another representation, and, some helpers for publishing.
- *
- * @since 5.1.2
- */
-public final class Transform
-{
-  private Transform() {
-    // nothing
-  }
-
-  /**
-   * Transforming function.
-   */
-  public interface Function<I, O>
-  {
-    O apply(I rec);
-  }
-
-  /**
-   * Applies {@link Function} to an {@link Iterable} on the fly.
-   */
-  public static <I, O> Iterable<O> transform(final Iterable<I> iterable, final Function<I, O> function) {
-    return new Iterable<O>()
-    {
-      public Iterator<O> iterator() {
-        return new TransformIterator<I, O>(iterable.iterator(), function);
-      }
-    };
-  }
-
-  /**
-   * 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 Record.Type#ARTIFACT_ADD}. This method will create the output as "proper" Maven Indexer record
-   * streeam, by adding the {@link Type#DESCRIPTOR}, {@link Type#ROOT_GROUPS} and {@link Type#ALL_GROUPS} special
-   * records.
-   */
-  public static Iterable<Map<String, String>> decorateAndTransform(final Iterable<Record> iterable,
-                                                                   final String repoId)
-  {
-    final RecordCompactor recordCompactor = new RecordCompactor();
-    final TreeSet<String> allGroups = new TreeSet<String>();
-    final TreeSet<String> rootGroups = new TreeSet<String>();
-    final ArrayList<Iterator<Record>> iterators = new ArrayList<Iterator<Record>>();
-    iterators.add(Collections.singletonList(descriptor(repoId)).iterator());
-    iterators.add(iterable.iterator());
-    iterators.add(Collections.singletonList(allGroups(allGroups)).iterator());
-    iterators.add(Collections.singletonList(rootGroups(rootGroups)).iterator());
-    return transform(
-        new Iterable<Record>()
-        {
-          public Iterator<Record> iterator() {
-            return new ConcatIterator<Record>(iterators.iterator());
-          }
-        },
-        new Function<Record, Map<String, String>>()
-        {
-          public Map<String, String> apply(final Record rec) {
-            if (Type.DESCRIPTOR == rec.getType()) {
-              return recordCompactor.apply(descriptor(repoId));
-            }
-            else if (Type.ALL_GROUPS == rec.getType()) {
-              return recordCompactor.apply(allGroups(allGroups));
-            }
-            else if (Type.ROOT_GROUPS == rec.getType()) {
-              return recordCompactor.apply(rootGroups(rootGroups));
-            }
-            else {
-              final String groupId = rec.get(Record.GROUP_ID);
-              if (groupId != null) {
-                allGroups.add(groupId);
-                rootGroups.add(Utils.rootGroup(groupId));
-              }
-              return recordCompactor.apply(rec);
-            }
-          }
-        }
-    );
-  }
-
-  private static Record descriptor(final String repoId) {
-    HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
-    entries.put(Record.REPOSITORY_ID, repoId);
-    return new Record(Type.DESCRIPTOR, entries);
-  }
-
-  private static Record allGroups(final Collection<String> allGroups) {
-    HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
-    entries.put(Record.ALL_GROUPS, allGroups.toArray(new String[allGroups.size()]));
-    return new Record(Type.ALL_GROUPS, entries);
-  }
-
-  private static Record rootGroups(final Collection<String> rootGroups) {
-    HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
-    entries.put(Record.ROOT_GROUPS, rootGroups.toArray(new String[rootGroups.size()]));
-    return new Record(Type.ROOT_GROUPS, entries);
-  }
-
-  // ==
-
-  private static final class TransformIterator<I, O>
-      implements Iterator<O>
-  {
-    private final Iterator<I> iterator;
-
-    private final Function<I, O> function;
-
-    private TransformIterator(final Iterator<I> iterator, final Function<I, O> function) {
-      this.iterator = iterator;
-      this.function = function;
-    }
-
-    public boolean hasNext() {
-      return iterator.hasNext();
-    }
-
-    public O next() {
-      return function.apply(iterator.next());
-    }
-
-    public void remove() {
-      throw new UnsupportedOperationException("remove");
-    }
-  }
-
-  private static final class ConcatIterator<T>
-      implements Iterator<T>
-  {
-    private final Iterator<Iterator<T>> iterators;
-
-    private Iterator<T> current;
-
-    private T nextElement;
-
-    private ConcatIterator(final Iterator<Iterator<T>> iterators) {
-      this.iterators = iterators;
-      this.nextElement = getNextElement();
-    }
-
-    public boolean hasNext() {
-      return nextElement != null;
-    }
-
-    public T next() {
-      if (nextElement == null) {
-        throw new NoSuchElementException();
-      }
-      T result = nextElement;
-      nextElement = getNextElement();
-      return result;
-    }
-
-    public void remove() {
-      throw new UnsupportedOperationException("remove");
-    }
-
-    protected T getNextElement() {
-      if ((current == null || !current.hasNext()) && iterators.hasNext()) {
-        current = iterators.next();
-      }
-      while (current != null && !current.hasNext()) {
-        if (!iterators.hasNext()) {
-          current = null;
-          break;
-        }
-        current = iterators.next();
-      }
-      if (current != null) {
-        return current.next();
-      }
-      else {
-        return null;
-      }
-    }
-  }
-}
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 c978bd6..c5b210a 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
@@ -24,10 +24,14 @@
 import java.io.OutputStream;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.Properties;
 import java.util.TimeZone;
 import java.util.regex.Pattern;
 
+import org.apache.maven.index.reader.Record.EntryKey;
+import org.apache.maven.index.reader.Record.Type;
 import org.apache.maven.index.reader.ResourceHandler.Resource;
 import org.apache.maven.index.reader.WritableResourceHandler.WritableResource;
 
@@ -42,29 +46,29 @@
     // nothing
   }
 
-  static final String INDEX_FILE_PREFIX = "nexus-maven-repository-index";
+  public static final String INDEX_FILE_PREFIX = "nexus-maven-repository-index";
 
-  static final DateFormat INDEX_DATE_FORMAT;
+  public static final DateFormat INDEX_DATE_FORMAT;
 
   static {
     INDEX_DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
     INDEX_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
   }
 
-  static final String FIELD_SEPARATOR = "|";
+  public static final String FIELD_SEPARATOR = "|";
 
-  static final String NOT_AVAILABLE = "NA";
+  public static final String NOT_AVAILABLE = "NA";
 
-  static final String UINFO = "u";
+  public static final String UINFO = "u";
 
-  static final String INFO = "i";
+  public static final String INFO = "i";
 
-  static final Pattern FS_PATTERN = Pattern.compile(Pattern.quote(FIELD_SEPARATOR));
+  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.
    */
-  static Properties loadProperties(final InputStream inputStream) throws IOException {
+  public static Properties loadProperties(final InputStream inputStream) throws IOException {
     try {
       final Properties properties = new Properties();
       properties.load(inputStream);
@@ -79,7 +83,7 @@
    * Creates and loads {@link Properties} from provided {@link Resource} if exists, and closes the resource. If not
    * exists, returns {@code null}.
    */
-  static Properties loadProperties(final Resource resource) throws IOException {
+  public static Properties loadProperties(final Resource resource) throws IOException {
     final InputStream inputStream = resource.read();
     if (inputStream == null) {
       return null;
@@ -90,7 +94,7 @@
   /**
    * Saves {@link Properties} to provided {@link OutputStream} and closes the stream.
    */
-  static void storeProperties(final OutputStream outputStream, final Properties properties) throws IOException {
+  public static void storeProperties(final OutputStream outputStream, final Properties properties) throws IOException {
     try {
       properties.store(outputStream, "Maven Indexer Writer");
     }
@@ -103,7 +107,7 @@
   /**
    * Saves {@link Properties} to provided {@link WritableResource} and closes the resource.
    */
-  static void storeProperties(final WritableResource writableResource, final Properties properties) throws IOException {
+  public static void storeProperties(final WritableResource writableResource, final Properties properties) throws IOException {
     try {
       storeProperties(writableResource.write(), properties);
     }
@@ -113,23 +117,50 @@
   }
 
   /**
+   * Creates a record of type {@link Type#DESCRIPTOR}.
+   */
+  public static Record descriptor(final String repoId) {
+    HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
+    entries.put(Record.REPOSITORY_ID, repoId);
+    return new Record(Type.DESCRIPTOR, entries);
+  }
+
+  /**
+   * Creates a record of type {@link Type#ALL_GROUPS}.
+   */
+  public static Record allGroups(final Collection<String> allGroups) {
+    HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
+    entries.put(Record.ALL_GROUPS, allGroups.toArray(new String[allGroups.size()]));
+    return new Record(Type.ALL_GROUPS, entries);
+  }
+
+  /**
+   * Creates a record of type {@link Type#ROOT_GROUPS}.
+   */
+  public static Record rootGroups(final Collection<String> rootGroups) {
+    HashMap<EntryKey, Object> entries = new HashMap<EntryKey, Object>();
+    entries.put(Record.ROOT_GROUPS, rootGroups.toArray(new String[rootGroups.size()]));
+    return new Record(Type.ROOT_GROUPS, entries);
+  }
+
+  /**
    * Helper to translate the "NA" (not available) input into {@code null} value.
    */
-  static String renvl(final String v) {
+  public static String renvl(final String v) {
     return NOT_AVAILABLE.equals(v) ? null : v;
   }
 
   /**
    * Helper to translate {@code null} into "NA" (not available) value.
    */
-  static String nvl(final String v) {
+  public static String nvl(final String v) {
     return v == null ? NOT_AVAILABLE : v;
   }
 
   /**
    * Returns the "root group" of given groupId.
    */
-  static String rootGroup(final String groupId) {
+  public static String rootGroup(final String groupId) {
     int n = groupId.indexOf('.');
     if (n > -1) {
       return groupId.substring(0, n);
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 c091317..8fc4c34 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
@@ -31,6 +31,8 @@
 import org.junit.Ignore;
 import org.junit.Test;
 
+import static org.apache.maven.index.reader.TestUtils.expandFunction;
+import static com.google.common.collect.Iterables.transform;
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.hamcrest.core.IsNot.not;
 import static org.hamcrest.core.IsNull.nullValue;
@@ -60,7 +62,7 @@
         assertThat(chunkReader.getName(), equalTo("nexus-maven-repository-index.gz"));
         assertThat(chunkReader.getVersion(), equalTo(1));
         assertThat(chunkReader.getTimestamp().getTime(), equalTo(1243533418015L));
-        for (Record record : Transform.transform(chunkReader, new RecordExpander())) {
+        for (Record record : transform(chunkReader, expandFunction)) {
           records++;
         }
       }
@@ -92,7 +94,7 @@
         assertThat(chunkReader.getName(), equalTo("nexus-maven-repository-index.gz"));
         assertThat(chunkReader.getVersion(), equalTo(1));
         assertThat(chunkReader.getTimestamp().getTime(), equalTo(1243533418015L));
-        for (Record record : Transform.transform(chunkReader, new RecordExpander())) {
+        for (Record record : transform(chunkReader, expandFunction)) {
           records++;
         }
       }
@@ -149,7 +151,7 @@
         assertThat(chunkReader.getName(), equalTo("nexus-maven-repository-index.gz"));
         assertThat(chunkReader.getVersion(), equalTo(1));
         // assertThat(chunkReader.getTimestamp().getTime(), equalTo(1243533418015L));
-        for (Record record : Transform.transform(chunkReader, new RecordExpander())) {
+        for (Record record : transform(chunkReader, expandFunction)) {
           records++;
         }
       }
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 7573e07..d1e9bc4 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
@@ -24,6 +24,8 @@
 
 import org.junit.Test;
 
+import static org.apache.maven.index.reader.TestUtils.expandFunction;
+import static com.google.common.collect.Iterables.transform;
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.assertThat;
 
@@ -76,7 +78,7 @@
         assertThat(chunkReader.getName(), equalTo("nexus-maven-repository-index.gz"));
         assertThat(chunkReader.getVersion(), equalTo(1));
         // assertThat(chunkReader.getTimestamp().getTime(), equalTo(1243533418015L));
-        for (Record record : Transform.transform(chunkReader, new RecordExpander())) {
+        for (Record record : transform(chunkReader, expandFunction)) {
           records++;
         }
       }
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
new file mode 100644
index 0000000..348d199
--- /dev/null
+++ b/indexer-reader/src/test/java/org/apache/maven/index/reader/TestUtils.java
@@ -0,0 +1,108 @@
+package org.apache.maven.index.reader;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+import java.util.TreeSet;
+
+import com.google.common.base.Function;
+import org.apache.maven.index.reader.Record.Type;
+
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.transform;
+import static java.util.Collections.singletonList;
+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 static final RecordCompactor RECORD_COMPACTOR = new RecordCompactor();
+
+  private static final RecordExpander RECORD_EXPANDER = new RecordExpander();
+
+  public static Function<Record, Map<String, String>> compactFunction =
+      new Function<Record, Map<String, String>>()
+      {
+        public Map<String, String> apply(final Record input) {
+          return RECORD_COMPACTOR.apply(input);
+        }
+      };
+
+  public static Function<Map<String, String>, Record> expandFunction =
+      new Function<Map<String, String>, Record>()
+      {
+        public Record apply(final Map<String, String> input) {
+          return RECORD_EXPANDER.apply(input);
+        }
+      };
+
+  /**
+   * 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<String>();
+    final TreeSet<String> rootGroupsSet = new TreeSet<String>();
+    return transform(
+        concat(
+            singletonList(descriptor(repoId)),
+            iterable,
+            singletonList(allGroups(allGroupsSet)), // placeholder, will be recreated at the end with proper content
+            singletonList(rootGroups(rootGroupsSet)) // placeholder, will be recreated at the end with proper content
+        ),
+        new Function<Record, Record>()
+        {
+          public Record apply(final Record rec) {
+            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) {
+                allGroupsSet.add(groupId);
+                rootGroupsSet.add(rootGroup(groupId));
+              }
+              return rec;
+            }
+          }
+        }
+    );
+  }
+}
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 0eb302b..7d48154 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
@@ -29,12 +29,15 @@
 import org.apache.maven.index.reader.Record.Type;
 import org.junit.Test;
 
+import static org.apache.maven.index.reader.TestUtils.decorate;
+import static org.apache.maven.index.reader.TestUtils.compactFunction;
+import static com.google.common.collect.Iterables.transform;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.assertThat;
 
 /**
- * UT for {@link Transform}
+ * UT for {@link RecordCompactor} and {@linl RecordExpander}.
  */
 public class TransformTest
     extends TestSupport
@@ -45,7 +48,10 @@
     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 = Transform.decorateAndTransform(Arrays.asList(r1, r2, r3), indexId);
+    Iterable<Map<String, String>> iterable = transform(
+        decorate(Arrays.asList(r1, r2, r3), indexId),
+        compactFunction
+    );
 
     WritableResourceHandler writableResourceHandler = createWritableResourceHandler();
     try {