    /**
     * Returns a Tuple2<Iterable<Range>,Boolean> whose elements represent the Ranges to use for querying the shard table and whether or not this is
     * a "full-table-scan" query.
     *
     * @param scannerFactory
     * @param metadataHelper
     * @param config
     * @param queryTree
     * @return
     * @throws DatawaveQueryException
     */
    public Tuple2<CloseableIterable<QueryPlan>,Boolean> getQueryRanges(ScannerFactory scannerFactory, MetadataHelper metadataHelper,
                    ShardQueryConfiguration config, JexlNode queryTree) throws DatawaveQueryException {
        Preconditions.checkNotNull(queryTree);

        boolean needsFullTable = false;
        CloseableIterable<QueryPlan> ranges = null;

        // if we still have an unexecutable tree, then a full table scan is
        // required
        List<String> debugOutput = null;
        if (log.isDebugEnabled()) {
            debugOutput = new ArrayList<>(32);
        }
        STATE state = ExecutableDeterminationVisitor.getState(queryTree, config, metadataHelper, debugOutput);
        if (log.isDebugEnabled()) {
            logDebug(debugOutput, "ExecutableDeterminationVisitor at getQueryRanges:");
        }
        if (state != STATE.EXECUTABLE) {
            if (state == STATE.ERROR) {
                log.warn("After expanding the query, it is determined that the query cannot be executed due to index-only fields mixed with expressions that cannot be run against the index.");
                BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.INDEX_ONLY_FIELDS_MIXED_INVALID_EXPRESSIONS);
                throw new InvalidQueryException(qe);
            }
            log.warn("After expanding the query, it is determined that the query cannot be executed against the field index and a full table scan is required");
            needsFullTable = true;
        }

        // if a simple examination of the query has not forced a full table
        // scan, then lets try to compute ranges
        if (!needsFullTable) {

            // count the terms
            int termCount = TermCountingVisitor.countTerms(queryTree);
            if (termCount >= pushdownThreshold) {
                if (log.isTraceEnabled()) {
                    log.trace("pushing down query because it has " + termCount + " when our max is " + pushdownThreshold);
                }
                config.setCollapseUids(true);
            }
            TraceStopwatch stopwatch = config.getTimers().newStartedStopwatch("DefaultQueryPlanner - Begin stream of ranges from inverted index");

            RangeStream stream = initializeRangeStream(config, scannerFactory, metadataHelper);

            stream.setCondenseUids(condenseUidsInRangeStream);

            stream.setCompressUids(compressUidsInRangeStream);

            ranges = stream.streamPlans(queryTree);

            if (log.isTraceEnabled()) {
                log.trace("query stream is " + stream.context());
            }

            // if a term threshold is exceeded and we cannot handle that, then
            // throw unsupported
            boolean thresholdExceeded = StreamContext.EXCEEDED_TERM_THRESHOLD.equals(stream.context());
            if (thresholdExceeded && !config.canHandleExceededTermThreshold()) {
                throw new UnsupportedOperationException(EXCEED_TERM_EXPANSION_ERROR);
            }

            if (StreamContext.UNINDEXED.equals(stream.context())) {
                log.debug("Needs full table scan because of unindexed fields");
                needsFullTable = true;
            } else if (StreamContext.DELAYED_FIELD.equals(stream.context())) {
                log.debug("Needs full table scan because query consists of only delayed expressions");
                needsFullTable = true;
            }
            // if a value threshold is exceeded and we cannot handle that, then
            // force a full table scan
            else if (StreamContext.EXCEEDED_VALUE_THRESHOLD.equals(stream.context()) && !config.canHandleExceededValueThreshold()) {
                log.debug("Needs full table scan because we exceeded the value threshold and config.canHandleExceededValueThreshold() is false");
                needsFullTable = true;
            }

            stopwatch.stop();
        }
        if (needsFullTable) {
            if (config.getFullTableScanEnabled()) {
                ranges = this.getFullScanRange(config, queryTree);
            } else {
                if (log.isTraceEnabled())
                    log.trace("Full table scans are not enabled, query will not be run");
                QueryException qe = new QueryException(DatawaveErrorCode.FULL_TABLE_SCAN_REQUIRED_BUT_DISABLED);
                throw new FullTableScansDisallowedException(qe);
            }
            if (log.isTraceEnabled())
                log.trace("Ranges are " + ranges);
        }

        return new Tuple2<>(ranges, needsFullTable);
    }

    /**
     * Returns a Tuple2<Iterable<Range>,Boolean> whose elements represent the Ranges to use for querying the shard table and whether or not this is
     * a "full-table-scan" query.
     *
     * @param scannerFactory
     * @param metadataHelper
     * @param config
     * @param queryTree
     * @return
     * @throws DatawaveQueryException
     */
    public Tuple2<CloseableIterable<QueryPlan>,Boolean> getQueryRanges(ScannerFactory scannerFactory, MetadataHelper metadataHelper,
                    ShardQueryConfiguration config, JexlNode queryTree) throws DatawaveQueryException {
        Preconditions.checkNotNull(queryTree);

        boolean needsFullTable = false;
        CloseableIterable<QueryPlan> ranges = null;

        // if we still have an unexecutable tree, then a full table scan is
        // required
        List<String> debugOutput = null;
        if (log.isDebugEnabled()) {
            debugOutput = new ArrayList<>(32);
        }
        STATE state = ExecutableDeterminationVisitor.getState(queryTree, config, metadataHelper, debugOutput);
        if (log.isDebugEnabled()) {
            logDebug(debugOutput, "ExecutableDeterminationVisitor at getQueryRanges:");
        }
        if (state != STATE.EXECUTABLE) {
            if (state == STATE.ERROR) {
                log.warn("After expanding the query, it is determined that the query cannot be executed due to index-only fields mixed with expressions that cannot be run against the index.");
                BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.INDEX_ONLY_FIELDS_MIXED_INVALID_EXPRESSIONS);
                throw new InvalidQueryException(qe);
            }
            log.warn("After expanding the query, it is determined that the query cannot be executed against the field index and a full table scan is required");
            needsFullTable = true;
        }

        // if a simple examination of the query has not forced a full table
        // scan, then lets try to compute ranges
        if (!needsFullTable) {

            // count the terms
            int termCount = TermCountingVisitor.countTerms(queryTree);
            if (termCount >= pushdownThreshold) {
                if (log.isTraceEnabled()) {
                    log.trace("pushing down query because it has " + termCount + " when our max is " + pushdownThreshold);
                }
                config.setCollapseUids(true);
            }
            TraceStopwatch stopwatch = config.getTimers().newStartedStopwatch("DefaultQueryPlanner - Begin stream of ranges from inverted index");

            RangeStream stream = initializeRangeStream(config, scannerFactory, metadataHelper);

            stream.setCondenseUids(condenseUidsInRangeStream);

            stream.setCompressUids(compressUidsInRangeStream);

            ranges = stream.streamPlans(queryTree);

            if (log.isTraceEnabled()) {
                log.trace("query stream is " + stream.context());
            }

            // if a term threshold is exceeded and we cannot handle that, then
            // throw unsupported
            boolean thresholdExceeded = StreamContext.EXCEEDED_TERM_THRESHOLD.equals(stream.context());
            if (thresholdExceeded && !config.canHandleExceededTermThreshold()) {
                throw new UnsupportedOperationException(EXCEED_TERM_EXPANSION_ERROR);
            }

            if (StreamContext.UNINDEXED.equals(stream.context())) {
                log.debug("Needs full table scan because of unindexed fields");
                needsFullTable = true;
            } else if (StreamContext.DELAYED_FIELD.equals(stream.context())) {
                log.debug("Needs full table scan because query consists of only delayed expressions");
                needsFullTable = true;
            }
            // if a value threshold is exceeded and we cannot handle that, then
            // force a full table scan
            else if (StreamContext.EXCEEDED_VALUE_THRESHOLD.equals(stream.context()) && !config.canHandleExceededValueThreshold()) {
                log.debug("Needs full table scan because we exceeded the value threshold and config.canHandleExceededValueThreshold() is false");
                needsFullTable = true;
            }

            stopwatch.stop();
        }
        if (needsFullTable) {
            if (config.getFullTableScanEnabled()) {
                ranges = this.getFullScanRange(config, queryTree);
            } else {
                if (log.isTraceEnabled())
                    log.trace("Full table scans are not enabled, query will not be run");
                QueryException qe = new QueryException(DatawaveErrorCode.FULL_TABLE_SCAN_REQUIRED_BUT_DISABLED);
                throw new FullTableScansDisallowedException(qe);
            }
            if (log.isTraceEnabled())
                log.trace("Ranges are " + ranges);
        }

        return new Tuple2<CloseableIterable<QueryPlan>,Boolean>(ranges, needsFullTable);
    }

Replace Generic With Diamond Tuple2<CloseableIterable<QueryPlan>,Boolean> with Tuple2<> in method public getQueryRanges(scannerFactory ScannerFactory, metadataHelper MetadataHelper, config ShardQueryConfiguration, queryTree JexlNode) : Tuple2<CloseableIterable<QueryPlan>,Boolean> from class datawave.query.planner.DefaultQueryPlanner


    public UniqueTransform(Set<String> fields) {
        this.fields = fields;
        this.bloom = BloomFilter.create(new ByteFunnel(), 500000, 1e-15);
        if (DEBUG) {
            this.seen = new HashSet<>();
        }
        if (log.isTraceEnabled())
            log.trace("unique fields: " + this.fields);
    }

    public UniqueTransform(Set<String> fields) {
        this.fields = fields;
        this.bloom = BloomFilter.create(new ByteFunnel(), 500000, 1e-15);
        if (DEBUG) {
            this.seen = new HashSet<ByteSequence>();
        }
        if (log.isTraceEnabled())
            log.trace("unique fields: " + this.fields);
    }

Replace Generic With Diamond HashSet<ByteSequence> with HashSet<> in method public UniqueTransform(fields Set<String>) from class datawave.query.transformer.UniqueTransform


    @Test(expected = IllegalArgumentException.class)
    public void testInvalidEnum() {
        // this should throw because BAD_BASE doesn't contain a 0 index
        new ProtostuffField<>(BAD_BASE.class);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testInvalidEnum() {
        // this should throw because BAD_BASE doesn't contain a 0 index
        ProtostuffField<BAD_BASE> ERROR_OUT = new ProtostuffField<BAD_BASE>(BAD_BASE.class);
    }

Replace Generic With Diamond ProtostuffField<BAD_BASE> with ProtostuffField<> in method public testInvalidEnum() : void from class datawave.webservice.query.result.util.protostuff.ProtostuffFieldTest


    public void addMessage(String message) {
        if (this.messages == null) {
            this.messages = new ArrayList<>();
        }
        this.messages.add(message);
    }

    public void addMessage(String message) {
        if (this.messages == null) {
            this.messages = new ArrayList<String>();
        }
        this.messages.add(message);
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public addMessage(message String) : void from class datawave.webservice.result.BaseResponse


        public GenericResponse<T> newMessage() {
            return new GenericResponse<>();
        }

        public GenericResponse<T> newMessage() {
            return new GenericResponse<T>();
        }

Replace Generic With Diamond GenericResponse<T> with GenericResponse<> in method public newMessage() : GenericResponse<T> from class datawave.webservice.result.GenericResponse.GenericResponseSchema


        @SuppressWarnings("unchecked")
        public void mergeFrom(Input input, GenericResponse<T> message) throws IOException {
            LinkedList<QueryExceptionType> exceptions = null;
            int number;
            while ((number = input.readFieldNumber(this)) != 0) {
                switch (number) {
                    case 1:
                        message.setOperationTimeMS(input.readUInt64());
                        break;
                    case 2:
                        message.addMessage(input.readString());
                        break;
                    case 3:
                        if (exceptions == null)
                            exceptions = new LinkedList<>();
                        exceptions.add(input.mergeObject(null, QueryExceptionType.getSchema()));
                        break;
                    case 4:
                        // ignore
                        break;
                    case 5:
                        message.result = (T) input.readString();
                        break;
                    case 6:
                        message.result = (T) Boolean.valueOf(input.readBool());
                        break;
                    case 7:
                        message.result = (T) Integer.valueOf(input.readSInt32());
                        break;
                    case 8:
                        message.result = (T) Long.valueOf(input.readSInt64());
                        break;
                    case 9:
                        message.result = (T) Float.valueOf(input.readFloat());
                        break;
                    case 10:
                        message.result = (T) Double.valueOf(input.readDouble());
                        break;
                    case 11:
                        message.result = (T) input.readByteArray();
                        break;

                    default:
                        input.handleUnknownField(number, this);
                        break;
                }
            }
            if (exceptions != null)
                message.setExceptions(exceptions);
        }

        @SuppressWarnings("unchecked")
        public void mergeFrom(Input input, GenericResponse<T> message) throws IOException {
            LinkedList<QueryExceptionType> exceptions = null;
            int number;
            while ((number = input.readFieldNumber(this)) != 0) {
                switch (number) {
                    case 1:
                        message.setOperationTimeMS(input.readUInt64());
                        break;
                    case 2:
                        message.addMessage(input.readString());
                        break;
                    case 3:
                        if (exceptions == null)
                            exceptions = new LinkedList<QueryExceptionType>();
                        exceptions.add(input.mergeObject(null, QueryExceptionType.getSchema()));
                        break;
                    case 4:
                        // ignore
                        break;
                    case 5:
                        message.result = (T) input.readString();
                        break;
                    case 6:
                        message.result = (T) Boolean.valueOf(input.readBool());
                        break;
                    case 7:
                        message.result = (T) Integer.valueOf(input.readSInt32());
                        break;
                    case 8:
                        message.result = (T) Long.valueOf(input.readSInt64());
                        break;
                    case 9:
                        message.result = (T) Float.valueOf(input.readFloat());
                        break;
                    case 10:
                        message.result = (T) Double.valueOf(input.readDouble());
                        break;
                    case 11:
                        message.result = (T) input.readByteArray();
                        break;

                    default:
                        input.handleUnknownField(number, this);
                        break;
                }
            }
            if (exceptions != null)
                message.setExceptions(exceptions);
        }

Replace Generic With Diamond LinkedList<QueryExceptionType> with LinkedList<> in method public mergeFrom(input Input, message GenericResponse<T>) : void from class datawave.webservice.result.GenericResponse.GenericResponseSchema


    /**
     * Get a predicate that will apply this transform.
     *
     * @return A unique transform predicate
     */
    public Predicate<Entry<Key,Document>> getUniquePredicate() {
        return input -> UniqueTransform.this.apply(input) != null;
    }

    /**
     * Get a predicate that will apply this transform.
     *
     * @return A unique transform predicate
     */
    public Predicate<Entry<Key,Document>> getUniquePredicate() {
        return new Predicate<Entry<Key,Document>>() {
            @Override
            public boolean apply(@Nullable Entry<Key,Document> input) {
                return UniqueTransform.this.apply(input) != null;
            }
        };
    }

Replace Anonymous With Lambda datawave.query.transformer.UniqueTransform.getUniquePredicate.new Predicate<Entry<Key,Document>> with input -> UniqueTransform.this.apply(input) != null in method public getUniquePredicate() : Predicate<Entry<Key,Document>> from class datawave.query.transformer.UniqueTransform


    @Test
    public void testUniqueness() {
        Random random = new Random(2000);
        List<Document> input = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            input.add(createDocument(random, false));
        }

        // choose three fields such that the number of unique document is less than half the number of documents but greater than 10
        Set<String> fields = new HashSet<>();
        int expected = input.size();
        while (expected > input.size() / 2 || expected < 10) {
            fields.clear();
            while (fields.size() < 3) {
                fields.add("Attr" + random.nextInt(100));
            }
            expected = countUniqueness(input, fields);
        }

        Transformer docToEntry = input1 -> {
            Document d = (Document) input1;
            return Maps.immutableEntry(d.getMetadata(), d);
        };
        TransformIterator inputIterator = new TransformIterator(input.iterator(), docToEntry);
        UniqueTransform transform = new UniqueTransform(fields);
        Iterator iter = Iterators.transform(inputIterator, transform);

        List<Object> eventList = Lists.newArrayList();
        while (iter.hasNext()) {
            Object next = iter.next();
            if (next != null) {
                eventList.add(next);
            }
        }

        Assert.assertEquals(expected, eventList.size());
        Assert.assertNull(transform.apply(null));
    }

    @Test
    public void testUniqueness() {
        Random random = new Random(2000);
        List<Document> input = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            input.add(createDocument(random, false));
        }

        // choose three fields such that the number of unique document is less than half the number of documents but greater than 10
        Set<String> fields = new HashSet<>();
        int expected = input.size();
        while (expected > input.size() / 2 || expected < 10) {
            fields.clear();
            while (fields.size() < 3) {
                fields.add("Attr" + random.nextInt(100));
            }
            expected = countUniqueness(input, fields);
        }

        Transformer docToEntry = new Transformer() {
            @Override
            public Object transform(Object input) {
                Document d = (Document) input;
                return Maps.immutableEntry(d.getMetadata(), d);
            }
        };
        TransformIterator inputIterator = new TransformIterator(input.iterator(), docToEntry);
        UniqueTransform transform = new UniqueTransform(fields);
        Iterator iter = Iterators.transform(inputIterator, transform);

        List<Object> eventList = Lists.newArrayList();
        while (iter.hasNext()) {
            Object next = iter.next();
            if (next != null) {
                eventList.add(next);
            }
        }

        Assert.assertEquals(expected, eventList.size());
        Assert.assertNull(transform.apply(null));
    }

Replace Anonymous With Lambda datawave.query.transformer.UniqueTransformTest.testUniqueness.docToEntry.new Transformer with input1 -> {Document d=(Document)input1; in method public testUniqueness() : void from class datawave.query.transformer.UniqueTransformTest


    public <T> RequestEntity<T> createRequestEntity(ProxiedUserDetails currentUser, T body, MultiValueMap<String,String> additionalHeaders, HttpMethod method,
                    UriComponents uri) {
        String token = jwtTokenHandler.createTokenFromUsers(currentUser.getUsername(), currentUser.getProxiedUsers());
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);
        if (additionalHeaders != null) {
            additionalHeaders.forEach(headers::put);
        }
        return new RequestEntity<>(body, headers, method, uri.toUri());
    }

    public <T> RequestEntity<T> createRequestEntity(ProxiedUserDetails currentUser, T body, MultiValueMap<String,String> additionalHeaders, HttpMethod method,
                    UriComponents uri) {
        String token = jwtTokenHandler.createTokenFromUsers(currentUser.getUsername(), currentUser.getProxiedUsers());
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);
        if (additionalHeaders != null) {
            additionalHeaders.forEach(headers::put);
        }
        return new RequestEntity<T>(body, headers, method, uri.toUri());
    }

Replace Generic With Diamond RequestEntity<T> with RequestEntity<> in method public createRequestEntity(currentUser ProxiedUserDetails, body T, additionalHeaders MultiValueMap<String,String>, method HttpMethod, uri UriComponents) : RequestEntity<T> from class datawave.microservice.authorization.jwt.JWTRestTemplate


    /**
     * This is a helper method which will allow us to run all of our threads simultaneously, thus increasing the chance that we will encounter a concurrency
     * problem if there is one.
     *
     * All of the runnables that are passed in will block, and will not begin execution until the afterInitBlocker CountDownLatch has been activated. This
     * should ensure that all of the threads begin execution simultaneously.
     */
    public static void assertConcurrent(final String message, final List<? extends Runnable> runnables, final int maxTimeoutSeconds)
                    throws InterruptedException {
        final int numThreads = runnables.size();
        final List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<>());
        final ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
        try {
            final CountDownLatch allExecutorThreadsReady = new CountDownLatch(numThreads);
            final CountDownLatch afterInitBlocker = new CountDownLatch(1);
            final CountDownLatch allDone = new CountDownLatch(numThreads);
            for (final Runnable submittedTestRunnable : runnables) {
                threadPool.submit(() -> {
                    allExecutorThreadsReady.countDown();
                    try {
                        afterInitBlocker.await();
                        submittedTestRunnable.run();
                    } catch (final Throwable e) {
                        exceptions.add(e);
                    } finally {
                        allDone.countDown();
                    }
                });
            }
            // wait until all threads are ready
            assertTrue("Timeout initializing threads! Perform long lasting initializations before passing runnables to assertConcurrent",
                            allExecutorThreadsReady.await(runnables.size() * 10, TimeUnit.MILLISECONDS));
            // start all test runners
            afterInitBlocker.countDown();
            assertTrue(message + " timeout! More than" + maxTimeoutSeconds + "seconds", allDone.await(maxTimeoutSeconds, TimeUnit.SECONDS));
        } finally {
            threadPool.shutdownNow();
        }
        assertTrue(message + " failed with exception(s)" + exceptions, exceptions.isEmpty());
    }

    /**
     * This is a helper method which will allow us to run all of our threads simultaneously, thus increasing the chance that we will encounter a concurrency
     * problem if there is one.
     *
     * All of the runnables that are passed in will block, and will not begin execution until the afterInitBlocker CountDownLatch has been activated. This
     * should ensure that all of the threads begin execution simultaneously.
     */
    public static void assertConcurrent(final String message, final List<? extends Runnable> runnables, final int maxTimeoutSeconds)
                    throws InterruptedException {
        final int numThreads = runnables.size();
        final List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<Throwable>());
        final ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
        try {
            final CountDownLatch allExecutorThreadsReady = new CountDownLatch(numThreads);
            final CountDownLatch afterInitBlocker = new CountDownLatch(1);
            final CountDownLatch allDone = new CountDownLatch(numThreads);
            for (final Runnable submittedTestRunnable : runnables) {
                threadPool.submit(() -> {
                    allExecutorThreadsReady.countDown();
                    try {
                        afterInitBlocker.await();
                        submittedTestRunnable.run();
                    } catch (final Throwable e) {
                        exceptions.add(e);
                    } finally {
                        allDone.countDown();
                    }
                });
            }
            // wait until all threads are ready
            assertTrue("Timeout initializing threads! Perform long lasting initializations before passing runnables to assertConcurrent",
                            allExecutorThreadsReady.await(runnables.size() * 10, TimeUnit.MILLISECONDS));
            // start all test runners
            afterInitBlocker.countDown();
            assertTrue(message + " timeout! More than" + maxTimeoutSeconds + "seconds", allDone.await(maxTimeoutSeconds, TimeUnit.SECONDS));
        } finally {
            threadPool.shutdownNow();
        }
        assertTrue(message + " failed with exception(s)" + exceptions, exceptions.isEmpty());
    }

Replace Generic With Diamond ArrayList<Throwable> with ArrayList<> in method public assertConcurrent(message String, runnables List<? extends Runnable>, maxTimeoutSeconds int) : void from class datawave.common.util.concurrent.BoundedBlockingQueueTest


    private long getLongProperty(final String prop, final long defaultValue) {
        if (this.myEnv != null && this.myEnv.getConfig() != null) {
            AccumuloConfiguration conf = this.myEnv.getConfig();
            Map<String,String> properties = new TreeMap<>();
            conf.getProperties(properties, new AccumuloConfiguration.MatchFilter(prop));
            if (properties.containsKey(prop)) {
                return Long.parseLong(properties.get(prop));
            }
        }
        return defaultValue;
    }

    private long getLongProperty(final String prop, final long defaultValue) {
        if (this.myEnv != null && this.myEnv.getConfig() != null) {
            AccumuloConfiguration conf = this.myEnv.getConfig();
            Map<String,String> properties = new TreeMap<String,String>();
            conf.getProperties(properties, new AccumuloConfiguration.MatchFilter(prop));
            if (properties.containsKey(prop)) {
                return Long.parseLong(properties.get(prop));
            }
        }
        return defaultValue;
    }

Replace Generic With Diamond TreeMap<String,String> with TreeMap<> in method private getLongProperty(prop String, defaultValue long) : long from class datawave.iterators.filter.ConfigurableAgeOffFilter


        Builder(MERGE_MODE mergeMode) {
            transitionMaps.add(new HashMap<>());
            stateTtlList.add(null);
            statePriorityList.add(null);
            this.isMerge = mergeMode.equals(MERGE_MODE.ON);
        }

        Builder(MERGE_MODE mergeMode) {
            transitionMaps.add(new HashMap<Byte,Integer>());
            stateTtlList.add(null);
            statePriorityList.add(null);
            this.isMerge = mergeMode.equals(MERGE_MODE.ON);
        }

Replace Generic With Diamond HashMap<Byte,Integer> with HashMap<> in method package Builder(mergeMode MERGE_MODE) from class datawave.iterators.filter.TokenTtlTrie.Builder


        /**
         * Add a token to the TtlTrie under construction, along with the TTL value the specified token should be associated with.
         */
        @Override
        public Builder addToken(byte[] token, long ttl) {
            int curState = 0;
            for (byte b : token) {
                Map<Byte,Integer> transMap = transitionMaps.get(curState);
                if (transMap.containsKey(b)) {
                    curState = transMap.get(b);
                } else {
                    curState = transitionMaps.size();
                    transitionMaps.add(new HashMap<>());
                    stateTtlList.add(null);
                    statePriorityList.add(null);
                    transMap.put(b, curState);
                }
            }
            int myPriority = ++entryCount;
            // if this is a merge of two configs, override ttl with latest seen
            if (stateTtlList.get(curState) == null) {
                stateTtlList.set(curState, ttl);
                statePriorityList.set(curState, myPriority);
            } else if (isMerge) {
                // maintain original priority just update the ttl
                stateTtlList.set(curState, ttl);
            } else {
                throw new IllegalArgumentException(String.format("Token '%s'(#%d) already specified at index %d", new String(token),
                                statePriorityList.get(curState), myPriority));
            }
            return this;
        }

        /**
         * Add a token to the TtlTrie under construction, along with the TTL value the specified token should be associated with.
         */
        @Override
        public Builder addToken(byte[] token, long ttl) {
            int curState = 0;
            for (byte b : token) {
                Map<Byte,Integer> transMap = transitionMaps.get(curState);
                if (transMap.containsKey(b)) {
                    curState = transMap.get(b);
                } else {
                    curState = transitionMaps.size();
                    transitionMaps.add(new HashMap<Byte,Integer>());
                    stateTtlList.add(null);
                    statePriorityList.add(null);
                    transMap.put(b, curState);
                }
            }
            int myPriority = ++entryCount;
            // if this is a merge of two configs, override ttl with latest seen
            if (stateTtlList.get(curState) == null) {
                stateTtlList.set(curState, ttl);
                statePriorityList.set(curState, myPriority);
            } else if (isMerge) {
                // maintain original priority just update the ttl
                stateTtlList.set(curState, ttl);
            } else {
                throw new IllegalArgumentException(String.format("Token '%s'(#%d) already specified at index %d", new String(token),
                                statePriorityList.get(curState), myPriority));
            }
            return this;
        }

Replace Generic With Diamond HashMap<Byte,Integer> with HashMap<> in method public addToken(token byte[], ttl long) : Builder from class datawave.iterators.filter.TokenTtlTrie.Builder


    static public ColumnVisibility simplifyColumnVisibilityForAuthorizations(ColumnVisibility columnVisibility, Collection<Authorizations> authorizations)
                    throws MarkingFunctions.Exception {

        ColumnVisibility simplifiedCV = columnVisibility;

        Node node = columnVisibility.getParseTree();
        if (node.getType() == NodeType.OR) {
            if (log.isTraceEnabled()) {
                log.trace("Top level OR Node, removing unsatisfied branches from: " + columnVisibility.toString());
            }
            byte[] expression = columnVisibility.getExpression();
            if (authorizations != null) {
                HashSet<VisibilityEvaluator> ve = new HashSet<>();
                for (Authorizations a : authorizations)
                    ve.add(new VisibilityEvaluator(a));
                removeUnsatisfiedTopLevelOrNodes(ve, expression, node);
            }

            simplifiedCV = ColumnVisibilityHelper.flatten(node, expression);
            if (log.isTraceEnabled()) {
                log.trace("removed unsatisfied branches, visibility now: " + simplifiedCV.toString());
            }
        }
        return simplifiedCV;
    }

    static public ColumnVisibility simplifyColumnVisibilityForAuthorizations(ColumnVisibility columnVisibility, Collection<Authorizations> authorizations)
                    throws MarkingFunctions.Exception {

        ColumnVisibility simplifiedCV = columnVisibility;

        Node node = columnVisibility.getParseTree();
        if (node.getType() == NodeType.OR) {
            if (log.isTraceEnabled()) {
                log.trace("Top level OR Node, removing unsatisfied branches from: " + columnVisibility.toString());
            }
            byte[] expression = columnVisibility.getExpression();
            if (authorizations != null) {
                HashSet<VisibilityEvaluator> ve = new HashSet<VisibilityEvaluator>();
                for (Authorizations a : authorizations)
                    ve.add(new VisibilityEvaluator(a));
                removeUnsatisfiedTopLevelOrNodes(ve, expression, node);
            }

            simplifiedCV = ColumnVisibilityHelper.flatten(node, expression);
            if (log.isTraceEnabled()) {
                log.trace("removed unsatisfied branches, visibility now: " + simplifiedCV.toString());
            }
        }
        return simplifiedCV;
    }

Replace Generic With Diamond HashSet<VisibilityEvaluator> with HashSet<> in method public simplifyColumnVisibilityForAuthorizations(columnVisibility ColumnVisibility, authorizations Collection<Authorizations>) : ColumnVisibility from class datawave.marking.ColumnVisibilityHelper


    private void updateLeadingLiteralAndWildCard() {
        leadingLiteral = null;
        hasWildCard = false;

        // a stack of literal builders used for nested capturing groups. If empty then we are at the top level.
        LinkedList<StringBuilder> literalBuilders = new LinkedList<>();
        // the current literal builder
        StringBuilder literalBuilder = new StringBuilder();
        // appendLiteral is set false once we have found a regex and we need to terminate with what we have
        boolean appendLiteral = true;

        for (int i = 0; i < regexParts.length; i++) {
            RegexPart part = regexParts[i];

            // if we are done and we have already resolved all nestings, then we are done
            if (!appendLiteral && literalBuilders.isEmpty()) {
                break;
            }

            // simply ignore nonCapturing portions
            if (part.nonCapturing) {
                continue;
            }

            // if a literal then append to the current builder
            if (part.type.isLiteral()) {
                if (appendLiteral && atLeastOnce(i)) {
                    if (part.type == RegexType.ESCAPED_LITERAL) {
                        literalBuilder.append(part.regex.substring(1));
                    } else {
                        literalBuilder.append(part.regex);
                    }
                }
            }
            // if a capturing group, the push the literal builders
            else if (part.regex.equals("(")) {
                literalBuilders.addLast(literalBuilder);
                literalBuilder = new StringBuilder();
            }
            // if ending a capturing group, then pop the literal builders, appending as appropriate
            else if (part.regex.equals(")")) {
                if (atLeastOnce(i)) {
                    literalBuilders.getLast().append(literalBuilder.toString());
                }
                literalBuilder = literalBuilders.removeLast();
            } else {
                // if a logical OR, then empty the literal we are working on
                if (part.regex.equals("|")) {
                    literalBuilder.setLength(0);
                }

                // we are now done appending literals as we have found a non-literal
                appendLiteral = false;

                // we can set the hasWildCard to true now
                hasWildCard = true;
            }
        }
        if (literalBuilder.length() > 0) {
            leadingLiteral = literalBuilder.toString();
        }
    }

    private void updateLeadingLiteralAndWildCard() {
        leadingLiteral = null;
        hasWildCard = false;

        // a stack of literal builders used for nested capturing groups. If empty then we are at the top level.
        LinkedList<StringBuilder> literalBuilders = new LinkedList<StringBuilder>();
        // the current literal builder
        StringBuilder literalBuilder = new StringBuilder();
        // appendLiteral is set false once we have found a regex and we need to terminate with what we have
        boolean appendLiteral = true;

        for (int i = 0; i < regexParts.length; i++) {
            RegexPart part = regexParts[i];

            // if we are done and we have already resolved all nestings, then we are done
            if (!appendLiteral && literalBuilders.isEmpty()) {
                break;
            }

            // simply ignore nonCapturing portions
            if (part.nonCapturing) {
                continue;
            }

            // if a literal then append to the current builder
            if (part.type.isLiteral()) {
                if (appendLiteral && atLeastOnce(i)) {
                    if (part.type == RegexType.ESCAPED_LITERAL) {
                        literalBuilder.append(part.regex.substring(1));
                    } else {
                        literalBuilder.append(part.regex);
                    }
                }
            }
            // if a capturing group, the push the literal builders
            else if (part.regex.equals("(")) {
                literalBuilders.addLast(literalBuilder);
                literalBuilder = new StringBuilder();
            }
            // if ending a capturing group, then pop the literal builders, appending as appropriate
            else if (part.regex.equals(")")) {
                if (atLeastOnce(i)) {
                    literalBuilders.getLast().append(literalBuilder.toString());
                }
                literalBuilder = literalBuilders.removeLast();
            } else {
                // if a logical OR, then empty the literal we are working on
                if (part.regex.equals("|")) {
                    literalBuilder.setLength(0);
                }

                // we are now done appending literals as we have found a non-literal
                appendLiteral = false;

                // we can set the hasWildCard to true now
                hasWildCard = true;
            }
        }
        if (literalBuilder.length() > 0) {
            leadingLiteral = literalBuilder.toString();
        }
    }

Replace Generic With Diamond LinkedList<StringBuilder> with LinkedList<> in method private updateLeadingLiteralAndWildCard() : void from class datawave.query.parser.JavaRegexAnalyzer


    private boolean allDigits(RegexPart[] tuple) {
        LinkedList<Boolean> negatedCharClass = new LinkedList<>();
        boolean negated = false;
        for (RegexPart part : tuple) {
            switch (part.type) {
                case LITERAL:
                    for (int i = 0; i < part.regex.length(); i++) {
                        if (negated == Character.isDigit(part.regex.charAt(i))) {
                            return false;
                        }
                    }
                    break;
                case ESCAPED_LITERAL:
                    if (negated == Character.isDigit(part.regex.charAt(1))) {
                        return false;
                    }
                    break;
                case REGEX:
                    if (part.regex.equals("[")) {
                        negatedCharClass.addLast(Boolean.valueOf(negated));
                    } else if (part.regex.equals("[^")) {
                        negatedCharClass.addLast(Boolean.valueOf(negated));
                        negated = !negated;
                    } else if (part.regex.equals("]")) {
                        negated = negatedCharClass.removeLast();
                    }
                    break;
                case ESCAPED_REGEX: {
                    if (part.regex.charAt(1) == 'p' || part.regex.charAt(1) == 'P') {
                        if (negated == DIGIT_CHARACTER_CLASSES.contains(part.regex)) {
                            return false;
                        }
                    } else if (negated == (NON_DIGIT_ESCAPED_REGEX_CHARS.indexOf(part.regex.charAt(1)) < 0)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private boolean allDigits(RegexPart[] tuple) {
        LinkedList<Boolean> negatedCharClass = new LinkedList<Boolean>();
        boolean negated = false;
        for (RegexPart part : tuple) {
            switch (part.type) {
                case LITERAL:
                    for (int i = 0; i < part.regex.length(); i++) {
                        if (negated == Character.isDigit(part.regex.charAt(i))) {
                            return false;
                        }
                    }
                    break;
                case ESCAPED_LITERAL:
                    if (negated == Character.isDigit(part.regex.charAt(1))) {
                        return false;
                    }
                    break;
                case REGEX:
                    if (part.regex.equals("[")) {
                        negatedCharClass.addLast(Boolean.valueOf(negated));
                    } else if (part.regex.equals("[^")) {
                        negatedCharClass.addLast(Boolean.valueOf(negated));
                        negated = !negated;
                    } else if (part.regex.equals("]")) {
                        negated = negatedCharClass.removeLast();
                    }
                    break;
                case ESCAPED_REGEX: {
                    if (part.regex.charAt(1) == 'p' || part.regex.charAt(1) == 'P') {
                        if (negated == DIGIT_CHARACTER_CLASSES.contains(part.regex)) {
                            return false;
                        }
                    } else if (negated == (NON_DIGIT_ESCAPED_REGEX_CHARS.indexOf(part.regex.charAt(1)) < 0)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

Replace Generic With Diamond LinkedList<Boolean> with LinkedList<> in method private allDigits(tuple RegexPart[]) : boolean from class datawave.query.parser.JavaRegexAnalyzer


    /**
     * Split up a list of parts using a specified separator. If a separator is found inside of a nested group, then that group and its ancestors begin and end
     * parentheses will be returned as separate parts. Separators are included as separate parts.
     *
     * @param character
     * @param escaped
     * @return the part lists
     * @throws JavaRegexParseException
     */
    public List<String> splitParts(char character, boolean escaped) throws JavaRegexParseException {
        // create the part
        RegexType type = (escaped ? RegexType.ESCAPED_LITERAL : RegexType.LITERAL);
        if (escaped && (ESCAPED_REGEX_CHARS.indexOf(character) >= 0)) {
            type = RegexType.ESCAPED_REGEX;
        } else if (!escaped && (RESERVED_CHARS.indexOf(character) >= 0)) {
            type = RegexType.REGEX;
        }
        List<RegexPart[]> parts = splitParts(this.regexParts, new RegexPart(Character.toString(character), type, false));
        List<String> regex = new ArrayList<>();
        for (RegexPart[] part : parts) {
            regex.add(getRegex(part));
        }
        return regex;
    }

    /**
     * Split up a list of parts using a specified separator. If a separator is found inside of a nested group, then that group and its ancestors begin and end
     * parentheses will be returned as separate parts. Separators are included as separate parts.
     *
     * @param character
     * @param escaped
     * @return the part lists
     * @throws JavaRegexParseException
     */
    public List<String> splitParts(char character, boolean escaped) throws JavaRegexParseException {
        // create the part
        RegexType type = (escaped ? RegexType.ESCAPED_LITERAL : RegexType.LITERAL);
        if (escaped && (ESCAPED_REGEX_CHARS.indexOf(character) >= 0)) {
            type = RegexType.ESCAPED_REGEX;
        } else if (!escaped && (RESERVED_CHARS.indexOf(character) >= 0)) {
            type = RegexType.REGEX;
        }
        List<RegexPart[]> parts = splitParts(this.regexParts, new RegexPart(Character.toString(character), type, false));
        List<String> regex = new ArrayList<String>();
        for (RegexPart[] part : parts) {
            regex.add(getRegex(part));
        }
        return regex;
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public splitParts(character char, escaped boolean) : List<String> from class datawave.query.parser.JavaRegexAnalyzer


    /**
     * Split up a list of parts using a specified separator. If a separator is found inside of a nested group, then that group and its ancestors begin and end
     * parentheses will be returned as separate parts as well as alternates. Separators are included as separate parts.
     *
     * @param parts
     * @param separator
     * @return the part lists
     * @throws JavaRegexParseException
     */
    private List<RegexPart[]> splitParts(RegexPart[] parts, RegexPart separator) throws JavaRegexParseException {
        LinkedList<RegexPart[]> tuples = new LinkedList<>();
        int start = 0;
        int level = 0;
        int separationLevel = 0;
        for (int i = 0; i < parts.length; i++) {
            if (parts[i].equals(OPEN_PAREN)) {
                level++;
            } else if (parts[i].equals(CLOSE_PAREN)) {
                if (level == 0) {
                    throw new JavaRegexParseException("Non matching groups", -1);
                }
                level--;
                if (level < separationLevel) {
                    if (start < i) {
                        tuples.addLast(Arrays.copyOfRange(parts, start, i));
                    }
                    tuples.addLast(new RegexPart[] {CLOSE_PAREN});
                    start = i + 1;
                    // now move the separation level up one
                    separationLevel = level;
                }
            } else if (parts[i].equals(separator)) {
                // split up appropriately accounting for levels and alternates
                separationLevel = level;
                int begin = start;
                for (int j = start; j < i; j++) {
                    if (parts[j].equals(ALTERNATE)) {
                        if (start < j) {
                            tuples.addLast(Arrays.copyOfRange(parts, start, j));
                        }
                        tuples.addLast(new RegexPart[] {ALTERNATE});
                        start = j + 1;
                    } else if (parts[j].equals(OPEN_PAREN)) {
                        if (start < j) {
                            tuples.addLast(Arrays.copyOfRange(parts, start, j));
                        }
                        tuples.addLast(new RegexPart[] {OPEN_PAREN});
                        start = j + 1;
                    } else if (parts[j].equals(CLOSE_PAREN)) {
                        // we found a closing paren which must have a matching open paren within a non-separated section

                        // move back to the matching paren
                        RegexPart[] last = tuples.removeLast();
                        while (last.length != 1 || !last[0].equals(OPEN_PAREN)) {
                            start -= last.length;
                            last = tuples.removeLast();
                        }
                        start -= last.length;
                        last = (tuples.isEmpty() || start == begin ? null : tuples.removeLast());

                        // now move back to the previous paren, separator, or beginning
                        while (last != null && (last.length != 1 || !(last[0].equals(OPEN_PAREN) || last[0].equals(separator)))) {
                            start -= last.length;
                            last = (tuples.isEmpty() || start == begin ? null : tuples.removeLast());
                        }
                        if (last != null) {
                            tuples.addLast(last);
                        }
                    }
                }

                if (i > start) {
                    tuples.addLast(Arrays.copyOfRange(parts, start, i));
                }
                tuples.addLast(new RegexPart[] {separator});
                start = i + 1;
            }
        }
        if (level > 0) {
            throw new JavaRegexParseException("Non matching groups", -1);
        }
        if (parts.length > start) {
            tuples.addLast(Arrays.copyOfRange(parts, start, parts.length));
        }

        return tuples;
    }

    /**
     * Split up a list of parts using a specified separator. If a separator is found inside of a nested group, then that group and its ancestors begin and end
     * parentheses will be returned as separate parts as well as alternates. Separators are included as separate parts.
     *
     * @param parts
     * @param separator
     * @return the part lists
     * @throws JavaRegexParseException
     */
    private List<RegexPart[]> splitParts(RegexPart[] parts, RegexPart separator) throws JavaRegexParseException {
        LinkedList<RegexPart[]> tuples = new LinkedList<RegexPart[]>();
        int start = 0;
        int level = 0;
        int separationLevel = 0;
        for (int i = 0; i < parts.length; i++) {
            if (parts[i].equals(OPEN_PAREN)) {
                level++;
            } else if (parts[i].equals(CLOSE_PAREN)) {
                if (level == 0) {
                    throw new JavaRegexParseException("Non matching groups", -1);
                }
                level--;
                if (level < separationLevel) {
                    if (start < i) {
                        tuples.addLast(Arrays.copyOfRange(parts, start, i));
                    }
                    tuples.addLast(new RegexPart[] {CLOSE_PAREN});
                    start = i + 1;
                    // now move the separation level up one
                    separationLevel = level;
                }
            } else if (parts[i].equals(separator)) {
                // split up appropriately accounting for levels and alternates
                separationLevel = level;
                int begin = start;
                for (int j = start; j < i; j++) {
                    if (parts[j].equals(ALTERNATE)) {
                        if (start < j) {
                            tuples.addLast(Arrays.copyOfRange(parts, start, j));
                        }
                        tuples.addLast(new RegexPart[] {ALTERNATE});
                        start = j + 1;
                    } else if (parts[j].equals(OPEN_PAREN)) {
                        if (start < j) {
                            tuples.addLast(Arrays.copyOfRange(parts, start, j));
                        }
                        tuples.addLast(new RegexPart[] {OPEN_PAREN});
                        start = j + 1;
                    } else if (parts[j].equals(CLOSE_PAREN)) {
                        // we found a closing paren which must have a matching open paren within a non-separated section

                        // move back to the matching paren
                        RegexPart[] last = tuples.removeLast();
                        while (last.length != 1 || !last[0].equals(OPEN_PAREN)) {
                            start -= last.length;
                            last = tuples.removeLast();
                        }
                        start -= last.length;
                        last = (tuples.isEmpty() || start == begin ? null : tuples.removeLast());

                        // now move back to the previous paren, separator, or beginning
                        while (last != null && (last.length != 1 || !(last[0].equals(OPEN_PAREN) || last[0].equals(separator)))) {
                            start -= last.length;
                            last = (tuples.isEmpty() || start == begin ? null : tuples.removeLast());
                        }
                        if (last != null) {
                            tuples.addLast(last);
                        }
                    }
                }

                if (i > start) {
                    tuples.addLast(Arrays.copyOfRange(parts, start, i));
                }
                tuples.addLast(new RegexPart[] {separator});
                start = i + 1;
            }
        }
        if (level > 0) {
            throw new JavaRegexParseException("Non matching groups", -1);
        }
        if (parts.length > start) {
            tuples.addLast(Arrays.copyOfRange(parts, start, parts.length));
        }

        return tuples;
    }

Replace Generic With Diamond LinkedList<RegexPart[]> with LinkedList<> in method private splitParts(parts RegexPart[], separator RegexPart) : List<RegexPart[]> from class datawave.query.parser.JavaRegexAnalyzer


    public StringTuple(int size) {
        values = new ArrayList<>(size);
    }

    public StringTuple(int size) {
        values = new ArrayList<String>(size);
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public StringTuple(size int) from class datawave.query.util.StringTuple


    /**
     * Create an object from it's classname using args for arguments
     *
     * @param className
     *            the string classname to get a new instance of
     * @param args
     *            the arguments to a public constructor of classname
     * @return the newly instantiated object
     */
    public static Object create(String className, Object... args) {
        if (logger.isDebugEnabled()) {
            logger.debug("ObjectFactory.create1(" + className + "," + Arrays.toString(args) + ")");
        }
        try {
            Class<?> clazz = Class.forName(className);
            List<Class<?>> types = new ArrayList<>();
            for (Object o : args) {
                if (o == null) {
                    types.add(null);
                } else {
                    types.add(o.getClass());
                }
            }

            Constructor<?> constructor = null;

            // Look for exact match
            try {
                constructor = clazz.getConstructor(types.toArray(new Class[0]));
            } catch (NoSuchMethodException e) {
                logger.debug("No constructor for [" + className + "] in ObjectFactory.create())");
            }

            // Look for assignable match if nothing exact was found
            if (constructor == null) {
                Constructor<?>[] constructors = clazz.getConstructors();
                for (int i = 0; i < constructors.length && constructor == null; i++) {
                    Constructor<?> c = constructors[i];
                    Class<?> ctypes[] = c.getParameterTypes();

                    if (logger.isDebugEnabled()) {
                        logger.debug("Checking:" + className + ", " + clazz);
                        logger.debug("   types   :" + Arrays.toString(ctypes));
                        logger.debug("   numParms:" + ctypes.length + " =? " + types.size());
                    }

                    if (ctypes.length != types.size()) {
                        logger.debug("    not equal:");
                        constructor = null;
                        continue;
                    }
                    constructor = c;
                    for (int j = 0; j < types.size(); j++) {
                        Class<?> a = ctypes[j];
                        Class<?> b = types.get(j);
                        if (a == null || b == null) {
                            continue;
                        }

                        if (a.isAssignableFrom(b)) {
                            logger.debug("   param=" + a + "  assignable " + b);
                        } else {
                            b = getPrim(b);
                            if (a.isAssignableFrom(b)) {
                                logger.debug("   param:" + a + "  assignable " + b);
                            } else {
                                logger.debug("   param:" + a + " !assignable " + b);
                                constructor = null;
                                break;
                            }
                        }
                    }
                }
            }
            Object newObject = null;
            if (constructor == null) {
                logger.info("Failed to find constructor for args(" + args.length + ") types(" + types.size() + ") : " + types);
            } else {
                newObject = constructor.newInstance(args);
            }
            return newObject;
        } catch (ClassNotFoundException e1) {
            logger.error("Could not find class", e1);
            throw new Error(e1);
        } catch (InstantiationException e3) {
            logger.error("Could not instantiate", e3);
            throw new Error(e3);
        } catch (IllegalAccessException e4) {
            logger.error("Could not call constructor", e4);
            throw new Error(e4);
        } catch (InvocationTargetException e5) {
            logger.error("Constructor failed", e5);
            throw new Error(e5);
        } catch (Throwable t) {
            logger.error("Problem in factory", t);
            throw new Error(t);
        }
    }

    /**
     * Create an object from it's classname using args for arguments
     *
     * @param className
     *            the string classname to get a new instance of
     * @param args
     *            the arguments to a public constructor of classname
     * @return the newly instantiated object
     */
    public static Object create(String className, Object... args) {
        if (logger.isDebugEnabled()) {
            logger.debug("ObjectFactory.create1(" + className + "," + Arrays.toString(args) + ")");
        }
        try {
            Class<?> clazz = Class.forName(className);
            List<Class<?>> types = new ArrayList<Class<?>>();
            for (Object o : args) {
                if (o == null) {
                    types.add(null);
                } else {
                    types.add(o.getClass());
                }
            }

            Constructor<?> constructor = null;

            // Look for exact match
            try {
                constructor = clazz.getConstructor(types.toArray(new Class[0]));
            } catch (NoSuchMethodException e) {
                logger.debug("No constructor for [" + className + "] in ObjectFactory.create())");
            }

            // Look for assignable match if nothing exact was found
            if (constructor == null) {
                Constructor<?>[] constructors = clazz.getConstructors();
                for (int i = 0; i < constructors.length && constructor == null; i++) {
                    Constructor<?> c = constructors[i];
                    Class<?> ctypes[] = c.getParameterTypes();

                    if (logger.isDebugEnabled()) {
                        logger.debug("Checking:" + className + ", " + clazz);
                        logger.debug("   types   :" + Arrays.toString(ctypes));
                        logger.debug("   numParms:" + ctypes.length + " =? " + types.size());
                    }

                    if (ctypes.length != types.size()) {
                        logger.debug("    not equal:");
                        constructor = null;
                        continue;
                    }
                    constructor = c;
                    for (int j = 0; j < types.size(); j++) {
                        Class<?> a = ctypes[j];
                        Class<?> b = types.get(j);
                        if (a == null || b == null) {
                            continue;
                        }

                        if (a.isAssignableFrom(b)) {
                            logger.debug("   param=" + a + "  assignable " + b);
                        } else {
                            b = getPrim(b);
                            if (a.isAssignableFrom(b)) {
                                logger.debug("   param:" + a + "  assignable " + b);
                            } else {
                                logger.debug("   param:" + a + " !assignable " + b);
                                constructor = null;
                                break;
                            }
                        }
                    }
                }
            }
            Object newObject = null;
            if (constructor == null) {
                logger.info("Failed to find constructor for args(" + args.length + ") types(" + types.size() + ") : " + types);
            } else {
                newObject = constructor.newInstance(args);
            }
            return newObject;
        } catch (ClassNotFoundException e1) {
            logger.error("Could not find class", e1);
            throw new Error(e1);
        } catch (InstantiationException e3) {
            logger.error("Could not instantiate", e3);
            throw new Error(e3);
        } catch (IllegalAccessException e4) {
            logger.error("Could not call constructor", e4);
            throw new Error(e4);
        } catch (InvocationTargetException e5) {
            logger.error("Constructor failed", e5);
            throw new Error(e5);
        } catch (Throwable t) {
            logger.error("Problem in factory", t);
            throw new Error(t);
        }
    }

Replace Generic With Diamond ArrayList<Class<?>> with ArrayList<> in method public create(className String, args Object...) : Object from class datawave.util.ObjectFactory


        public Entry() {
            this.values = new ArrayList<>();
        }

        public Entry() {
            this.values = new ArrayList<String>();
        }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public Entry() from class datawave.util.StringMultimapSchema.Entry


    @Override
    public void addSecurityMarking(String domain, String marking) {
        if (null == securityMarkings) {
            securityMarkings = new HashMap<>();
        }
        securityMarkings.put(domain, marking);
        syncSecurityMarkingsToFields();
    }

    @Override
    public void addSecurityMarking(String domain, String marking) {
        if (null == securityMarkings) {
            securityMarkings = new HashMap<String,String>();
        }
        securityMarkings.put(domain, marking);
        syncSecurityMarkingsToFields();
    }

Replace Generic With Diamond HashMap<String,String> with HashMap<> in method public addSecurityMarking(domain String, marking String) : void from class datawave.ingest.config.RawRecordContainerImpl


    public void setup(Type type, Configuration config) {
        // Process the field aliases
        _fieldNameAliases = new HashMap<>();
        String[] a = config.getStrings(type.typeName() + FIELD_ALIASES, (String[]) null);
        if (null != a) {
            for (String s : a) {
                String[] parts = StringUtils.split(s, ':');
                if (parts.length == 2)
                    _fieldNameAliases.put(parts[0], parts[1]);
                else
                    throw new IllegalArgumentException("Missing alias for " + parts[0]);
            }
        }
        _indexNameAliases = new HashMap<>();
        Boolean indexAliasesAllowed = config.getBoolean(type.typeName() + INDEX_ALIASES_ENABLED, false);
        if (indexAliasesAllowed) {
            String indexAliasesConfig = config.get(type.typeName() + INDEX_ALIASES, null);
            if (null != indexAliasesConfig) {
                for (String indexAliasStr : StringUtils.split(indexAliasesConfig, ';')) {
                    if (indexAliasStr.length() > 0) {
                        String[] parts = StringUtils.split(indexAliasStr, ':');
                        if (parts.length == 2) {
                            HashSet<String> aliases = new HashSet<>();
                            for (String alias : StringUtils.split(parts[1], ',')) {
                                aliases.add(canonicalizeFieldName(alias, FIELD.NAME));
                            }
                            _indexNameAliases.put(parts[0], aliases);
                        } else {
                            throw new IllegalArgumentException("Improperly formatted index alias");
                        }
                    }
                }
            }
        }
    }

    public void setup(Type type, Configuration config) {
        // Process the field aliases
        _fieldNameAliases = new HashMap<>();
        String[] a = config.getStrings(type.typeName() + FIELD_ALIASES, (String[]) null);
        if (null != a) {
            for (String s : a) {
                String[] parts = StringUtils.split(s, ':');
                if (parts.length == 2)
                    _fieldNameAliases.put(parts[0], parts[1]);
                else
                    throw new IllegalArgumentException("Missing alias for " + parts[0]);
            }
        }
        _indexNameAliases = new HashMap<>();
        Boolean indexAliasesAllowed = config.getBoolean(type.typeName() + INDEX_ALIASES_ENABLED, false);
        if (indexAliasesAllowed) {
            String indexAliasesConfig = config.get(type.typeName() + INDEX_ALIASES, null);
            if (null != indexAliasesConfig) {
                for (String indexAliasStr : StringUtils.split(indexAliasesConfig, ';')) {
                    if (indexAliasStr.length() > 0) {
                        String[] parts = StringUtils.split(indexAliasStr, ':');
                        if (parts.length == 2) {
                            HashSet<String> aliases = new HashSet<String>();
                            for (String alias : StringUtils.split(parts[1], ',')) {
                                aliases.add(canonicalizeFieldName(alias, FIELD.NAME));
                            }
                            _indexNameAliases.put(parts[0], aliases);
                        } else {
                            throw new IllegalArgumentException("Improperly formatted index alias");
                        }
                    }
                }
            }
        }
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public setup(type Type, config Configuration) : void from class datawave.ingest.data.config.ingest.FieldNameAliaserNormalizer


        /**
         * A convenience routine to get a configuration value
         *
         * @param type
         * @param instance
         * @param config
         * @param key
         * @return The value, null if not available
         */
        protected String[] getStrings(Type type, String instance, Configuration config, String key, String[] defaultVal) {
            for (String prefix : getConfPrefixes(type, instance)) {
                String[] value = config.getStrings(prefix + key, (String[]) null);
                if (value != null) {
                    String concatValue = "";
                    ArrayList<String> escapedValue = new ArrayList<>();
                    for (int i = 0; i < value.length; i++) {
                        concatValue += value[i];
                        if (i != value.length - 1)
                            concatValue += ",";
                    }
                    int start = 0;
                    int end = 0;
                    while (end < concatValue.length()) {
                        if (concatValue.charAt(end) == ',' && concatValue.charAt(end - 1) != '\\') {
                            escapedValue.add(concatValue.substring(start, end).replace("\\,", ","));
                            start = end + 1;
                        }
                        end++;
                    }
                    if (start != end)
                        escapedValue.add(concatValue.substring(start, end).replace("\\,", ","));
                    return escapedValue.toArray(new String[escapedValue.size()]);
                }
            }
            return defaultVal;
        }

        /**
         * A convenience routine to get a configuration value
         *
         * @param type
         * @param instance
         * @param config
         * @param key
         * @return The value, null if not available
         */
        protected String[] getStrings(Type type, String instance, Configuration config, String key, String[] defaultVal) {
            for (String prefix : getConfPrefixes(type, instance)) {
                String[] value = config.getStrings(prefix + key, (String[]) null);
                if (value != null) {
                    String concatValue = "";
                    ArrayList<String> escapedValue = new ArrayList<String>();
                    for (int i = 0; i < value.length; i++) {
                        concatValue += value[i];
                        if (i != value.length - 1)
                            concatValue += ",";
                    }
                    int start = 0;
                    int end = 0;
                    while (end < concatValue.length()) {
                        if (concatValue.charAt(end) == ',' && concatValue.charAt(end - 1) != '\\') {
                            escapedValue.add(concatValue.substring(start, end).replace("\\,", ","));
                            start = end + 1;
                        }
                        end++;
                    }
                    if (start != end)
                        escapedValue.add(concatValue.substring(start, end).replace("\\,", ","));
                    return escapedValue.toArray(new String[escapedValue.size()]);
                }
            }
            return defaultVal;
        }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method protected getStrings(type Type, instance String, config Configuration, key String, defaultVal String[]) : String[] from class datawave.ingest.data.config.ingest.VirtualIngest.VirtualFieldNormalizer


    @Override
    public List<String> getSynonyms(String term, String termType, boolean includeTerm) {
        return new ArrayList<>(getSynonyms(dezone(term), termType, includeTerm));
    }

    @Override
    public List<String> getSynonyms(String term, String termType, boolean includeTerm) {
        return new ArrayList<String>(getSynonyms(dezone(term), termType, includeTerm));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public getSynonyms(term String, termType String, includeTerm boolean) : List<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public Collection<String> emailAddressTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        Set<String> synonyms = new LinkedHashSet<>();

        String addr = zw[0];
        String zone = zw[1];

        String lcaddr = addr.toLowerCase();

        // include downcased version if it is different or if includeTerm is
        // flagged
        if ((!addr.equals(lcaddr)) || includeTerm) {
            synonyms.add(lcaddr + zone);
        }

        int atpos = addr.indexOf("@");
        if (atpos > 0) {
            String name = lcaddr.substring(0, atpos);
            String domain = lcaddr.substring(atpos);
            synonyms.add(name + zone);

            if (emailDomainTokensEnabled) {
                synonyms.add(domain + zone);
            }

            if (emailWordTokensEnabled) {
                getTokenWords(name, zone, synonyms);
            }

            if (domain.equals("@gmail.com")) {
                String me_name = name.replaceAll("[\\.]", "").replaceAll("\\+.*", "");
                if (!me_name.equals(name)) {
                    synonyms.add(me_name + domain + zone);
                }
            }
        } else if (emailWordTokensEnabled) {
            getTokenWords(lcaddr, zone, synonyms);
        }

        if (lcaddr.lastIndexOf(".") <= lcaddr.length() - 7) {
            // hedge against things improperly identified as e-mail addresses
            // by always tokenizing e-mail addresses with long ending domains.
            getTokenWords(lcaddr, zone, synonyms);
        }

        return synonyms;
    }

    @Override
    public Collection<String> emailAddressTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        Set<String> synonyms = new LinkedHashSet<String>();

        String addr = zw[0];
        String zone = zw[1];

        String lcaddr = addr.toLowerCase();

        // include downcased version if it is different or if includeTerm is
        // flagged
        if ((!addr.equals(lcaddr)) || includeTerm) {
            synonyms.add(lcaddr + zone);
        }

        int atpos = addr.indexOf("@");
        if (atpos > 0) {
            String name = lcaddr.substring(0, atpos);
            String domain = lcaddr.substring(atpos);
            synonyms.add(name + zone);

            if (emailDomainTokensEnabled) {
                synonyms.add(domain + zone);
            }

            if (emailWordTokensEnabled) {
                getTokenWords(name, zone, synonyms);
            }

            if (domain.equals("@gmail.com")) {
                String me_name = name.replaceAll("[\\.]", "").replaceAll("\\+.*", "");
                if (!me_name.equals(name)) {
                    synonyms.add(me_name + domain + zone);
                }
            }
        } else if (emailWordTokensEnabled) {
            getTokenWords(lcaddr, zone, synonyms);
        }

        if (lcaddr.lastIndexOf(".") <= lcaddr.length() - 7) {
            // hedge against things improperly identified as e-mail addresses
            // by always tokenizing e-mail addresses with long ending domains.
            getTokenWords(lcaddr, zone, synonyms);
        }

        return synonyms;
    }

Replace Generic With Diamond LinkedHashSet<String> with LinkedHashSet<> in method public emailAddressTokens(zw String[], reverse_indexing boolean, includeTerm boolean) : Collection<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public List<String> emailAddressTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<>(emailAddressTokens(dezone(term), reverse_indexing, includeTerm));
    }

    @Override
    public List<String> emailAddressTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<String>(emailAddressTokens(dezone(term), reverse_indexing, includeTerm));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public emailAddressTokens(term String, reverse_indexing boolean, includeTerm boolean) : List<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public Collection<String> ipAddressTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        Set<String> synonyms = new LinkedHashSet<>();

        String addr = zw[0];
        String zone = zw[1];

        String lcaddr = addr.toLowerCase();

        // include the downcased term if it is different from the
        // original form or the include term flag is raised.
        if ((!addr.equals(lcaddr)) || includeTerm) {
            synonyms.add(lcaddr + zone);
        }

        return synonyms;
    }

    @Override
    public Collection<String> ipAddressTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        Set<String> synonyms = new LinkedHashSet<String>();

        String addr = zw[0];
        String zone = zw[1];

        String lcaddr = addr.toLowerCase();

        // include the downcased term if it is different from the
        // original form or the include term flag is raised.
        if ((!addr.equals(lcaddr)) || includeTerm) {
            synonyms.add(lcaddr + zone);
        }

        return synonyms;
    }

Replace Generic With Diamond LinkedHashSet<String> with LinkedHashSet<> in method public ipAddressTokens(zw String[], reverse_indexing boolean, includeTerm boolean) : Collection<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public List<String> ipAddressTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<>(ipAddressTokens(dezone(term), reverse_indexing, includeTerm));
    }

    @Override
    public List<String> ipAddressTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<String>(ipAddressTokens(dezone(term), reverse_indexing, includeTerm));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public ipAddressTokens(term String, reverse_indexing boolean, includeTerm boolean) : List<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public List<String> timestampTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<>(timestampTokens(dezone(term), reverse_indexing, includeTerm));
    }

    @Override
    public List<String> timestampTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<String>(timestampTokens(dezone(term), reverse_indexing, includeTerm));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public timestampTokens(term String, reverse_indexing boolean, includeTerm boolean) : List<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public Collection<String> timestampTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        if (reverse_indexing)
            return Collections.emptyList();

        Set<String> synonyms = new LinkedHashSet<>();

        String tstamp = zw[0].toLowerCase();
        String zone = zw[1];

        String lctstamp = tstamp.toLowerCase();

        if ((!tstamp.equals(lctstamp)) || includeTerm) {
            synonyms.add(lctstamp + zone);
        }

        tstamp = lctstamp; // reuse tstamp for edits

        // extract the y,m,d portion prior to t.
        int tPos = tstamp.indexOf("t");
        if (tPos > 0) {
            String daystamp = tstamp.substring(0, tPos);
            synonyms.add(daystamp + zone);
            tstamp = tstamp.substring(0, tPos);
        }

        // todo: something with the time and zone here.

        // add what remains as well.
        if (!tstamp.equals(lctstamp)) {
            synonyms.add(tstamp + zone);
        }

        return synonyms;
    }

    @Override
    public Collection<String> timestampTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        if (reverse_indexing)
            return Collections.emptyList();

        Set<String> synonyms = new LinkedHashSet<String>();

        String tstamp = zw[0].toLowerCase();
        String zone = zw[1];

        String lctstamp = tstamp.toLowerCase();

        if ((!tstamp.equals(lctstamp)) || includeTerm) {
            synonyms.add(lctstamp + zone);
        }

        tstamp = lctstamp; // reuse tstamp for edits

        // extract the y,m,d portion prior to t.
        int tPos = tstamp.indexOf("t");
        if (tPos > 0) {
            String daystamp = tstamp.substring(0, tPos);
            synonyms.add(daystamp + zone);
            tstamp = tstamp.substring(0, tPos);
        }

        // todo: something with the time and zone here.

        // add what remains as well.
        if (!tstamp.equals(lctstamp)) {
            synonyms.add(tstamp + zone);
        }

        return synonyms;
    }

Replace Generic With Diamond LinkedHashSet<String> with LinkedHashSet<> in method public timestampTokens(zw String[], reverse_indexing boolean, includeTerm boolean) : Collection<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public Collection<String> filePathTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        // Nothing to do if reverse indexing
        if (reverse_indexing)
            return Collections.emptyList();

        Set<String> synonyms = new LinkedHashSet<>();

        String zlc = zw[0].toLowerCase();
        String zone = zw[1];

        // emit non-path normalized, lc version first if it is
        // different from the base form or include term is flagged.
        if ((!zlc.equals(zw[0])) || includeTerm) {
            synonyms.add(zlc + zone);
        }

        // Path normalization
        if (zlc.indexOf("\\") > -1) {
            // emit path normalized, lc version.
            // yes, this regex really matches one or more '\' characters.
            zlc = zlc.replaceAll("\\\\+", "/");
            synonyms.add(zlc + zone);
        }

        // Replace runs of consecutive slashes with a single slash.
        if (zlc.indexOf("//") > -1) {
            zlc = zlc.replaceAll("/+", "/");
        }

        // Remove trailing slashes.
        if (zlc.endsWith("/")) {
            zlc = zlc.substring(0, zlc.length() - 1);
        }

        // space separated directory walk fix
        // e.g: c:/program files/foo/bar.exe bar~2.exe
        // not: c:/program files/temp .net files/foobar
        // easier to fix this here than re-process the buds.
        String extra = null;
        int startPos = zlc.length();
        int spacePos = zlc.lastIndexOf(" ", startPos);
        int slashPos = zlc.lastIndexOf("/", startPos);

        // working from the end to the beginning, look at spaces
        // prior to the final slash. Check the tokens on either side
        // of the space to see if the left side has something that looks
        // like a file extension >or< the right side has something that
        // looks like an 8.3 filename. If any of these are true, we've found
        // our delimiter.
        while (spacePos > slashPos + 1) {
            if ((spacePos >= 4 && '.' == zlc.charAt(spacePos - 4)) || (startPos >= 2 && '~' == zlc.charAt(startPos - 2))
                            || (startPos >= 6 && '~' == zlc.charAt(startPos - 6))) {
                extra = zlc.substring(spacePos + 1);
                synonyms.add(extra + zone); // e.g barca~2.exe
                zlc = zlc.substring(0, spacePos); // everything else
                synonyms.add(zlc + zone);
                break;
            }
            // next space.
            startPos = spacePos - 1;
            spacePos = zlc.lastIndexOf(" ", startPos);
        }

        // File path without drive letter
        if (zlc.indexOf(":/") == 1 && zlc.length() > 4) {
            synonyms.add(zlc.substring(3) + zone);
        }

        // lowercased portions of trailing segments
        // (to avoid leading wildcard search)
        slashPos = zlc.indexOf("/");
        int segstart = 0;
        String zseg;

        // extract path segments, and trailing path segments.
        // trailing path segments eliminate the need for leading wildcard search,
        // while path segments allow more natural search upon filenames with spaces.
        while (segstart <= slashPos || segstart < zlc.length()) {
            if (segstart <= slashPos) {
                // slash delimited components of zlc
                zseg = zlc.substring(segstart, slashPos);
            } else // assume (segstart < zlc.length())
            {
                zseg = zlc.substring(segstart);
            }

            if (zseg.length() > 0) {
                synonyms.add(zseg + zone);

                spacePos = zseg.indexOf(" ");
                if (spacePos > -1) {
                    // extract space delimited components of zseg.
                    int zsegstart = 0;
                    while (zsegstart <= spacePos && spacePos < zseg.length()) {
                        synonyms.add(zseg.substring(zsegstart, spacePos) + zone);
                        zsegstart = spacePos + 1;
                        spacePos = zseg.indexOf(" ", zsegstart);
                    }

                    if (zsegstart < zseg.length()) {
                        synonyms.add(zseg.substring(zsegstart) + zone);
                    }
                }
            }

            // if there are more path components to process.
            if (segstart <= slashPos) {
                segstart = slashPos + 1;
                synonyms.add(zlc.substring(segstart) + zone); // trailing bits of the path.
                slashPos = zlc.indexOf("/", segstart);
            } else {
                break;
            }
        }

        if (fileWordTokensEnabled) {
            getTokenWords(zlc, zone, synonyms);
            if (extra != null) {
                getTokenWords(extra, zone, synonyms);
            }
        }

        return synonyms;
    }

    @Override
    public Collection<String> filePathTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        // Nothing to do if reverse indexing
        if (reverse_indexing)
            return Collections.emptyList();

        Set<String> synonyms = new LinkedHashSet<String>();

        String zlc = zw[0].toLowerCase();
        String zone = zw[1];

        // emit non-path normalized, lc version first if it is
        // different from the base form or include term is flagged.
        if ((!zlc.equals(zw[0])) || includeTerm) {
            synonyms.add(zlc + zone);
        }

        // Path normalization
        if (zlc.indexOf("\\") > -1) {
            // emit path normalized, lc version.
            // yes, this regex really matches one or more '\' characters.
            zlc = zlc.replaceAll("\\\\+", "/");
            synonyms.add(zlc + zone);
        }

        // Replace runs of consecutive slashes with a single slash.
        if (zlc.indexOf("//") > -1) {
            zlc = zlc.replaceAll("/+", "/");
        }

        // Remove trailing slashes.
        if (zlc.endsWith("/")) {
            zlc = zlc.substring(0, zlc.length() - 1);
        }

        // space separated directory walk fix
        // e.g: c:/program files/foo/bar.exe bar~2.exe
        // not: c:/program files/temp .net files/foobar
        // easier to fix this here than re-process the buds.
        String extra = null;
        int startPos = zlc.length();
        int spacePos = zlc.lastIndexOf(" ", startPos);
        int slashPos = zlc.lastIndexOf("/", startPos);

        // working from the end to the beginning, look at spaces
        // prior to the final slash. Check the tokens on either side
        // of the space to see if the left side has something that looks
        // like a file extension >or< the right side has something that
        // looks like an 8.3 filename. If any of these are true, we've found
        // our delimiter.
        while (spacePos > slashPos + 1) {
            if ((spacePos >= 4 && '.' == zlc.charAt(spacePos - 4)) || (startPos >= 2 && '~' == zlc.charAt(startPos - 2))
                            || (startPos >= 6 && '~' == zlc.charAt(startPos - 6))) {
                extra = zlc.substring(spacePos + 1);
                synonyms.add(extra + zone); // e.g barca~2.exe
                zlc = zlc.substring(0, spacePos); // everything else
                synonyms.add(zlc + zone);
                break;
            }
            // next space.
            startPos = spacePos - 1;
            spacePos = zlc.lastIndexOf(" ", startPos);
        }

        // File path without drive letter
        if (zlc.indexOf(":/") == 1 && zlc.length() > 4) {
            synonyms.add(zlc.substring(3) + zone);
        }

        // lowercased portions of trailing segments
        // (to avoid leading wildcard search)
        slashPos = zlc.indexOf("/");
        int segstart = 0;
        String zseg;

        // extract path segments, and trailing path segments.
        // trailing path segments eliminate the need for leading wildcard search,
        // while path segments allow more natural search upon filenames with spaces.
        while (segstart <= slashPos || segstart < zlc.length()) {
            if (segstart <= slashPos) {
                // slash delimited components of zlc
                zseg = zlc.substring(segstart, slashPos);
            } else // assume (segstart < zlc.length())
            {
                zseg = zlc.substring(segstart);
            }

            if (zseg.length() > 0) {
                synonyms.add(zseg + zone);

                spacePos = zseg.indexOf(" ");
                if (spacePos > -1) {
                    // extract space delimited components of zseg.
                    int zsegstart = 0;
                    while (zsegstart <= spacePos && spacePos < zseg.length()) {
                        synonyms.add(zseg.substring(zsegstart, spacePos) + zone);
                        zsegstart = spacePos + 1;
                        spacePos = zseg.indexOf(" ", zsegstart);
                    }

                    if (zsegstart < zseg.length()) {
                        synonyms.add(zseg.substring(zsegstart) + zone);
                    }
                }
            }

            // if there are more path components to process.
            if (segstart <= slashPos) {
                segstart = slashPos + 1;
                synonyms.add(zlc.substring(segstart) + zone); // trailing bits of the path.
                slashPos = zlc.indexOf("/", segstart);
            } else {
                break;
            }
        }

        if (fileWordTokensEnabled) {
            getTokenWords(zlc, zone, synonyms);
            if (extra != null) {
                getTokenWords(extra, zone, synonyms);
            }
        }

        return synonyms;
    }

Replace Generic With Diamond LinkedHashSet<String> with LinkedHashSet<> in method public filePathTokens(zw String[], reverse_indexing boolean, includeTerm boolean) : Collection<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public List<String> filePathTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<>(filePathTokens(dezone(term), reverse_indexing, includeTerm));
    }

    @Override
    public List<String> filePathTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<String>(filePathTokens(dezone(term), reverse_indexing, includeTerm));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public filePathTokens(term String, reverse_indexing boolean, includeTerm boolean) : List<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public Collection<String> httpRequestTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        // Nothing to do if reverse indexing
        if (reverse_indexing)
            return Collections.emptyList();

        Set<String> synonyms = new LinkedHashSet<>();

        String lc = zw[0].toLowerCase();
        String zone = zw[1];

        // Include the downcased request if different from the original term
        // or includeTerm is raised.
        if ((!lc.equals(zw[0])) || includeTerm) {
            synonyms.add(lc + zone);
        }

        int methodPos = lc.indexOf(" ");
        int versionPos = lc.indexOf(" http", methodPos + 1);

        if (methodPos > 0 && versionPos > methodPos) {
            String method = lc.substring(0, methodPos);
            String requestUri = lc.substring(methodPos + 1, versionPos);
            String version = lc.substring(versionPos + 1);

            synonyms.add(method + zone);
            synonyms.addAll(urlTokens(new String[] {requestUri, zone}, false, includeTerm));
            synonyms.add(version + zone);

            versionPos = version.indexOf("/");
            if (versionPos > 0) {
                synonyms.add(version.substring(0, versionPos) + zone);
            }
        } else { // can't parse, treat as a URL
            synonyms.addAll(urlTokens(zw, false, includeTerm));
        }

        return synonyms;
    }

    @Override
    public Collection<String> httpRequestTokens(String[] zw, boolean reverse_indexing, boolean includeTerm) {
        // Nothing to do if reverse indexing
        if (reverse_indexing)
            return Collections.emptyList();

        Set<String> synonyms = new LinkedHashSet<String>();

        String lc = zw[0].toLowerCase();
        String zone = zw[1];

        // Include the downcased request if different from the original term
        // or includeTerm is raised.
        if ((!lc.equals(zw[0])) || includeTerm) {
            synonyms.add(lc + zone);
        }

        int methodPos = lc.indexOf(" ");
        int versionPos = lc.indexOf(" http", methodPos + 1);

        if (methodPos > 0 && versionPos > methodPos) {
            String method = lc.substring(0, methodPos);
            String requestUri = lc.substring(methodPos + 1, versionPos);
            String version = lc.substring(versionPos + 1);

            synonyms.add(method + zone);
            synonyms.addAll(urlTokens(new String[] {requestUri, zone}, false, includeTerm));
            synonyms.add(version + zone);

            versionPos = version.indexOf("/");
            if (versionPos > 0) {
                synonyms.add(version.substring(0, versionPos) + zone);
            }
        } else { // can't parse, treat as a URL
            synonyms.addAll(urlTokens(zw, false, includeTerm));
        }

        return synonyms;
    }

Replace Generic With Diamond LinkedHashSet<String> with LinkedHashSet<> in method public httpRequestTokens(zw String[], reverse_indexing boolean, includeTerm boolean) : Collection<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public List<String> httpRequestTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<>(httpRequestTokens(dezone(term), reverse_indexing, includeTerm));
    }

    @Override
    public List<String> httpRequestTokens(String term, boolean reverse_indexing, boolean includeTerm) {
        return new ArrayList<String>(httpRequestTokens(dezone(term), reverse_indexing, includeTerm));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public httpRequestTokens(term String, reverse_indexing boolean, includeTerm boolean) : List<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public Collection<String> dirtyTokens(String[] zw, boolean includeTerm) {
        Set<String> synonyms = new LinkedHashSet<>();

        String lc = zw[0].toLowerCase();
        String zone = zw[1];

        // Include the downcased original if different from the original term
        // or includeTerm is raised.
        if ((!lc.equals(zw[0])) || includeTerm) {
            synonyms.add(lc + zone);
        }

        // Include the synonyms of the 'original with dirtyTokens removed'.
        synonyms.addAll(getTermSynonyms(dirtyTokensPtrn.matcher(zw[0]).replaceAll("") + zone, includeTerm));
        if (dirtyWordTokensEnabled) {
            getTokenWords(zw[0], zw[1], synonyms);
        }

        return synonyms;
    }

    @Override
    public Collection<String> dirtyTokens(String[] zw, boolean includeTerm) {
        Set<String> synonyms = new LinkedHashSet<String>();

        String lc = zw[0].toLowerCase();
        String zone = zw[1];

        // Include the downcased original if different from the original term
        // or includeTerm is raised.
        if ((!lc.equals(zw[0])) || includeTerm) {
            synonyms.add(lc + zone);
        }

        // Include the synonyms of the 'original with dirtyTokens removed'.
        synonyms.addAll(getTermSynonyms(dirtyTokensPtrn.matcher(zw[0]).replaceAll("") + zone, includeTerm));
        if (dirtyWordTokensEnabled) {
            getTokenWords(zw[0], zw[1], synonyms);
        }

        return synonyms;
    }

Replace Generic With Diamond LinkedHashSet<String> with LinkedHashSet<> in method public dirtyTokens(zw String[], includeTerm boolean) : Collection<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch


    @Override
    public List<String> dirtyTokens(String term, boolean includeTerm) {
        return new ArrayList<>(dirtyTokens(dezone(term), includeTerm));
    }

    @Override
    public List<String> dirtyTokens(String term, boolean includeTerm) {
        return new ArrayList<String>(dirtyTokens(dezone(term), includeTerm));
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public dirtyTokens(term String, includeTerm boolean) : List<String> from class datawave.ingest.data.tokenize.DefaultTokenSearch