    public static void processEvent(DataTypeHandler<Text> handler, ExtendedDataTypeHandler<Text,BulkIngestKey,Value> edgeHandler, RawRecordContainer event,
                    int expectedShardKeys, int expectedShardIndexKeys, int expectedShardReverseIndexKeys, int expectedEdgeKeys, boolean printKeysOnlyOnFail) {

        Assert.assertNotNull("Event was null.", event);
        Multimap<String,NormalizedContentInterface> eventFields = handler.getHelper(event.getDataType()).getEventFields(event);
        VirtualIngest vHelper = (VirtualIngest) handler.getHelper(event.getDataType());
        Multimap<String,NormalizedContentInterface> virtualFields = vHelper.getVirtualFields(eventFields);
        for (Map.Entry<String,NormalizedContentInterface> v : virtualFields.entries()) {
            eventFields.put(v.getKey(), v.getValue());
        }
        Multimap<BulkIngestKey,Value> results = handler.processBulk(new Text(), event, eventFields, new MockStatusReporter());
        Set<Key> shardKeys = new HashSet<>();
        Set<Key> shardIndexKeys = new HashSet<>();
        Set<Key> shardReverseIndexKeys = new HashSet<>();
        Set<Key> edgeKeys = new HashSet<>();
        Map<Text,Integer> countMap = Maps.newHashMap();

        for (BulkIngestKey k : results.keySet()) {
            Text tableName = k.getTableName();
            if (countMap.containsKey(tableName)) {
                countMap.put(tableName, countMap.get(tableName) + 1);
            } else {
                countMap.put(tableName, 1);
            }
        }

        for (Map.Entry<BulkIngestKey,Value> e : results.entries()) {

            BulkIngestKey bik = e.getKey();
            if (log.isDebugEnabled() && isDocumentKey(bik.getKey())) {
                log.debug("Found Document Key: " + bik.getKey());
                log.debug("value:\n" + e.getValue());
            }

            if (bik.getTableName().equals(shardTableName)) {
                shardKeys.add(bik.getKey());
            } else if (bik.getTableName().equals(shardIndexTableName)) {
                shardIndexKeys.add(bik.getKey());
            } else if (bik.getTableName().equals(shardReverseIndexTableName)) {
                shardReverseIndexKeys.add(bik.getKey());
            } else {
                Assert.fail("unknown table: " + bik.getTableName() + " key: " + bik.getKey());
            }

        }

        // Process edges
        countMap.put(edgeTableName, 0);
        if (null != edgeHandler) {
            MyCachingContextWriter contextWriter = new MyCachingContextWriter();
            StandaloneTaskAttemptContext<Text,RawRecordContainerImpl,BulkIngestKey,Value> ctx = new StandaloneTaskAttemptContext<>(
                            ((RawRecordContainerImpl) event).getConf(), new StandaloneStatusReporter());

            try {
                contextWriter.setup(ctx.getConfiguration(), false);
                edgeHandler.process(null, event, eventFields, ctx, contextWriter);
                contextWriter.commit(ctx);
                for (Map.Entry<BulkIngestKey,Value> entry : contextWriter.getCache().entries()) {
                    if (entry.getKey().getTableName().equals(edgeTableName)) {
                        edgeKeys.add(entry.getKey().getKey());
                    }
                    if (countMap.containsKey(entry.getKey().getTableName())) {
                        countMap.put(entry.getKey().getTableName(), countMap.get(entry.getKey().getTableName()) + 1);
                    } else {
                        countMap.put(entry.getKey().getTableName(), 1);
                    }
                }
            } catch (Throwable t) {
                log.error("Error during edge processing", t);
                throw new RuntimeException(t);
            }
        }

        Set<String> keyPrint = new TreeSet<>();

        for (Key k : shardKeys) {
            keyPrint.add("shard key: " + k.getRow() + " ::: " + k.getColumnFamily().toString().replaceAll(NB, "%00;") + " ::: "
                            + k.getColumnQualifier().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnVisibility() + " ::: " + k.getTimestamp() + "\n");
        }

        // check index keys
        for (Key k : shardIndexKeys) {
            keyPrint.add("shardIndex key: " + k.getRow() + " ::: " + k.getColumnFamily().toString().replaceAll(NB, "%00;") + " ::: "
                            + k.getColumnQualifier().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnVisibility() + " ::: " + k.getTimestamp() + "\n");
        }

        // check reverse index keys
        for (Key k : shardReverseIndexKeys) {
            keyPrint.add("reverseShardIndex key: " + k.getRow() + " ::: " + k.getColumnFamily().toString().replaceAll(NB, "%00;") + " ::: "
                            + k.getColumnQualifier().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnVisibility() + " ::: " + k.getTimestamp() + "\n");
        }

        // check edge keys
        for (Key k : edgeKeys) {
            keyPrint.add("edge key: " + k.getRow().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnFamily().toString().replaceAll(NB, "%00;")
                            + " ::: " + k.getColumnQualifier().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnVisibility() + " ::: "
                            + k.getTimestamp() + "\n");
        }

        try {
            if (!printKeysOnlyOnFail) {
                for (String keyString : keyPrint) {
                    log.info(keyString.trim());
                }
            }
            Assert.assertTrue(countMap.get(shardTableName) == expectedShardKeys && countMap.get(shardIndexTableName) == expectedShardIndexKeys
                            && countMap.get(shardReverseIndexTableName) == expectedShardReverseIndexKeys && countMap.get(edgeTableName) == expectedEdgeKeys);
        } catch (AssertionError ae) {
            if (printKeysOnlyOnFail) {
                for (String keyString : keyPrint) {
                    log.info(keyString.trim());
                }
            }
            Assert.fail(String.format("Expected: %s shard, %s index, %s reverse index, and %s edge keys.\nFound: %s, %s, %s, and %s respectively",
                            expectedShardKeys, expectedShardIndexKeys, expectedShardReverseIndexKeys, expectedEdgeKeys, countMap.get(shardTableName),
                            countMap.get(shardIndexTableName), countMap.get(shardReverseIndexTableName), countMap.get(edgeTableName)));
        }
    }

    public static void processEvent(DataTypeHandler<Text> handler, ExtendedDataTypeHandler<Text,BulkIngestKey,Value> edgeHandler, RawRecordContainer event,
                    int expectedShardKeys, int expectedShardIndexKeys, int expectedShardReverseIndexKeys, int expectedEdgeKeys, boolean printKeysOnlyOnFail) {

        Assert.assertNotNull("Event was null.", event);
        Multimap<String,NormalizedContentInterface> eventFields = handler.getHelper(event.getDataType()).getEventFields(event);
        VirtualIngest vHelper = (VirtualIngest) handler.getHelper(event.getDataType());
        Multimap<String,NormalizedContentInterface> virtualFields = vHelper.getVirtualFields(eventFields);
        for (Map.Entry<String,NormalizedContentInterface> v : virtualFields.entries()) {
            eventFields.put(v.getKey(), v.getValue());
        }
        Multimap<BulkIngestKey,Value> results = handler.processBulk(new Text(), event, eventFields, new MockStatusReporter());
        Set<Key> shardKeys = new HashSet<>();
        Set<Key> shardIndexKeys = new HashSet<>();
        Set<Key> shardReverseIndexKeys = new HashSet<>();
        Set<Key> edgeKeys = new HashSet<>();
        Map<Text,Integer> countMap = Maps.newHashMap();

        for (BulkIngestKey k : results.keySet()) {
            Text tableName = k.getTableName();
            if (countMap.containsKey(tableName)) {
                countMap.put(tableName, countMap.get(tableName) + 1);
            } else {
                countMap.put(tableName, 1);
            }
        }

        for (Map.Entry<BulkIngestKey,Value> e : results.entries()) {

            BulkIngestKey bik = e.getKey();
            if (log.isDebugEnabled() && isDocumentKey(bik.getKey())) {
                log.debug("Found Document Key: " + bik.getKey());
                log.debug("value:\n" + e.getValue());
            }

            if (bik.getTableName().equals(shardTableName)) {
                shardKeys.add(bik.getKey());
            } else if (bik.getTableName().equals(shardIndexTableName)) {
                shardIndexKeys.add(bik.getKey());
            } else if (bik.getTableName().equals(shardReverseIndexTableName)) {
                shardReverseIndexKeys.add(bik.getKey());
            } else {
                Assert.fail("unknown table: " + bik.getTableName() + " key: " + bik.getKey());
            }

        }

        // Process edges
        countMap.put(edgeTableName, 0);
        if (null != edgeHandler) {
            MyCachingContextWriter contextWriter = new MyCachingContextWriter();
            StandaloneTaskAttemptContext<Text,RawRecordContainerImpl,BulkIngestKey,Value> ctx = new StandaloneTaskAttemptContext<>(
                            ((RawRecordContainerImpl) event).getConf(), new StandaloneStatusReporter());

            try {
                contextWriter.setup(ctx.getConfiguration(), false);
                edgeHandler.process(null, event, eventFields, ctx, contextWriter);
                contextWriter.commit(ctx);
                for (Map.Entry<BulkIngestKey,Value> entry : contextWriter.getCache().entries()) {
                    if (entry.getKey().getTableName().equals(edgeTableName)) {
                        edgeKeys.add(entry.getKey().getKey());
                    }
                    if (countMap.containsKey(entry.getKey().getTableName())) {
                        countMap.put(entry.getKey().getTableName(), countMap.get(entry.getKey().getTableName()) + 1);
                    } else {
                        countMap.put(entry.getKey().getTableName(), 1);
                    }
                }
            } catch (Throwable t) {
                log.error("Error during edge processing", t);
                throw new RuntimeException(t);
            }
        }

        Set<String> keyPrint = new TreeSet<String>();

        for (Key k : shardKeys) {
            keyPrint.add("shard key: " + k.getRow() + " ::: " + k.getColumnFamily().toString().replaceAll(NB, "%00;") + " ::: "
                            + k.getColumnQualifier().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnVisibility() + " ::: " + k.getTimestamp() + "\n");
        }

        // check index keys
        for (Key k : shardIndexKeys) {
            keyPrint.add("shardIndex key: " + k.getRow() + " ::: " + k.getColumnFamily().toString().replaceAll(NB, "%00;") + " ::: "
                            + k.getColumnQualifier().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnVisibility() + " ::: " + k.getTimestamp() + "\n");
        }

        // check reverse index keys
        for (Key k : shardReverseIndexKeys) {
            keyPrint.add("reverseShardIndex key: " + k.getRow() + " ::: " + k.getColumnFamily().toString().replaceAll(NB, "%00;") + " ::: "
                            + k.getColumnQualifier().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnVisibility() + " ::: " + k.getTimestamp() + "\n");
        }

        // check edge keys
        for (Key k : edgeKeys) {
            keyPrint.add("edge key: " + k.getRow().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnFamily().toString().replaceAll(NB, "%00;")
                            + " ::: " + k.getColumnQualifier().toString().replaceAll(NB, "%00;") + " ::: " + k.getColumnVisibility() + " ::: "
                            + k.getTimestamp() + "\n");
        }

        try {
            if (!printKeysOnlyOnFail) {
                for (String keyString : keyPrint) {
                    log.info(keyString.trim());
                }
            }
            Assert.assertTrue(countMap.get(shardTableName) == expectedShardKeys && countMap.get(shardIndexTableName) == expectedShardIndexKeys
                            && countMap.get(shardReverseIndexTableName) == expectedShardReverseIndexKeys && countMap.get(edgeTableName) == expectedEdgeKeys);
        } catch (AssertionError ae) {
            if (printKeysOnlyOnFail) {
                for (String keyString : keyPrint) {
                    log.info(keyString.trim());
                }
            }
            Assert.fail(String.format("Expected: %s shard, %s index, %s reverse index, and %s edge keys.\nFound: %s, %s, %s, and %s respectively",
                            expectedShardKeys, expectedShardIndexKeys, expectedShardReverseIndexKeys, expectedEdgeKeys, countMap.get(shardTableName),
                            countMap.get(shardIndexTableName), countMap.get(shardReverseIndexTableName), countMap.get(edgeTableName)));
        }
    }

Replace Generic With Diamond TreeSet<String> with TreeSet<> in method public processEvent(handler DataTypeHandler<Text>, edgeHandler ExtendedDataTypeHandler<Text,BulkIngestKey,Value>, event RawRecordContainer, expectedShardKeys int, expectedShardIndexKeys int, expectedShardReverseIndexKeys int, expectedEdgeKeys int, printKeysOnlyOnFail boolean) : void from class datawave.ingest.json.mr.handler.ColumnBasedHandlerTestUtil


    @Test
    public void testJsonContentHandlers() throws Exception {
        conf.addResource(ClassLoader.getSystemResource("config/ingest/all-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/tvmaze-ingest-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/edge-ingest-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/metadata-config.xml"));
        TypeRegistry.getInstance(conf);
        JsonDataTypeHelper helper = new JsonDataTypeHelper();
        helper.setup(conf);

        // Set up the IngestHelper
        JsonIngestHelper ingestHelper = new JsonIngestHelper();
        ingestHelper.setup(conf);

        // Set up the ColumnBasedHandler
        TaskAttemptContext context = new TaskAttemptContextImpl(conf, new TaskAttemptID());
        ContentJsonColumnBasedHandler<Text> jsonHandler = new ContentJsonColumnBasedHandler<>();
        jsonHandler.setup(context);

        // Set up the Reader
        JsonRecordReader reader = getJsonRecordReader("/input/tvmaze-seinfeld.json");

        Assert.assertTrue("First Record did not read properly?", reader.nextKeyValue());
        RawRecordContainer event = reader.getEvent();
        Assert.assertNotNull("Event 1 was null.", event);
        Assert.assertTrue("Event 1 has parsing errors", event.getErrors().isEmpty());

        // Set up the edge
        ProtobufEdgeDataTypeHandler<Text,BulkIngestKey,Value> edgeHandler = new ProtobufEdgeDataTypeHandler<>();
        edgeHandler.setup(context);

        ColumnBasedHandlerTestUtil.processEvent(jsonHandler, edgeHandler, event, 231, 90, 4, 38, PRINT_GENERATED_KEYS_ONLY_ON_FAIL);

        reader.close();
    }

    @Test
    public void testJsonContentHandlers() throws Exception {
        conf.addResource(ClassLoader.getSystemResource("config/ingest/all-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/tvmaze-ingest-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/edge-ingest-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/metadata-config.xml"));
        TypeRegistry.getInstance(conf);
        JsonDataTypeHelper helper = new JsonDataTypeHelper();
        helper.setup(conf);

        // Set up the IngestHelper
        JsonIngestHelper ingestHelper = new JsonIngestHelper();
        ingestHelper.setup(conf);

        // Set up the ColumnBasedHandler
        TaskAttemptContext context = new TaskAttemptContextImpl(conf, new TaskAttemptID());
        ContentJsonColumnBasedHandler<Text> jsonHandler = new ContentJsonColumnBasedHandler<Text>();
        jsonHandler.setup(context);

        // Set up the Reader
        JsonRecordReader reader = getJsonRecordReader("/input/tvmaze-seinfeld.json");

        Assert.assertTrue("First Record did not read properly?", reader.nextKeyValue());
        RawRecordContainer event = reader.getEvent();
        Assert.assertNotNull("Event 1 was null.", event);
        Assert.assertTrue("Event 1 has parsing errors", event.getErrors().isEmpty());

        // Set up the edge
        ProtobufEdgeDataTypeHandler<Text,BulkIngestKey,Value> edgeHandler = new ProtobufEdgeDataTypeHandler<>();
        edgeHandler.setup(context);

        ColumnBasedHandlerTestUtil.processEvent(jsonHandler, edgeHandler, event, 231, 90, 4, 38, PRINT_GENERATED_KEYS_ONLY_ON_FAIL);

        reader.close();
    }

Replace Generic With Diamond ContentJsonColumnBasedHandler<Text> with ContentJsonColumnBasedHandler<> in method public testJsonContentHandlers() : void from class datawave.ingest.json.mr.handler.ContentJsonColumnBasedHandlerTest


    @Test
    public void testNyctlc01() throws Exception {
        log.debug("---testNyctlc01---");
        conf.addResource(ClassLoader.getSystemResource("config/ingest/all-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/nyctlc-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/metadata-config.xml"));
        TypeRegistry.getInstance(conf);
        NYCTLCHelper helper = new NYCTLCHelper();
        helper.setup(conf);

        // Set up the IngestHelper
        NYCTLCIngestHelper ingestHelper = new NYCTLCIngestHelper();
        ingestHelper.setup(conf);

        // Set up the ColumnBasedHandler
        TaskAttemptContext context = new TaskAttemptContextImpl(conf, new TaskAttemptID());
        AbstractColumnBasedHandler<Text> abstractHandler = new AbstractColumnBasedHandler<>();
        abstractHandler.setup(context);

        // Set up the Reader
        NYCTLCReader reader = getNYCTLCRecordReader("/input/nyctlc.csv");

        // ----------------------------------------------------------------------
        // EVENT 1
        Assert.assertTrue("First Record did not read properly?", reader.nextKeyValue());
        RawRecordContainer event = reader.getEvent();
        Assert.assertNotNull("Event 1 was null.", event);
        Assert.assertTrue("Event 1 has parsing errors", event.getErrors().isEmpty());
        System.out.println("================================= EVENT 1 =================================");
        ColumnBasedHandlerTestUtil.processEvent(abstractHandler, null, event, 28, 6, 0, 0, false);

        // ----------------------------------------------------------------------
        // EVENT 2
        Assert.assertTrue("Second Record did not read properly?", reader.nextKeyValue());
        event = reader.getEvent();
        Assert.assertNotNull("Event 2 was null.", event);
        Assert.assertTrue("Event 2 has parsing errors", event.getErrors().isEmpty());
        System.out.println("================================= EVENT 2 =================================");
        ColumnBasedHandlerTestUtil.processEvent(abstractHandler, null, event, 29, 6, 0, 0, false);

        // ----------------------------------------------------------------------
        // EVENT 3
        Assert.assertTrue("Third Record did not read properly?", reader.nextKeyValue());
        event = reader.getEvent();
        Assert.assertNotNull("Event 3 was null.", event);
        Assert.assertTrue("Event 3 has parsing errors", event.getErrors().isEmpty());
        System.out.println("================================= EVENT 3 =================================");
        ColumnBasedHandlerTestUtil.processEvent(abstractHandler, null, event, 28, 6, 0, 0, false);

        reader.close();
    }

    @Test
    public void testNyctlc01() throws Exception {
        log.debug("---testNyctlc01---");
        conf.addResource(ClassLoader.getSystemResource("config/ingest/all-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/nyctlc-config.xml"));
        conf.addResource(ClassLoader.getSystemResource("config/ingest/metadata-config.xml"));
        TypeRegistry.getInstance(conf);
        NYCTLCHelper helper = new NYCTLCHelper();
        helper.setup(conf);

        // Set up the IngestHelper
        NYCTLCIngestHelper ingestHelper = new NYCTLCIngestHelper();
        ingestHelper.setup(conf);

        // Set up the ColumnBasedHandler
        TaskAttemptContext context = new TaskAttemptContextImpl(conf, new TaskAttemptID());
        AbstractColumnBasedHandler<Text> abstractHandler = new AbstractColumnBasedHandler<Text>();
        abstractHandler.setup(context);

        // Set up the Reader
        NYCTLCReader reader = getNYCTLCRecordReader("/input/nyctlc.csv");

        // ----------------------------------------------------------------------
        // EVENT 1
        Assert.assertTrue("First Record did not read properly?", reader.nextKeyValue());
        RawRecordContainer event = reader.getEvent();
        Assert.assertNotNull("Event 1 was null.", event);
        Assert.assertTrue("Event 1 has parsing errors", event.getErrors().isEmpty());
        System.out.println("================================= EVENT 1 =================================");
        ColumnBasedHandlerTestUtil.processEvent(abstractHandler, null, event, 28, 6, 0, 0, false);

        // ----------------------------------------------------------------------
        // EVENT 2
        Assert.assertTrue("Second Record did not read properly?", reader.nextKeyValue());
        event = reader.getEvent();
        Assert.assertNotNull("Event 2 was null.", event);
        Assert.assertTrue("Event 2 has parsing errors", event.getErrors().isEmpty());
        System.out.println("================================= EVENT 2 =================================");
        ColumnBasedHandlerTestUtil.processEvent(abstractHandler, null, event, 29, 6, 0, 0, false);

        // ----------------------------------------------------------------------
        // EVENT 3
        Assert.assertTrue("Third Record did not read properly?", reader.nextKeyValue());
        event = reader.getEvent();
        Assert.assertNotNull("Event 3 was null.", event);
        Assert.assertTrue("Event 3 has parsing errors", event.getErrors().isEmpty());
        System.out.println("================================= EVENT 3 =================================");
        ColumnBasedHandlerTestUtil.processEvent(abstractHandler, null, event, 28, 6, 0, 0, false);

        reader.close();
    }

Replace Generic With Diamond AbstractColumnBasedHandler<Text> with AbstractColumnBasedHandler<> in method public testNyctlc01() : void from class datawave.ingest.nyctlc.mr.handler.NYCTLCColumnBasedHandlerTest


    private void fillSortedSets() throws IOException {
        String sourceRow = this.fiRow.toString();
        setupRowBasedHdfsBackedSet(sourceRow);

        // for each range, fork off a runnable
        List<Future<?>> futures = new ArrayList<>(boundingFiRanges.size());
        if (log.isDebugEnabled()) {
            log.debug("Processing " + boundingFiRanges + " for " + this);
        }

        for (Range range : boundingFiRanges) {
            if (log.isTraceEnabled()) {
                log.trace("range -> " + range);
            }
            final Range boundingFiRange = range;
            futures.add(fillSet(boundingFiRange));
        }

        boolean failed = false;
        Exception exception = null;
        Object result = null;

        // wait for all of the threads to complete
        for (Future<?> future : futures) {
            checkTiming();

            if (failed || this.setControl.isCancelledQuery()) {
                future.cancel(false);
            } else {
                try {
                    result = future.get();
                } catch (Exception e) {
                    exception = e;
                    result = e;
                }
                if (result != null) {
                    failed = true;
                    this.setControl.setCancelled();
                }
            }
            if (this.setControl.isCancelledQuery()) {
                break;
            }
        }

        if (failed) {
            log.error("Failed to complete ivarator cache: " + result, exception);
            throw new IvaratorException("Failed to complete ivarator cache: " + result, exception);
        }

        // now reset the current source to the next viable range
        moveToNextRow();
    }

    private void fillSortedSets() throws IOException {
        String sourceRow = this.fiRow.toString();
        setupRowBasedHdfsBackedSet(sourceRow);

        // for each range, fork off a runnable
        List<Future<?>> futures = new ArrayList<Future<?>>(boundingFiRanges.size());
        if (log.isDebugEnabled()) {
            log.debug("Processing " + boundingFiRanges + " for " + this);
        }

        for (Range range : boundingFiRanges) {
            if (log.isTraceEnabled()) {
                log.trace("range -> " + range);
            }
            final Range boundingFiRange = range;
            futures.add(fillSet(boundingFiRange));
        }

        boolean failed = false;
        Exception exception = null;
        Object result = null;

        // wait for all of the threads to complete
        for (Future<?> future : futures) {
            checkTiming();

            if (failed || this.setControl.isCancelledQuery()) {
                future.cancel(false);
            } else {
                try {
                    result = future.get();
                } catch (Exception e) {
                    exception = e;
                    result = e;
                }
                if (result != null) {
                    failed = true;
                    this.setControl.setCancelled();
                }
            }
            if (this.setControl.isCancelledQuery()) {
                break;
            }
        }

        if (failed) {
            log.error("Failed to complete ivarator cache: " + result, exception);
            throw new IvaratorException("Failed to complete ivarator cache: " + result, exception);
        }

        // now reset the current source to the next viable range
        moveToNextRow();
    }

Replace Generic With Diamond ArrayList<Future<?>> with ArrayList<> in method private fillSortedSets() : void from class datawave.core.iterators.DatawaveFieldIndexCachingIteratorJexl


    private void getNextUnsortedKey() throws IOException {
        this.keyValues = null;

        // if we are in a row but bounding ranges is empty, then something has gone awry
        if (fiRow != null && boundingFiRanges.isEmpty()) {
            throw new IvaratorException("Ivarator found to be in an illegal state with empty bounding FiRanges: fiRow = " + fiRow + " and lastRangeSeeked = "
                            + lastRangeSeeked);
        }

        // create a set if needed (does not actually need to be thread safe as we are only using one thread in this case)
        if (this.threadSafeSet == null) {
            this.threadSafeSet = new TreeSet<>();
        } else {
            this.threadSafeSet.clear();
        }

        // if this is the first time through, then create a separate source, and seek
        if (this.fiSource == null) {
            this.fiSource = getSourceCopy(true);
            if (!this.boundingFiRanges.isEmpty()) {
                if (log.isTraceEnabled()) {
                    log.trace("Seeking fisource to " + this.boundingFiRanges.get(0));
                }
                this.fiSource.seek(this.boundingFiRanges.get(0), EMPTY_CFS, false);
            }
        }

        while (!this.boundingFiRanges.isEmpty() && this.threadSafeSet.isEmpty()) {
            // track through the ranges and rows until we have a hit
            while (!this.boundingFiRanges.isEmpty() && !this.fiSource.hasTop()) {
                this.boundingFiRanges.remove(0);
                if (this.boundingFiRanges.isEmpty()) {
                    moveToNextRow();
                }
                if (!this.boundingFiRanges.isEmpty()) {
                    if (log.isTraceEnabled()) {
                        log.trace("Seeking fisource to " + this.boundingFiRanges.get(0));
                    }
                    this.fiSource.seek(this.boundingFiRanges.get(0), EMPTY_CFS, false);
                }
            }

            if (this.fiSource.hasTop()) {
                addKey(this.fiSource.getTopKey(), this.fiSource.getTopValue());
                this.fiSource.next();
            }
        }
    }

    private void getNextUnsortedKey() throws IOException {
        this.keyValues = null;

        // if we are in a row but bounding ranges is empty, then something has gone awry
        if (fiRow != null && boundingFiRanges.isEmpty()) {
            throw new IvaratorException("Ivarator found to be in an illegal state with empty bounding FiRanges: fiRow = " + fiRow + " and lastRangeSeeked = "
                            + lastRangeSeeked);
        }

        // create a set if needed (does not actually need to be thread safe as we are only using one thread in this case)
        if (this.threadSafeSet == null) {
            this.threadSafeSet = new TreeSet<KeyValueSerializable>();
        } else {
            this.threadSafeSet.clear();
        }

        // if this is the first time through, then create a separate source, and seek
        if (this.fiSource == null) {
            this.fiSource = getSourceCopy(true);
            if (!this.boundingFiRanges.isEmpty()) {
                if (log.isTraceEnabled()) {
                    log.trace("Seeking fisource to " + this.boundingFiRanges.get(0));
                }
                this.fiSource.seek(this.boundingFiRanges.get(0), EMPTY_CFS, false);
            }
        }

        while (!this.boundingFiRanges.isEmpty() && this.threadSafeSet.isEmpty()) {
            // track through the ranges and rows until we have a hit
            while (!this.boundingFiRanges.isEmpty() && !this.fiSource.hasTop()) {
                this.boundingFiRanges.remove(0);
                if (this.boundingFiRanges.isEmpty()) {
                    moveToNextRow();
                }
                if (!this.boundingFiRanges.isEmpty()) {
                    if (log.isTraceEnabled()) {
                        log.trace("Seeking fisource to " + this.boundingFiRanges.get(0));
                    }
                    this.fiSource.seek(this.boundingFiRanges.get(0), EMPTY_CFS, false);
                }
            }

            if (this.fiSource.hasTop()) {
                addKey(this.fiSource.getTopKey(), this.fiSource.getTopValue());
                this.fiSource.next();
            }
        }
    }

Replace Generic With Diamond TreeSet<KeyValueSerializable> with TreeSet<> in method private getNextUnsortedKey() : void from class datawave.core.iterators.DatawaveFieldIndexCachingIteratorJexl


    /**
     * This will setup the set for the specified range. This will attempt to reuse precomputed and persisted sets if we are allowed to.
     *
     * @param row
     * @throws IOException
     */
    protected void setupRowBasedHdfsBackedSet(String row) throws IOException {
        // we are done if cancelled
        if (this.setControl.isCancelledQuery()) {
            return;
        }

        try {
            // get the row specific dir
            Path rowDir = getRowDir(row);

            // if we are not allowing reuse of directories, then delete it
            if (!allowDirReuse && this.fs.exists(rowDir)) {
                this.fs.delete(rowDir, true);
            }

            // ensure the directory is created
            if (!this.fs.exists(rowDir)) {
                this.fs.mkdirs(rowDir);
                this.createdRowDir = true;
            } else {
                this.createdRowDir = false;
            }

            this.set = new HdfsBackedSortedSet<>(null, hdfsBackedSetBufferSize, fs, rowDir, maxOpenFiles);
            this.threadSafeSet = Collections.synchronizedSortedSet(this.set);
            this.currentRow = row;
            this.setControl.takeOwnership(row, this);

            // if this set is not marked as complete (meaning completely filled AND persisted), then we cannot trust the contents and we need to recompute.
            if (!this.setControl.isCompleteAndPersisted(row)) {
                this.set.clear();
                this.keyValues = null;
            } else {
                this.keyValues = this.set.iterator();
            }

            // reset the keyValues counter as we have a new set here
            scannedKeys.set(0);
        } catch (IOException ioe) {
            throw new IllegalStateException("Unable to create Hdfs backed sorted set", ioe);
        }
    }

    /**
     * This will setup the set for the specified range. This will attempt to reuse precomputed and persisted sets if we are allowed to.
     *
     * @param row
     * @throws IOException
     */
    protected void setupRowBasedHdfsBackedSet(String row) throws IOException {
        // we are done if cancelled
        if (this.setControl.isCancelledQuery()) {
            return;
        }

        try {
            // get the row specific dir
            Path rowDir = getRowDir(row);

            // if we are not allowing reuse of directories, then delete it
            if (!allowDirReuse && this.fs.exists(rowDir)) {
                this.fs.delete(rowDir, true);
            }

            // ensure the directory is created
            if (!this.fs.exists(rowDir)) {
                this.fs.mkdirs(rowDir);
                this.createdRowDir = true;
            } else {
                this.createdRowDir = false;
            }

            this.set = new HdfsBackedSortedSet<KeyValueSerializable>(null, hdfsBackedSetBufferSize, fs, rowDir, maxOpenFiles);
            this.threadSafeSet = Collections.synchronizedSortedSet(this.set);
            this.currentRow = row;
            this.setControl.takeOwnership(row, this);

            // if this set is not marked as complete (meaning completely filled AND persisted), then we cannot trust the contents and we need to recompute.
            if (!this.setControl.isCompleteAndPersisted(row)) {
                this.set.clear();
                this.keyValues = null;
            } else {
                this.keyValues = this.set.iterator();
            }

            // reset the keyValues counter as we have a new set here
            scannedKeys.set(0);
        } catch (IOException ioe) {
            throw new IllegalStateException("Unable to create Hdfs backed sorted set", ioe);
        }
    }

Replace Generic With Diamond HdfsBackedSortedSet<KeyValueSerializable> with HdfsBackedSortedSet<> in method protected setupRowBasedHdfsBackedSet(row String) : void from class datawave.core.iterators.DatawaveFieldIndexCachingIteratorJexl


    @Override
    protected List<Range> buildBoundingFiRanges(Text rowId, Text fiName, Text fieldValue) {
        if (fst != null || isNegated()) {
            Key startKey = null;
            Key endKey = null;
            startKey = new Key(rowId, fiName);
            endKey = new Key(rowId, new Text(fiName.toString() + Constants.NULL_BYTE_STRING));
            return new RangeSplitter(new Range(startKey, true, endKey, true), getMaxRangeSplit());
        } else {
            List<Range> ranges = new ArrayList<>();
            for (String value : values) {
                ranges.add(buildBoundingRange(rowId, fiName, new Text(value)));
            }
            // TODO: reduce (or expand) ranges by maxRangeSplit
            return ranges;
        }
    }

    @Override
    protected List<Range> buildBoundingFiRanges(Text rowId, Text fiName, Text fieldValue) {
        if (fst != null || isNegated()) {
            Key startKey = null;
            Key endKey = null;
            startKey = new Key(rowId, fiName);
            endKey = new Key(rowId, new Text(fiName.toString() + Constants.NULL_BYTE_STRING));
            return new RangeSplitter(new Range(startKey, true, endKey, true), getMaxRangeSplit());
        } else {
            List<Range> ranges = new ArrayList<Range>();
            for (String value : values) {
                ranges.add(buildBoundingRange(rowId, fiName, new Text(value)));
            }
            // TODO: reduce (or expand) ranges by maxRangeSplit
            return ranges;
        }
    }

Replace Generic With Diamond ArrayList<Range> with ArrayList<> in method protected buildBoundingFiRanges(rowId Text, fiName Text, fieldValue Text) : List<Range> from class datawave.core.iterators.DatawaveFieldIndexListIteratorJexl


    private ThreadPoolExecutor createExecutorService(int maxThreads, String name) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(maxThreads, maxThreads, 5 * 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
                        new NamingThreadFactory(name));
        pool.allowCoreThreadTimeOut(true);
        return pool;
    }

    private ThreadPoolExecutor createExecutorService(int maxThreads, String name) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(maxThreads, maxThreads, 5 * 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
                        new NamingThreadFactory(name));
        pool.allowCoreThreadTimeOut(true);
        return pool;
    }

Replace Generic With Diamond ThreadPoolExecutor with ThreadPoolExecutor in method private createExecutorService(maxThreads int, name String) : ThreadPoolExecutor from class datawave.core.iterators.IteratorThreadPoolManager


    private int getMaxThreads(final String prop) {
        if (this.confFactory != null) {
            AccumuloConfiguration conf = this.confFactory.getConfiguration();
            Map<String,String> properties = new TreeMap<>();
            conf.getProperties(properties, new AccumuloConfiguration.MatchFilter(prop));
            if (properties.containsKey(prop)) {
                return Integer.parseInt(properties.get(prop));
            }
        }
        return DEFAULT_THREAD_POOL_SIZE;
    }

    private int getMaxThreads(final String prop) {
        if (this.confFactory != null) {
            AccumuloConfiguration conf = this.confFactory.getConfiguration();
            Map<String,String> properties = new TreeMap<String,String>();
            conf.getProperties(properties, new AccumuloConfiguration.MatchFilter(prop));
            if (properties.containsKey(prop)) {
                return Integer.parseInt(properties.get(prop));
            }
        }
        return DEFAULT_THREAD_POOL_SIZE;
    }

Replace Generic With Diamond TreeMap<String,String> with TreeMap<> in method private getMaxThreads(prop String) : int from class datawave.core.iterators.IteratorThreadPoolManager


    /**
     * Split a range into N ranges.
     *
     * @param range
     * @param numRanges
     * @return A list of N ranges. 1 range is returned if no splitting is possible.
     */
    protected List<Range> splitRange(Range range, int numRanges) {
        List<Range> splitRanges = new ArrayList<>();

        List<ByteSequence> start = getStartKeyElements(range.getStartKey());
        List<ByteSequence> end = getEndKeyElements(start, range.getEndKey());

        // loop through the key elements until we find a difference between the start and end
        for (int i = 0; i < start.size(); i++) {

            // if we have a difference, then go to work
            ByteSequence x = start.get(i);
            ByteSequence y = end.get(i);
            if (!equivalentElements(x, y)) {

                // get two integers representing the start and end that can be divided into numRanges
                BigInteger[] integers = getIntegers(x, y, numRanges);
                BigInteger xInt = integers[0];
                BigInteger div = integers[2];

                // Get the values initialized for the first range
                Key startKey = range.getStartKey();
                byte[] cv = (startKey == null ? new byte[0] : startKey.getColumnVisibility().getBytes());
                long ts = (startKey == null ? 0 : range.getStartKey().getTimestamp());
                boolean startKeyInclusive = range.isStartKeyInclusive();
                boolean endKeyInclusive = false;

                // now create ranges using the bytes for the integers between xInt and yInt by step sizes of div
                for (int j = 0; j < numRanges; j++) {
                    // Get the values for the end of the range
                    ByteSequence endRange = y;
                    Key endKey = range.getEndKey();

                    if (j < (numRanges - 1)) {
                        // if not the last range, then calculate the intermediate end key
                        xInt = xInt.add(div);
                        byte[] bytes = xInt.toByteArray();
                        if (bytes[0] == 0) {
                            endRange = new ArrayByteSequence(bytes, 1, bytes.length - 1);
                        } else {
                            endRange = new ArrayByteSequence(bytes);
                        }
                        // using the start components on either side of the calculated end element to ensure we do not
                        // create an invalid range (where start > end)
                        endKey = getKey(start.subList(0, i), endRange, start.subList(i + 1, end.size()), cv, ts);
                    } else {
                        // if the last range, then use the ending inclusive flag
                        endKeyInclusive = range.isEndKeyInclusive();
                    }

                    // create the range
                    splitRanges.add(new Range(startKey, startKeyInclusive, endKey, endKeyInclusive));

                    // now setup for the next range
                    startKeyInclusive = true;
                    endKeyInclusive = false;
                    startKey = endKey;
                }
                break;
            }
        }

        if (splitRanges.isEmpty()) {
            splitRanges.add(range);
        }

        return splitRanges;
    }

    /**
     * Split a range into N ranges.
     *
     * @param range
     * @param numRanges
     * @return A list of N ranges. 1 range is returned if no splitting is possible.
     */
    protected List<Range> splitRange(Range range, int numRanges) {
        List<Range> splitRanges = new ArrayList<Range>();

        List<ByteSequence> start = getStartKeyElements(range.getStartKey());
        List<ByteSequence> end = getEndKeyElements(start, range.getEndKey());

        // loop through the key elements until we find a difference between the start and end
        for (int i = 0; i < start.size(); i++) {

            // if we have a difference, then go to work
            ByteSequence x = start.get(i);
            ByteSequence y = end.get(i);
            if (!equivalentElements(x, y)) {

                // get two integers representing the start and end that can be divided into numRanges
                BigInteger[] integers = getIntegers(x, y, numRanges);
                BigInteger xInt = integers[0];
                BigInteger div = integers[2];

                // Get the values initialized for the first range
                Key startKey = range.getStartKey();
                byte[] cv = (startKey == null ? new byte[0] : startKey.getColumnVisibility().getBytes());
                long ts = (startKey == null ? 0 : range.getStartKey().getTimestamp());
                boolean startKeyInclusive = range.isStartKeyInclusive();
                boolean endKeyInclusive = false;

                // now create ranges using the bytes for the integers between xInt and yInt by step sizes of div
                for (int j = 0; j < numRanges; j++) {
                    // Get the values for the end of the range
                    ByteSequence endRange = y;
                    Key endKey = range.getEndKey();

                    if (j < (numRanges - 1)) {
                        // if not the last range, then calculate the intermediate end key
                        xInt = xInt.add(div);
                        byte[] bytes = xInt.toByteArray();
                        if (bytes[0] == 0) {
                            endRange = new ArrayByteSequence(bytes, 1, bytes.length - 1);
                        } else {
                            endRange = new ArrayByteSequence(bytes);
                        }
                        // using the start components on either side of the calculated end element to ensure we do not
                        // create an invalid range (where start > end)
                        endKey = getKey(start.subList(0, i), endRange, start.subList(i + 1, end.size()), cv, ts);
                    } else {
                        // if the last range, then use the ending inclusive flag
                        endKeyInclusive = range.isEndKeyInclusive();
                    }

                    // create the range
                    splitRanges.add(new Range(startKey, startKeyInclusive, endKey, endKeyInclusive));

                    // now setup for the next range
                    startKeyInclusive = true;
                    endKeyInclusive = false;
                    startKey = endKey;
                }
                break;
            }
        }

        if (splitRanges.isEmpty()) {
            splitRanges.add(range);
        }

        return splitRanges;
    }

Replace Generic With Diamond ArrayList<Range> with ArrayList<> in method protected splitRange(range Range, numRanges int) : List<Range> from class datawave.core.iterators.RangeSplitter


    /**
     * Return a list of ByteSequence objects representing the row, cf, and cq in that order.
     *
     * @param key
     * @return the byte sequences
     */
    protected List<ByteSequence> getKeyElements(Key key) {
        List<ByteSequence> bytes = new ArrayList<>();
        bytes.add(key.getRowData());
        bytes.add(key.getColumnFamilyData());
        bytes.add(key.getColumnQualifierData());
        return bytes;
    }

    /**
     * Return a list of ByteSequence objects representing the row, cf, and cq in that order.
     *
     * @param key
     * @return the byte sequences
     */
    protected List<ByteSequence> getKeyElements(Key key) {
        List<ByteSequence> bytes = new ArrayList<ByteSequence>();
        bytes.add(key.getRowData());
        bytes.add(key.getColumnFamilyData());
        bytes.add(key.getColumnQualifierData());
        return bytes;
    }

Replace Generic With Diamond ArrayList<ByteSequence> with ArrayList<> in method protected getKeyElements(key Key) : List<ByteSequence> from class datawave.core.iterators.RangeSplitter


    /**
     * Return a list of ByteSequence objects representing the row, cf, and cq in that order. If the key is null, then return 3 empty byte sequences.
     *
     * @param key
     * @return the byte sequences
     */
    protected List<ByteSequence> getStartKeyElements(Key key) {
        if (key != null) {
            return getKeyElements(key);
        } else {
            List<ByteSequence> bytes = new ArrayList<>();
            bytes.add(new ArrayByteSequence(new byte[1]));
            bytes.add(new ArrayByteSequence(new byte[1]));
            bytes.add(new ArrayByteSequence(new byte[1]));
            return bytes;
        }
    }

    /**
     * Return a list of ByteSequence objects representing the row, cf, and cq in that order. If the key is null, then return 3 empty byte sequences.
     *
     * @param key
     * @return the byte sequences
     */
    protected List<ByteSequence> getStartKeyElements(Key key) {
        if (key != null) {
            return getKeyElements(key);
        } else {
            List<ByteSequence> bytes = new ArrayList<ByteSequence>();
            bytes.add(new ArrayByteSequence(new byte[1]));
            bytes.add(new ArrayByteSequence(new byte[1]));
            bytes.add(new ArrayByteSequence(new byte[1]));
            return bytes;
        }
    }

Replace Generic With Diamond ArrayList<ByteSequence> with ArrayList<> in method protected getStartKeyElements(key Key) : List<ByteSequence> from class datawave.core.iterators.RangeSplitter


    /**
     * Return a list of ByteSequence objects representing the row, cf, and cq in that order. However since we are dealing with the end key, we need to fix up a
     * few things. For empty elements, return 3 byte sequences filled with 0xFF the same size as the start byte sequences. This will allow us to calculate
     * reasonable ranges ranges.
     *
     * @param key
     * @return the byte sequences
     */
    protected List<ByteSequence> getEndKeyElements(List<ByteSequence> startElements, Key key) {
        List<ByteSequence> bytes = new ArrayList<>(startElements.size());
        if (key != null) {
            List<ByteSequence> endElements = getKeyElements(key);
            for (int i = 0; i < endElements.size(); i++) {
                ByteSequence startBytes = startElements.get(i);
                ByteSequence endBytes = endElements.get(i);
                if (endBytes.length() == 0 && startBytes.length() > 0) {
                    byte[] end = new byte[startBytes.length()];
                    Arrays.fill(end, (byte) 0xFF);
                    bytes.add(new ArrayByteSequence(end));
                } else {
                    bytes.add(endBytes);
                }
            }
        } else {
            for (ByteSequence startBytes : startElements) {
                byte[] end = new byte[startBytes.length()];
                Arrays.fill(end, (byte) 0xFF);
                bytes.add(new ArrayByteSequence(end));
            }
        }
        return bytes;
    }

    /**
     * Return a list of ByteSequence objects representing the row, cf, and cq in that order. However since we are dealing with the end key, we need to fix up a
     * few things. For empty elements, return 3 byte sequences filled with 0xFF the same size as the start byte sequences. This will allow us to calculate
     * reasonable ranges ranges.
     *
     * @param key
     * @return the byte sequences
     */
    protected List<ByteSequence> getEndKeyElements(List<ByteSequence> startElements, Key key) {
        List<ByteSequence> bytes = new ArrayList<ByteSequence>(startElements.size());
        if (key != null) {
            List<ByteSequence> endElements = getKeyElements(key);
            for (int i = 0; i < endElements.size(); i++) {
                ByteSequence startBytes = startElements.get(i);
                ByteSequence endBytes = endElements.get(i);
                if (endBytes.length() == 0 && startBytes.length() > 0) {
                    byte[] end = new byte[startBytes.length()];
                    Arrays.fill(end, (byte) 0xFF);
                    bytes.add(new ArrayByteSequence(end));
                } else {
                    bytes.add(endBytes);
                }
            }
        } else {
            for (ByteSequence startBytes : startElements) {
                byte[] end = new byte[startBytes.length()];
                Arrays.fill(end, (byte) 0xFF);
                bytes.add(new ArrayByteSequence(end));
            }
        }
        return bytes;
    }

Replace Generic With Diamond ArrayList<ByteSequence> with ArrayList<> in method protected getEndKeyElements(startElements List<ByteSequence>, key Key) : List<ByteSequence> from class datawave.core.iterators.RangeSplitter


        public QueryLock build() throws ConfigException, MalformedURLException {
            List<QueryLock> locks = new ArrayList<>();
            if (!isEmpty(zookeeperConfig)) {
                if (queryId == null) {
                    throw new IllegalArgumentException("Cannot create a query lock without a query id");
                }

                locks.add(new ZookeeperQueryLock(zookeeperConfig, cleanupInterval, queryId));
            }

            if (!isEmpty(fstURIs) || (!isEmpty(ivaratorURIs) && ivaratorURIs.contains("hdfs://"))) {
                if (!isEmpty(hdfsSiteConfigs) || fsCache != null) {
                    if (queryId == null) {
                        throw new IllegalArgumentException("Cannot create a query lock without a query id");
                    }

                    if (!isEmpty(fstURIs)) {
                        if (fsCache == null) {
                            locks.add(new HdfsQueryLock(hdfsSiteConfigs, fstURIs, queryId));
                        } else {
                            locks.add(new HdfsQueryLock(fsCache, fstURIs, queryId));
                        }
                    }
                    if (!isEmpty(ivaratorURIs) && ivaratorURIs.contains("hdfs://")) {
                        if (fsCache == null) {
                            locks.add(new HdfsQueryLock(hdfsSiteConfigs, ivaratorURIs, queryId));
                        } else {
                            locks.add(new HdfsQueryLock(fsCache, ivaratorURIs, queryId));
                        }
                    }
                } else {
                    throw new IllegalArgumentException("Configured hdfs URIs but missing hdfs configuration");
                }
            }

            if (locks.size() == 1) {
                return locks.get(0);
            } else if (locks.size() > 1) {
                return new CombinedQueryLock(locks);
            } else {
                return null;
            }

        }

        public QueryLock build() throws ConfigException, MalformedURLException {
            List<QueryLock> locks = new ArrayList<QueryLock>();
            if (!isEmpty(zookeeperConfig)) {
                if (queryId == null) {
                    throw new IllegalArgumentException("Cannot create a query lock without a query id");
                }

                locks.add(new ZookeeperQueryLock(zookeeperConfig, cleanupInterval, queryId));
            }

            if (!isEmpty(fstURIs) || (!isEmpty(ivaratorURIs) && ivaratorURIs.contains("hdfs://"))) {
                if (!isEmpty(hdfsSiteConfigs) || fsCache != null) {
                    if (queryId == null) {
                        throw new IllegalArgumentException("Cannot create a query lock without a query id");
                    }

                    if (!isEmpty(fstURIs)) {
                        if (fsCache == null) {
                            locks.add(new HdfsQueryLock(hdfsSiteConfigs, fstURIs, queryId));
                        } else {
                            locks.add(new HdfsQueryLock(fsCache, fstURIs, queryId));
                        }
                    }
                    if (!isEmpty(ivaratorURIs) && ivaratorURIs.contains("hdfs://")) {
                        if (fsCache == null) {
                            locks.add(new HdfsQueryLock(hdfsSiteConfigs, ivaratorURIs, queryId));
                        } else {
                            locks.add(new HdfsQueryLock(fsCache, ivaratorURIs, queryId));
                        }
                    }
                } else {
                    throw new IllegalArgumentException("Configured hdfs URIs but missing hdfs configuration");
                }
            }

            if (locks.size() == 1) {
                return locks.get(0);
            } else if (locks.size() > 1) {
                return new CombinedQueryLock(locks);
            } else {
                return null;
            }

        }

Replace Generic With Diamond ArrayList<QueryLock> with ArrayList<> in method public build() : QueryLock from class datawave.core.iterators.querylock.QueryLock.Builder


    protected synchronized void initialize(Configuration conf, boolean initRanges) throws IOException {

        if (isOpen) {
            close();
            executor = Executors.newFixedThreadPool(READ_AHEAD_THREADS, new RecordIteratorFactory("RecordIterator "));
        }

        fileIterators = new ConcurrentLinkedDeque<>();

        rfileReferences = new ConcurrentLinkedDeque<>();

        List<SortedKeyValueIterator<Key,Value>> iterators = Lists.newArrayList();

        Set<Path> pathSet = Sets.newHashSet();

        for (FileRangeSplit split : fileRangeSplits) {
            List<Range> myRanges = split.getRanges();
            if (initRanges) {
                for (Range myRange : myRanges) {
                    addRange(myRange);
                }
            }

            pathSet.add(split.getPath());

        }

        FileOperations fops = RFileOperations.getInstance();

        futures.clear();
        numberFiles = pathSet.size();
        for (Path path : pathSet) {

            try {

                if (null != path)
                    futures.add(iterFromFile(fops, path, conf));
            } catch (Exception e) {

            }

        }

        for (Future<SortedKeyValueIterator<Key,Value>> future : futures) {

            SortedKeyValueIterator<Key,Value> rfileIter = null;
            try {
                rfileIter = future.get();
            } catch (ExecutionException e) {
                close();
                throw new RuntimeException(e.getCause());
            } catch (Exception e) {

            }
            if (null != rfileIter)
                iterators.add(rfileIter);

        }

        executor.shutdownNow();

        futures.clear();

        SortedKeyValueIterator<Key,Value> topIter = new MultiIterator(iterators, true);

        boolean applyDeletingIterator = conf.getBoolean("range.record.reader.apply.delete", true);
        if (applyDeletingIterator)
            topIter = new DeletingIterator(topIter, false);

        try {
            globalIter = applyTableIterators(topIter, conf);
            globalIter = buildTopIterators(globalIter, conf);
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            throw new IOException(e);
        }

        if (initRanges) {
            rangeQueue = new LinkedList<>();
            rangeQueue.addAll(ranges);
        }

        isOpen = true;
    }

    protected synchronized void initialize(Configuration conf, boolean initRanges) throws IOException {

        if (isOpen) {
            close();
            executor = Executors.newFixedThreadPool(READ_AHEAD_THREADS, new RecordIteratorFactory("RecordIterator "));
        }

        fileIterators = new ConcurrentLinkedDeque<>();

        rfileReferences = new ConcurrentLinkedDeque<>();

        List<SortedKeyValueIterator<Key,Value>> iterators = Lists.newArrayList();

        Set<Path> pathSet = Sets.newHashSet();

        for (FileRangeSplit split : fileRangeSplits) {
            List<Range> myRanges = split.getRanges();
            if (initRanges) {
                for (Range myRange : myRanges) {
                    addRange(myRange);
                }
            }

            pathSet.add(split.getPath());

        }

        FileOperations fops = RFileOperations.getInstance();

        futures.clear();
        numberFiles = pathSet.size();
        for (Path path : pathSet) {

            try {

                if (null != path)
                    futures.add(iterFromFile(fops, path, conf));
            } catch (Exception e) {

            }

        }

        for (Future<SortedKeyValueIterator<Key,Value>> future : futures) {

            SortedKeyValueIterator<Key,Value> rfileIter = null;
            try {
                rfileIter = future.get();
            } catch (ExecutionException e) {
                close();
                throw new RuntimeException(e.getCause());
            } catch (Exception e) {

            }
            if (null != rfileIter)
                iterators.add(rfileIter);

        }

        executor.shutdownNow();

        futures.clear();

        SortedKeyValueIterator<Key,Value> topIter = new MultiIterator(iterators, true);

        boolean applyDeletingIterator = conf.getBoolean("range.record.reader.apply.delete", true);
        if (applyDeletingIterator)
            topIter = new DeletingIterator(topIter, false);

        try {
            globalIter = applyTableIterators(topIter, conf);
            globalIter = buildTopIterators(globalIter, conf);
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            throw new IOException(e);
        }

        if (initRanges) {
            rangeQueue = new LinkedList<Range>();
            rangeQueue.addAll(ranges);
        }

        isOpen = true;
    }

Replace Generic With Diamond LinkedList<Range> with LinkedList<> in method protected initialize(conf Configuration, initRanges boolean) : void from class datawave.mr.bulk.RecordIterator


    /**
     * @param topIter
     * @param conf
     * @return
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws IOException
     */
    protected SortedKeyValueIterator<Key,Value> buildTopIterators(SortedKeyValueIterator<Key,Value> topIter, Configuration conf) throws ClassNotFoundException,
                    InstantiationException, IllegalAccessException, IOException {

        List<AccumuloIterator> iterators = BulkInputFormat.getIterators(conf);
        List<AccumuloIteratorOption> options = BulkInputFormat.getIteratorOptions(conf);

        Map<String,IteratorSetting> scanIterators = new HashMap<>();
        for (AccumuloIterator iterator : iterators) {
            scanIterators.put(iterator.getIteratorName(), new IteratorSetting(iterator.getPriority(), iterator.getIteratorName(), iterator.getIteratorClass()));
        }
        for (AccumuloIteratorOption option : options) {
            scanIterators.get(option.getIteratorName()).addOption(option.getKey(), option.getValue());
        }

        SortedKeyValueIterator<Key,Value> newIter = topIter;

        BulkIteratorEnvironment myData = new BulkIteratorEnvironment(IteratorScope.scan);
        // ensure we create the iterators in priority order
        Collections.sort(iterators, (o1, o2) -> {
            if (o1.getPriority() < o2.getPriority()) {
                return -1;
            } else if (o1.getPriority() > o2.getPriority()) {
                return 1;
            } else {
                return o1.getIteratorName().compareTo(o2.getIteratorName());
            }
        });
        for (AccumuloIterator iterator : iterators) {

            IteratorSetting settings = scanIterators.get(iterator.getIteratorName());

            Class<? extends SortedKeyValueIterator> iter = Class.forName(settings.getIteratorClass()).asSubclass(SortedKeyValueIterator.class);

            SortedKeyValueIterator<Key,Value> newInstance = iter.newInstance();

            newInstance.init(newIter, settings.getOptions(), myData);

            newIter = newInstance;
        }
        return newIter;
    }

    /**
     * @param topIter
     * @param conf
     * @return
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws IOException
     */
    protected SortedKeyValueIterator<Key,Value> buildTopIterators(SortedKeyValueIterator<Key,Value> topIter, Configuration conf) throws ClassNotFoundException,
                    InstantiationException, IllegalAccessException, IOException {

        List<AccumuloIterator> iterators = BulkInputFormat.getIterators(conf);
        List<AccumuloIteratorOption> options = BulkInputFormat.getIteratorOptions(conf);

        Map<String,IteratorSetting> scanIterators = new HashMap<String,IteratorSetting>();
        for (AccumuloIterator iterator : iterators) {
            scanIterators.put(iterator.getIteratorName(), new IteratorSetting(iterator.getPriority(), iterator.getIteratorName(), iterator.getIteratorClass()));
        }
        for (AccumuloIteratorOption option : options) {
            scanIterators.get(option.getIteratorName()).addOption(option.getKey(), option.getValue());
        }

        SortedKeyValueIterator<Key,Value> newIter = topIter;

        BulkIteratorEnvironment myData = new BulkIteratorEnvironment(IteratorScope.scan);
        // ensure we create the iterators in priority order
        Collections.sort(iterators, (o1, o2) -> {
            if (o1.getPriority() < o2.getPriority()) {
                return -1;
            } else if (o1.getPriority() > o2.getPriority()) {
                return 1;
            } else {
                return o1.getIteratorName().compareTo(o2.getIteratorName());
            }
        });
        for (AccumuloIterator iterator : iterators) {

            IteratorSetting settings = scanIterators.get(iterator.getIteratorName());

            Class<? extends SortedKeyValueIterator> iter = Class.forName(settings.getIteratorClass()).asSubclass(SortedKeyValueIterator.class);

            SortedKeyValueIterator<Key,Value> newInstance = iter.newInstance();

            newInstance.init(newIter, settings.getOptions(), myData);

            newIter = newInstance;
        }
        return newIter;
    }

Replace Generic With Diamond HashMap<String,IteratorSetting> with HashMap<> in method protected buildTopIterators(topIter SortedKeyValueIterator<Key,Value>, conf Configuration) : SortedKeyValueIterator<Key,Value> from class datawave.mr.bulk.RecordIterator


    /**
     * Collect a set of hosts from all child InputSplits.
     *
     * @throws InterruptedException
     */
    public String[] getLocations() throws IOException, InterruptedException {
        HashSet<String> hosts = new HashSet<>();
        for (InputSplit s : splits) {
            String[] hints = s.getLocations();
            if (hints != null && hints.length > 0) {
                for (String host : hints) {
                    hosts.add(host);
                }
            }
        }
        return hosts.toArray(new String[hosts.size()]);
    }

    /**
     * Collect a set of hosts from all child InputSplits.
     *
     * @throws InterruptedException
     */
    public String[] getLocations() throws IOException, InterruptedException {
        HashSet<String> hosts = new HashSet<String>();
        for (InputSplit s : splits) {
            String[] hints = s.getLocations();
            if (hints != null && hints.length > 0) {
                for (String host : hints) {
                    hosts.add(host);
                }
            }
        }
        return hosts.toArray(new String[hosts.size()]);
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public getLocations() : String[] from class datawave.mr.bulk.split.TabletSplitSplit


    @Override
    public void init(SortedKeyValueIterator<Key,Value> source, Map<String,String> options, IteratorEnvironment env) throws IOException {
        if (log.isTraceEnabled()) {
            log.trace("AncestorQueryIterator init()");
        }

        super.init(source, options, env);

        // force evaluation of ranges to find missed hits
        this.mustUseFieldIndex = true;

        // TODO: Figure out why this is in the TLD logic:

        // Replace the fieldIndexKeyDataTypeFilter with a chain of "anded" index-filtering predicates.
        // If no other predicates are configured via the indexfiltering.classes property, the method
        // simply returns the existing fieldIndexKeyDataTypeFilter value. Otherwise, the returned value
        // contains an "anded" chain of newly configured predicates following the existing
        // fieldIndexKeyDataTypeFilter value (assuming it is defined with something other than the default
        // "ALWAYS_TRUE" KeyIdentity.Function).
        fieldIndexKeyDataTypeFilter = parseIndexFilteringChain(new SourcedOptions<>(source, env, options));

        disableIndexOnlyDocuments = false;
    }

    @Override
    public void init(SortedKeyValueIterator<Key,Value> source, Map<String,String> options, IteratorEnvironment env) throws IOException {
        if (log.isTraceEnabled()) {
            log.trace("AncestorQueryIterator init()");
        }

        super.init(source, options, env);

        // force evaluation of ranges to find missed hits
        this.mustUseFieldIndex = true;

        // TODO: Figure out why this is in the TLD logic:

        // Replace the fieldIndexKeyDataTypeFilter with a chain of "anded" index-filtering predicates.
        // If no other predicates are configured via the indexfiltering.classes property, the method
        // simply returns the existing fieldIndexKeyDataTypeFilter value. Otherwise, the returned value
        // contains an "anded" chain of newly configured predicates following the existing
        // fieldIndexKeyDataTypeFilter value (assuming it is defined with something other than the default
        // "ALWAYS_TRUE" KeyIdentity.Function).
        fieldIndexKeyDataTypeFilter = parseIndexFilteringChain(new SourcedOptions<String,String>(source, env, options));

        disableIndexOnlyDocuments = false;
    }

Replace Generic With Diamond SourcedOptions<String,String> with SourcedOptions<> in method public init(source SortedKeyValueIterator<Key,Value>, options Map<String,String>, env IteratorEnvironment) : void from class datawave.query.ancestor.AncestorQueryIterator


    @Override
    public Attribute<?> reduceToKeep() {
        Set<Attribute<? extends Comparable<?>>> replacements = new HashSet<>();
        for (Iterator<Attribute<? extends Comparable<?>>> it = this.attributes.iterator(); it.hasNext();) {
            Attribute<?> attr = it.next();
            this._count -= attr.size();
            if (trackSizes) {
                this._bytes -= attr.sizeInBytes() + 24 + 24;
            }
            if (attr.isToKeep()) {
                Attribute<?> newAttr = attr.reduceToKeep();
                if (newAttr == null) {
                    it.remove();
                } else {
                    this._count += newAttr.size();
                    if (trackSizes) {
                        this._bytes += newAttr.sizeInBytes() + 24 + 24;
                    }
                    if (attr != newAttr) {
                        it.remove();
                        replacements.add(newAttr);
                    }
                }
            } else {
                it.remove();
            }
        }
        this.attributes.addAll(replacements);
        invalidateMetadata();

        if (this.attributes.isEmpty()) {
            return null;
        } else if (this.attributes.size() == 1) {
            return this.attributes.iterator().next();
        } else {
            return this;
        }
    }

    @Override
    public Attribute<?> reduceToKeep() {
        Set<Attribute<? extends Comparable<?>>> replacements = new HashSet<Attribute<? extends Comparable<?>>>();
        for (Iterator<Attribute<? extends Comparable<?>>> it = this.attributes.iterator(); it.hasNext();) {
            Attribute<?> attr = it.next();
            this._count -= attr.size();
            if (trackSizes) {
                this._bytes -= attr.sizeInBytes() + 24 + 24;
            }
            if (attr.isToKeep()) {
                Attribute<?> newAttr = attr.reduceToKeep();
                if (newAttr == null) {
                    it.remove();
                } else {
                    this._count += newAttr.size();
                    if (trackSizes) {
                        this._bytes += newAttr.sizeInBytes() + 24 + 24;
                    }
                    if (attr != newAttr) {
                        it.remove();
                        replacements.add(newAttr);
                    }
                }
            } else {
                it.remove();
            }
        }
        this.attributes.addAll(replacements);
        invalidateMetadata();

        if (this.attributes.isEmpty()) {
            return null;
        } else if (this.attributes.size() == 1) {
            return this.attributes.iterator().next();
        } else {
            return this;
        }
    }

Replace Generic With Diamond HashSet<Attribute<? extends Comparable<?>>> with HashSet<> in method public reduceToKeep() : Attribute<?> from class datawave.query.attributes.Attributes


    public List<String> assembleValues(String field, Map<String,List<String>> valueMap) {

        List<String> values = new ArrayList<>();
        List<List<String>> valueLists = new ArrayList<>();
        Iterable<String> fieldSplit = Splitter.on("|").split(field);

        int numSplits = 0;
        for (String s : fieldSplit) {

            if (valueMap.containsKey(s)) {
                valueLists.add(valueMap.get(s));
            } else {
                valueLists.add(new ArrayList<>());
                if (log.isTraceEnabled()) {
                    log.trace("Cardinalty field " + s + " of configured field " + field + " not found");
                }
                return values;
            }
            numSplits++;
        }

        if (numSplits == 1) {
            for (String s : valueLists.get(0)) {
                values.add(s);
            }
        } else {
            List<List<String>> cartesianProduct = cartesianProduct(valueLists);
            for (List<String> l : cartesianProduct) {
                values.add(StringUtils.join(l, "\0"));
            }
        }
        return values;
    }

    public List<String> assembleValues(String field, Map<String,List<String>> valueMap) {

        List<String> values = new ArrayList<>();
        List<List<String>> valueLists = new ArrayList<>();
        Iterable<String> fieldSplit = Splitter.on("|").split(field);

        int numSplits = 0;
        for (String s : fieldSplit) {

            if (valueMap.containsKey(s)) {
                valueLists.add(valueMap.get(s));
            } else {
                valueLists.add(new ArrayList<String>());
                if (log.isTraceEnabled()) {
                    log.trace("Cardinalty field " + s + " of configured field " + field + " not found");
                }
                return values;
            }
            numSplits++;
        }

        if (numSplits == 1) {
            for (String s : valueLists.get(0)) {
                values.add(s);
            }
        } else {
            List<List<String>> cartesianProduct = cartesianProduct(valueLists);
            for (List<String> l : cartesianProduct) {
                values.add(StringUtils.join(l, "\0"));
            }
        }
        return values;
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public assembleValues(field String, valueMap Map<String,List<String>>) : List<String> from class datawave.query.cardinality.CardinalityRecord


    public static <T extends ValueTuple> FunctionalSet<T> singleton(T value) {
        return new SingletonFunctionalSet<>(value);
    }

    public static <T extends ValueTuple> FunctionalSet<T> singleton(T value) {
        return new SingletonFunctionalSet<T>(value);
    }

Replace Generic With Diamond SingletonFunctionalSet<T> with SingletonFunctionalSet<> in method public singleton(value T) : FunctionalSet<T> from class datawave.query.collections.FunctionalSet


    public static <T extends ValueTuple> FunctionalSet<T> unmodifiableSet(FunctionalSet<T> set) {
        return new UnmodifiableSet<>(set);
    }

    public static <T extends ValueTuple> FunctionalSet<T> unmodifiableSet(FunctionalSet<T> set) {
        return new UnmodifiableSet<T>(set);
    }

Replace Generic With Diamond UnmodifiableSet<T> with UnmodifiableSet<> in method public unmodifiableSet(set FunctionalSet<T>) : FunctionalSet<T> from class datawave.query.collections.FunctionalSet


    public Collection<T> getValuesForGroups(Object in) {

        Collection<T> values = new FunctionalSet<>();
        if (in instanceof String) {

            Object value = this.getValueForGroup((String) in);
            if (value != null) {
                return FunctionalSet.singleton(this.getValueForGroup((String) in));
            } else {
                return FunctionalSet.empty();
            }
        }
        if (in instanceof Collection) {
            for (Object group : (Collection) in) {
                T obj = this.getValueForGroup((String) group);
                if (obj != null) {
                    values.add(obj);
                }
            }
        }
        if (log.isTraceEnabled())
            log.trace("getValuesForGroups(" + in + ") returning " + values);
        return values;
    }

    public Collection<T> getValuesForGroups(Object in) {

        Collection<T> values = new FunctionalSet<T>();
        if (in instanceof String) {

            Object value = this.getValueForGroup((String) in);
            if (value != null) {
                return FunctionalSet.singleton(this.getValueForGroup((String) in));
            } else {
                return FunctionalSet.empty();
            }
        }
        if (in instanceof Collection) {
            for (Object group : (Collection) in) {
                T obj = this.getValueForGroup((String) group);
                if (obj != null) {
                    values.add(obj);
                }
            }
        }
        if (log.isTraceEnabled())
            log.trace("getValuesForGroups(" + in + ") returning " + values);
        return values;
    }

Replace Generic With Diamond FunctionalSet<T> with FunctionalSet<> in method public getValuesForGroups(in Object) : Collection<T> from class datawave.query.collections.FunctionalSet


    public Collection<T> getValuesForGroups(Collection<String> groups) {
        Collection<T> values = new FunctionalSet<>();
        for (String group : groups) {
            T obj = this.getValueForGroup(group);
            if (obj != null) {
                values.add(obj);
            }
        }
        if (log.isTraceEnabled())
            log.trace("getValuesForGroups(" + groups + ") returning " + values);
        return values;
    }

    public Collection<T> getValuesForGroups(Collection<String> groups) {
        Collection<T> values = new FunctionalSet<T>();
        for (String group : groups) {
            T obj = this.getValueForGroup(group);
            if (obj != null) {
                values.add(obj);
            }
        }
        if (log.isTraceEnabled())
            log.trace("getValuesForGroups(" + groups + ") returning " + values);
        return values;
    }

Replace Generic With Diamond FunctionalSet<T> with FunctionalSet<> in method public getValuesForGroups(groups Collection<String>) : Collection<T> from class datawave.query.collections.FunctionalSet


    public Object compareWith(Object reference, String operatorString) {
        Collection<Object> values = new HashSet<>();
        for (Iterator<T> iterator = iterator(); iterator.hasNext();) {
            ValueTuple next = iterator.next();
            Object nextValue = next.getValue();
            if (nextValue instanceof Type) {
                Type nextType = (Type) nextValue;
                Class typeClass = nextType.getClass();
                Type referenceType = Type.Factory.createType(typeClass.getName());
                referenceType.setDelegateFromString(reference.toString());
                switch (CharMatcher.WHITESPACE.removeFrom(operatorString)) {
                    case "<":
                        if (nextType.normalize().compareTo(referenceType.normalize()) < 0) {
                            values.add(next);
                        }
                        break;
                    case "<=":
                        if (nextType.normalize().compareTo(referenceType.normalize()) <= 0) {
                            values.add(next);
                        }
                        break;
                    case "==":
                        if (nextType.normalize().compareTo(referenceType.normalize()) == 0) {
                            values.add(next);
                        }
                        break;
                    case "=":
                        if (nextType.normalize().compareTo(referenceType.normalize()) == 0) {
                            values.add(next);
                        }
                        break;
                    case ">=":
                        if (nextType.normalize().compareTo(referenceType.normalize()) >= 0) {
                            values.add(next);
                        }
                        break;
                    case ">":
                        if (nextType.normalize().compareTo(referenceType.normalize()) > 0) {
                            values.add(next);
                        }
                        break;
                    case "!=":
                        if (nextType.normalize().compareTo(referenceType.normalize()) != 0) {
                            values.add(next);
                        }
                        break;
                    default:
                        throw new IllegalArgumentException("cannot use " + operatorString + " in this equation");
                }
            }
        }
        log.debug("returning:" + values);
        return values;
    }

    public Object compareWith(Object reference, String operatorString) {
        Collection<Object> values = new HashSet<Object>();
        for (Iterator<T> iterator = iterator(); iterator.hasNext();) {
            ValueTuple next = iterator.next();
            Object nextValue = next.getValue();
            if (nextValue instanceof Type) {
                Type nextType = (Type) nextValue;
                Class typeClass = nextType.getClass();
                Type referenceType = Type.Factory.createType(typeClass.getName());
                referenceType.setDelegateFromString(reference.toString());
                switch (CharMatcher.WHITESPACE.removeFrom(operatorString)) {
                    case "<":
                        if (nextType.normalize().compareTo(referenceType.normalize()) < 0) {
                            values.add(next);
                        }
                        break;
                    case "<=":
                        if (nextType.normalize().compareTo(referenceType.normalize()) <= 0) {
                            values.add(next);
                        }
                        break;
                    case "==":
                        if (nextType.normalize().compareTo(referenceType.normalize()) == 0) {
                            values.add(next);
                        }
                        break;
                    case "=":
                        if (nextType.normalize().compareTo(referenceType.normalize()) == 0) {
                            values.add(next);
                        }
                        break;
                    case ">=":
                        if (nextType.normalize().compareTo(referenceType.normalize()) >= 0) {
                            values.add(next);
                        }
                        break;
                    case ">":
                        if (nextType.normalize().compareTo(referenceType.normalize()) > 0) {
                            values.add(next);
                        }
                        break;
                    case "!=":
                        if (nextType.normalize().compareTo(referenceType.normalize()) != 0) {
                            values.add(next);
                        }
                        break;
                    default:
                        throw new IllegalArgumentException("cannot use " + operatorString + " in this equation");
                }
            }
        }
        log.debug("returning:" + values);
        return values;
    }

Replace Generic With Diamond HashSet<Object> with HashSet<> in method public compareWith(reference Object, operatorString String) : Object from class datawave.query.collections.FunctionalSet


    public Collection<Range> getRanges() {
        final Collection<Range> orderedCopy;
        synchronized (this.ranges) {
            orderedCopy = new ArrayList<>(this.ranges);
        }
        return orderedCopy;
    }

    public Collection<Range> getRanges() {
        final Collection<Range> orderedCopy;
        synchronized (this.ranges) {
            orderedCopy = new ArrayList<Range>(this.ranges);
        }
        return orderedCopy;
    }

Replace Generic With Diamond ArrayList<Range> with ArrayList<> in method public getRanges() : Collection<Range> from class datawave.query.config.ContentQueryConfiguration


    @SuppressWarnings("unchecked")
    public void setFilterClassNames(List<String> filterClassNames) {
        this.filterClassNames = new ArrayList<>((filterClassNames != null ? filterClassNames : Collections.EMPTY_LIST));
    }

    @SuppressWarnings("unchecked")
    public void setFilterClassNames(List<String> filterClassNames) {
        this.filterClassNames = new ArrayList<String>((filterClassNames != null ? filterClassNames : Collections.EMPTY_LIST));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public setFilterClassNames(filterClassNames List<String>) : void from class datawave.query.config.ShardQueryConfiguration


    /**
     * Gets any predicate-based filters to apply when scanning through the field index. These filters will be "anded" with the default data type filter, if any,
     * used to construct the IndexIterator (particularly via the TLDQueryIterator).
     *
     * @param classNames
     *            the names of predicate-implemented classes to use when scanning the field index
     */
    @SuppressWarnings("unchecked")
    public void setIndexFilteringClassNames(List<String> classNames) {
        this.indexFilteringClassNames = new ArrayList<>((classNames != null ? classNames : Collections.EMPTY_LIST));
    }

    /**
     * Gets any predicate-based filters to apply when scanning through the field index. These filters will be "anded" with the default data type filter, if any,
     * used to construct the IndexIterator (particularly via the TLDQueryIterator).
     *
     * @param classNames
     *            the names of predicate-implemented classes to use when scanning the field index
     */
    @SuppressWarnings("unchecked")
    public void setIndexFilteringClassNames(List<String> classNames) {
        this.indexFilteringClassNames = new ArrayList<String>((classNames != null ? classNames : Collections.EMPTY_LIST));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public setIndexFilteringClassNames(classNames List<String>) : void from class datawave.query.config.ShardQueryConfiguration


    @Override
    public EventBase transform(DiscoveredThing thing) {
        Preconditions.checkNotNull(thing, "Received a null object to transform!");

        EventBase event = this.responseObjectFactory.getEvent();
        Map<String,String> markings;
        try {
            markings = this.markingFunctions.translateFromColumnVisibility(new ColumnVisibility(thing.getColumnVisibility()));
        } catch (Exception e) {
            throw new RuntimeException("could not parse to markings: " + thing.getColumnVisibility());
        }
        event.setMarkings(markings);

        List<FieldBase> fields = new ArrayList<>();

        fields.add(this.makeField("VALUE", markings, "", 0L, thing.getTerm()));
        /**
         * Added query model to alias FIELD
         */
        fields.add(this.makeField("FIELD", markings, "", 0L, myQueryModel.aliasFieldNameReverseModel(thing.getField())));
        fields.add(this.makeField("DATE", markings, "", 0L, thing.getDate()));
        fields.add(this.makeField("DATA TYPE", markings, "", 0L, thing.getType()));

        // If requested return counts separated by colvis, all counts by colvis could be > total record count
        if (thing.getCountsByColumnVisibility() != null && thing.getCountsByColumnVisibility().size() > 0) {
            for (Map.Entry<Writable,Writable> entry : thing.getCountsByColumnVisibility().entrySet()) {
                try {
                    Map<String,String> eMarkings = this.markingFunctions.translateFromColumnVisibility(new ColumnVisibility(entry.getKey().toString()));
                    fields.add(this.makeField("RECORD COUNT", new HashMap<>(), entry.getKey().toString(), 0L, entry.getValue().toString()));
                } catch (Exception e) {
                    throw new RuntimeException("could not parse to markings: " + thing.getColumnVisibility());
                }

            }
        } else {
            fields.add(this.makeField("RECORD COUNT", markings, "", 0L, Long.toString(thing.getCount())));
        }

        event.setFields(fields);

        Metadata metadata = new Metadata();
        metadata.setInternalId(""); // there is no UUID for a single index pointer
        metadata.setDataType(thing.getType()); // duplicate
        metadata.setRow(thing.getTerm()); // duplicate
        metadata.setTable(logic.getTableName());
        event.setMetadata(metadata);
        return event;
    }

    @Override
    public EventBase transform(DiscoveredThing thing) {
        Preconditions.checkNotNull(thing, "Received a null object to transform!");

        EventBase event = this.responseObjectFactory.getEvent();
        Map<String,String> markings;
        try {
            markings = this.markingFunctions.translateFromColumnVisibility(new ColumnVisibility(thing.getColumnVisibility()));
        } catch (Exception e) {
            throw new RuntimeException("could not parse to markings: " + thing.getColumnVisibility());
        }
        event.setMarkings(markings);

        List<FieldBase> fields = new ArrayList<>();

        fields.add(this.makeField("VALUE", markings, "", 0L, thing.getTerm()));
        /**
         * Added query model to alias FIELD
         */
        fields.add(this.makeField("FIELD", markings, "", 0L, myQueryModel.aliasFieldNameReverseModel(thing.getField())));
        fields.add(this.makeField("DATE", markings, "", 0L, thing.getDate()));
        fields.add(this.makeField("DATA TYPE", markings, "", 0L, thing.getType()));

        // If requested return counts separated by colvis, all counts by colvis could be > total record count
        if (thing.getCountsByColumnVisibility() != null && thing.getCountsByColumnVisibility().size() > 0) {
            for (Map.Entry<Writable,Writable> entry : thing.getCountsByColumnVisibility().entrySet()) {
                try {
                    Map<String,String> eMarkings = this.markingFunctions.translateFromColumnVisibility(new ColumnVisibility(entry.getKey().toString()));
                    fields.add(this.makeField("RECORD COUNT", new HashMap<String,String>(), entry.getKey().toString(), 0L, entry.getValue().toString()));
                } catch (Exception e) {
                    throw new RuntimeException("could not parse to markings: " + thing.getColumnVisibility());
                }

            }
        } else {
            fields.add(this.makeField("RECORD COUNT", markings, "", 0L, Long.toString(thing.getCount())));
        }

        event.setFields(fields);

        Metadata metadata = new Metadata();
        metadata.setInternalId(""); // there is no UUID for a single index pointer
        metadata.setDataType(thing.getType()); // duplicate
        metadata.setRow(thing.getTerm()); // duplicate
        metadata.setTable(logic.getTableName());
        event.setMetadata(metadata);
        return event;
    }

Replace Generic With Diamond HashMap<String,String> with HashMap<> in method public transform(thing DiscoveredThing) : EventBase from class datawave.query.discovery.DiscoveryTransformer


    @Override
    public Object visit(ASTAndNode node, Object data) {
        List<JexlNode> otherNodes = new ArrayList<>();
        Map<LiteralRange<?>,List<JexlNode>> ranges = JexlASTHelper.getBoundedRangesIndexAgnostic(node, otherNodes, true);
        if (ranges.size() == 1 && otherNodes.isEmpty()) {
            LiteralRange<?> range = ranges.keySet().iterator().next();
            values.addRange(range.getFieldName(), range);
        } else {
            super.visit(node, data);
        }

        return null;
    }

    @Override
    public Object visit(ASTAndNode node, Object data) {
        List<JexlNode> otherNodes = new ArrayList<JexlNode>();
        Map<LiteralRange<?>,List<JexlNode>> ranges = JexlASTHelper.getBoundedRangesIndexAgnostic(node, otherNodes, true);
        if (ranges.size() == 1 && otherNodes.isEmpty()) {
            LiteralRange<?> range = ranges.keySet().iterator().next();
            values.addRange(range.getFieldName(), range);
        } else {
            super.visit(node, data);
        }

        return null;
    }

Replace Generic With Diamond ArrayList<JexlNode> with ArrayList<> in method public visit(node ASTAndNode, data Object) : Object from class datawave.query.discovery.FindLiteralsAndPatternsVisitor


    @Override
    public LiteralRange<String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject obj = json.getAsJsonObject();
        String fieldName = (obj.get("FN") == null ? null : obj.get("FN").getAsString());
        String lower = (obj.get("L") == null ? null : obj.get("L").getAsString());
        String upper = (obj.get("U") == null ? null : obj.get("U").getAsString());
        LiteralRange.NodeOperand operand = (obj.get("O") == null ? null : LiteralRange.NodeOperand.valueOf(obj.get("O").getAsString()));
        Boolean lowerInclusive = (obj.get("LI") == null ? null : obj.get("LI").getAsBoolean());
        Boolean upperInclusive = (obj.get("UI") == null ? null : obj.get("UI").getAsBoolean());

        return new LiteralRange<>(lower, lowerInclusive, upper, upperInclusive, fieldName, operand);
    }

    @Override
    public LiteralRange<String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject obj = json.getAsJsonObject();
        String fieldName = (obj.get("FN") == null ? null : obj.get("FN").getAsString());
        String lower = (obj.get("L") == null ? null : obj.get("L").getAsString());
        String upper = (obj.get("U") == null ? null : obj.get("U").getAsString());
        LiteralRange.NodeOperand operand = (obj.get("O") == null ? null : LiteralRange.NodeOperand.valueOf(obj.get("O").getAsString()));
        Boolean lowerInclusive = (obj.get("LI") == null ? null : obj.get("LI").getAsBoolean());
        Boolean upperInclusive = (obj.get("UI") == null ? null : obj.get("UI").getAsBoolean());

        return new LiteralRange<String>(lower, lowerInclusive, upper, upperInclusive, fieldName, operand);
    }

Replace Generic With Diamond LiteralRange<String> with LiteralRange<> in method public deserialize(json JsonElement, typeOfT Type, context JsonDeserializationContext) : LiteralRange<String> from class datawave.query.discovery.LiteralRangeSerializer