    @Override
    public DescendantCount apply(final Tuple3<Range,Key,List<Entry<Key,Value>>> tuple) {
        // Extract the key and document attributes from which the child count will be determined
        final Range range;
        final Key key;
        final List<Entry<Key,Value>> documentAttributes;
        if (null != tuple) {
            range = tuple.first();
            key = tuple.second();
            documentAttributes = tuple.third();
        } else {
            range = null;
            key = null;
            documentAttributes = null;
        }

        // Get the descendant count(s), including applicable keys
        DescendantCount finalCount = ZERO_COUNT;
        if ((null != range) && (null != key) && (this.outputChildCount || this.outputHasChildren || this.outputDescendantCount)) {
            // Get the raw count
            CountResult count = null;
            try {
                count = this.countDescendants(range, key, documentAttributes);
            } catch (final IOException e) {
                final String message = "Unable to count child events";
                LOG.error(message, e);
            }

            // Create a list of key entries based on tallied counts, if any
            if (null != count) {
                // Create keys
                if (count.hasDescendants()) {
                    final List<Key> countKeys = new LinkedList<>();
                    if (this.outputHasChildren && count.hasDescendants()) {
                        final ColumnVisibility visibility = key.getColumnVisibilityParsed();
                        long timestamp = key.getTimestamp();
                        boolean hasChildren = count.hasDescendants();
                        final Key hasChildrenKey = new Key(key.getRow(), key.getColumnFamily(), new Text(QueryOptions.DEFAULT_HAS_CHILDREN_FIELDNAME + '\0'
                                        + Boolean.toString(hasChildren)), visibility, timestamp);
                        countKeys.add(hasChildrenKey);
                    }

                    if (this.outputChildCount && count.hasDescendants()) {
                        final ColumnVisibility visibility = key.getColumnVisibilityParsed();
                        long timestamp = key.getTimestamp();
                        int numChildren = count.getFirstGenerationCount();
                        final Key childCountKey = new Key(key.getRow(), key.getColumnFamily(), new Text(QueryOptions.DEFAULT_CHILD_COUNT_FIELDNAME + '\0'
                                        + Integer.toString(numChildren)), visibility, timestamp);
                        countKeys.add(childCountKey);
                    }

                    if (this.outputDescendantCount && (count.getAllGenerationsCount() > 0)) {
                        final ColumnVisibility visibility = key.getColumnVisibilityParsed();
                        long timestamp = key.getTimestamp();
                        int numDescendants = count.getAllGenerationsCount();
                        final Text text;
                        if (count.skippedDescendants()) {
                            text = new Text(QueryOptions.DEFAULT_DESCENDANT_COUNT_FIELDNAME + '\0' + Integer.toString(numDescendants - 1) + '+');
                        } else {
                            text = new Text(QueryOptions.DEFAULT_DESCENDANT_COUNT_FIELDNAME + '\0' + Integer.toString(numDescendants));
                        }

                        final Key descendantCountKey = new Key(key.getRow(), key.getColumnFamily(), text, visibility, timestamp);
                        countKeys.add(descendantCountKey);
                    }

                    if (!countKeys.isEmpty()) {
                        count.setKeys(countKeys);
                    }
                }

                // Re-assign the return value;
                finalCount = count;
            }
        }

        return finalCount;
    }

    @Override
    public DescendantCount apply(final Tuple3<Range,Key,List<Entry<Key,Value>>> tuple) {
        // Extract the key and document attributes from which the child count will be determined
        final Range range;
        final Key key;
        final List<Entry<Key,Value>> documentAttributes;
        if (null != tuple) {
            range = tuple.first();
            key = tuple.second();
            documentAttributes = tuple.third();
        } else {
            range = null;
            key = null;
            documentAttributes = null;
        }

        // Get the descendant count(s), including applicable keys
        DescendantCount finalCount = ZERO_COUNT;
        if ((null != range) && (null != key) && (this.outputChildCount || this.outputHasChildren || this.outputDescendantCount)) {
            // Get the raw count
            CountResult count = null;
            try {
                count = this.countDescendants(range, key, documentAttributes);
            } catch (final IOException e) {
                final String message = "Unable to count child events";
                LOG.error(message, e);
            }

            // Create a list of key entries based on tallied counts, if any
            if (null != count) {
                // Create keys
                if (count.hasDescendants()) {
                    final List<Key> countKeys = new LinkedList<Key>();
                    if (this.outputHasChildren && count.hasDescendants()) {
                        final ColumnVisibility visibility = key.getColumnVisibilityParsed();
                        long timestamp = key.getTimestamp();
                        boolean hasChildren = count.hasDescendants();
                        final Key hasChildrenKey = new Key(key.getRow(), key.getColumnFamily(), new Text(QueryOptions.DEFAULT_HAS_CHILDREN_FIELDNAME + '\0'
                                        + Boolean.toString(hasChildren)), visibility, timestamp);
                        countKeys.add(hasChildrenKey);
                    }

                    if (this.outputChildCount && count.hasDescendants()) {
                        final ColumnVisibility visibility = key.getColumnVisibilityParsed();
                        long timestamp = key.getTimestamp();
                        int numChildren = count.getFirstGenerationCount();
                        final Key childCountKey = new Key(key.getRow(), key.getColumnFamily(), new Text(QueryOptions.DEFAULT_CHILD_COUNT_FIELDNAME + '\0'
                                        + Integer.toString(numChildren)), visibility, timestamp);
                        countKeys.add(childCountKey);
                    }

                    if (this.outputDescendantCount && (count.getAllGenerationsCount() > 0)) {
                        final ColumnVisibility visibility = key.getColumnVisibilityParsed();
                        long timestamp = key.getTimestamp();
                        int numDescendants = count.getAllGenerationsCount();
                        final Text text;
                        if (count.skippedDescendants()) {
                            text = new Text(QueryOptions.DEFAULT_DESCENDANT_COUNT_FIELDNAME + '\0' + Integer.toString(numDescendants - 1) + '+');
                        } else {
                            text = new Text(QueryOptions.DEFAULT_DESCENDANT_COUNT_FIELDNAME + '\0' + Integer.toString(numDescendants));
                        }

                        final Key descendantCountKey = new Key(key.getRow(), key.getColumnFamily(), text, visibility, timestamp);
                        countKeys.add(descendantCountKey);
                    }

                    if (!countKeys.isEmpty()) {
                        count.setKeys(countKeys);
                    }
                }

                // Re-assign the return value;
                finalCount = count;
            }
        }

        return finalCount;
    }

Replace Generic With Diamond LinkedList<Key> with LinkedList<> in method public apply(tuple Tuple3<Range,Key,List<Entry<Key,Value>>>) : DescendantCount from class datawave.query.function.DescendantCountFunction


    @Override
    public Entry<DocumentData,Document> apply(Entry<Key,Document> from) {
        // We want to ensure that we have a non-empty colqual
        if (null == from || null == from.getKey() || null == from.getValue())
            return null;
        Range keyRange = getKeyRange(from);

        try {

            source.seek(keyRange, columnFamilies, inclusive);

            if (log.isDebugEnabled())
                log.debug(source.hasTop() + " Key range is " + keyRange);

            final List<Entry<Key,Value>> attrs; // Assign only once for
                                                // efficiency
            final Set<Key> docKeys = new HashSet<>();
            if (source.hasTop()) {
                attrs = this.collectDocumentAttributes(from.getKey(), docKeys, keyRange);
                this.appendHierarchyFields(attrs, keyRange, from.getKey());
            } else {
                attrs = Collections.emptyList();
            }

            return Maps.immutableEntry(new DocumentData(from.getKey(), docKeys, attrs), from.getValue());
        } catch (IOException e) {
            log.error("Unable to collection document attributes for evaluation: " + keyRange, e);
            QueryException qe = new QueryException(DatawaveErrorCode.DOCUMENT_EVALUATION_ERROR, e);
            throw new DatawaveFatalQueryException(qe);
        }

    }

    @Override
    public Entry<DocumentData,Document> apply(Entry<Key,Document> from) {
        // We want to ensure that we have a non-empty colqual
        if (null == from || null == from.getKey() || null == from.getValue())
            return null;
        Range keyRange = getKeyRange(from);

        try {

            source.seek(keyRange, columnFamilies, inclusive);

            if (log.isDebugEnabled())
                log.debug(source.hasTop() + " Key range is " + keyRange);

            final List<Entry<Key,Value>> attrs; // Assign only once for
                                                // efficiency
            final Set<Key> docKeys = new HashSet<Key>();
            if (source.hasTop()) {
                attrs = this.collectDocumentAttributes(from.getKey(), docKeys, keyRange);
                this.appendHierarchyFields(attrs, keyRange, from.getKey());
            } else {
                attrs = Collections.emptyList();
            }

            return Maps.immutableEntry(new DocumentData(from.getKey(), docKeys, attrs), from.getValue());
        } catch (IOException e) {
            log.error("Unable to collection document attributes for evaluation: " + keyRange, e);
            QueryException qe = new QueryException(DatawaveErrorCode.DOCUMENT_EVALUATION_ERROR, e);
            throw new DatawaveFatalQueryException(qe);
        }

    }

Replace Generic With Diamond HashSet<Key> with HashSet<> in method public apply(from Entry<Key,Document>) : Entry<DocumentData,Document> from class datawave.query.function.KeyToDocumentData


    public IndexInfo union(IndexInfo o) {
        return union(o, new ArrayList<>());
    }

    public IndexInfo union(IndexInfo o) {
        return union(o, new ArrayList<JexlNode>());
    }

Replace Generic With Diamond ArrayList<JexlNode> with ArrayList<> in method public union(o IndexInfo) : IndexInfo from class datawave.query.index.lookup.IndexInfo


    public IndexInfo intersect(IndexInfo o) {
        return intersect(o, new ArrayList<>(), this);
    }

    public IndexInfo intersect(IndexInfo o) {
        return intersect(o, new ArrayList<JexlNode>(), this);
    }

Replace Generic With Diamond ArrayList<JexlNode> with ArrayList<> in method public intersect(o IndexInfo) : IndexInfo from class datawave.query.index.lookup.IndexInfo


    private boolean isWithinBoundedRange(JexlNode node) {
        if (node.jjtGetParent() instanceof ASTAndNode) {
            List<JexlNode> otherNodes = new ArrayList<>();
            Map<LiteralRange<?>,List<JexlNode>> ranges = JexlASTHelper.getBoundedRangesIndexAgnostic((ASTAndNode) (node.jjtGetParent()), otherNodes, false);
            if (ranges.size() == 1 && otherNodes.isEmpty()) {
                return true;
            }
        }
        return false;
    }

    private boolean isWithinBoundedRange(JexlNode node) {
        if (node.jjtGetParent() instanceof ASTAndNode) {
            List<JexlNode> otherNodes = new ArrayList<JexlNode>();
            Map<LiteralRange<?>,List<JexlNode>> ranges = JexlASTHelper.getBoundedRangesIndexAgnostic((ASTAndNode) (node.jjtGetParent()), otherNodes, false);
            if (ranges.size() == 1 && otherNodes.isEmpty()) {
                return true;
            }
        }
        return false;
    }

Replace Generic With Diamond ArrayList<JexlNode> with ArrayList<> in method private isWithinBoundedRange(node JexlNode) : boolean from class datawave.query.index.lookup.RangeStream


    public ShardLimitingIterator(Iterator<Entry<Key,Value>> kvIter, int maxShardsPerDay) {
        this.kvIter = new PeekingIterator<>(kvIter);
        this.maxShardsPerDay = maxShardsPerDay;
        currentQueue = Queues.newArrayDeque();
    }

    public ShardLimitingIterator(Iterator<Entry<Key,Value>> kvIter, int maxShardsPerDay) {
        this.kvIter = new PeekingIterator<Entry<Key,Value>>(kvIter);
        this.maxShardsPerDay = maxShardsPerDay;
        currentQueue = Queues.newArrayDeque();
    }

Replace Generic With Diamond PeekingIterator<Entry<Key,Value>> with PeekingIterator<> in method public ShardLimitingIterator(kvIter Iterator<Entry<Key,Value>>, maxShardsPerDay int) from class datawave.query.index.lookup.ShardLimitingIterator


    @SuppressWarnings({"unchecked", "rawtypes"})
    public Union(Iterable<? extends IndexStream> children) {
        this.children = new PriorityQueue(16, PeekOrdering.make(new TupleComparator<>()));
        this.childrenNodes = Lists.newArrayList();
        delayedNodes = Lists.newArrayList();
        int childrenCount = 0;
        boolean childrenIgnored = false;
        boolean unindexedField = false;
        boolean delayedField = false;
        boolean exceededTermThreshold = false;
        boolean exceededValueThreshold = false;
        for (IndexStream stream : children) {

            if (log.isDebugEnabled()) {
                childrenContextDebug.add(stream.getContextDebug());
            }

            childrenCount++;
            if (log.isTraceEnabled()) {
                log.trace("Union of " + stream.currentNode() + " " + stream.hasNext() + " " + JexlStringBuildingVisitor.buildQuery(stream.currentNode()));
                log.trace("Union of " + stream.toString() + " " + stream.context());
            }

            if (StreamContext.NO_OP == stream.context())
                continue;
            if (StreamContext.EXCEEDED_VALUE_THRESHOLD == stream.context()) {
                exceededValueThreshold = true;
            } else if (StreamContext.EXCEEDED_TERM_THRESHOLD == stream.context()) {
                exceededTermThreshold = true;
            } else if (StreamContext.UNINDEXED == stream.context()) {
                this.childrenNodes.add(stream.currentNode());
                this.delayedNodes.add(stream.currentNode());
                unindexedField = true;
                continue;
            } else if (StreamContext.DELAYED_FIELD == stream.context()) {
                this.childrenNodes.add(stream.currentNode());
                this.delayedNodes.add(stream.currentNode());
                delayedField = true;
                continue;
            }

            if (stream.hasNext()) {

                this.children.add(stream);
                this.childrenNodes.add(stream.currentNode());
            } else {
                switch (stream.context()) {

                    case INITIALIZED:
                        // this should never be returned
                        throw new RuntimeException("Invalid state in RangeStream");
                    case IGNORED:
                        childrenIgnored = true;
                        this.childrenNodes.add(stream.currentNode());
                        this.delayedNodes.add(stream.currentNode());
                        break;
                    case EXCEEDED_VALUE_THRESHOLD:
                    case EXCEEDED_TERM_THRESHOLD:
                        if (log.isTraceEnabled())
                            log.trace("Adding current node to stream");
                        /**
                         * Helpful for debugging
                         */
                        this.childrenNodes.add(stream.currentNode());
                        break;
                    case VARIABLE:
                    case UNKNOWN_FIELD:
                        this.delayedNodes.add(stream.currentNode());
                    case ABSENT:
                    case PRESENT:

                        break;
                    default:
                        break;
                }
            }
        }
        if (log.isTraceEnabled())
            log.trace("children count is " + childrenCount + " " + childrenNodes.size() + " " + this.children.size());
        if (childrenNodes.size() == 1)
            currNode = JexlNodeFactory.createUnwrappedOrNode(this.childrenNodes);
        else
            currNode = JexlNodeFactory.createOrNode(this.childrenNodes);

        if (this.children.isEmpty()) {
            if (childrenIgnored || childrenCount == 0) {
                this.context = StreamContext.IGNORED;
                this.contextDebug = "no children";
            } else if (unindexedField) {
                this.context = StreamContext.UNINDEXED;
                this.contextDebug = "unindexed child";
            } else if (delayedField) {
                this.context = StreamContext.DELAYED_FIELD;
                this.contextDebug = "delayed child";
            } else {
                this.context = StreamContext.ABSENT;
                this.contextDebug = "no children";
            }
        } else {
            if (exceededTermThreshold) {
                this.context = StreamContext.EXCEEDED_TERM_THRESHOLD;
                this.contextDebug = "ExceededTermThreshold child";
            } else if (exceededValueThreshold) {
                this.context = StreamContext.EXCEEDED_VALUE_THRESHOLD;
                this.contextDebug = "ExceededValueThreshold child";
            } else if (unindexedField) {
                this.context = StreamContext.UNINDEXED;
                this.contextDebug = "Unindexed child";
            } else {
                this.context = StreamContext.PRESENT;
                this.contextDebug = "children are present";
            }

            next();
        }
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    public Union(Iterable<? extends IndexStream> children) {
        this.children = new PriorityQueue(16, PeekOrdering.make(new TupleComparator<String,IndexInfo>()));
        this.childrenNodes = Lists.newArrayList();
        delayedNodes = Lists.newArrayList();
        int childrenCount = 0;
        boolean childrenIgnored = false;
        boolean unindexedField = false;
        boolean delayedField = false;
        boolean exceededTermThreshold = false;
        boolean exceededValueThreshold = false;
        for (IndexStream stream : children) {

            if (log.isDebugEnabled()) {
                childrenContextDebug.add(stream.getContextDebug());
            }

            childrenCount++;
            if (log.isTraceEnabled()) {
                log.trace("Union of " + stream.currentNode() + " " + stream.hasNext() + " " + JexlStringBuildingVisitor.buildQuery(stream.currentNode()));
                log.trace("Union of " + stream.toString() + " " + stream.context());
            }

            if (StreamContext.NO_OP == stream.context())
                continue;
            if (StreamContext.EXCEEDED_VALUE_THRESHOLD == stream.context()) {
                exceededValueThreshold = true;
            } else if (StreamContext.EXCEEDED_TERM_THRESHOLD == stream.context()) {
                exceededTermThreshold = true;
            } else if (StreamContext.UNINDEXED == stream.context()) {
                this.childrenNodes.add(stream.currentNode());
                this.delayedNodes.add(stream.currentNode());
                unindexedField = true;
                continue;
            } else if (StreamContext.DELAYED_FIELD == stream.context()) {
                this.childrenNodes.add(stream.currentNode());
                this.delayedNodes.add(stream.currentNode());
                delayedField = true;
                continue;
            }

            if (stream.hasNext()) {

                this.children.add(stream);
                this.childrenNodes.add(stream.currentNode());
            } else {
                switch (stream.context()) {

                    case INITIALIZED:
                        // this should never be returned
                        throw new RuntimeException("Invalid state in RangeStream");
                    case IGNORED:
                        childrenIgnored = true;
                        this.childrenNodes.add(stream.currentNode());
                        this.delayedNodes.add(stream.currentNode());
                        break;
                    case EXCEEDED_VALUE_THRESHOLD:
                    case EXCEEDED_TERM_THRESHOLD:
                        if (log.isTraceEnabled())
                            log.trace("Adding current node to stream");
                        /**
                         * Helpful for debugging
                         */
                        this.childrenNodes.add(stream.currentNode());
                        break;
                    case VARIABLE:
                    case UNKNOWN_FIELD:
                        this.delayedNodes.add(stream.currentNode());
                    case ABSENT:
                    case PRESENT:

                        break;
                    default:
                        break;
                }
            }
        }
        if (log.isTraceEnabled())
            log.trace("children count is " + childrenCount + " " + childrenNodes.size() + " " + this.children.size());
        if (childrenNodes.size() == 1)
            currNode = JexlNodeFactory.createUnwrappedOrNode(this.childrenNodes);
        else
            currNode = JexlNodeFactory.createOrNode(this.childrenNodes);

        if (this.children.isEmpty()) {
            if (childrenIgnored || childrenCount == 0) {
                this.context = StreamContext.IGNORED;
                this.contextDebug = "no children";
            } else if (unindexedField) {
                this.context = StreamContext.UNINDEXED;
                this.contextDebug = "unindexed child";
            } else if (delayedField) {
                this.context = StreamContext.DELAYED_FIELD;
                this.contextDebug = "delayed child";
            } else {
                this.context = StreamContext.ABSENT;
                this.contextDebug = "no children";
            }
        } else {
            if (exceededTermThreshold) {
                this.context = StreamContext.EXCEEDED_TERM_THRESHOLD;
                this.contextDebug = "ExceededTermThreshold child";
            } else if (exceededValueThreshold) {
                this.context = StreamContext.EXCEEDED_VALUE_THRESHOLD;
                this.contextDebug = "ExceededValueThreshold child";
            } else if (unindexedField) {
                this.context = StreamContext.UNINDEXED;
                this.contextDebug = "Unindexed child";
            } else {
                this.context = StreamContext.PRESENT;
                this.contextDebug = "children are present";
            }

            next();
        }
    }

Replace Generic With Diamond PriorityQueue with PriorityQueue in method public Union(children Iterable<? extends IndexStream>) from class datawave.query.index.lookup.Union


    /**
     * Create an iterator that will allow for lazy, incremental fetching of index-only values
     *
     * @param fieldName
     *            The field to fetch
     * @return An iterator that will allow for lazy, incremental fetching of index-only values
     */
    @SuppressWarnings("unchecked")
    public <E> Iterator<E> newLazyFetchingIterator(final String fieldName) {
        Collection<E> values = Collections.emptySet();
        Iterator<E> iterator = values.iterator();
        try {
            // Create a specialized, index-only KeyToDocumentData
            final IndexOnlyKeyToDocumentData keyToDocumentData = new IndexOnlyKeyToDocumentData(this.parentRange, fieldName, this.indexOnlySeeker, false);

            // Initialize the fetch
            final Iterator<Entry<Key,Document>> documents = this.initializeFetch(fieldName, keyToDocumentData);

            // Populate the document
            final Iterator<Tuple2<Key,Document>> tupleItr = Iterators.transform(documents, new EntryToTuple<>());
            final EmptyTermFrequencyFunction tfFunction = new EmptyTermFrequencyFunction();
            final Iterator<Tuple3<Key,Document,Map<String,Object>>> itrWithContext = TraceIterators.transform(tupleItr, tfFunction, "Term Frequency Lookup");
            final Iterator<Tuple3<Key,Document,DatawaveJexlContext>> itrWithDatawaveJexlContext = Iterators.transform(itrWithContext,
                            new SingleValueContextCreator(fieldName));

            // Replace the return value with a lazy-fetching iterator
            iterator = (Iterator<E>) Iterators.transform(itrWithDatawaveJexlContext, new TupleToGenericFunction(fieldName));
        } catch (final Exception e) {
            final String message = "Could not perform function on index-only field '" + fieldName + "\' for range " + this.parentRange;
            LOG.error(message, e);
        }

        return iterator;
    }

    /**
     * Create an iterator that will allow for lazy, incremental fetching of index-only values
     *
     * @param fieldName
     *            The field to fetch
     * @return An iterator that will allow for lazy, incremental fetching of index-only values
     */
    @SuppressWarnings("unchecked")
    public <E> Iterator<E> newLazyFetchingIterator(final String fieldName) {
        Collection<E> values = Collections.emptySet();
        Iterator<E> iterator = values.iterator();
        try {
            // Create a specialized, index-only KeyToDocumentData
            final IndexOnlyKeyToDocumentData keyToDocumentData = new IndexOnlyKeyToDocumentData(this.parentRange, fieldName, this.indexOnlySeeker, false);

            // Initialize the fetch
            final Iterator<Entry<Key,Document>> documents = this.initializeFetch(fieldName, keyToDocumentData);

            // Populate the document
            final Iterator<Tuple2<Key,Document>> tupleItr = Iterators.transform(documents, new EntryToTuple<Key,Document>());
            final EmptyTermFrequencyFunction tfFunction = new EmptyTermFrequencyFunction();
            final Iterator<Tuple3<Key,Document,Map<String,Object>>> itrWithContext = TraceIterators.transform(tupleItr, tfFunction, "Term Frequency Lookup");
            final Iterator<Tuple3<Key,Document,DatawaveJexlContext>> itrWithDatawaveJexlContext = Iterators.transform(itrWithContext,
                            new SingleValueContextCreator(fieldName));

            // Replace the return value with a lazy-fetching iterator
            iterator = (Iterator<E>) Iterators.transform(itrWithDatawaveJexlContext, new TupleToGenericFunction(fieldName));
        } catch (final Exception e) {
            final String message = "Could not perform function on index-only field '" + fieldName + "\' for range " + this.parentRange;
            LOG.error(message, e);
        }

        return iterator;
    }

Replace Generic With Diamond EntryToTuple<Key,Document> with EntryToTuple<> in method public newLazyFetchingIterator(fieldName String) : Iterator<E> from class datawave.query.iterator.IndexOnlyFunctionIterator


    @Override
    public Iterator<Entry<Key,Document>> mapDocument(SortedKeyValueIterator<Key,Value> deepSourceCopy, Iterator<Entry<Key,Document>> documents,
                    CompositeMetadata compositeMetadata) {
        Iterator<Tuple2<Key,Document>> parentDocuments = Iterators.transform(documents, new GetParentDocument(
        // no evaluation filter here as this is post evaluation
                        new KeyToDocumentData(deepSourceCopy, this.myEnvironment, this.documentOptions, this.equality, null, this.includeHierarchyFields,
                                        this.includeHierarchyFields), new Aggregation(this.getTimeFilter(), this.typeMetadataWithNonIndexed, compositeMetadata,
                                        this.isIncludeGroupingContext(), this.includeRecordId, this.parentDisableIndexOnlyDocuments, null)));

        Iterator<Entry<Key,Document>> retDocuments = Iterators.transform(parentDocuments, new TupleToEntry<>());
        retDocuments = Iterators.transform(retDocuments, new ParentQueryIterator.KeepAllFlagSetter());
        return retDocuments;
    }

    @Override
    public Iterator<Entry<Key,Document>> mapDocument(SortedKeyValueIterator<Key,Value> deepSourceCopy, Iterator<Entry<Key,Document>> documents,
                    CompositeMetadata compositeMetadata) {
        Iterator<Tuple2<Key,Document>> parentDocuments = Iterators.transform(documents, new GetParentDocument(
        // no evaluation filter here as this is post evaluation
                        new KeyToDocumentData(deepSourceCopy, this.myEnvironment, this.documentOptions, this.equality, null, this.includeHierarchyFields,
                                        this.includeHierarchyFields), new Aggregation(this.getTimeFilter(), this.typeMetadataWithNonIndexed, compositeMetadata,
                                        this.isIncludeGroupingContext(), this.includeRecordId, this.parentDisableIndexOnlyDocuments, null)));

        Iterator<Entry<Key,Document>> retDocuments = Iterators.transform(parentDocuments, new TupleToEntry<Key,Document>());
        retDocuments = Iterators.transform(retDocuments, new ParentQueryIterator.KeepAllFlagSetter());
        return retDocuments;
    }

Replace Generic With Diamond TupleToEntry<Key,Document> with TupleToEntry<> in method public mapDocument(deepSourceCopy SortedKeyValueIterator<Key,Value>, documents Iterator<Entry<Key,Document>>, compositeMetadata CompositeMetadata) : Iterator<Entry<Key,Document>> from class datawave.query.iterator.ParentQueryIterator


    protected IteratorBuildingVisitor createIteratorBuildingVisitor(Class<? extends IteratorBuildingVisitor> c, final Range documentRange,
                    boolean isQueryFullySatisfied, boolean sortedUIDs) throws MalformedURLException, ConfigException, IllegalAccessException,
                    InstantiationException {
        if (log.isTraceEnabled()) {
            log.trace(documentRange);
        }

        // determine the list of indexed fields
        Set<String> indexedFields = new HashSet<>(this.getTypeMetadata().keySet());
        indexedFields.removeAll(this.getNonIndexedDataTypeMap().keySet());

        return c.newInstance().setSource(this, this.myEnvironment).setTimeFilter(this.getTimeFilter()).setTypeMetadata(this.getTypeMetadata())
                        .setFieldsToAggregate(this.getNonEventFields()).setAttrFilter(this.getEvaluationFilter())
                        .setDatatypeFilter(this.getFieldIndexKeyDataTypeFilter()).setFiAggregator(this.fiAggregator)
                        .setHdfsFileSystem(this.getFileSystemCache()).setQueryLock(this.getQueryLock())
                        .setIvaratorCacheDirURIAlternatives(this.getIvaratorCacheBaseURIsAsList()).setQueryId(this.getQueryId()).setScanId(this.getScanId())
                        .setIvaratorCacheSubDirPrefix(this.getHdfsCacheSubDirPrefix()).setHdfsFileCompressionCodec(this.getHdfsFileCompressionCodec())
                        .setIvaratorCacheBufferSize(this.getIvaratorCacheBufferSize())
                        .setIvaratorCacheScanPersistThreshold(this.getIvaratorCacheScanPersistThreshold())
                        .setIvaratorCacheScanTimeout(this.getIvaratorCacheScanTimeout()).setMaxRangeSplit(this.getMaxIndexRangeSplit())
                        .setIvaratorMaxOpenFiles(this.getIvaratorMaxOpenFiles()).setIvaratorSources(this, this.getMaxIvaratorSources())
                        .setIncludes(indexedFields).setTermFrequencyFields(this.getTermFrequencyFields()).setIsQueryFullySatisfied(isQueryFullySatisfied)
                        .setSortedUIDs(sortedUIDs).limit(documentRange).disableIndexOnly(disableFiEval).limit(this.sourceLimit)
                        .setCollectTimingDetails(this.collectTimingDetails).setQuerySpanCollector(this.querySpanCollector)
                        .setIndexOnlyFields(this.getAllIndexOnlyFields()).setAllowTermFrequencyLookup(this.allowTermFrequencyLookup)
                        .setCompositeMetadata(compositeMetadata);
        // TODO: .setStatsPort(this.statsdHostAndPort);
    }

    protected IteratorBuildingVisitor createIteratorBuildingVisitor(Class<? extends IteratorBuildingVisitor> c, final Range documentRange,
                    boolean isQueryFullySatisfied, boolean sortedUIDs) throws MalformedURLException, ConfigException, IllegalAccessException,
                    InstantiationException {
        if (log.isTraceEnabled()) {
            log.trace(documentRange);
        }

        // determine the list of indexed fields
        Set<String> indexedFields = new HashSet<String>(this.getTypeMetadata().keySet());
        indexedFields.removeAll(this.getNonIndexedDataTypeMap().keySet());

        return c.newInstance().setSource(this, this.myEnvironment).setTimeFilter(this.getTimeFilter()).setTypeMetadata(this.getTypeMetadata())
                        .setFieldsToAggregate(this.getNonEventFields()).setAttrFilter(this.getEvaluationFilter())
                        .setDatatypeFilter(this.getFieldIndexKeyDataTypeFilter()).setFiAggregator(this.fiAggregator)
                        .setHdfsFileSystem(this.getFileSystemCache()).setQueryLock(this.getQueryLock())
                        .setIvaratorCacheDirURIAlternatives(this.getIvaratorCacheBaseURIsAsList()).setQueryId(this.getQueryId()).setScanId(this.getScanId())
                        .setIvaratorCacheSubDirPrefix(this.getHdfsCacheSubDirPrefix()).setHdfsFileCompressionCodec(this.getHdfsFileCompressionCodec())
                        .setIvaratorCacheBufferSize(this.getIvaratorCacheBufferSize())
                        .setIvaratorCacheScanPersistThreshold(this.getIvaratorCacheScanPersistThreshold())
                        .setIvaratorCacheScanTimeout(this.getIvaratorCacheScanTimeout()).setMaxRangeSplit(this.getMaxIndexRangeSplit())
                        .setIvaratorMaxOpenFiles(this.getIvaratorMaxOpenFiles()).setIvaratorSources(this, this.getMaxIvaratorSources())
                        .setIncludes(indexedFields).setTermFrequencyFields(this.getTermFrequencyFields()).setIsQueryFullySatisfied(isQueryFullySatisfied)
                        .setSortedUIDs(sortedUIDs).limit(documentRange).disableIndexOnly(disableFiEval).limit(this.sourceLimit)
                        .setCollectTimingDetails(this.collectTimingDetails).setQuerySpanCollector(this.querySpanCollector)
                        .setIndexOnlyFields(this.getAllIndexOnlyFields()).setAllowTermFrequencyLookup(this.allowTermFrequencyLookup)
                        .setCompositeMetadata(compositeMetadata);
        // TODO: .setStatsPort(this.statsdHostAndPort);
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method protected createIteratorBuildingVisitor(c Class<? extends IteratorBuildingVisitor>, documentRange Range, isQueryFullySatisfied boolean, sortedUIDs boolean) : IteratorBuildingVisitor from class datawave.query.iterator.QueryIterator


    protected SatisfactionVisitor createSatisfiabilityVisitor(boolean isQueryFullySatisfiedInitialState) {

        // determine the list of indexed fields
        Set<String> indexedFields = new HashSet<>(this.getTypeMetadata().keySet());
        indexedFields.removeAll(this.getNonIndexedDataTypeMap().keySet());

        SatisfactionVisitor satisfactionVisitor = new SatisfactionVisitor(getNonEventFields(), indexedFields, Collections.emptySet(),
                        isQueryFullySatisfiedInitialState);
        return satisfactionVisitor;
    }

    protected SatisfactionVisitor createSatisfiabilityVisitor(boolean isQueryFullySatisfiedInitialState) {

        // determine the list of indexed fields
        Set<String> indexedFields = new HashSet<String>(this.getTypeMetadata().keySet());
        indexedFields.removeAll(this.getNonIndexedDataTypeMap().keySet());

        SatisfactionVisitor satisfactionVisitor = new SatisfactionVisitor(getNonEventFields(), indexedFields, Collections.emptySet(),
                        isQueryFullySatisfiedInitialState);
        return satisfactionVisitor;
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method protected createSatisfiabilityVisitor(isQueryFullySatisfiedInitialState boolean) : SatisfactionVisitor from class datawave.query.iterator.QueryIterator


    public Set<String> getAllIndexOnlyFields() {
        Set<String> allIndexOnlyFields = new HashSet<>();
        // index only fields are by definition not in the event
        if (indexOnlyFields != null)
            allIndexOnlyFields.addAll(indexOnlyFields);
        // composite fields are index only as well, unless they are overloaded composites
        if (compositeMetadata != null)
            for (Multimap<String,String> compositeFieldMap : compositeMetadata.getCompositeFieldMapByType().values())
                for (String compositeField : compositeFieldMap.keySet())
                    if (!CompositeIngest.isOverloadedCompositeField(compositeFieldMap, compositeField))
                        allIndexOnlyFields.add(compositeField);
        return allIndexOnlyFields;
    }

    public Set<String> getAllIndexOnlyFields() {
        Set<String> allIndexOnlyFields = new HashSet<String>();
        // index only fields are by definition not in the event
        if (indexOnlyFields != null)
            allIndexOnlyFields.addAll(indexOnlyFields);
        // composite fields are index only as well, unless they are overloaded composites
        if (compositeMetadata != null)
            for (Multimap<String,String> compositeFieldMap : compositeMetadata.getCompositeFieldMapByType().values())
                for (String compositeField : compositeFieldMap.keySet())
                    if (!CompositeIngest.isOverloadedCompositeField(compositeFieldMap, compositeField))
                        allIndexOnlyFields.add(compositeField);
        return allIndexOnlyFields;
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public getAllIndexOnlyFields() : Set<String> from class datawave.query.iterator.QueryOptions


    /**
     * Get the fields that contain data that may not be in the event
     *
     * @return
     */
    public Set<String> getNonEventFields() {
        Set<String> nonEventFields = new HashSet<>();
        // index only fields are by definition not in the event
        if (indexOnlyFields != null)
            nonEventFields.addAll(indexOnlyFields);
        // term frequency fields contain forms of the data (tokens) that are not in the event in the same form
        if (termFrequencyFields != null)
            nonEventFields.addAll(termFrequencyFields);
        // composite metadata contains combined fields that are not in the event in the same form
        if (compositeMetadata != null)
            for (Multimap<String,String> compositeFieldMap : compositeMetadata.getCompositeFieldMapByType().values())
                for (String compositeField : compositeFieldMap.keySet())
                    if (!CompositeIngest.isOverloadedCompositeField(compositeFieldMap, compositeField))
                        nonEventFields.add(compositeField);
        return nonEventFields;
    }

    /**
     * Get the fields that contain data that may not be in the event
     *
     * @return
     */
    public Set<String> getNonEventFields() {
        Set<String> nonEventFields = new HashSet<String>();
        // index only fields are by definition not in the event
        if (indexOnlyFields != null)
            nonEventFields.addAll(indexOnlyFields);
        // term frequency fields contain forms of the data (tokens) that are not in the event in the same form
        if (termFrequencyFields != null)
            nonEventFields.addAll(termFrequencyFields);
        // composite metadata contains combined fields that are not in the event in the same form
        if (compositeMetadata != null)
            for (Multimap<String,String> compositeFieldMap : compositeMetadata.getCompositeFieldMapByType().values())
                for (String compositeField : compositeFieldMap.keySet())
                    if (!CompositeIngest.isOverloadedCompositeField(compositeFieldMap, compositeField))
                        nonEventFields.add(compositeField);
        return nonEventFields;
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public getNonEventFields() : Set<String> from class datawave.query.iterator.QueryOptions


    public SourceManager(int initialSize, SortedKeyValueIterator<Key,Value> source) {
        this.initialSize = initialSize;
        child = new SourceManager(source);
        sourceQueue = null;
        sourceQueue = new LinkedList<>();
    }

    public SourceManager(int initialSize, SortedKeyValueIterator<Key,Value> source) {
        this.initialSize = initialSize;
        child = new SourceManager(source);
        sourceQueue = null;
        sourceQueue = new LinkedList<SourceManager>();
    }

Replace Generic With Diamond LinkedList<SourceManager> with LinkedList<> in method public SourceManager(initialSize int, source SortedKeyValueIterator<Key,Value>) from class datawave.query.iterator.SourceManager


    public SourceManager(SortedKeyValueIterator<Key,Value> source) {
        this.initialSize = 0;
        this.child = null;
        originalSource = source;
        sourceQueue = new LinkedList<>();
    }

    public SourceManager(SortedKeyValueIterator<Key,Value> source) {
        this.initialSize = 0;
        this.child = null;
        originalSource = source;
        sourceQueue = new LinkedList<SourceManager>();
    }

Replace Generic With Diamond LinkedList<SourceManager> with LinkedList<> in method public SourceManager(source SortedKeyValueIterator<Key,Value>) from class datawave.query.iterator.SourceManager


    public void initialize() {
        Comparator<T> keyComp = Util.keyComparator();
        // nestedIteratorComparator will keep a deterministic ordering, unlike hashCodeComparator
        Comparator<NestedIterator<T>> itrComp = Util.nestedIteratorComparator();

        transformer = Util.keyTransformer();
        transforms = new HashMap<>();

        includeHeads = TreeMultimap.create(keyComp, itrComp);
        includeHeads = initSubtree(includeHeads, includes, transformer, transforms, true);

        if (excludes.isEmpty()) {
            excludeHeads = Util.getEmpty();
        } else {
            excludeHeads = TreeMultimap.create(keyComp, itrComp);
            // pass null in for transforms as excludes are not returned
            excludeHeads = initSubtree(excludeHeads, excludes, transformer, null, false);
        }

        next();
    }

    public void initialize() {
        Comparator<T> keyComp = Util.keyComparator();
        // nestedIteratorComparator will keep a deterministic ordering, unlike hashCodeComparator
        Comparator<NestedIterator<T>> itrComp = Util.nestedIteratorComparator();

        transformer = Util.keyTransformer();
        transforms = new HashMap<T,T>();

        includeHeads = TreeMultimap.create(keyComp, itrComp);
        includeHeads = initSubtree(includeHeads, includes, transformer, transforms, true);

        if (excludes.isEmpty()) {
            excludeHeads = Util.getEmpty();
        } else {
            excludeHeads = TreeMultimap.create(keyComp, itrComp);
            // pass null in for transforms as excludes are not returned
            excludeHeads = initSubtree(excludeHeads, excludes, transformer, null, false);
        }

        next();
    }

Replace Generic With Diamond HashMap<T,T> with HashMap<> in method public initialize() : void from class datawave.query.iterator.logic.AndIterator


/**
     * Allows creators of this iterator to defer creating the sorted mapping of values to iterators until some condition is met. This is intended to let us
     * build the tree of iterators in init() and defer sorting the iterators until after seek() is called.
     */
    public void initialize() {
        Comparator<T> keyComp = Util.keyComparator();
        // nestedIteratorComparator will keep a deterministic ordering, unlike hashCodeComparator
        Comparator<NestedIterator<T>> itrComp = Util.nestedIteratorComparator();

        transformer = Util.keyTransformer();
        transforms = new HashMap<>();

        includeHeads = TreeMultimap.create(keyComp, itrComp);
        initSubtree(includeHeads, includes, transformer, transforms, false);

        if (excludes.isEmpty()) {
            excludeHeads = Util.getEmpty();
        } else {
            excludeHeads = TreeMultimap.create(keyComp, itrComp);
            // pass null in for transforms as excludes are not returned
            initSubtree(excludeHeads, excludes, transformer, null, false);
        }

        next();
    }

/**
     * Allows creators of this iterator to defer creating the sorted mapping of values to iterators until some condition is met. This is intended to let us
     * build the tree of iterators in init() and defer sorting the iterators until after seek() is called.
     */
    public void initialize() {
        Comparator<T> keyComp = Util.keyComparator();
        // nestedIteratorComparator will keep a deterministic ordering, unlike hashCodeComparator
        Comparator<NestedIterator<T>> itrComp = Util.nestedIteratorComparator();

        transformer = Util.keyTransformer();
        transforms = new HashMap<T,T>();

        includeHeads = TreeMultimap.create(keyComp, itrComp);
        initSubtree(includeHeads, includes, transformer, transforms, false);

        if (excludes.isEmpty()) {
            excludeHeads = Util.getEmpty();
        } else {
            excludeHeads = TreeMultimap.create(keyComp, itrComp);
            // pass null in for transforms as excludes are not returned
            initSubtree(excludeHeads, excludes, transformer, null, false);
        }

        next();
    }

Replace Generic With Diamond HashMap<T,T> with HashMap<> in method public initialize() : void from class datawave.query.iterator.logic.OrIterator


    /**
     * Row : shardId Fam : fieldName Qual: fieldValue \x00 datatype
     *
     * @return our new top key with the aggregated columnVisibility
     */
    private Key buildReturnKey() {
        if (log.isTraceEnabled()) {
            log.trace("buildReturnKey, currentRow: " + this.currentRow);
            log.trace("buildReturnKey, currentFieldName: " + this.currentFieldName);
            log.trace("buildReturnKey, currentFieldValue: " + this.currentFieldValue);
        }

        Text cq = new Text(this.currentFieldValue);
        if (this.uniqByDataTypeOption) {
            TextUtil.textAppend(cq, this.currentDataType);
        }

        // Combine the column visibilities into a single one
        // NOTE: key.getColumnVisibility actually returns a Text object so we need to convert them
        Set<ColumnVisibility> columnVisibilities = new HashSet<>();
        for (Text t : this.visibilitySet) {
            columnVisibilities.add(new ColumnVisibility(t));
        }
        ColumnVisibility cv;
        try {
            cv = markingFunctions.combine(columnVisibilities);
        } catch (MarkingFunctions.Exception e) {
            log.error("Could not combine visibilities: " + visibilitySet + "  " + e);
            return null;
        }

        return new Key(this.currentRow, new Text(this.currentFieldName), cq, new Text(cv.getExpression()), this.maxTimeStamp);
    }

    /**
     * Row : shardId Fam : fieldName Qual: fieldValue \x00 datatype
     *
     * @return our new top key with the aggregated columnVisibility
     */
    private Key buildReturnKey() {
        if (log.isTraceEnabled()) {
            log.trace("buildReturnKey, currentRow: " + this.currentRow);
            log.trace("buildReturnKey, currentFieldName: " + this.currentFieldName);
            log.trace("buildReturnKey, currentFieldValue: " + this.currentFieldValue);
        }

        Text cq = new Text(this.currentFieldValue);
        if (this.uniqByDataTypeOption) {
            TextUtil.textAppend(cq, this.currentDataType);
        }

        // Combine the column visibilities into a single one
        // NOTE: key.getColumnVisibility actually returns a Text object so we need to convert them
        Set<ColumnVisibility> columnVisibilities = new HashSet<ColumnVisibility>();
        for (Text t : this.visibilitySet) {
            columnVisibilities.add(new ColumnVisibility(t));
        }
        ColumnVisibility cv;
        try {
            cv = markingFunctions.combine(columnVisibilities);
        } catch (MarkingFunctions.Exception e) {
            log.error("Could not combine visibilities: " + visibilitySet + "  " + e);
            return null;
        }

        return new Key(this.currentRow, new Text(this.currentFieldName), cq, new Text(cv.getExpression()), this.maxTimeStamp);
    }

Replace Generic With Diamond HashSet<ColumnVisibility> with HashSet<> in method private buildReturnKey() : Key from class datawave.query.iterators.FieldIndexCountingIterator


    public Set<String> getHitSet() {
        Set<String> hits = new HashSet<>();
        for (ValueTuple value : hitSet) {
            hits.add(value.getFieldName().toString() + ':' + value.getValue());
        }
        return hits;
    }

    public Set<String> getHitSet() {
        Set<String> hits = new HashSet<String>();
        for (ValueTuple value : hitSet) {
            hits.add(value.getFieldName().toString() + ':' + value.getValue());
        }
        return hits;
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public getHitSet() : Set<String> from class datawave.query.jexl.HitListArithmetic


    /**
     * Constructor
     *
     * @param context
     *            A non-null MapContext, presumably an instance of {@link DatawaveJexlContext}
     * @param iterator
     *            A non-null IndexOnlyFunctionIterator
     */
    public IndexOnlyJexlContext(final MapContext context, final IndexOnlyFunctionIterator<T> iterator) {
        checkNotNull(context, this.getClass().getSimpleName() + " cannot be initialized with a null " + MapContext.class.getSimpleName());
        checkNotNull(iterator, this.getClass().getSimpleName() + " cannot be initialized with a null " + IndexOnlyFunctionIterator.class.getSimpleName());
        this.parent = context;
        this.iterator = iterator;

        // Create a collection of index-only field names for quick lookup
        final Collection<String> fields = this.iterator.getIndexOnlyFields();
        if (null != fields) {
            this.indexOnlyFields = Collections.unmodifiableSet(new HashSet<>(fields));
        } else {
            this.indexOnlyFields = Collections.emptySet();
        }

        // Create a weak hashmap to allow garbage collection in case of abnormally large sets of index-only records, yet prevent duplicate
        // fetching if the values can be held in memory.
        this.lazyFetchingIndexOnlySets = Collections.synchronizedMap(new WeakHashMap<>());
    }

    /**
     * Constructor
     *
     * @param context
     *            A non-null MapContext, presumably an instance of {@link DatawaveJexlContext}
     * @param iterator
     *            A non-null IndexOnlyFunctionIterator
     */
    public IndexOnlyJexlContext(final MapContext context, final IndexOnlyFunctionIterator<T> iterator) {
        checkNotNull(context, this.getClass().getSimpleName() + " cannot be initialized with a null " + MapContext.class.getSimpleName());
        checkNotNull(iterator, this.getClass().getSimpleName() + " cannot be initialized with a null " + IndexOnlyFunctionIterator.class.getSimpleName());
        this.parent = context;
        this.iterator = iterator;

        // Create a collection of index-only field names for quick lookup
        final Collection<String> fields = this.iterator.getIndexOnlyFields();
        if (null != fields) {
            this.indexOnlyFields = Collections.unmodifiableSet(new HashSet<>(fields));
        } else {
            this.indexOnlyFields = Collections.emptySet();
        }

        // Create a weak hashmap to allow garbage collection in case of abnormally large sets of index-only records, yet prevent duplicate
        // fetching if the values can be held in memory.
        this.lazyFetchingIndexOnlySets = Collections.synchronizedMap(new WeakHashMap<String,WeakReference<Collection<?>>>());
    }

Replace Generic With Diamond WeakHashMap<String,WeakReference<Collection<?>>> with WeakHashMap<> in method public IndexOnlyJexlContext(context MapContext, iterator IndexOnlyFunctionIterator<T>) from class datawave.query.jexl.IndexOnlyJexlContext


    private Collection<?> getLazyFetchingSet(final String name) {
        final Collection<?> lazyFetchingSet;
        if ((null != name) && !name.isEmpty() && this.indexOnlyFields.contains(name)) {
            // See if there's a set already available in memory
            final WeakReference<Collection<?>> ref = this.lazyFetchingIndexOnlySets.get(name);
            final Collection<?> values;
            if (null != ref) {
                values = ref.get();
            } else {
                values = null;
            }

            // Use the set obtained from memory, or create a new one. Fetching won't occur until the
            // set is used, such as asking for its size, iterator, etc.
            if (null != values) {
                lazyFetchingSet = values;
            } else {
                lazyFetchingSet = Collections.synchronizedSet(new IndexOnlyLazyFetchingSet<>(name, this.iterator));
                this.lazyFetchingIndexOnlySets.put(name, new WeakReference<>(lazyFetchingSet));
            }
        } else {
            lazyFetchingSet = null;
        }

        return lazyFetchingSet;
    }

    private Collection<?> getLazyFetchingSet(final String name) {
        final Collection<?> lazyFetchingSet;
        if ((null != name) && !name.isEmpty() && this.indexOnlyFields.contains(name)) {
            // See if there's a set already available in memory
            final WeakReference<Collection<?>> ref = this.lazyFetchingIndexOnlySets.get(name);
            final Collection<?> values;
            if (null != ref) {
                values = ref.get();
            } else {
                values = null;
            }

            // Use the set obtained from memory, or create a new one. Fetching won't occur until the
            // set is used, such as asking for its size, iterator, etc.
            if (null != values) {
                lazyFetchingSet = values;
            } else {
                lazyFetchingSet = Collections.synchronizedSet(new IndexOnlyLazyFetchingSet<>(name, this.iterator));
                this.lazyFetchingIndexOnlySets.put(name, new WeakReference<Collection<?>>(lazyFetchingSet));
            }
        } else {
            lazyFetchingSet = null;
        }

        return lazyFetchingSet;
    }

Replace Generic With Diamond WeakReference<Collection<?>> with WeakReference<> in method private getLazyFetchingSet(name String) : Collection<?> from class datawave.query.jexl.IndexOnlyJexlContext


    /**
     * Expand a node given a mapping of fields to values. If the list is empty, then the original regex should be used.
     *
     * @param containerType
     *            should we create OR nodes or AND nodes
     * @param node
     * @param fieldsToValues
     *            A mapping of fields to values. If the values for a field is empty, then the original regex should be used.
     * @return A new sub query
     */
    public static JexlNode createNodeTreeFromFieldsToValues(ContainerType containerType, JexlNode node, JexlNode orgNode, IndexLookupMap fieldsToValues) {
        // no expansions needed if the fieldname threshold is exceeded
        if (fieldsToValues.isKeyThresholdExceeded()) {
            return new ExceededTermThresholdMarkerJexlNode(orgNode);
        }

        Set<String> fields = fieldsToValues.keySet();

        JexlNode parentNode = (containerType.equals(ContainerType.OR_NODE) ? new ASTOrNode(ParserTreeConstants.JJTORNODE) : new ASTAndNode(
                        ParserTreeConstants.JJTANDNODE));
        int parentNodeChildCount = 0;

        JexlNodes.ensureCapacity(parentNode, fields.size());
        for (String field : fields) {
            ValueSet valuesForField = fieldsToValues.get(field);

            // a threshold exceeded set of values requires using the original
            // node with a new fieldname, wrapped with a marker node
            if (valuesForField.isThresholdExceeded()) {
                // create a set of nodes wrapping each pattern
                List<String> patterns = new ArrayList<>(fieldsToValues.getPatterns() == null ? new ArrayList<>() : fieldsToValues.getPatterns());
                if (patterns.isEmpty()) {
                    JexlNode child = new ExceededValueThresholdMarkerJexlNode(buildUntypedNode(orgNode, field));

                    parentNode.jjtAddChild(child, parentNodeChildCount);
                    child.jjtSetParent(parentNode);

                    parentNodeChildCount++;
                } else if (patterns.size() == 1) {
                    JexlNode child = new ExceededValueThresholdMarkerJexlNode(buildUntypedNode(orgNode, field, patterns.get(0)));

                    parentNode.jjtAddChild(child, parentNodeChildCount);
                    child.jjtSetParent(parentNode);

                    parentNodeChildCount++;
                } else {
                    int childNodeChildCount = 0;
                    JexlNode childNode = (containerType.equals(ContainerType.OR_NODE) ? new ASTOrNode(ParserTreeConstants.JJTORNODE) : new ASTAndNode(
                                    ParserTreeConstants.JJTANDNODE));
                    JexlNodes.ensureCapacity(childNode, patterns.size());
                    for (String pattern : patterns) {
                        JexlNode child = new ExceededValueThresholdMarkerJexlNode(buildUntypedNode(orgNode, field, pattern));

                        childNode.jjtAddChild(child, childNodeChildCount);
                        child.jjtSetParent(childNode);

                        childNodeChildCount++;
                    }

                    if (0 < childNodeChildCount) {
                        JexlNode wrappedChildNode = wrap(childNode);
                        childNode.jjtSetParent(wrappedChildNode);

                        parentNode.jjtAddChild(wrappedChildNode, parentNodeChildCount);
                        childNode.jjtSetParent(childNode);

                        parentNodeChildCount++;
                    }
                }
            }

            // Don't create an OR if we have only one value, directly attach it
            else if (1 == valuesForField.size()) {
                JexlNode child = buildUntypedNode(node, field, valuesForField.iterator().next());

                parentNode.jjtAddChild(child, parentNodeChildCount);
                child.jjtSetParent(parentNode);

                parentNodeChildCount++;
            } else {
                int childNodeChildCount = 0;
                JexlNode childNode = (containerType.equals(ContainerType.OR_NODE) ? new ASTOrNode(ParserTreeConstants.JJTORNODE) : new ASTAndNode(
                                ParserTreeConstants.JJTANDNODE));
                JexlNodes.ensureCapacity(childNode, valuesForField.size());
                for (String value : valuesForField) {
                    JexlNode child = buildUntypedNode(node, field, value);

                    childNode.jjtAddChild(child, childNodeChildCount);
                    child.jjtSetParent(childNode);

                    childNodeChildCount++;
                }

                if (0 < childNodeChildCount) {
                    JexlNode wrappedChildNode = wrap(childNode);
                    childNode.jjtSetParent(wrappedChildNode);

                    parentNode.jjtAddChild(wrappedChildNode, parentNodeChildCount);
                    childNode.jjtSetParent(childNode);

                    parentNodeChildCount++;
                }
            }
        }

        switch (parentNodeChildCount) {
            case 0:
                return orgNode;
            case 1:
                JexlNode child = parentNode.jjtGetChild(0);
                JexlNodes.promote(parentNode, child);
                return child;
            default:
                JexlNode wrappedParentNode = wrap(parentNode);
                parentNode.jjtSetParent(wrappedParentNode);
                return wrappedParentNode;
        }
    }

    /**
     * Expand a node given a mapping of fields to values. If the list is empty, then the original regex should be used.
     *
     * @param containerType
     *            should we create OR nodes or AND nodes
     * @param node
     * @param fieldsToValues
     *            A mapping of fields to values. If the values for a field is empty, then the original regex should be used.
     * @return A new sub query
     */
    public static JexlNode createNodeTreeFromFieldsToValues(ContainerType containerType, JexlNode node, JexlNode orgNode, IndexLookupMap fieldsToValues) {
        // no expansions needed if the fieldname threshold is exceeded
        if (fieldsToValues.isKeyThresholdExceeded()) {
            return new ExceededTermThresholdMarkerJexlNode(orgNode);
        }

        Set<String> fields = fieldsToValues.keySet();

        JexlNode parentNode = (containerType.equals(ContainerType.OR_NODE) ? new ASTOrNode(ParserTreeConstants.JJTORNODE) : new ASTAndNode(
                        ParserTreeConstants.JJTANDNODE));
        int parentNodeChildCount = 0;

        JexlNodes.ensureCapacity(parentNode, fields.size());
        for (String field : fields) {
            ValueSet valuesForField = fieldsToValues.get(field);

            // a threshold exceeded set of values requires using the original
            // node with a new fieldname, wrapped with a marker node
            if (valuesForField.isThresholdExceeded()) {
                // create a set of nodes wrapping each pattern
                List<String> patterns = new ArrayList<String>(fieldsToValues.getPatterns() == null ? new ArrayList<String>() : fieldsToValues.getPatterns());
                if (patterns.isEmpty()) {
                    JexlNode child = new ExceededValueThresholdMarkerJexlNode(buildUntypedNode(orgNode, field));

                    parentNode.jjtAddChild(child, parentNodeChildCount);
                    child.jjtSetParent(parentNode);

                    parentNodeChildCount++;
                } else if (patterns.size() == 1) {
                    JexlNode child = new ExceededValueThresholdMarkerJexlNode(buildUntypedNode(orgNode, field, patterns.get(0)));

                    parentNode.jjtAddChild(child, parentNodeChildCount);
                    child.jjtSetParent(parentNode);

                    parentNodeChildCount++;
                } else {
                    int childNodeChildCount = 0;
                    JexlNode childNode = (containerType.equals(ContainerType.OR_NODE) ? new ASTOrNode(ParserTreeConstants.JJTORNODE) : new ASTAndNode(
                                    ParserTreeConstants.JJTANDNODE));
                    JexlNodes.ensureCapacity(childNode, patterns.size());
                    for (String pattern : patterns) {
                        JexlNode child = new ExceededValueThresholdMarkerJexlNode(buildUntypedNode(orgNode, field, pattern));

                        childNode.jjtAddChild(child, childNodeChildCount);
                        child.jjtSetParent(childNode);

                        childNodeChildCount++;
                    }

                    if (0 < childNodeChildCount) {
                        JexlNode wrappedChildNode = wrap(childNode);
                        childNode.jjtSetParent(wrappedChildNode);

                        parentNode.jjtAddChild(wrappedChildNode, parentNodeChildCount);
                        childNode.jjtSetParent(childNode);

                        parentNodeChildCount++;
                    }
                }
            }

            // Don't create an OR if we have only one value, directly attach it
            else if (1 == valuesForField.size()) {
                JexlNode child = buildUntypedNode(node, field, valuesForField.iterator().next());

                parentNode.jjtAddChild(child, parentNodeChildCount);
                child.jjtSetParent(parentNode);

                parentNodeChildCount++;
            } else {
                int childNodeChildCount = 0;
                JexlNode childNode = (containerType.equals(ContainerType.OR_NODE) ? new ASTOrNode(ParserTreeConstants.JJTORNODE) : new ASTAndNode(
                                ParserTreeConstants.JJTANDNODE));
                JexlNodes.ensureCapacity(childNode, valuesForField.size());
                for (String value : valuesForField) {
                    JexlNode child = buildUntypedNode(node, field, value);

                    childNode.jjtAddChild(child, childNodeChildCount);
                    child.jjtSetParent(childNode);

                    childNodeChildCount++;
                }

                if (0 < childNodeChildCount) {
                    JexlNode wrappedChildNode = wrap(childNode);
                    childNode.jjtSetParent(wrappedChildNode);

                    parentNode.jjtAddChild(wrappedChildNode, parentNodeChildCount);
                    childNode.jjtSetParent(childNode);

                    parentNodeChildCount++;
                }
            }
        }

        switch (parentNodeChildCount) {
            case 0:
                return orgNode;
            case 1:
                JexlNode child = parentNode.jjtGetChild(0);
                JexlNodes.promote(parentNode, child);
                return child;
            default:
                JexlNode wrappedParentNode = wrap(parentNode);
                parentNode.jjtSetParent(wrappedParentNode);
                return wrappedParentNode;
        }
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public createNodeTreeFromFieldsToValues(containerType ContainerType, node JexlNode, orgNode JexlNode, fieldsToValues IndexLookupMap) : JexlNode from class datawave.query.jexl.JexlNodeFactory


        protected static JexlNode getIndexNode(String fieldName, Envelope env, int maxExpansion) {
            List<Envelope> envs = new ArrayList<>();
            envs.add(env);
            return getIndexNode(fieldName, envs, maxExpansion);
        }

        protected static JexlNode getIndexNode(String fieldName, Envelope env, int maxExpansion) {
            List<Envelope> envs = new ArrayList<Envelope>();
            envs.add(env);
            return getIndexNode(fieldName, envs, maxExpansion);
        }

Replace Generic With Diamond ArrayList<Envelope> with ArrayList<> in method protected getIndexNode(fieldName String, env Envelope, maxExpansion int) : JexlNode from class datawave.query.jexl.functions.GeoWaveFunctionsDescriptor.GeoWaveJexlArgumentDescriptor


        protected static JexlNode getIndexNode(String fieldName, List<Envelope> envs, int maxExpansion) {
            List<ByteArrayRange> allRanges = new ArrayList<>();
            int maxRanges = maxExpansion / envs.size();
            for (Envelope env : envs) {
                for (MultiDimensionalNumericData range : GeometryUtils.basicConstraintsFromEnvelope(env).getIndexConstraints(GeometryNormalizer.indexStrategy)) {
                    allRanges.addAll(GeometryNormalizer.indexStrategy.getQueryRanges(range, maxRanges));
                }
            }
            allRanges = ByteArrayRange.mergeIntersections(allRanges, ByteArrayRange.MergeOperation.UNION);

            Iterable<JexlNode> rangeNodes = Iterables.transform(allRanges, new ByteArrayRangeToJexlNode(fieldName));

            // now link em up
            return JexlNodeFactory.createOrNode(rangeNodes);
        }

        protected static JexlNode getIndexNode(String fieldName, List<Envelope> envs, int maxExpansion) {
            List<ByteArrayRange> allRanges = new ArrayList<ByteArrayRange>();
            int maxRanges = maxExpansion / envs.size();
            for (Envelope env : envs) {
                for (MultiDimensionalNumericData range : GeometryUtils.basicConstraintsFromEnvelope(env).getIndexConstraints(GeometryNormalizer.indexStrategy)) {
                    allRanges.addAll(GeometryNormalizer.indexStrategy.getQueryRanges(range, maxRanges));
                }
            }
            allRanges = ByteArrayRange.mergeIntersections(allRanges, ByteArrayRange.MergeOperation.UNION);

            Iterable<JexlNode> rangeNodes = Iterables.transform(allRanges, new ByteArrayRangeToJexlNode(fieldName));

            // now link em up
            return JexlNodeFactory.createOrNode(rangeNodes);
        }

Replace Generic With Diamond ArrayList<ByteArrayRange> with ArrayList<> in method protected getIndexNode(fieldName String, envs List<Envelope>, maxExpansion int) : JexlNode from class datawave.query.jexl.functions.GeoWaveFunctionsDescriptor.GeoWaveJexlArgumentDescriptor


        public static Set<Set<String>> product(Set<Set<String>> a, JexlNode b) {
            Set<Set<String>> fieldSets = new HashSet<>();
            if (b instanceof ASTOrNode) {
                for (String field2 : JexlASTHelper.getIdentifierNames(b)) {
                    for (Set<String> fields1 : a) {
                        Set<String> fields = new HashSet<>();
                        fields.addAll(fields1);
                        fields.add(field2);
                        fieldSets.add(fields);
                    }
                }
            } else {
                Set<String> fields2 = JexlASTHelper.getIdentifierNames(b);
                for (Set<String> fields1 : a) {
                    Set<String> fields = new HashSet<>();
                    fields.addAll(fields1);
                    fields.addAll(fields2);
                    fieldSets.add(fields);
                }
            }
            return fieldSets;
        }

        public static Set<Set<String>> product(Set<Set<String>> a, JexlNode b) {
            Set<Set<String>> fieldSets = new HashSet<>();
            if (b instanceof ASTOrNode) {
                for (String field2 : JexlASTHelper.getIdentifierNames(b)) {
                    for (Set<String> fields1 : a) {
                        Set<String> fields = new HashSet<String>();
                        fields.addAll(fields1);
                        fields.add(field2);
                        fieldSets.add(fields);
                    }
                }
            } else {
                Set<String> fields2 = JexlASTHelper.getIdentifierNames(b);
                for (Set<String> fields1 : a) {
                    Set<String> fields = new HashSet<>();
                    fields.addAll(fields1);
                    fields.addAll(fields2);
                    fieldSets.add(fields);
                }
            }
            return fieldSets;
        }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public product(a Set<Set<String>>, b JexlNode) : Set<Set<String>> from class datawave.query.jexl.functions.arguments.JexlArgumentDescriptor.Fields


        public static Set<Set<String>> product(Set<Set<String>> a, Set<Set<String>> b) {
            Set<Set<String>> fieldSets = new HashSet<>();
            for (Set<String> fields2 : b) {
                for (Set<String> fields1 : a) {
                    Set<String> fields = new HashSet<>();
                    fields.addAll(fields1);
                    fields.addAll(fields2);
                    fieldSets.add(fields);
                }
            }
            return fieldSets;
        }

        public static Set<Set<String>> product(Set<Set<String>> a, Set<Set<String>> b) {
            Set<Set<String>> fieldSets = new HashSet<>();
            for (Set<String> fields2 : b) {
                for (Set<String> fields1 : a) {
                    Set<String> fields = new HashSet<String>();
                    fields.addAll(fields1);
                    fields.addAll(fields2);
                    fieldSets.add(fields);
                }
            }
            return fieldSets;
        }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public product(a Set<Set<String>>, b Set<Set<String>>) : Set<Set<String>> from class datawave.query.jexl.functions.arguments.JexlArgumentDescriptor.Fields


    /**
     * Used only for the Edge'Source'QueryLogic Basically function support was an afterthought only to support old code in the existing Edge'Source'QueryLogic A
     * list with a single Identity context is returned in the following format: Identity = FUNCTION Opperator = FUNCTION LITER = "{function string}" //eg
     * source.has_all(SINK, "t1", "t2", ...)
     */
    public Object visit(ASTFunctionNode node, Object data) {
        if (node.jjtGetParent() instanceof ASTJexlScript) {
            // then we're the only node in here, we need to come up with ranges from the function itself, or fail the query
            throw new IllegalArgumentException("Cannot perform has_all without specifying a pattern for the edge 'SOURCE'.");
        }

        int numChildren = node.jjtGetNumChildren();
        StringBuilder sb = new StringBuilder();
        String fieldName = null;
        Set<String> edgeTypes = new HashSet<>();

        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            if (0 == i) {
                sb.append(node.jjtGetChild(i).image);
            } else if (1 == i) {
                if (!allowedFunctions.contains(node.jjtGetChild(i).image.toLowerCase())) {
                    BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.FUNCTION_NOT_FOUND, node.jjtGetChild(i).image
                                    + " not supported function for EdgeQuery");
                    throw new UnsupportedOperationException(qe);
                }
                sb.append(":");
                sb.append(node.jjtGetChild(i).image);
            } else if (2 == i) {
                sb.append("(");
                sb.append(getLiteral(node.jjtGetChild(i)));
            } else if (2 < i) {
                sb.append(", ");
                sb.append("'" + getLiteral(node.jjtGetChild(i)).toLowerCase() + "'");
            }
        }

        sb.append(")");

        List<IdentityContext> contexts = new ArrayList<>();
        IdentityContext iContext = new IdentityContext(FUNCTION, sb.toString(), FUNCTION);

        contexts.add(iContext);
        return contexts;
    }

    /**
     * Used only for the Edge'Source'QueryLogic Basically function support was an afterthought only to support old code in the existing Edge'Source'QueryLogic A
     * list with a single Identity context is returned in the following format: Identity = FUNCTION Opperator = FUNCTION LITER = "{function string}" //eg
     * source.has_all(SINK, "t1", "t2", ...)
     */
    public Object visit(ASTFunctionNode node, Object data) {
        if (node.jjtGetParent() instanceof ASTJexlScript) {
            // then we're the only node in here, we need to come up with ranges from the function itself, or fail the query
            throw new IllegalArgumentException("Cannot perform has_all without specifying a pattern for the edge 'SOURCE'.");
        }

        int numChildren = node.jjtGetNumChildren();
        StringBuilder sb = new StringBuilder();
        String fieldName = null;
        Set<String> edgeTypes = new HashSet<String>();

        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            if (0 == i) {
                sb.append(node.jjtGetChild(i).image);
            } else if (1 == i) {
                if (!allowedFunctions.contains(node.jjtGetChild(i).image.toLowerCase())) {
                    BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.FUNCTION_NOT_FOUND, node.jjtGetChild(i).image
                                    + " not supported function for EdgeQuery");
                    throw new UnsupportedOperationException(qe);
                }
                sb.append(":");
                sb.append(node.jjtGetChild(i).image);
            } else if (2 == i) {
                sb.append("(");
                sb.append(getLiteral(node.jjtGetChild(i)));
            } else if (2 < i) {
                sb.append(", ");
                sb.append("'" + getLiteral(node.jjtGetChild(i)).toLowerCase() + "'");
            }
        }

        sb.append(")");

        List<IdentityContext> contexts = new ArrayList<>();
        IdentityContext iContext = new IdentityContext(FUNCTION, sb.toString(), FUNCTION);

        contexts.add(iContext);
        return contexts;
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public visit(node ASTFunctionNode, data Object) : Object from class datawave.query.jexl.visitors.EdgeTableRangeBuildingVisitor


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

        return null;
    }

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

        return null;
    }

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


    public static Set<String> extractNormalizedAttributes(AttributeFactory attrFactory, String fieldName, String fieldValue, Key key) {
        final Set<String> normalizedAttributes = new HashSet<>();

        final Queue<Attribute<?>> attrQueue = new LinkedList<>();
        attrQueue.add(attrFactory.create(fieldName, fieldValue, key, true));

        Attribute<?> attr;

        while ((attr = attrQueue.poll()) != null) {
            if (TypeAttribute.class.isAssignableFrom(attr.getClass())) {
                TypeAttribute dta = (TypeAttribute) attr;
                Type t = dta.getType();
                normalizedAttributes.add(t.getNormalizedValue());
            } else if (AttributeBag.class.isAssignableFrom(attr.getClass())) {
                attrQueue.addAll(((AttributeBag<?>) attr).getAttributes());
            } else {
                log.warn("Unexpected attribute type when extracting normalized values: " + attr.getClass().getCanonicalName());
            }
        }
        return normalizedAttributes;
    }

    public static Set<String> extractNormalizedAttributes(AttributeFactory attrFactory, String fieldName, String fieldValue, Key key) {
        final Set<String> normalizedAttributes = new HashSet<String>();

        final Queue<Attribute<?>> attrQueue = new LinkedList<>();
        attrQueue.add(attrFactory.create(fieldName, fieldValue, key, true));

        Attribute<?> attr;

        while ((attr = attrQueue.poll()) != null) {
            if (TypeAttribute.class.isAssignableFrom(attr.getClass())) {
                TypeAttribute dta = (TypeAttribute) attr;
                Type t = dta.getType();
                normalizedAttributes.add(t.getNormalizedValue());
            } else if (AttributeBag.class.isAssignableFrom(attr.getClass())) {
                attrQueue.addAll(((AttributeBag<?>) attr).getAttributes());
            } else {
                log.warn("Unexpected attribute type when extracting normalized values: " + attr.getClass().getCanonicalName());
            }
        }
        return normalizedAttributes;
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public extractNormalizedAttributes(attrFactory AttributeFactory, fieldName String, fieldValue String, key Key) : Set<String> from class datawave.query.jexl.visitors.EventDataQueryExpressionVisitor


    /**
     * allOrNone means that all contained children must be executable for this node to be executable. Used for expressions, scripts, and or nodes.
     */
    protected STATE allOrNone(JexlNode node, Object data) {
        STATE state;
        boolean containsIgnorable = false;
        // all children must be executable for a script to be executable
        Set<STATE> states = new HashSet<>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            states.add((STATE) (node.jjtGetChild(i).jjtAccept(this, data)));
        }
        if (log.isTraceEnabled()) {
            log.trace("node:" + PrintingVisitor.formattedQueryString(node));
            log.trace("states are:" + states);
        }
        // if only one state, then that is the state
        if (states.size() == 1) {
            state = states.iterator().next();
        } else {
            // else remove the ignorable state
            containsIgnorable = states.remove(STATE.IGNORABLE);
            // if now only one state, then that is the state
            if (states.size() == 1) {
                state = states.iterator().next();
            }
            // if we contain an error state, the error
            else if (states.contains(STATE.ERROR)) {
                state = STATE.ERROR;
            } else {
                // otherwise we have a PARTIAL state
                state = STATE.PARTIAL;
            }
        }
        if (output != null) {
            output.writeLine(data + node.toString() + '[' + states + (containsIgnorable ? ",IGNORABLE" : "") + "] -> " + state);
        }
        return state;
    }

    /**
     * allOrNone means that all contained children must be executable for this node to be executable. Used for expressions, scripts, and or nodes.
     */
    protected STATE allOrNone(JexlNode node, Object data) {
        STATE state;
        boolean containsIgnorable = false;
        // all children must be executable for a script to be executable
        Set<STATE> states = new HashSet<STATE>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            states.add((STATE) (node.jjtGetChild(i).jjtAccept(this, data)));
        }
        if (log.isTraceEnabled()) {
            log.trace("node:" + PrintingVisitor.formattedQueryString(node));
            log.trace("states are:" + states);
        }
        // if only one state, then that is the state
        if (states.size() == 1) {
            state = states.iterator().next();
        } else {
            // else remove the ignorable state
            containsIgnorable = states.remove(STATE.IGNORABLE);
            // if now only one state, then that is the state
            if (states.size() == 1) {
                state = states.iterator().next();
            }
            // if we contain an error state, the error
            else if (states.contains(STATE.ERROR)) {
                state = STATE.ERROR;
            } else {
                // otherwise we have a PARTIAL state
                state = STATE.PARTIAL;
            }
        }
        if (output != null) {
            output.writeLine(data + node.toString() + '[' + states + (containsIgnorable ? ",IGNORABLE" : "") + "] -> " + state);
        }
        return state;
    }

Replace Generic With Diamond HashSet<STATE> with HashSet<> in method protected allOrNone(node JexlNode, data Object) : STATE from class datawave.query.jexl.visitors.ExecutableDeterminationVisitor


    protected STATE unlessAnyNonExecutable(JexlNode node, Object data) {
        STATE state;
        boolean containsIgnorable = false;
        // all children must be executable for a script to be executable
        Set<STATE> states = new HashSet<>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            states.add((STATE) (node.jjtGetChild(i).jjtAccept(this, data)));
        }
        if (log.isTraceEnabled()) {
            log.trace("node:" + PrintingVisitor.formattedQueryString(node));
            log.trace("states are:" + states);
        }
        if (states.contains(STATE.NON_EXECUTABLE)) {
            return STATE.NON_EXECUTABLE;
        } else {
            return STATE.EXECUTABLE;
        }
    }

    protected STATE unlessAnyNonExecutable(JexlNode node, Object data) {
        STATE state;
        boolean containsIgnorable = false;
        // all children must be executable for a script to be executable
        Set<STATE> states = new HashSet<STATE>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            states.add((STATE) (node.jjtGetChild(i).jjtAccept(this, data)));
        }
        if (log.isTraceEnabled()) {
            log.trace("node:" + PrintingVisitor.formattedQueryString(node));
            log.trace("states are:" + states);
        }
        if (states.contains(STATE.NON_EXECUTABLE)) {
            return STATE.NON_EXECUTABLE;
        } else {
            return STATE.EXECUTABLE;
        }
    }

Replace Generic With Diamond HashSet<STATE> with HashSet<> in method protected unlessAnyNonExecutable(node JexlNode, data Object) : STATE from class datawave.query.jexl.visitors.ExecutableDeterminationVisitor


    /**
     * allOrSome means that some of the nodes must be executable for this to be executable. Any partial state results in a partial state however. Used for and
     * nodes.
     */
    protected STATE allOrSome(JexlNode node, Object data) {
        STATE state;
        boolean containsIgnorable = false;
        Set<STATE> states = new HashSet<>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            states.add((STATE) (node.jjtGetChild(i).jjtAccept(this, data + PREFIX)));
        }
        // if only one state, then that is the state
        if (states.size() == 1) {
            state = states.iterator().next();
        } else {
            // else remove the ignorable state
            containsIgnorable = states.remove(STATE.IGNORABLE);
            // if now only one state, then that is the state
            if (states.size() == 1) {
                state = states.iterator().next();
            }
            // if we contain an error state, the error
            else if (states.contains(STATE.ERROR)) {
                state = STATE.ERROR;
            }
            // if we have a partial state, then partial
            else if (states.contains(STATE.PARTIAL)) {
                state = STATE.PARTIAL;
            }
            // otherwise we have an executable state
            else {
                return STATE.EXECUTABLE;
            }
        }
        if (output != null) {
            output.writeLine(data + node.toString() + '[' + states + (containsIgnorable ? ",IGNORABLE" : "") + "] -> " + state);
        }
        return state;
    }

    /**
     * allOrSome means that some of the nodes must be executable for this to be executable. Any partial state results in a partial state however. Used for and
     * nodes.
     */
    protected STATE allOrSome(JexlNode node, Object data) {
        STATE state;
        boolean containsIgnorable = false;
        Set<STATE> states = new HashSet<STATE>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            states.add((STATE) (node.jjtGetChild(i).jjtAccept(this, data + PREFIX)));
        }
        // if only one state, then that is the state
        if (states.size() == 1) {
            state = states.iterator().next();
        } else {
            // else remove the ignorable state
            containsIgnorable = states.remove(STATE.IGNORABLE);
            // if now only one state, then that is the state
            if (states.size() == 1) {
                state = states.iterator().next();
            }
            // if we contain an error state, the error
            else if (states.contains(STATE.ERROR)) {
                state = STATE.ERROR;
            }
            // if we have a partial state, then partial
            else if (states.contains(STATE.PARTIAL)) {
                state = STATE.PARTIAL;
            }
            // otherwise we have an executable state
            else {
                return STATE.EXECUTABLE;
            }
        }
        if (output != null) {
            output.writeLine(data + node.toString() + '[' + states + (containsIgnorable ? ",IGNORABLE" : "") + "] -> " + state);
        }
        return state;
    }

Replace Generic With Diamond HashSet<STATE> with HashSet<> in method protected allOrSome(node JexlNode, data Object) : STATE from class datawave.query.jexl.visitors.ExecutableDeterminationVisitor


    /**
     * executableUnlessItIsnt means that none of the nodes may be non-executable or error for this to be executable. Introduced to catch NULL literals in a
     * disjuction
     */
    protected STATE executableUnlessItIsnt(JexlNode node, Object data) {
        STATE state;
        boolean containsIgnorable = false;
        Set<STATE> states = new HashSet<>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            states.add((STATE) (node.jjtGetChild(i).jjtAccept(this, data + PREFIX)));
        }
        // else remove the ignorable state
        containsIgnorable = states.remove(STATE.IGNORABLE);
        // if now only one state, then that is the state
        if (states.size() == 1) {
            state = states.iterator().next();
        }
        // if we contain an error state, the error
        else if (states.contains(STATE.ERROR)) {
            state = STATE.ERROR;
        } else if (states.contains(STATE.NON_EXECUTABLE)) {
            state = STATE.NON_EXECUTABLE;
        }
        // if we have a partial state, then partial
        else if (states.contains(STATE.PARTIAL)) {
            state = STATE.PARTIAL;
        }
        // otherwise we have an executable state
        else {
            return STATE.EXECUTABLE;
        }
        if (output != null) {
            output.writeLine(data + node.toString() + '[' + states + (containsIgnorable ? ",IGNORABLE" : "") + "] -> " + state);
        }
        return state;
    }

    /**
     * executableUnlessItIsnt means that none of the nodes may be non-executable or error for this to be executable. Introduced to catch NULL literals in a
     * disjuction
     */
    protected STATE executableUnlessItIsnt(JexlNode node, Object data) {
        STATE state;
        boolean containsIgnorable = false;
        Set<STATE> states = new HashSet<STATE>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            states.add((STATE) (node.jjtGetChild(i).jjtAccept(this, data + PREFIX)));
        }
        // else remove the ignorable state
        containsIgnorable = states.remove(STATE.IGNORABLE);
        // if now only one state, then that is the state
        if (states.size() == 1) {
            state = states.iterator().next();
        }
        // if we contain an error state, the error
        else if (states.contains(STATE.ERROR)) {
            state = STATE.ERROR;
        } else if (states.contains(STATE.NON_EXECUTABLE)) {
            state = STATE.NON_EXECUTABLE;
        }
        // if we have a partial state, then partial
        else if (states.contains(STATE.PARTIAL)) {
            state = STATE.PARTIAL;
        }
        // otherwise we have an executable state
        else {
            return STATE.EXECUTABLE;
        }
        if (output != null) {
            output.writeLine(data + node.toString() + '[' + states + (containsIgnorable ? ",IGNORABLE" : "") + "] -> " + state);
        }
        return state;
    }

Replace Generic With Diamond HashSet<STATE> with HashSet<> in method protected executableUnlessItIsnt(node JexlNode, data Object) : STATE from class datawave.query.jexl.visitors.ExecutableDeterminationVisitor


    @SuppressWarnings("unchecked")
    public static Set<String> getNonExistentFields(MetadataHelper helper, ASTJexlScript script, Set<String> datatypes, Set<String> specialFields) {
        FieldMissingFromSchemaVisitor visitor = new FieldMissingFromSchemaVisitor(helper, datatypes, specialFields);
        return (Set<String>) script.jjtAccept(visitor, new HashSet<>());
    }

    @SuppressWarnings("unchecked")
    public static Set<String> getNonExistentFields(MetadataHelper helper, ASTJexlScript script, Set<String> datatypes, Set<String> specialFields) {
        FieldMissingFromSchemaVisitor visitor = new FieldMissingFromSchemaVisitor(helper, datatypes, specialFields);
        return (Set<String>) script.jjtAccept(visitor, new HashSet<String>());
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public getNonExistentFields(helper MetadataHelper, script ASTJexlScript, datatypes Set<String>, specialFields Set<String>) : Set<String> from class datawave.query.jexl.visitors.FieldMissingFromSchemaVisitor


    /**
     *
     * @param node
     *            Jexl node
     * @param data
     *            The set of names which we have determined do not exist
     * @return the updated set of names which do not exist
     */
    protected Object genericVisit(JexlNode node, Object data) {
        @SuppressWarnings("unchecked")
        Set<String> nonExistentFieldNames = (null == data) ? new HashSet<>() : (Set<String>) data;
        List<ASTIdentifier> identifiers;

        // A node could be literal == literal in terms of an identityQuery
        try {
            identifiers = JexlASTHelper.getIdentifiers(node);
        } catch (NoSuchElementException e) {
            return nonExistentFieldNames;
        }

        if (identifiers.size() == 0) {
            // Catch cases where we have two literals
            // essentially everything but identifier op literal
            return nonExistentFieldNames;
        }

        for (ASTIdentifier identifier : identifiers) {
            String fieldName = JexlASTHelper.deconstructIdentifier(identifier);
            if (!this.allFieldsForDatatypes.contains(fieldName) && !specialFields.contains(fieldName)) {
                nonExistentFieldNames.add(fieldName);
            }
        }
        return nonExistentFieldNames;
    }

    /**
     *
     * @param node
     *            Jexl node
     * @param data
     *            The set of names which we have determined do not exist
     * @return the updated set of names which do not exist
     */
    protected Object genericVisit(JexlNode node, Object data) {
        @SuppressWarnings("unchecked")
        Set<String> nonExistentFieldNames = (null == data) ? new HashSet<String>() : (Set<String>) data;
        List<ASTIdentifier> identifiers;

        // A node could be literal == literal in terms of an identityQuery
        try {
            identifiers = JexlASTHelper.getIdentifiers(node);
        } catch (NoSuchElementException e) {
            return nonExistentFieldNames;
        }

        if (identifiers.size() == 0) {
            // Catch cases where we have two literals
            // essentially everything but identifier op literal
            return nonExistentFieldNames;
        }

        for (ASTIdentifier identifier : identifiers) {
            String fieldName = JexlASTHelper.deconstructIdentifier(identifier);
            if (!this.allFieldsForDatatypes.contains(fieldName) && !specialFields.contains(fieldName)) {
                nonExistentFieldNames.add(fieldName);
            }
        }
        return nonExistentFieldNames;
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method protected genericVisit(node JexlNode, data Object) : Object from class datawave.query.jexl.visitors.FieldMissingFromSchemaVisitor


    @Override
    public Object visit(ASTFunctionNode node, Object data) {
        JexlArgumentDescriptor desc = JexlFunctionArgumentDescriptorFactory.F.getArgumentDescriptor(node);
        @SuppressWarnings("unchecked")
        Set<String> nonExistentFieldNames = (null == data) ? new HashSet<>() : (Set<String>) data;

        for (String fieldName : desc.fields(this.helper, this.datatypeFilter)) {
            // deconstruct the identifier
            final String testFieldName = JexlASTHelper.deconstructIdentifier(fieldName);
            // changed to allow _ANYFIELD_ in functions
            if (!this.allFieldsForDatatypes.contains(testFieldName) && !specialFields.contains(fieldName)) {
                nonExistentFieldNames.add(testFieldName);
            }
        }

        return nonExistentFieldNames;
    }

    @Override
    public Object visit(ASTFunctionNode node, Object data) {
        JexlArgumentDescriptor desc = JexlFunctionArgumentDescriptorFactory.F.getArgumentDescriptor(node);
        @SuppressWarnings("unchecked")
        Set<String> nonExistentFieldNames = (null == data) ? new HashSet<String>() : (Set<String>) data;

        for (String fieldName : desc.fields(this.helper, this.datatypeFilter)) {
            // deconstruct the identifier
            final String testFieldName = JexlASTHelper.deconstructIdentifier(fieldName);
            // changed to allow _ANYFIELD_ in functions
            if (!this.allFieldsForDatatypes.contains(testFieldName) && !specialFields.contains(fieldName)) {
                nonExistentFieldNames.add(testFieldName);
            }
        }

        return nonExistentFieldNames;
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public visit(node ASTFunctionNode, data Object) : Object from class datawave.query.jexl.visitors.FieldMissingFromSchemaVisitor