	/**
	 * Waits until every matched element has the given attribute property the specified criteria.
	 *
	 * @return An object for specifying the criteria which the properties of the elements must meet.
	 *
	 * @since 0.9.0
	 */
	public <T> SeleniumQueryEvaluateUntil<T> prop(String propertyName) {
		return new SeleniumQueryEvaluateUntil<>(this.fluentWait, new PropGetter<T>(propertyName), seleniumQueryObject);
	}

	/**
	 * Waits until every matched element has the given attribute property the specified criteria.
	 *
	 * @return An object for specifying the criteria which the properties of the elements must meet.
	 *
	 * @since 0.9.0
	 */
	public <T> SeleniumQueryEvaluateUntil<T> prop(String propertyName) {
		return new SeleniumQueryEvaluateUntil<T>(this.fluentWait, new PropGetter<T>(propertyName), seleniumQueryObject);
	}

Replace Generic With Diamond SeleniumQueryEvaluateUntil<T> with SeleniumQueryEvaluateUntil<> in method public prop(propertyName String) : SeleniumQueryEvaluateUntil<T> from class io.github.seleniumquery.wait.SeleniumQueryWaitUntil


	/**
	 * Waits until every matched element's html meets the specified criteria.
	 *
	 * @return An object for specifying the criteria which the htmls of the elements must meet.
	 *
	 * @since 0.9.0
	 */
	public SeleniumQueryEvaluateUntil<String> html() {
		return new SeleniumQueryEvaluateUntil<>(this.fluentWait, HtmlGetter.HTML_GETTER, seleniumQueryObject);
	}

	/**
	 * Waits until every matched element's html meets the specified criteria.
	 *
	 * @return An object for specifying the criteria which the htmls of the elements must meet.
	 *
	 * @since 0.9.0
	 */
	public SeleniumQueryEvaluateUntil<String> html() {
		return new SeleniumQueryEvaluateUntil<String>(this.fluentWait, HtmlGetter.HTML_GETTER, seleniumQueryObject);
	}

Replace Generic With Diamond SeleniumQueryEvaluateUntil<String> with SeleniumQueryEvaluateUntil<> in method public html() : SeleniumQueryEvaluateUntil<String> from class io.github.seleniumquery.wait.SeleniumQueryWaitUntil


	/**
	 * Waits until the quantity of matched elements meets the specified criteria.
	 *
	 * @return An object for specifying the criteria which the quantity of the elements must meet.
	 *
	 * @since 0.9.0
	 */
	public SeleniumQueryEvaluateUntil<Integer> size() {
		return new SeleniumQueryEvaluateUntil<>(this.fluentWait, SizeGetter.SIZE_GETTER, seleniumQueryObject);
	}

	/**
	 * Waits until the quantity of matched elements meets the specified criteria.
	 *
	 * @return An object for specifying the criteria which the quantity of the elements must meet.
	 *
	 * @since 0.9.0
	 */
	public SeleniumQueryEvaluateUntil<Integer> size() {
		return new SeleniumQueryEvaluateUntil<Integer>(this.fluentWait, SizeGetter.SIZE_GETTER, seleniumQueryObject);
	}

Replace Generic With Diamond SeleniumQueryEvaluateUntil<Integer> with SeleniumQueryEvaluateUntil<> in method public size() : SeleniumQueryEvaluateUntil<Integer> from class io.github.seleniumquery.wait.SeleniumQueryWaitUntil


    private List<String> extractIdsList(String selector) {
        SeleniumQueryObject f = $(selector);

        List<String> actualIds = new ArrayList<>();
        for (WebElement webElement : f) {
            actualIds.add(webElement.getAttribute("id"));
        }
        return actualIds;
    }

    private List<String> extractIdsList(String selector) {
        SeleniumQueryObject f = $(selector);

        List<String> actualIds = new ArrayList<String>();
        for (WebElement webElement : f) {
            actualIds.add(webElement.getAttribute("id"));
        }
        return actualIds;
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method private extractIdsList(selector String) : List<String> from class endtoend.sizzle.SizzleTest


/**
     * Returns an array of elements with the given IDs
     * Example: q("main", "foo", "bar")
     * Result: [
, , <input id="bar">]
     */
    protected List<WebElement> q(String... ids) {
        List<WebElement> els = new ArrayList<>();
        for (String id : ids) {
            els.add(id(id));
        }
        return els;
    }

/**
     * Returns an array of elements with the given IDs
     * Example: q("main", "foo", "bar")
     * Result: [
, , <input id="bar">]
     */
    protected List<WebElement> q(String... ids) {
        List<WebElement> els = new ArrayList<WebElement>();
        for (String id : ids) {
            els.add(id(id));
        }
        return els;
    }

Replace Generic With Diamond ArrayList<WebElement> with ArrayList<> in method protected q(ids String...) : List<WebElement> from class endtoend.sizzle.SizzleTest


    @Test
    public void toImmutableRandomAccessList__returned_list_should_not_get_updated_if_source_list_does() {
        List<String> sourceList = new ArrayList<>();
        String s1 = "just some random value to prove we can add strings to this list";
        sourceList.add(s1);

        List<String> immutableSS = ListUtils.toImmutableRandomAccessList(sourceList);
        assertThat(immutableSS, contains(s1));

        String s2 = "some other value that shouldn't go into the immutable copy";
        sourceList.add(s2);
        assertThat(immutableSS, contains(s1));
    }

    @Test
    public void toImmutableRandomAccessList__returned_list_should_not_get_updated_if_source_list_does() {
        List<String> sourceList = new ArrayList<String>();
        String s1 = "just some random value to prove we can add strings to this list";
        sourceList.add(s1);

        List<String> immutableSS = ListUtils.toImmutableRandomAccessList(sourceList);
        assertThat(immutableSS, contains(s1));

        String s2 = "some other value that shouldn't go into the immutable copy";
        sourceList.add(s2);
        assertThat(immutableSS, contains(s1));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public toImmutableRandomAccessList__returned_list_should_not_get_updated_if_source_list_does() : void from class io.github.seleniumquery.utils.ListUtilsTest


    public static String[] ids(String selector) {
        SeleniumQueryObject f = $(selector);
        List<String> actualIds = new ArrayList<>();
        for (WebElement webElement : f) {
            actualIds.add(id(webElement));
        }
        return actualIds.toArray(new String[actualIds.size()]);
    }

    public static String[] ids(String selector) {
        SeleniumQueryObject f = $(selector);
        List<String> actualIds = new ArrayList<String>();
        for (WebElement webElement : f) {
            actualIds.add(id(webElement));
        }
        return actualIds.toArray(new String[actualIds.size()]);
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public ids(selector String) : String[] from class testinfrastructure.EndToEndTestUtils


    /**
     * Gets the @ids of all elements in the matched set.
     * @param sq matched set to extract ids from.
     * @return list of IDs.
     */
    public static List<String> ids(SeleniumQueryObject sq) {
        List<String> ids = new ArrayList<>(sq.size());
        for (WebElement element : sq) {
            ids.add(id(element));
        }
        return ids;
    }

    /**
     * Gets the @ids of all elements in the matched set.
     * @param sq matched set to extract ids from.
     * @return list of IDs.
     */
    public static List<String> ids(SeleniumQueryObject sq) {
        List<String> ids = new ArrayList<String>(sq.size());
        for (WebElement element : sq) {
            ids.add(id(element));
        }
        return ids;
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public ids(sq SeleniumQueryObject) : List<String> from class testinfrastructure.EndToEndTestUtils


    private Consumer<String> watcher(final String toString) {
        return new Consumer<>() {
            @Override
            public void accept(String s) {
                throw new UnsupportedOperationException();
            }

            public String toString() {
                return toString;
            }
        };
    }

    private Consumer<String> watcher(final String toString) {
        return new Consumer<String>() {
            @Override
            public void accept(String s) {
                throw new UnsupportedOperationException();
            }

            public String toString() {
                return toString;
            }
        };
    }

Replace Generic With Diamond Consumer<String> with Consumer<> in method private watcher(toString String) : Consumer<String> from class walkingkooka.store.WatchersTest


    private Consumer<String> watcher() {
        return new Consumer<>() {
            @Override
            public void accept(String s) {
                throw new UnsupportedOperationException();
            }

            @Override
            public String toString() {
                return "Watcher123";
            }
        };
    }

    private Consumer<String> watcher() {
        return new Consumer<String>() {
            @Override
            public void accept(String s) {
                throw new UnsupportedOperationException();
            }

            @Override
            public String toString() {
                return "Watcher123";
            }
        };
    }

Replace Generic With Diamond Consumer<String> with Consumer<> in method private watcher() : Consumer<String> from class walkingkooka.store.WatchersWatcherRemovingRunnableTest


    private EbnfParserCombinatorSyntaxTreeTransformer<ParserContext> syntaxTreeTransformer(final EbnfGrammarParserToken grammar) {
        final Map<EbnfIdentifierName, EbnfParserToken> identifierToToken = Maps.sorted();
        grammar.value()
                .stream()
                .filter(t -> t instanceof EbnfParserToken)
                .map(EbnfParserToken.class::cast)
                .filter(EbnfParserToken::isRule)
                .map(EbnfRuleParserToken.class::cast)
                .forEach(rule -> identifierToToken.put(rule.identifier().value(), rule.token()));

        return new EbnfParserCombinatorSyntaxTreeTransformer<>() {
            @Override
            public Parser<ParserContext> alternatives(final EbnfAlternativeParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> concatenation(final EbnfConcatenationParserToken token, final Parser<ParserContext> parser) {
                return parser.transform((sequenceParserToken, fakeParserContext) -> sequenceParserToken);
            }

            @Override
            public Parser<ParserContext> exception(final EbnfExceptionParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> group(final EbnfGroupParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> identifier(final EbnfIdentifierParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> optional(final EbnfOptionalParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> range(final EbnfRangeParserToken token, final Parser<ParserContext> ignored) {
                final char begin = this.characterForIdentifierOrTerminal(token.begin());
                final char end = this.characterForIdentifierOrTerminal(token.end());

                return Parsers.<FakeParserContext>stringCharPredicate(CharPredicates.range(begin, end), 1, 1)
                        .setToString(token.toString())
                        .cast();
            }

            private char characterForIdentifierOrTerminal(final EbnfParserToken token) {
                return token.isTerminal() ?
                        this.characterFromTerminal(token.cast(EbnfTerminalParserToken.class)) :
                        token.isIdentifier() ?
                                this.characterFromIdentifierReference(token.cast(EbnfIdentifierParserToken.class)) :
                                failInvalidRangeBound("Invalid range bound, expected terminal or identifier indirectly pointing to a terminal but got " + token, token);
            }

            private char characterFromIdentifierReference(final EbnfIdentifierParserToken identifier) {
                final EbnfIdentifierName identifierName = identifier.value();
                final EbnfParserToken target = identifierToToken.get(identifierName);
                if (null == target) {
                    this.failInvalidRangeBound("Unknown identifier \"" + identifierName + "\"", identifier);
                }
                return this.characterForIdentifierOrTerminal(target);
            }

            private char characterFromTerminal(final EbnfTerminalParserToken terminal) {
                final String value = terminal.value();
                final CharSequence unescaped = CharSequences.unescape(value);
                if (unescaped.length() != 1) {
                    failInvalidRangeBound("The range terminal does not contain a single character=" + terminal, terminal);
                }
                return unescaped.charAt(0);
            }

            private char failInvalidRangeBound(final String message, final EbnfParserToken token) {
                throw new EbnfTerminalParserTokenInvalidRangeBoundParserCombinatorException(message, token);
            }

            @Override
            public Parser<ParserContext> repeated(final EbnfRepeatedParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> terminal(final EbnfTerminalParserToken token, final Parser<ParserContext> parser) {
                return parser.transform((stringParserToken, contextIgnored) -> {
                    ParserToken result = stringParserToken;
                    try {
                        result = number(((StringParserToken) stringParserToken).value());
                    } catch (final NumberFormatException ignore) {
                    }
                    return result;
                }).cast();
            }
        };
    }

    private EbnfParserCombinatorSyntaxTreeTransformer<ParserContext> syntaxTreeTransformer(final EbnfGrammarParserToken grammar) {
        final Map<EbnfIdentifierName, EbnfParserToken> identifierToToken = Maps.sorted();
        grammar.value()
                .stream()
                .filter(t -> t instanceof EbnfParserToken)
                .map(EbnfParserToken.class::cast)
                .filter(EbnfParserToken::isRule)
                .map(EbnfRuleParserToken.class::cast)
                .forEach(rule -> identifierToToken.put(rule.identifier().value(), rule.token()));

        return new EbnfParserCombinatorSyntaxTreeTransformer<ParserContext>() {
            @Override
            public Parser<ParserContext> alternatives(final EbnfAlternativeParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> concatenation(final EbnfConcatenationParserToken token, final Parser<ParserContext> parser) {
                return parser.transform((sequenceParserToken, fakeParserContext) -> sequenceParserToken);
            }

            @Override
            public Parser<ParserContext> exception(final EbnfExceptionParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> group(final EbnfGroupParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> identifier(final EbnfIdentifierParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> optional(final EbnfOptionalParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> range(final EbnfRangeParserToken token, final Parser<ParserContext> ignored) {
                final char begin = this.characterForIdentifierOrTerminal(token.begin());
                final char end = this.characterForIdentifierOrTerminal(token.end());

                return Parsers.<FakeParserContext>stringCharPredicate(CharPredicates.range(begin, end), 1, 1)
                        .setToString(token.toString())
                        .cast();
            }

            private char characterForIdentifierOrTerminal(final EbnfParserToken token) {
                return token.isTerminal() ?
                        this.characterFromTerminal(token.cast(EbnfTerminalParserToken.class)) :
                        token.isIdentifier() ?
                                this.characterFromIdentifierReference(token.cast(EbnfIdentifierParserToken.class)) :
                                failInvalidRangeBound("Invalid range bound, expected terminal or identifier indirectly pointing to a terminal but got " + token, token);
            }

            private char characterFromIdentifierReference(final EbnfIdentifierParserToken identifier) {
                final EbnfIdentifierName identifierName = identifier.value();
                final EbnfParserToken target = identifierToToken.get(identifierName);
                if (null == target) {
                    this.failInvalidRangeBound("Unknown identifier \"" + identifierName + "\"", identifier);
                }
                return this.characterForIdentifierOrTerminal(target);
            }

            private char characterFromTerminal(final EbnfTerminalParserToken terminal) {
                final String value = terminal.value();
                final CharSequence unescaped = CharSequences.unescape(value);
                if (unescaped.length() != 1) {
                    failInvalidRangeBound("The range terminal does not contain a single character=" + terminal, terminal);
                }
                return unescaped.charAt(0);
            }

            private char failInvalidRangeBound(final String message, final EbnfParserToken token) {
                throw new EbnfTerminalParserTokenInvalidRangeBoundParserCombinatorException(message, token);
            }

            @Override
            public Parser<ParserContext> repeated(final EbnfRepeatedParserToken token, final Parser<ParserContext> parser) {
                return parser;
            }

            @Override
            public Parser<ParserContext> terminal(final EbnfTerminalParserToken token, final Parser<ParserContext> parser) {
                return parser.transform((stringParserToken, contextIgnored) -> {
                    ParserToken result = stringParserToken;
                    try {
                        result = number(((StringParserToken) stringParserToken).value());
                    } catch (final NumberFormatException ignore) {
                    }
                    return result;
                }).cast();
            }
        };
    }

Replace Generic With Diamond EbnfParserCombinatorSyntaxTreeTransformer<ParserContext> with EbnfParserCombinatorSyntaxTreeTransformer<> in method private syntaxTreeTransformer(grammar EbnfGrammarParserToken) : EbnfParserCombinatorSyntaxTreeTransformer<ParserContext> from class walkingkooka.text.cursor.parser.ebnf.combinator.EbnfParserCombinatorsTest


    /**
     * Utility method to take a {@code String[]} and return a {@code Set<String>} where the values are trimmed
     *
     * @param items
     *            String[] of items to trim and turn into a set
     * @return unique Set of strings where whitespace has been trimmed.
     */
    public static Set<String> cleanSet(Collection<String> items) {
        Set<String> itemSet = new HashSet<>();
        for (String item : items) {
            item = item.trim();
            if (!item.isEmpty()) {
                itemSet.add(item);
            }
        }
        return itemSet;
    }

    /**
     * Utility method to take a {@code String[]} and return a {@code Set<String>} where the values are trimmed
     *
     * @param items
     *            String[] of items to trim and turn into a set
     * @return unique Set of strings where whitespace has been trimmed.
     */
    public static Set<String> cleanSet(Collection<String> items) {
        Set<String> itemSet = new HashSet<String>();
        for (String item : items) {
            item = item.trim();
            if (!item.isEmpty()) {
                itemSet.add(item);
            }
        }
        return itemSet;
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public cleanSet(items Collection<String>) : Set<String> from class datawave.ingest.data.config.ingest.ContentBaseIngestHelper


    protected static Set<String> getCompressionTableBlackList(Configuration conf) {
        String tableListString = conf.get(COMPRESSION_BLACKLIST);
        if (tableListString == null) {
            return Collections.EMPTY_SET;
        } else {
            String[] tables = StringUtils.split(tableListString, ',');
            return new HashSet<>(Arrays.asList(tables));
        }
    }

    protected static Set<String> getCompressionTableBlackList(Configuration conf) {
        String tableListString = conf.get(COMPRESSION_BLACKLIST);
        if (tableListString == null) {
            return Collections.EMPTY_SET;
        } else {
            String[] tables = StringUtils.split(tableListString, ',');
            return new HashSet<String>(Arrays.asList(tables));
        }
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method protected getCompressionTableBlackList(conf Configuration) : Set<String> from class datawave.ingest.mapreduce.job.MultiRFileOutputFormatter


    /**
     * create and register a writer for retrieval later
     *
     * @param key
     *            The key used for later retrieval
     * @param table
     *            The table name
     * @param filename
     *            The path of the file being written to
     * @throws IOException
     */
    protected void createAndRegisterWriter(String key, String table, Path filename, AccumuloConfiguration tableConf) throws IOException, AccumuloException {
        // first get the writer count (how many writers have we made for this key)
        MutableInt count = writerCounts.get(key);
        if (count == null) {
            count = new MutableInt(1);
            writerCounts.put(key, count);
        } else {
            count.increment();
        }

        // update the filename with the count
        filename = insertFileCount(filename, count.intValue());

        // now create and register the writer
        SizeTrackingWriter writer = openWriter(filename.toString(), tableConf);
        writer.startDefaultLocalityGroup();
        writers.put(key, writer);
        unusedWriterPaths.put(key, filename);
        writerTableNames.put(key, table);
        if (shardedTableNames.contains(table)) {
            shardMapFileRowKeys.put(key, new HashSet<>());
            shardMapFiles.put(key, filename);
        }
    }

    /**
     * create and register a writer for retrieval later
     *
     * @param key
     *            The key used for later retrieval
     * @param table
     *            The table name
     * @param filename
     *            The path of the file being written to
     * @throws IOException
     */
    protected void createAndRegisterWriter(String key, String table, Path filename, AccumuloConfiguration tableConf) throws IOException, AccumuloException {
        // first get the writer count (how many writers have we made for this key)
        MutableInt count = writerCounts.get(key);
        if (count == null) {
            count = new MutableInt(1);
            writerCounts.put(key, count);
        } else {
            count.increment();
        }

        // update the filename with the count
        filename = insertFileCount(filename, count.intValue());

        // now create and register the writer
        SizeTrackingWriter writer = openWriter(filename.toString(), tableConf);
        writer.startDefaultLocalityGroup();
        writers.put(key, writer);
        unusedWriterPaths.put(key, filename);
        writerTableNames.put(key, table);
        if (shardedTableNames.contains(table)) {
            shardMapFileRowKeys.put(key, new HashSet<Text>());
            shardMapFiles.put(key, filename);
        }
    }

Replace Generic With Diamond HashSet<Text> with HashSet<> in method protected createAndRegisterWriter(key String, table String, filename Path, tableConf AccumuloConfiguration) : void from class datawave.ingest.mapreduce.job.MultiRFileOutputFormatter


    protected void setTableIdsAndConfigs() throws IOException {
        ZooKeeperInstance instance = new ZooKeeperInstance(ClientConfiguration.loadDefault().withInstance(conf.get(INSTANCE_NAME))
                        .withZkHosts(conf.get(ZOOKEEPERS)));
        Connector connector = null;
        tableConfigs = new HashMap<>();
        Iterable<String> localityGroupTables = Splitter.on(",").split(conf.get(CONFIGURE_LOCALITY_GROUPS, ""));
        try {
            connector = instance.getConnector(conf.get(USERNAME), new PasswordToken(Base64.decodeBase64(conf.get(PASSWORD))));

            tableIds = connector.tableOperations().tableIdMap();
            Set<String> compressionTableBlackList = getCompressionTableBlackList(conf);
            String compressionType = getCompressionType(conf);
            for (String tableName : tableIds.keySet()) {
                ConfigurationCopy tableConfig = new ConfigurationCopy(connector.tableOperations().getProperties(tableName));
                tableConfig.set(Property.TABLE_FILE_COMPRESSION_TYPE.getKey(), (compressionTableBlackList.contains(tableName) ? Compression.COMPRESSION_NONE
                                : compressionType));
                if (Iterables.contains(localityGroupTables, tableName)) {
                    Map<String,Set<Text>> localityGroups = connector.tableOperations().getLocalityGroups(tableName);
                    // pull the locality groups for this table.
                    Map<Text,String> cftlg = Maps.newHashMap();
                    Map<String,Set<ByteSequence>> lgtcf = Maps.newHashMap();
                    for (Entry<String,Set<Text>> locs : localityGroups.entrySet()) {
                        lgtcf.put(locs.getKey(), new HashSet<>());
                        for (Text loc : locs.getValue()) {
                            cftlg.put(loc, locs.getKey());
                            lgtcf.get(locs.getKey()).add(new ArrayByteSequence(loc.getBytes()));
                        }
                    }
                    columnFamilyToLocalityGroup.put(tableName, cftlg);
                    localityGroupToColumnFamilies.put(tableName, lgtcf);
                }
                tableConfigs.put(tableName, tableConfig);

            }
        } catch (AccumuloException | AccumuloSecurityException | TableNotFoundException e) {
            throw new IOException("Unable to get configuration.  Please call MultiRFileOutput.setAccumuloConfiguration with the proper credentials", e);
        }
    }

    protected void setTableIdsAndConfigs() throws IOException {
        ZooKeeperInstance instance = new ZooKeeperInstance(ClientConfiguration.loadDefault().withInstance(conf.get(INSTANCE_NAME))
                        .withZkHosts(conf.get(ZOOKEEPERS)));
        Connector connector = null;
        tableConfigs = new HashMap<>();
        Iterable<String> localityGroupTables = Splitter.on(",").split(conf.get(CONFIGURE_LOCALITY_GROUPS, ""));
        try {
            connector = instance.getConnector(conf.get(USERNAME), new PasswordToken(Base64.decodeBase64(conf.get(PASSWORD))));

            tableIds = connector.tableOperations().tableIdMap();
            Set<String> compressionTableBlackList = getCompressionTableBlackList(conf);
            String compressionType = getCompressionType(conf);
            for (String tableName : tableIds.keySet()) {
                ConfigurationCopy tableConfig = new ConfigurationCopy(connector.tableOperations().getProperties(tableName));
                tableConfig.set(Property.TABLE_FILE_COMPRESSION_TYPE.getKey(), (compressionTableBlackList.contains(tableName) ? Compression.COMPRESSION_NONE
                                : compressionType));
                if (Iterables.contains(localityGroupTables, tableName)) {
                    Map<String,Set<Text>> localityGroups = connector.tableOperations().getLocalityGroups(tableName);
                    // pull the locality groups for this table.
                    Map<Text,String> cftlg = Maps.newHashMap();
                    Map<String,Set<ByteSequence>> lgtcf = Maps.newHashMap();
                    for (Entry<String,Set<Text>> locs : localityGroups.entrySet()) {
                        lgtcf.put(locs.getKey(), new HashSet<ByteSequence>());
                        for (Text loc : locs.getValue()) {
                            cftlg.put(loc, locs.getKey());
                            lgtcf.get(locs.getKey()).add(new ArrayByteSequence(loc.getBytes()));
                        }
                    }
                    columnFamilyToLocalityGroup.put(tableName, cftlg);
                    localityGroupToColumnFamilies.put(tableName, lgtcf);
                }
                tableConfigs.put(tableName, tableConfig);

            }
        } catch (AccumuloException | AccumuloSecurityException | TableNotFoundException e) {
            throw new IOException("Unable to get configuration.  Please call MultiRFileOutput.setAccumuloConfiguration with the proper credentials", e);
        }
    }

Replace Generic With Diamond HashSet<ByteSequence> with HashSet<> in method protected setTableIdsAndConfigs() : void from class datawave.ingest.mapreduce.job.MultiRFileOutputFormatter


    /**
     * Cleanup the job. Note that this is deprecated in the super class but is still being used for this work. When the method has been removed from the super
     * class then this class will need to be reworked.
     */
    @Override
    public void cleanupJob(JobContext context) throws IOException {
        if (checkForEmptyDir) {
            if (this.outputPath != null) {
                Path pendingJobAttemptsPath = getPendingJobAttemptsPath();
                FileSystem fs = pendingJobAttemptsPath.getFileSystem(context.getConfiguration());
                // now verify we do not have any files left in the temporary directory structure
                List<Path> fileList = new ArrayList<>();
                if (containsFiles(fs, pendingJobAttemptsPath, fileList)) {
                    throw new FileExistsException("Found files still left in the temporary job attempts path: " + fileList);
                }
            }
        }
        super.cleanupJob(context);
    }

    /**
     * Cleanup the job. Note that this is deprecated in the super class but is still being used for this work. When the method has been removed from the super
     * class then this class will need to be reworked.
     */
    @Override
    public void cleanupJob(JobContext context) throws IOException {
        if (checkForEmptyDir) {
            if (this.outputPath != null) {
                Path pendingJobAttemptsPath = getPendingJobAttemptsPath();
                FileSystem fs = pendingJobAttemptsPath.getFileSystem(context.getConfiguration());
                // now verify we do not have any files left in the temporary directory structure
                List<Path> fileList = new ArrayList<Path>();
                if (containsFiles(fs, pendingJobAttemptsPath, fileList)) {
                    throw new FileExistsException("Found files still left in the temporary job attempts path: " + fileList);
                }
            }
        }
        super.cleanupJob(context);
    }

Replace Generic With Diamond ArrayList<Path> with ArrayList<> in method public cleanupJob(context JobContext) : void from class datawave.ingest.mapreduce.job.SafeFileOutputCommitter


    private void initStats(long startTime) {
        this.ctx = new StandaloneTaskAttemptContext<>(new Configuration(), new StandaloneStatusReporter());
        ctx.putIfAbsent(datawave.metrics.util.flag.InputFile.FLAGMAKER_START_TIME, startTime);
    }

    private void initStats(long startTime) {
        this.ctx = new StandaloneTaskAttemptContext<Object,Object,Object,Object>(new Configuration(), new StandaloneStatusReporter());
        ctx.putIfAbsent(datawave.metrics.util.flag.InputFile.FLAGMAKER_START_TIME, startTime);
    }

Replace Generic With Diamond StandaloneTaskAttemptContext<Object,Object,Object,Object> with StandaloneTaskAttemptContext<> in method private initStats(startTime long) : void from class datawave.util.flag.FlagMaker


    @Override
    public Set<Tuple2<String,Set<String>>> load(Range inputKey) throws Exception {

        Set<Tuple2<String,Set<String>>> locations = new HashSet<>();

        // determine the table id
        final String metadataString = inputKey.getStartKey().getRow().toString().intern();
        final String tableId = getTableId(metadataString);

        // determine our stop criteria
        final String stopRow = inputKey.getEndKey().getRow().toString().intern();

        // create a scan range that goes through the default tablet
        Key endKey = new Key(new KeyExtent(tableId, null, null).getMetadataEntry()).followingKey(PartialKey.ROW);
        Range metadataRange = new Range(inputKey.getStartKey(), inputKey.isStartKeyInclusive(), endKey, false);

        Scanner scanner = conn.createScanner(MetadataTable.NAME, Authorizations.EMPTY);
        MetadataSchema.TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
        scanner.fetchColumnFamily(MetadataSchema.TabletsSection.LastLocationColumnFamily.NAME);
        scanner.fetchColumnFamily(MetadataSchema.TabletsSection.DataFileColumnFamily.NAME);
        scanner.fetchColumnFamily(MetadataSchema.TabletsSection.CurrentLocationColumnFamily.NAME);
        scanner.fetchColumnFamily(MetadataSchema.TabletsSection.FutureLocationColumnFamily.NAME);
        scanner.setRange(metadataRange);

        RowIterator rowIter = new RowIterator(scanner);

        String baseLocation = defaultBasePath + MultiRfileInputformat.tableStr + tableId + Path.SEPARATOR;
        try {

            while (rowIter.hasNext()) {

                Iterator<Entry<Key,Value>> row = rowIter.next();
                String location = "";
                String endRow = "";
                Set<String> fileLocations = Sets.newHashSet();

                while (row.hasNext()) {
                    Entry<Key,Value> entry = row.next();
                    Key key = entry.getKey();
                    endRow = key.getRow().toString().intern();

                    if (key.getColumnFamily().equals(MetadataSchema.TabletsSection.DataFileColumnFamily.NAME)) {
                        String fileLocation = entry.getKey().getColumnQualifier().toString();
                        if (!fileLocation.contains(HDFS_BASE))
                            fileLocation = baseLocation.concat(entry.getKey().getColumnQualifier().toString());
                        fileLocations.add(fileLocation);
                    }

                    if (key.getColumnFamily().equals(MetadataSchema.TabletsSection.CurrentLocationColumnFamily.NAME)
                                    || key.getColumnFamily().equals(MetadataSchema.TabletsSection.FutureLocationColumnFamily.NAME)) {
                        location = entry.getValue().toString();
                    }

                }

                locations.add(new Tuple2<>(location, fileLocations));

                // if this row is equal to or past our stop row, then terminate
                if (endRow.compareTo(stopRow) >= 0) {
                    break;
                }
            }

        } finally {
            scanner.close();
        }

        return locations;
    }

    @Override
    public Set<Tuple2<String,Set<String>>> load(Range inputKey) throws Exception {

        Set<Tuple2<String,Set<String>>> locations = new HashSet<>();

        // determine the table id
        final String metadataString = inputKey.getStartKey().getRow().toString().intern();
        final String tableId = getTableId(metadataString);

        // determine our stop criteria
        final String stopRow = inputKey.getEndKey().getRow().toString().intern();

        // create a scan range that goes through the default tablet
        Key endKey = new Key(new KeyExtent(tableId, null, null).getMetadataEntry()).followingKey(PartialKey.ROW);
        Range metadataRange = new Range(inputKey.getStartKey(), inputKey.isStartKeyInclusive(), endKey, false);

        Scanner scanner = conn.createScanner(MetadataTable.NAME, Authorizations.EMPTY);
        MetadataSchema.TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
        scanner.fetchColumnFamily(MetadataSchema.TabletsSection.LastLocationColumnFamily.NAME);
        scanner.fetchColumnFamily(MetadataSchema.TabletsSection.DataFileColumnFamily.NAME);
        scanner.fetchColumnFamily(MetadataSchema.TabletsSection.CurrentLocationColumnFamily.NAME);
        scanner.fetchColumnFamily(MetadataSchema.TabletsSection.FutureLocationColumnFamily.NAME);
        scanner.setRange(metadataRange);

        RowIterator rowIter = new RowIterator(scanner);

        String baseLocation = defaultBasePath + MultiRfileInputformat.tableStr + tableId + Path.SEPARATOR;
        try {

            while (rowIter.hasNext()) {

                Iterator<Entry<Key,Value>> row = rowIter.next();
                String location = "";
                String endRow = "";
                Set<String> fileLocations = Sets.newHashSet();

                while (row.hasNext()) {
                    Entry<Key,Value> entry = row.next();
                    Key key = entry.getKey();
                    endRow = key.getRow().toString().intern();

                    if (key.getColumnFamily().equals(MetadataSchema.TabletsSection.DataFileColumnFamily.NAME)) {
                        String fileLocation = entry.getKey().getColumnQualifier().toString();
                        if (!fileLocation.contains(HDFS_BASE))
                            fileLocation = baseLocation.concat(entry.getKey().getColumnQualifier().toString());
                        fileLocations.add(fileLocation);
                    }

                    if (key.getColumnFamily().equals(MetadataSchema.TabletsSection.CurrentLocationColumnFamily.NAME)
                                    || key.getColumnFamily().equals(MetadataSchema.TabletsSection.FutureLocationColumnFamily.NAME)) {
                        location = entry.getValue().toString();
                    }

                }

                locations.add(new Tuple2<String,Set<String>>(location, fileLocations));

                // if this row is equal to or past our stop row, then terminate
                if (endRow.compareTo(stopRow) >= 0) {
                    break;
                }
            }

        } finally {
            scanner.close();
        }

        return locations;
    }

Replace Generic With Diamond Tuple2<String,Set<String>> with Tuple2<> in method public load(inputKey Range) : Set<Tuple2<String,Set<String>>> from class datawave.mr.bulk.MetadataCacheLoader


    @Override
    public void seek(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException {
        Span span = Trace.start("QueryIterator.seek");

        if (this.isIncludeGroupingContext() == false
                        && (this.query.contains("grouping:") || this.query.contains("matchesInGroup") || this.query.contains("MatchesInGroup") || this.query
                                        .contains("atomValuesMatch"))) {
            this.setIncludeGroupingContext(true);
            this.groupingContextAddedByMe = true;
        } else {
            this.groupingContextAddedByMe = false;
        }

        try {
            if (log.isDebugEnabled()) {
                log.debug("Seek range: " + range + " " + query);
            }
            this.range = range;

            // determine whether this is a teardown/rebuild range
            long resultCount = 0;
            if (!range.isStartKeyInclusive()) {
                // see if we have a count in the cf
                Key startKey = range.getStartKey();
                String[] parts = StringUtils.split(startKey.getColumnFamily().toString(), '\0');
                if (parts.length == 3) {
                    resultCount = NumericalEncoder.decode(parts[0]).longValue();
                    // remove the count from the range
                    startKey = new Key(startKey.getRow(), new Text(parts[1] + '\0' + parts[2]), startKey.getColumnQualifier(), startKey.getColumnVisibility(),
                                    startKey.getTimestamp());
                    this.range = range = new Range(startKey, range.isStartKeyInclusive(), range.getEndKey(), range.isEndKeyInclusive());
                }
            }

            // determine whether this is a document specific range
            Range documentRange = isDocumentSpecificRange(range) ? range : null;

            // if we have a document specific range, but the key is not
            // inclusive then we have already returned the document; this scan
            // is done
            if (documentRange != null && !documentRange.isStartKeyInclusive()) {
                if (log.isTraceEnabled()) {
                    log.trace("Received non-inclusive event specific range: " + documentRange);
                }
                if (gatherTimingDetails()) {
                    this.seekKeySource = new EvaluationTrackingNestedIterator(QuerySpan.Stage.EmptyTree, trackingSpan, new EmptyTreeIterable());
                } else {
                    this.seekKeySource = new EmptyTreeIterable();
                }
            }

            // if the Range is for a single document and the query doesn't reference any index-only or tokenized fields
            else if (documentRange != null && (!this.isContainsIndexOnlyTerms() && this.getTermFrequencyFields().isEmpty() && !super.mustUseFieldIndex)) {
                if (log.isTraceEnabled())
                    log.trace("Received event specific range: " + documentRange);
                // We can take a shortcut to the directly to the event
                Map.Entry<Key,Document> documentKey = Maps.immutableEntry(super.getDocumentKey.apply(documentRange), new Document());
                if (log.isTraceEnabled())
                    log.trace("Transformed document key: " + documentKey);
                // we can only trim if we're certain that the projected fields
                // aren't needed for evaluation

                if (gatherTimingDetails()) {
                    this.seekKeySource = new EvaluationTrackingNestedIterator(QuerySpan.Stage.DocumentSpecificTree, trackingSpan,
                                    new DocumentSpecificNestedIterator(documentKey));
                } else {
                    this.seekKeySource = new DocumentSpecificNestedIterator(documentKey);
                }
            } else {
                this.seekKeySource = buildDocumentIterator(documentRange, range, columnFamilies, inclusive);
            }

            // Create the pipeline iterator for document aggregation and
            // evaluation within a thread pool
            PipelineIterator pipelineIter = PipelineFactory.createIterator(this.seekKeySource, getMaxEvaluationPipelines(), getMaxPipelineCachedResults(),
                            getSerialPipelineRequest(), querySpanCollector, trackingSpan, this, sourceForDeepCopies.deepCopy(myEnvironment), myEnvironment,
                            yield, yieldThresholdMs);

            pipelineIter.setCollectTimingDetails(collectTimingDetails);
            // TODO pipelineIter.setStatsdHostAndPort(statsdHostAndPort);

            pipelineIter.startPipeline();

            // gather Key,Document Entries from the pipelines
            Iterator<Entry<Key,Document>> pipelineDocuments = pipelineIter;

            if (log.isTraceEnabled()) {
                pipelineDocuments = Iterators.filter(pipelineDocuments, keyDocumentEntry -> {
                    log.trace("after pipeline, keyDocumentEntry:" + keyDocumentEntry);
                    return true;
                });
            }

            // now apply the unique transform if requested
            UniqueTransform uniquify = getUniqueTransform();
            if (uniquify != null) {
                pipelineDocuments = Iterators.filter(pipelineDocuments, uniquify.getUniquePredicate());
            }

            // apply the grouping transform if requested and if the batch size is greater than zero
            // if the batch size is 0, then grouping is computed only on the web server
            GroupingTransform groupify = getGroupingTransform();
            if (groupify != null && this.groupFieldsBatchSize > 0) {

                pipelineDocuments = groupingTransform.getGroupingIterator(pipelineDocuments, this.groupFieldsBatchSize);

                if (log.isTraceEnabled()) {
                    pipelineDocuments = Iterators.filter(pipelineDocuments, keyDocumentEntry -> {
                        log.trace("after grouping, keyDocumentEntry:" + keyDocumentEntry);
                        return true;
                    });
                }

            }

            if (this.getReturnType() == ReturnType.kryo) {
                // Serialize the Document using Kryo
                this.serializedDocuments = Iterators.transform(pipelineDocuments, new KryoDocumentSerializer(isReducedResponse(), isCompressResults()));
            } else if (this.getReturnType() == ReturnType.writable) {
                // Use the Writable interface to serialize the Document
                this.serializedDocuments = Iterators.transform(pipelineDocuments, new WritableDocumentSerializer(isReducedResponse()));
            } else if (this.getReturnType() == ReturnType.tostring) {
                // Just return a toString() representation of the document
                this.serializedDocuments = Iterators.transform(pipelineDocuments, new ToStringDocumentSerializer(isReducedResponse()));
            } else {
                throw new IllegalArgumentException("Unknown return type of: " + this.getReturnType());
            }

            if (log.isTraceEnabled()) {
                KryoDocumentDeserializer dser = new KryoDocumentDeserializer();
                this.serializedDocuments = Iterators.filter(this.serializedDocuments, keyValueEntry -> {
                    log.trace("after serializing, keyValueEntry:" + dser.apply(keyValueEntry));
                    return true;
                });
            }

            // now add the result count to the keys (required when not sorting UIDs)
            // Cannot do this on document specific ranges as the count would place the keys outside the initial range
            if (!sortedUIDs && documentRange == null) {
                this.serializedDocuments = new ResultCountingIterator(serializedDocuments, resultCount, yield);
            } else if (this.sortedUIDs) {
                // we have sorted UIDs, so we can mask out the cq
                this.serializedDocuments = new KeyAdjudicator<>(serializedDocuments, yield);
            }

            // only add the final document tracking iterator which sends stats back to the client if collectTimingDetails is true
            if (collectTimingDetails) {
                Range r = (documentRange == null) ? this.range : documentRange;
                // if there is no document to return, then add an empty document
                // to store the timing metadata
                this.serializedDocuments = new FinalDocumentTrackingIterator(querySpanCollector, trackingSpan, r, this.serializedDocuments,
                                this.getReturnType(), this.isReducedResponse(), this.isCompressResults(), this.yield);
            }
            if (log.isTraceEnabled()) {
                KryoDocumentDeserializer dser = new KryoDocumentDeserializer();
                this.serializedDocuments = Iterators.filter(this.serializedDocuments, keyValueEntry -> {
                    log.debug("finally, considering:" + dser.apply(keyValueEntry));
                    return true;
                });
            }

            // Determine if we have items to return
            prepareKeyValue(span);
        } catch (Exception e) {
            handleException(e);
        } finally {
            if (gatherTimingDetails() && trackingSpan != null && querySpanCollector != null) {
                querySpanCollector.addQuerySpan(trackingSpan);
            }
            if (null != span) {
                span.stop();
            }
            QueryStatsDClient client = getStatsdClient();
            if (client != null) {
                client.flush();
            }
        }
    }

    @Override
    public void seek(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException {
        Span span = Trace.start("QueryIterator.seek");

        if (this.isIncludeGroupingContext() == false
                        && (this.query.contains("grouping:") || this.query.contains("matchesInGroup") || this.query.contains("MatchesInGroup") || this.query
                                        .contains("atomValuesMatch"))) {
            this.setIncludeGroupingContext(true);
            this.groupingContextAddedByMe = true;
        } else {
            this.groupingContextAddedByMe = false;
        }

        try {
            if (log.isDebugEnabled()) {
                log.debug("Seek range: " + range + " " + query);
            }
            this.range = range;

            // determine whether this is a teardown/rebuild range
            long resultCount = 0;
            if (!range.isStartKeyInclusive()) {
                // see if we have a count in the cf
                Key startKey = range.getStartKey();
                String[] parts = StringUtils.split(startKey.getColumnFamily().toString(), '\0');
                if (parts.length == 3) {
                    resultCount = NumericalEncoder.decode(parts[0]).longValue();
                    // remove the count from the range
                    startKey = new Key(startKey.getRow(), new Text(parts[1] + '\0' + parts[2]), startKey.getColumnQualifier(), startKey.getColumnVisibility(),
                                    startKey.getTimestamp());
                    this.range = range = new Range(startKey, range.isStartKeyInclusive(), range.getEndKey(), range.isEndKeyInclusive());
                }
            }

            // determine whether this is a document specific range
            Range documentRange = isDocumentSpecificRange(range) ? range : null;

            // if we have a document specific range, but the key is not
            // inclusive then we have already returned the document; this scan
            // is done
            if (documentRange != null && !documentRange.isStartKeyInclusive()) {
                if (log.isTraceEnabled()) {
                    log.trace("Received non-inclusive event specific range: " + documentRange);
                }
                if (gatherTimingDetails()) {
                    this.seekKeySource = new EvaluationTrackingNestedIterator(QuerySpan.Stage.EmptyTree, trackingSpan, new EmptyTreeIterable());
                } else {
                    this.seekKeySource = new EmptyTreeIterable();
                }
            }

            // if the Range is for a single document and the query doesn't reference any index-only or tokenized fields
            else if (documentRange != null && (!this.isContainsIndexOnlyTerms() && this.getTermFrequencyFields().isEmpty() && !super.mustUseFieldIndex)) {
                if (log.isTraceEnabled())
                    log.trace("Received event specific range: " + documentRange);
                // We can take a shortcut to the directly to the event
                Map.Entry<Key,Document> documentKey = Maps.immutableEntry(super.getDocumentKey.apply(documentRange), new Document());
                if (log.isTraceEnabled())
                    log.trace("Transformed document key: " + documentKey);
                // we can only trim if we're certain that the projected fields
                // aren't needed for evaluation

                if (gatherTimingDetails()) {
                    this.seekKeySource = new EvaluationTrackingNestedIterator(QuerySpan.Stage.DocumentSpecificTree, trackingSpan,
                                    new DocumentSpecificNestedIterator(documentKey));
                } else {
                    this.seekKeySource = new DocumentSpecificNestedIterator(documentKey);
                }
            } else {
                this.seekKeySource = buildDocumentIterator(documentRange, range, columnFamilies, inclusive);
            }

            // Create the pipeline iterator for document aggregation and
            // evaluation within a thread pool
            PipelineIterator pipelineIter = PipelineFactory.createIterator(this.seekKeySource, getMaxEvaluationPipelines(), getMaxPipelineCachedResults(),
                            getSerialPipelineRequest(), querySpanCollector, trackingSpan, this, sourceForDeepCopies.deepCopy(myEnvironment), myEnvironment,
                            yield, yieldThresholdMs);

            pipelineIter.setCollectTimingDetails(collectTimingDetails);
            // TODO pipelineIter.setStatsdHostAndPort(statsdHostAndPort);

            pipelineIter.startPipeline();

            // gather Key,Document Entries from the pipelines
            Iterator<Entry<Key,Document>> pipelineDocuments = pipelineIter;

            if (log.isTraceEnabled()) {
                pipelineDocuments = Iterators.filter(pipelineDocuments, keyDocumentEntry -> {
                    log.trace("after pipeline, keyDocumentEntry:" + keyDocumentEntry);
                    return true;
                });
            }

            // now apply the unique transform if requested
            UniqueTransform uniquify = getUniqueTransform();
            if (uniquify != null) {
                pipelineDocuments = Iterators.filter(pipelineDocuments, uniquify.getUniquePredicate());
            }

            // apply the grouping transform if requested and if the batch size is greater than zero
            // if the batch size is 0, then grouping is computed only on the web server
            GroupingTransform groupify = getGroupingTransform();
            if (groupify != null && this.groupFieldsBatchSize > 0) {

                pipelineDocuments = groupingTransform.getGroupingIterator(pipelineDocuments, this.groupFieldsBatchSize);

                if (log.isTraceEnabled()) {
                    pipelineDocuments = Iterators.filter(pipelineDocuments, keyDocumentEntry -> {
                        log.trace("after grouping, keyDocumentEntry:" + keyDocumentEntry);
                        return true;
                    });
                }

            }

            if (this.getReturnType() == ReturnType.kryo) {
                // Serialize the Document using Kryo
                this.serializedDocuments = Iterators.transform(pipelineDocuments, new KryoDocumentSerializer(isReducedResponse(), isCompressResults()));
            } else if (this.getReturnType() == ReturnType.writable) {
                // Use the Writable interface to serialize the Document
                this.serializedDocuments = Iterators.transform(pipelineDocuments, new WritableDocumentSerializer(isReducedResponse()));
            } else if (this.getReturnType() == ReturnType.tostring) {
                // Just return a toString() representation of the document
                this.serializedDocuments = Iterators.transform(pipelineDocuments, new ToStringDocumentSerializer(isReducedResponse()));
            } else {
                throw new IllegalArgumentException("Unknown return type of: " + this.getReturnType());
            }

            if (log.isTraceEnabled()) {
                KryoDocumentDeserializer dser = new KryoDocumentDeserializer();
                this.serializedDocuments = Iterators.filter(this.serializedDocuments, keyValueEntry -> {
                    log.trace("after serializing, keyValueEntry:" + dser.apply(keyValueEntry));
                    return true;
                });
            }

            // now add the result count to the keys (required when not sorting UIDs)
            // Cannot do this on document specific ranges as the count would place the keys outside the initial range
            if (!sortedUIDs && documentRange == null) {
                this.serializedDocuments = new ResultCountingIterator(serializedDocuments, resultCount, yield);
            } else if (this.sortedUIDs) {
                // we have sorted UIDs, so we can mask out the cq
                this.serializedDocuments = new KeyAdjudicator<Value>(serializedDocuments, yield);
            }

            // only add the final document tracking iterator which sends stats back to the client if collectTimingDetails is true
            if (collectTimingDetails) {
                Range r = (documentRange == null) ? this.range : documentRange;
                // if there is no document to return, then add an empty document
                // to store the timing metadata
                this.serializedDocuments = new FinalDocumentTrackingIterator(querySpanCollector, trackingSpan, r, this.serializedDocuments,
                                this.getReturnType(), this.isReducedResponse(), this.isCompressResults(), this.yield);
            }
            if (log.isTraceEnabled()) {
                KryoDocumentDeserializer dser = new KryoDocumentDeserializer();
                this.serializedDocuments = Iterators.filter(this.serializedDocuments, keyValueEntry -> {
                    log.debug("finally, considering:" + dser.apply(keyValueEntry));
                    return true;
                });
            }

            // Determine if we have items to return
            prepareKeyValue(span);
        } catch (Exception e) {
            handleException(e);
        } finally {
            if (gatherTimingDetails() && trackingSpan != null && querySpanCollector != null) {
                querySpanCollector.addQuerySpan(trackingSpan);
            }
            if (null != span) {
                span.stop();
            }
            QueryStatsDClient client = getStatsdClient();
            if (client != null) {
                client.flush();
            }
        }
    }

Replace Generic With Diamond KeyAdjudicator<Value> with KeyAdjudicator<> in method public seek(range Range, columnFamilies Collection<ByteSequence>, inclusive boolean) : void from class datawave.query.iterator.QueryIterator


    /**
     * Create the pipeline. It is very important that this pipeline can handle resetting the bottom iterator with a new value. This means that hasNext() needs
     * to call the next iterator. The only state that can be maintained is the next value ready after hasNext() has been called. Once next returns the value,
     * the next hasNext() call must call the next iterator again. So for example Iterators.filter() cannot be used as it uses a google commons AbstractIterator
     * that maintains an iterator state (failed, ready, done); use statelessFilter above instead.
     *
     * @param deepSourceCopy
     * @param documentSpecificSource
     * @return iterator of keys and values
     */
    public Iterator<Entry<Key,Document>> createDocumentPipeline(SortedKeyValueIterator<Key,Value> deepSourceCopy,
                    final NestedQueryIterator<Key> documentSpecificSource, QuerySpanCollector querySpanCollector) {

        QuerySpan trackingSpan = null;
        if (gatherTimingDetails()) {
            trackingSpan = new QuerySpan(getStatsdClient());
        }
        if (log.isTraceEnabled()) {
            log.trace("createDocumentPipeline");
        }
        final Function<Entry<Key,Document>,Entry<DocumentData,Document>> docMapper;

        if (isFieldIndexSatisfyingQuery()) {
            if (log.isTraceEnabled()) {
                log.trace("isFieldIndexSatisfyingQuery");
            }
            docMapper = new Function<Entry<Key,Document>,Entry<DocumentData,Document>>() {
                @Nullable
                @Override
                public Entry<DocumentData,Document> apply(@Nullable Entry<Key,Document> input) {

                    Entry<DocumentData,Document> entry = null;
                    if (input != null) {
                        entry = Maps.immutableEntry(new DocumentData(input.getKey(), Collections.singleton(input.getKey()), Collections.EMPTY_LIST),
                                        input.getValue());
                    }
                    return entry;
                }
            };
        } else {
            docMapper = new KeyToDocumentData(deepSourceCopy, myEnvironment, documentOptions, super.equality, getEvaluationFilter(),
                            this.includeHierarchyFields, this.includeHierarchyFields);
        }

        Iterator<Entry<DocumentData,Document>> sourceIterator = Iterators.transform(documentSpecificSource, from -> {
            Entry<Key,Document> entry = Maps.immutableEntry(from, documentSpecificSource.document());
            return docMapper.apply(entry);
        });

        // Take the document Keys and transform it into Entry<Key,Document>,
        // removing Attributes for this Document
        // which do not fall within the expected time range
        Iterator<Entry<Key,Document>> documents = null;
        Aggregation a = new Aggregation(this.getTimeFilter(), this.typeMetadataWithNonIndexed, compositeMetadata, this.isIncludeGroupingContext(),
                        this.includeRecordId, this.disableIndexOnlyDocuments(), getEvaluationFilter(), isTrackSizes());
        if (gatherTimingDetails()) {
            documents = Iterators.transform(sourceIterator, new EvaluationTrackingFunction<>(QuerySpan.Stage.Aggregation, trackingSpan, a));
        } else {
            documents = Iterators.transform(sourceIterator, a);
        }

        // Inject the data type as a field if the user requested it
        if (this.includeDatatype) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.DataTypeAsField, trackingSpan, new DataTypeAsField(
                                this.datatypeKey)));
            } else {
                documents = Iterators.transform(documents, new DataTypeAsField(this.datatypeKey));
            }
        }

        // Inject the document permutations if required
        if (!this.getDocumentPermutations().isEmpty()) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.DocumentPermutation, trackingSpan,
                                new DocumentPermutation.DocumentPermutationAggregation(this.getDocumentPermutations())));
            } else {
                documents = Iterators.transform(documents, new DocumentPermutation.DocumentPermutationAggregation(this.getDocumentPermutations()));
            }
        }

        if (gatherTimingDetails()) {
            documents = new EvaluationTrackingIterator(QuerySpan.Stage.DocumentEvaluation, trackingSpan, getEvaluation(documentSpecificSource, deepSourceCopy,
                            documents, compositeMetadata, typeMetadataWithNonIndexed));
        } else {
            documents = getEvaluation(documentSpecificSource, deepSourceCopy, documents, compositeMetadata, typeMetadataWithNonIndexed);
        }

        // a hook to allow mapping the document such as with the TLD or Parent
        // query logics
        // or if the document was not aggregated in the first place because the
        // field index fields completely satisfied the query
        documents = mapDocument(deepSourceCopy, documents, compositeMetadata);

        // apply any configured post processing
        documents = getPostProcessingChain(documents);
        if (gatherTimingDetails()) {
            documents = new EvaluationTrackingIterator(QuerySpan.Stage.PostProcessing, trackingSpan, documents);
        }

        // Filter out masked values if requested
        if (this.filterMaskedValues) {
            MaskedValueFilterInterface mvfi = MaskedValueFilterFactory.get(this.isIncludeGroupingContext(), this.isReducedResponse());
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.MaskedValueFilter, trackingSpan, mvfi));
            } else {
                documents = Iterators.transform(documents, mvfi);
            }
        }

        // now filter the attributes to those with the keep flag set true
        if (gatherTimingDetails()) {
            documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.AttributeKeepFilter, trackingSpan,
                            new AttributeKeepFilter<>()));
        } else {
            documents = Iterators.transform(documents, new AttributeKeepFilter<>());
        }

        // Project fields using a whitelist or a blacklist before serialization
        if (this.projectResults) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.DocumentProjection, trackingSpan, getProjection()));
            } else {
                documents = Iterators.transform(documents, getProjection());
            }
        }

        // remove the composite entries
        documents = Iterators.transform(documents, this.getCompositeProjection());

        // Filter out any Documents which are empty (e.g. due to attribute
        // projection or visibility filtering)
        if (gatherTimingDetails()) {
            documents = statelessFilter(documents, new EvaluationTrackingPredicate<>(QuerySpan.Stage.EmptyDocumentFilter, trackingSpan,
                            new EmptyDocumentFilter()));
            documents = Iterators
                            .transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.DocumentMetadata, trackingSpan, new DocumentMetadata()));
        } else {
            documents = statelessFilter(documents, new EmptyDocumentFilter());
            documents = Iterators.transform(documents, new DocumentMetadata());
        }

        if (!this.limitFieldsMap.isEmpty()) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents,
                                new EvaluationTrackingFunction<>(QuerySpan.Stage.LimitFields, trackingSpan, new LimitFields(this.getLimitFieldsMap())));
            } else {
                documents = Iterators.transform(documents, new LimitFields(this.getLimitFieldsMap()));
            }
        }

        // do I need to remove the grouping context I added above?
        if (groupingContextAddedByMe) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.RemoveGroupingContext, trackingSpan,
                                new RemoveGroupingContext()));
            } else {
                documents = Iterators.transform(documents, new RemoveGroupingContext());
            }
        }

        // only add the pipeline query span collection iterator which will cache metrics with each document if collectTimingDetails is true
        if (collectTimingDetails) {
            // if there is not a result, then add the trackingSpan to the
            // QuerySpanCollector
            // if there was a result, then the metrics from the trackingSpan
            // will be added here
            documents = new PipelineQuerySpanCollectionIterator(querySpanCollector, trackingSpan, documents);
        }

        return documents;
    }

    /**
     * Create the pipeline. It is very important that this pipeline can handle resetting the bottom iterator with a new value. This means that hasNext() needs
     * to call the next iterator. The only state that can be maintained is the next value ready after hasNext() has been called. Once next returns the value,
     * the next hasNext() call must call the next iterator again. So for example Iterators.filter() cannot be used as it uses a google commons AbstractIterator
     * that maintains an iterator state (failed, ready, done); use statelessFilter above instead.
     *
     * @param deepSourceCopy
     * @param documentSpecificSource
     * @return iterator of keys and values
     */
    public Iterator<Entry<Key,Document>> createDocumentPipeline(SortedKeyValueIterator<Key,Value> deepSourceCopy,
                    final NestedQueryIterator<Key> documentSpecificSource, QuerySpanCollector querySpanCollector) {

        QuerySpan trackingSpan = null;
        if (gatherTimingDetails()) {
            trackingSpan = new QuerySpan(getStatsdClient());
        }
        if (log.isTraceEnabled()) {
            log.trace("createDocumentPipeline");
        }
        final Function<Entry<Key,Document>,Entry<DocumentData,Document>> docMapper;

        if (isFieldIndexSatisfyingQuery()) {
            if (log.isTraceEnabled()) {
                log.trace("isFieldIndexSatisfyingQuery");
            }
            docMapper = new Function<Entry<Key,Document>,Entry<DocumentData,Document>>() {
                @Nullable
                @Override
                public Entry<DocumentData,Document> apply(@Nullable Entry<Key,Document> input) {

                    Entry<DocumentData,Document> entry = null;
                    if (input != null) {
                        entry = Maps.immutableEntry(new DocumentData(input.getKey(), Collections.singleton(input.getKey()), Collections.EMPTY_LIST),
                                        input.getValue());
                    }
                    return entry;
                }
            };
        } else {
            docMapper = new KeyToDocumentData(deepSourceCopy, myEnvironment, documentOptions, super.equality, getEvaluationFilter(),
                            this.includeHierarchyFields, this.includeHierarchyFields);
        }

        Iterator<Entry<DocumentData,Document>> sourceIterator = Iterators.transform(documentSpecificSource, from -> {
            Entry<Key,Document> entry = Maps.immutableEntry(from, documentSpecificSource.document());
            return docMapper.apply(entry);
        });

        // Take the document Keys and transform it into Entry<Key,Document>,
        // removing Attributes for this Document
        // which do not fall within the expected time range
        Iterator<Entry<Key,Document>> documents = null;
        Aggregation a = new Aggregation(this.getTimeFilter(), this.typeMetadataWithNonIndexed, compositeMetadata, this.isIncludeGroupingContext(),
                        this.includeRecordId, this.disableIndexOnlyDocuments(), getEvaluationFilter(), isTrackSizes());
        if (gatherTimingDetails()) {
            documents = Iterators.transform(sourceIterator, new EvaluationTrackingFunction<>(QuerySpan.Stage.Aggregation, trackingSpan, a));
        } else {
            documents = Iterators.transform(sourceIterator, a);
        }

        // Inject the data type as a field if the user requested it
        if (this.includeDatatype) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.DataTypeAsField, trackingSpan, new DataTypeAsField(
                                this.datatypeKey)));
            } else {
                documents = Iterators.transform(documents, new DataTypeAsField(this.datatypeKey));
            }
        }

        // Inject the document permutations if required
        if (!this.getDocumentPermutations().isEmpty()) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.DocumentPermutation, trackingSpan,
                                new DocumentPermutation.DocumentPermutationAggregation(this.getDocumentPermutations())));
            } else {
                documents = Iterators.transform(documents, new DocumentPermutation.DocumentPermutationAggregation(this.getDocumentPermutations()));
            }
        }

        if (gatherTimingDetails()) {
            documents = new EvaluationTrackingIterator(QuerySpan.Stage.DocumentEvaluation, trackingSpan, getEvaluation(documentSpecificSource, deepSourceCopy,
                            documents, compositeMetadata, typeMetadataWithNonIndexed));
        } else {
            documents = getEvaluation(documentSpecificSource, deepSourceCopy, documents, compositeMetadata, typeMetadataWithNonIndexed);
        }

        // a hook to allow mapping the document such as with the TLD or Parent
        // query logics
        // or if the document was not aggregated in the first place because the
        // field index fields completely satisfied the query
        documents = mapDocument(deepSourceCopy, documents, compositeMetadata);

        // apply any configured post processing
        documents = getPostProcessingChain(documents);
        if (gatherTimingDetails()) {
            documents = new EvaluationTrackingIterator(QuerySpan.Stage.PostProcessing, trackingSpan, documents);
        }

        // Filter out masked values if requested
        if (this.filterMaskedValues) {
            MaskedValueFilterInterface mvfi = MaskedValueFilterFactory.get(this.isIncludeGroupingContext(), this.isReducedResponse());
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.MaskedValueFilter, trackingSpan, mvfi));
            } else {
                documents = Iterators.transform(documents, mvfi);
            }
        }

        // now filter the attributes to those with the keep flag set true
        if (gatherTimingDetails()) {
            documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.AttributeKeepFilter, trackingSpan,
                            new AttributeKeepFilter<Key>()));
        } else {
            documents = Iterators.transform(documents, new AttributeKeepFilter<Key>());
        }

        // Project fields using a whitelist or a blacklist before serialization
        if (this.projectResults) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.DocumentProjection, trackingSpan, getProjection()));
            } else {
                documents = Iterators.transform(documents, getProjection());
            }
        }

        // remove the composite entries
        documents = Iterators.transform(documents, this.getCompositeProjection());

        // Filter out any Documents which are empty (e.g. due to attribute
        // projection or visibility filtering)
        if (gatherTimingDetails()) {
            documents = statelessFilter(documents, new EvaluationTrackingPredicate<>(QuerySpan.Stage.EmptyDocumentFilter, trackingSpan,
                            new EmptyDocumentFilter()));
            documents = Iterators
                            .transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.DocumentMetadata, trackingSpan, new DocumentMetadata()));
        } else {
            documents = statelessFilter(documents, new EmptyDocumentFilter());
            documents = Iterators.transform(documents, new DocumentMetadata());
        }

        if (!this.limitFieldsMap.isEmpty()) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents,
                                new EvaluationTrackingFunction<>(QuerySpan.Stage.LimitFields, trackingSpan, new LimitFields(this.getLimitFieldsMap())));
            } else {
                documents = Iterators.transform(documents, new LimitFields(this.getLimitFieldsMap()));
            }
        }

        // do I need to remove the grouping context I added above?
        if (groupingContextAddedByMe) {
            if (gatherTimingDetails()) {
                documents = Iterators.transform(documents, new EvaluationTrackingFunction<>(QuerySpan.Stage.RemoveGroupingContext, trackingSpan,
                                new RemoveGroupingContext()));
            } else {
                documents = Iterators.transform(documents, new RemoveGroupingContext());
            }
        }

        // only add the pipeline query span collection iterator which will cache metrics with each document if collectTimingDetails is true
        if (collectTimingDetails) {
            // if there is not a result, then add the trackingSpan to the
            // QuerySpanCollector
            // if there was a result, then the metrics from the trackingSpan
            // will be added here
            documents = new PipelineQuerySpanCollectionIterator(querySpanCollector, trackingSpan, documents);
        }

        return documents;
    }

Replace Generic With Diamond EvaluationTrackingFunction<> with EvaluationTrackingFunction<> in method public createDocumentPipeline(deepSourceCopy SortedKeyValueIterator<Key,Value>, documentSpecificSource NestedQueryIterator<Key>, querySpanCollector QuerySpanCollector) : Iterator<Entry<Key,Document>> from class datawave.query.iterator.QueryIterator


    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public Iterator<Entry<Key,Document>> getDocumentIterator(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException,
                    ConfigException, InstantiationException, IllegalAccessException {
        // Otherwise, we have to use the field index
        // Seek() the boolean logic stuff
        createAndSeekIndexIterator(range, columnFamilies, inclusive);

        Function<Entry<Key,Document>,Entry<DocumentData,Document>> keyToDoc = null;

        EventDataQueryFieldFilter projection = null;

        Iterator<Entry<Key,Document>> documents = null;

        if (!configuration.getFacetedFields().isEmpty()) {
            projection = new EventDataQueryFieldFilter();
            projection.initializeWhitelist(configuration.getFacetedFields());
        }

        if (!configuration.hasFieldLimits() || projection != null) {
            keyToDoc = new KeyToDocumentData(source.deepCopy(myEnvironment), super.equality, projection, this.includeHierarchyFields,
                            this.includeHierarchyFields);
        }

        AccumuloTreeIterable<Key,DocumentData> doc = null;
        if (null != keyToDoc) {
            doc = new AccumuloTreeIterable<>(fieldIndexResults.tree, keyToDoc);
        } else {
            if (log.isTraceEnabled()) {
                log.trace("Skipping document lookup, because we don't need it");
            }
            doc = new AccumuloTreeIterable<>(fieldIndexResults.tree, new Function<Entry<Key,Document>,Entry<DocumentData,Document>>() {

                @Override
                @Nullable
                public Entry<DocumentData,Document> apply(@Nullable Entry<Key,Document> input) {

                    Set<Key> docKeys = Sets.newHashSet();

                    List<Entry<Key,Value>> attrs = Lists.newArrayList();

                    return Maps.immutableEntry(new DocumentData(input.getKey(), docKeys, attrs), input.getValue());
                }

            });
        }

        doc.seek(range, columnFamilies, inclusive);

        TypeMetadata typeMetadata = this.getTypeMetadata();

        documents = Iterators.transform(doc.iterator(), new Aggregation(this.getTimeFilter(), typeMetadata, compositeMetadata, this.isIncludeGroupingContext(),
                        this.includeRecordId, false, null));

        switch (configuration.getType()) {
            case SHARD_COUNT:
            case DAY_COUNT:

                SortedKeyValueIterator<Key,Value> sourceDeepCopy = source.deepCopy(myEnvironment);

                documents = getEvaluation(sourceDeepCopy, documents, compositeMetadata, typeMetadata);

                // Take the document Keys and transform it into Entry<Key,Document>, removing Attributes for this Document
                // which do not fall within the expected time range
                documents = Iterators.transform(documents, new DocumentCountCardinality(configuration.getType(), !merge));
            default:
                break;
        }

        return documents;

    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public Iterator<Entry<Key,Document>> getDocumentIterator(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException,
                    ConfigException, InstantiationException, IllegalAccessException {
        // Otherwise, we have to use the field index
        // Seek() the boolean logic stuff
        createAndSeekIndexIterator(range, columnFamilies, inclusive);

        Function<Entry<Key,Document>,Entry<DocumentData,Document>> keyToDoc = null;

        EventDataQueryFieldFilter projection = null;

        Iterator<Entry<Key,Document>> documents = null;

        if (!configuration.getFacetedFields().isEmpty()) {
            projection = new EventDataQueryFieldFilter();
            projection.initializeWhitelist(configuration.getFacetedFields());
        }

        if (!configuration.hasFieldLimits() || projection != null) {
            keyToDoc = new KeyToDocumentData(source.deepCopy(myEnvironment), super.equality, projection, this.includeHierarchyFields,
                            this.includeHierarchyFields);
        }

        AccumuloTreeIterable<Key,DocumentData> doc = null;
        if (null != keyToDoc) {
            doc = new AccumuloTreeIterable<Key,DocumentData>(fieldIndexResults.tree, keyToDoc);
        } else {
            if (log.isTraceEnabled()) {
                log.trace("Skipping document lookup, because we don't need it");
            }
            doc = new AccumuloTreeIterable<Key,DocumentData>(fieldIndexResults.tree, new Function<Entry<Key,Document>,Entry<DocumentData,Document>>() {

                @Override
                @Nullable
                public Entry<DocumentData,Document> apply(@Nullable Entry<Key,Document> input) {

                    Set<Key> docKeys = Sets.newHashSet();

                    List<Entry<Key,Value>> attrs = Lists.newArrayList();

                    return Maps.immutableEntry(new DocumentData(input.getKey(), docKeys, attrs), input.getValue());
                }

            });
        }

        doc.seek(range, columnFamilies, inclusive);

        TypeMetadata typeMetadata = this.getTypeMetadata();

        documents = Iterators.transform(doc.iterator(), new Aggregation(this.getTimeFilter(), typeMetadata, compositeMetadata, this.isIncludeGroupingContext(),
                        this.includeRecordId, false, null));

        switch (configuration.getType()) {
            case SHARD_COUNT:
            case DAY_COUNT:

                SortedKeyValueIterator<Key,Value> sourceDeepCopy = source.deepCopy(myEnvironment);

                documents = getEvaluation(sourceDeepCopy, documents, compositeMetadata, typeMetadata);

                // Take the document Keys and transform it into Entry<Key,Document>, removing Attributes for this Document
                // which do not fall within the expected time range
                documents = Iterators.transform(documents, new DocumentCountCardinality(configuration.getType(), !merge));
            default:
                break;
        }

        return documents;

    }

Replace Generic With Diamond AccumuloTreeIterable<Key,DocumentData> with AccumuloTreeIterable<> in method public getDocumentIterator(range Range, columnFamilies Collection<ByteSequence>, inclusive boolean) : Iterator<Entry<Key,Document>> from class datawave.query.iterator.facets.DynamicFacetIterator


    private void evaluate(Key key, Document document, NestedQuery<Key> nestedQuery) {
        if (log.isTraceEnabled()) {
            log.trace("Adding evaluation of " + key + " to pipeline");
        }
        Pipeline pipeline = pipelines.checkOut(key, document, nestedQuery);

        evaluationQueue.add(new Tuple2<>(IteratorThreadPoolManager.executeEvaluation(pipeline, pipeline.toString()), pipeline));
    }

    private void evaluate(Key key, Document document, NestedQuery<Key> nestedQuery) {
        if (log.isTraceEnabled()) {
            log.trace("Adding evaluation of " + key + " to pipeline");
        }
        Pipeline pipeline = pipelines.checkOut(key, document, nestedQuery);

        evaluationQueue.add(new Tuple2<Future<?>,Pipeline>(IteratorThreadPoolManager.executeEvaluation(pipeline, pipeline.toString()), pipeline));
    }

Replace Generic With Diamond Tuple2<Future<?>,Pipeline> with Tuple2<> in method private evaluate(key Key, document Document, nestedQuery NestedQuery<Key>) : void from class datawave.query.iterator.pipeline.PipelineIterator


    protected Tuple2<String,String> parserFieldNameValue(Key topKey) {
        return new Tuple2<>(topKey.getColumnFamily().toString().substring(3), parseValue(topKey.getColumnQualifier().toString()));
    }

    protected Tuple2<String,String> parserFieldNameValue(Key topKey) {
        return new Tuple2<String,String>(topKey.getColumnFamily().toString().substring(3), parseValue(topKey.getColumnQualifier().toString()));
    }

Replace Generic With Diamond Tuple2<String,String> with Tuple2<> in method protected parserFieldNameValue(topKey Key) : Tuple2<String,String> from class datawave.query.jexl.functions.IdentityAggregator


    @Override
    protected Tuple2<String,String> parserFieldNameValue(Key topKey) {
        DatawaveKey parser = new DatawaveKey(topKey);
        return new Tuple2<>(parser.getFieldName(), parser.getFieldValue());
    }

    @Override
    protected Tuple2<String,String> parserFieldNameValue(Key topKey) {
        DatawaveKey parser = new DatawaveKey(topKey);
        return new Tuple2<String,String>(parser.getFieldName(), parser.getFieldValue());
    }

Replace Generic With Diamond Tuple2<String,String> with Tuple2<> in method protected parserFieldNameValue(topKey Key) : Tuple2<String,String> from class datawave.query.jexl.functions.TermFrequencyAggregator


    /**
     * Create lists of normalizers that maps to the function arguments. Each list is a unique list of normalizers. Each list will be applied to the arguments to
     * produce a separate function instance.
     *
     * @param function
     * @param allNormalizers
     * @param descriptor
     * @param helper
     * @param datatypeFilter
     * @return the list of normalizer lists
     */
    private static List<List<Type<?>>> getNormalizerListsForArgs(ASTFunctionNode function, Multimap<String,Type<?>> allNormalizers,
                    JexlArgumentDescriptor descriptor, MetadataHelper helper, Set<String> datatypeFilter) {
        List<List<Type<?>>> lists = new ArrayList<>();

        lists.add(new ArrayList<>(Arrays.asList(new Type<?>[function.jjtGetNumChildren()])));

        // first we go through the arguments and determine those that reference the same field.
        // this is done by assuming that if the fields returned by descriptor.fields is the same
        // for two separate arguments, then those arguments will refer to each field separately.
        // This implies that a cross product of normalizations is NOT required for those groups of
        // arguments. For example a geo function may have one field for lats, and another for lons.
        // for those arguments we want a cross-product of normalizations. However for content functions,
        // all of the arguments will refer to the same set of fields so we assume that the content
        // functions will be applied to each field in turn instead of every combination thereof.
        Map<Set<String>,Set<Integer>> fieldGroups = new HashMap<>();
        Set<String> EMPTY_SET = new HashSet<>();
        for (int i = 0; i < function.jjtGetNumChildren(); i++) {
            // get the fields that go with this argument IFF this is a string literal argument
            Set<String> fields = EMPTY_SET;
            List<JexlNode> literals = JexlASTHelper.getLiterals(function.jjtGetChild(i));
            if ((literals.size() == 1) && (literals.get(0) instanceof ASTStringLiteral)) {
                fields = new HashSet<>(descriptor.fieldsForNormalization(helper, datatypeFilter, i - 2));
            }
            if (fieldGroups.containsKey(fields)) {
                fieldGroups.get(fields).add(i);
            } else {
                Set<Integer> args = new HashSet<>();
                args.add(i);
                fieldGroups.put(fields, args);
            }
        }

        // now for each group of fields, get the set of normalizers and create the cross-product with
        // the other groups.
        for (Map.Entry<Set<String>,Set<Integer>> argGroup : fieldGroups.entrySet()) {
            // now compile all of the possible normalizers for this argument group
            Set<Type<?>> normalizers = new HashSet<>();
            if (argGroup.getKey().isEmpty()) {
                normalizers.add(NO_OP);
            } else {
                for (String field : argGroup.getKey()) {
                    normalizers.addAll(allNormalizers.get(field));
                }
            }

            // and now expand the lists of normalizers per the normalizers for this argument
            if (normalizers.size() == 1) {
                Type<?> normalizer = normalizers.iterator().next();
                // simply add the normalizer entry to each existing map
                for (List<Type<?>> list : lists) {
                    for (Integer argIndex : argGroup.getValue()) {
                        list.set(argIndex, normalizer);
                    }
                }
            } else {
                // for each normalizer, create a separate copy of the maps
                List<List<Type<?>>> lists2 = new ArrayList<>();
                for (Type<?> normalizer : normalizers) {
                    for (List<Type<?>> list : lists) {
                        List<Type<?>> list2 = new ArrayList<>(list);
                        for (Integer argIndex : argGroup.getValue()) {
                            list2.set(argIndex, normalizer);
                        }
                        lists2.add(list2);
                    }
                }
                lists = lists2;
            }
        }
        return lists;
    }

    /**
     * Create lists of normalizers that maps to the function arguments. Each list is a unique list of normalizers. Each list will be applied to the arguments to
     * produce a separate function instance.
     *
     * @param function
     * @param allNormalizers
     * @param descriptor
     * @param helper
     * @param datatypeFilter
     * @return the list of normalizer lists
     */
    private static List<List<Type<?>>> getNormalizerListsForArgs(ASTFunctionNode function, Multimap<String,Type<?>> allNormalizers,
                    JexlArgumentDescriptor descriptor, MetadataHelper helper, Set<String> datatypeFilter) {
        List<List<Type<?>>> lists = new ArrayList<>();

        lists.add(new ArrayList<Type<?>>(Arrays.asList(new Type<?>[function.jjtGetNumChildren()])));

        // first we go through the arguments and determine those that reference the same field.
        // this is done by assuming that if the fields returned by descriptor.fields is the same
        // for two separate arguments, then those arguments will refer to each field separately.
        // This implies that a cross product of normalizations is NOT required for those groups of
        // arguments. For example a geo function may have one field for lats, and another for lons.
        // for those arguments we want a cross-product of normalizations. However for content functions,
        // all of the arguments will refer to the same set of fields so we assume that the content
        // functions will be applied to each field in turn instead of every combination thereof.
        Map<Set<String>,Set<Integer>> fieldGroups = new HashMap<>();
        Set<String> EMPTY_SET = new HashSet<>();
        for (int i = 0; i < function.jjtGetNumChildren(); i++) {
            // get the fields that go with this argument IFF this is a string literal argument
            Set<String> fields = EMPTY_SET;
            List<JexlNode> literals = JexlASTHelper.getLiterals(function.jjtGetChild(i));
            if ((literals.size() == 1) && (literals.get(0) instanceof ASTStringLiteral)) {
                fields = new HashSet<>(descriptor.fieldsForNormalization(helper, datatypeFilter, i - 2));
            }
            if (fieldGroups.containsKey(fields)) {
                fieldGroups.get(fields).add(i);
            } else {
                Set<Integer> args = new HashSet<>();
                args.add(i);
                fieldGroups.put(fields, args);
            }
        }

        // now for each group of fields, get the set of normalizers and create the cross-product with
        // the other groups.
        for (Map.Entry<Set<String>,Set<Integer>> argGroup : fieldGroups.entrySet()) {
            // now compile all of the possible normalizers for this argument group
            Set<Type<?>> normalizers = new HashSet<>();
            if (argGroup.getKey().isEmpty()) {
                normalizers.add(NO_OP);
            } else {
                for (String field : argGroup.getKey()) {
                    normalizers.addAll(allNormalizers.get(field));
                }
            }

            // and now expand the lists of normalizers per the normalizers for this argument
            if (normalizers.size() == 1) {
                Type<?> normalizer = normalizers.iterator().next();
                // simply add the normalizer entry to each existing map
                for (List<Type<?>> list : lists) {
                    for (Integer argIndex : argGroup.getValue()) {
                        list.set(argIndex, normalizer);
                    }
                }
            } else {
                // for each normalizer, create a separate copy of the maps
                List<List<Type<?>>> lists2 = new ArrayList<>();
                for (Type<?> normalizer : normalizers) {
                    for (List<Type<?>> list : lists) {
                        List<Type<?>> list2 = new ArrayList<>(list);
                        for (Integer argIndex : argGroup.getValue()) {
                            list2.set(argIndex, normalizer);
                        }
                        lists2.add(list2);
                    }
                }
                lists = lists2;
            }
        }
        return lists;
    }

Replace Generic With Diamond ArrayList<Type<?>> with ArrayList<> in method private getNormalizerListsForArgs(function ASTFunctionNode, allNormalizers Multimap<String,Type<?>>, descriptor JexlArgumentDescriptor, helper MetadataHelper, datatypeFilter Set<String>) : List<List<Type<?>>> from class datawave.query.jexl.visitors.FunctionNormalizationRebuildingVisitor


    /**
     * Performs a lookup in the global index / reverse index and returns a RangeCalculator
     *
     * @param config
     * @param queryTree
     * @return range calculator
     */
    protected CloseableIterable<QueryPlan> getFullScanRange(ShardQueryConfiguration config, JexlNode queryTree) {
        if (log.isTraceEnabled()) {
            log.trace("Building full scan range ");
            PrintingVisitor.printQuery(queryTree);
        }
        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        cal.setTime(config.getBeginDate());

        // Truncate the time on the startKey
        String startKey = config.getShardDateFormatter().format(DateUtils.truncate(cal, Calendar.DAY_OF_MONTH).getTime());

        // Truncate and bump the time on the endKey
        String endKey = config.getShardDateFormatter().format(getEndDateForIndexLookup(config.getEndDate()));

        Range r = new Range(startKey, true, endKey, false);

        if (log.isTraceEnabled()) {
            log.trace("Produced range is " + r);
        }

        return new CloseableListIterable<>(Collections.singletonList(new QueryPlan(queryTree, r)));
    }

    /**
     * Performs a lookup in the global index / reverse index and returns a RangeCalculator
     *
     * @param config
     * @param queryTree
     * @return range calculator
     */
    protected CloseableIterable<QueryPlan> getFullScanRange(ShardQueryConfiguration config, JexlNode queryTree) {
        if (log.isTraceEnabled()) {
            log.trace("Building full scan range ");
            PrintingVisitor.printQuery(queryTree);
        }
        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        cal.setTime(config.getBeginDate());

        // Truncate the time on the startKey
        String startKey = config.getShardDateFormatter().format(DateUtils.truncate(cal, Calendar.DAY_OF_MONTH).getTime());

        // Truncate and bump the time on the endKey
        String endKey = config.getShardDateFormatter().format(getEndDateForIndexLookup(config.getEndDate()));

        Range r = new Range(startKey, true, endKey, false);

        if (log.isTraceEnabled()) {
            log.trace("Produced range is " + r);
        }

        return new CloseableListIterable<QueryPlan>(Collections.singletonList(new QueryPlan(queryTree, r)));
    }

Replace Generic With Diamond CloseableListIterable<QueryPlan> with CloseableListIterable<> in method protected getFullScanRange(config ShardQueryConfiguration, queryTree JexlNode) : CloseableIterable<QueryPlan> from class datawave.query.planner.DefaultQueryPlanner