    @Override
    public Collection<String> urlTokens(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_url = zw[0].toLowerCase();
        String zone = zw[1];
        String prevUrl;
        int loopCount = 0;

        do {
            prevUrl = lc_url.toString();

            int querypos = lc_url.indexOf("?");
            int schemepos = lc_url.indexOf("://");
            int fragpos = lc_url.indexOf("#");

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

            // if there is a scheme://host:port/
            if (schemepos > -1 && lc_url.length() > schemepos + 4) {
                // Add url without scheme
                synonyms.add(lc_url.substring(schemepos + 3) + zone);

                // Just the URL path, excluding host, including query and fragment strings.
                int pathstart = lc_url.indexOf("/", schemepos + 4);
                if (pathstart > -1) {
                    synonyms.add(lc_url.substring(pathstart) + zone);

                    // without fragment
                    if (fragpos > pathstart) {
                        synonyms.add(lc_url.substring(pathstart, fragpos) + zone);
                    }

                    // without query or fragment
                    if (querypos > pathstart) {
                        synonyms.add(lc_url.substring(pathstart, querypos) + zone);
                    }

                    // Just the host or ip
                    int portpos = lc_url.indexOf(":", schemepos + 4);
                    if (portpos > schemepos && portpos < pathstart) {
                        synonyms.add(lc_url.substring(schemepos + 3, portpos) + zone);
                    } else {
                        synonyms.add(lc_url.substring(schemepos + 3, pathstart) + zone);
                    }
                }
            }

            // Index the the fragment separately if there is one
            if (fragpos > -1) {
                synonyms.add(lc_url.substring(0, fragpos) + zone);
                if (fragpos + 1 < lc_url.length()) {
                    String frag = lc_url.substring(fragpos + 1);

                    synonyms.add(frag + zone);
                }
            }

            // Index the query string separately if there is one.
            if (querypos > -1 && querypos < lc_url.length() - 1) {
                int endq = fragpos > querypos ? fragpos : lc_url.length();
                synonyms.add(lc_url.substring(0, querypos) + zone);
                String params[] = lc_url.substring(querypos + 1, endq).split("&");
                for (String param : params) {
                    if (param.length() > 0) {
                        try {
                            String decoded = urlDecode(param);
                            synonyms.add(decoded + zone);

                            // See if we have an embedded url or email address as a parameter
                            if (param.indexOf("=") > 0) {
                                String kv[] = decoded.split("=", 2);
                                if (kv != null && kv.length == 2 && kv[1].length() > 4) {
                                    if (kv[1].startsWith("http://") || kv[1].startsWith("https://")) {
                                        synonyms.addAll(urlTokens(new String[] {kv[1], zone}, false, includeTerm));
                                    } else if (kv[1].indexOf("@") > 0) {
                                        int atPos = kv[1].indexOf("@");
                                        synonyms.add(kv[1] + zone);
                                        if (atPos + 1 < kv[1].length()) {
                                            synonyms.add(kv[1].substring(atPos) + zone);
                                        }
                                    }
                                }
                            }
                        } catch (Throwable t) {
                            logger.warn("Exception caught when URLDecoding parameter, using encoded version: " + param, t);
                            synonyms.add(param + zone);
                        }
                    }

                }
            }

            // Decompose the url to find the path and then chop off the leading
            // bits to produce a series of tokens include sub-paths. Eventually
            // this should produce the filename referenced by the url.
            String url_path = lc_url;

            // trim fragpos, this should appear after the querypos, so we do
            // it first.
            if (fragpos > -1) {
                url_path = url_path.substring(0, fragpos);
            }

            // trim querypos that appears in the string prior to the fragpos
            if (querypos > -1 && querypos < url_path.length() && ((querypos <= fragpos) || fragpos < 0)) {
                url_path = url_path.substring(0, querypos);
            }

            // trim leading scheme
            if (schemepos > -1 && schemepos + 3 < url_path.length()) {
                url_path = url_path.substring(schemepos + 3);
            }

            // collapse multiple slashes.
            if (url_path.indexOf("//") > -1) {
                url_path = url_path.replaceAll("/+", "/");
            }

            // trim trailing slash.
            if (url_path.endsWith("/")) {
                url_path = url_path.substring(0, url_path.length() - 1);
            }

            // trim leading path segments, adding each as a synonym.
            int slashpos = url_path.indexOf("/");
            while (slashpos > -1 && (slashpos < (url_path.length() - 1))) {
                synonyms.add(url_path.substring(slashpos + 1) + zone);
                slashpos = url_path.indexOf("/", slashpos + 1);
            }

            // Index words from this url
            if (urlWordTokensEnabled) {
                getTokenWords(lc_url, zone, synonyms);
            }

            try {
                lc_url = urlDecode(lc_url);
            } catch (Throwable t) {
                logger.warn("Exception caught when URLDecoding url, using encoded version: " + lc_url, t);
            }

        } while (!lc_url.toString().equals(prevUrl.toString()) && ++loopCount <= maxUrlDecodes);

        return synonyms;
    }

    @Override
    public Collection<String> urlTokens(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_url = zw[0].toLowerCase();
        String zone = zw[1];
        String prevUrl;
        int loopCount = 0;

        do {
            prevUrl = lc_url.toString();

            int querypos = lc_url.indexOf("?");
            int schemepos = lc_url.indexOf("://");
            int fragpos = lc_url.indexOf("#");

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

            // if there is a scheme://host:port/
            if (schemepos > -1 && lc_url.length() > schemepos + 4) {
                // Add url without scheme
                synonyms.add(lc_url.substring(schemepos + 3) + zone);

                // Just the URL path, excluding host, including query and fragment strings.
                int pathstart = lc_url.indexOf("/", schemepos + 4);
                if (pathstart > -1) {
                    synonyms.add(lc_url.substring(pathstart) + zone);

                    // without fragment
                    if (fragpos > pathstart) {
                        synonyms.add(lc_url.substring(pathstart, fragpos) + zone);
                    }

                    // without query or fragment
                    if (querypos > pathstart) {
                        synonyms.add(lc_url.substring(pathstart, querypos) + zone);
                    }

                    // Just the host or ip
                    int portpos = lc_url.indexOf(":", schemepos + 4);
                    if (portpos > schemepos && portpos < pathstart) {
                        synonyms.add(lc_url.substring(schemepos + 3, portpos) + zone);
                    } else {
                        synonyms.add(lc_url.substring(schemepos + 3, pathstart) + zone);
                    }
                }
            }

            // Index the the fragment separately if there is one
            if (fragpos > -1) {
                synonyms.add(lc_url.substring(0, fragpos) + zone);
                if (fragpos + 1 < lc_url.length()) {
                    String frag = lc_url.substring(fragpos + 1);

                    synonyms.add(frag + zone);
                }
            }

            // Index the query string separately if there is one.
            if (querypos > -1 && querypos < lc_url.length() - 1) {
                int endq = fragpos > querypos ? fragpos : lc_url.length();
                synonyms.add(lc_url.substring(0, querypos) + zone);
                String params[] = lc_url.substring(querypos + 1, endq).split("&");
                for (String param : params) {
                    if (param.length() > 0) {
                        try {
                            String decoded = urlDecode(param);
                            synonyms.add(decoded + zone);

                            // See if we have an embedded url or email address as a parameter
                            if (param.indexOf("=") > 0) {
                                String kv[] = decoded.split("=", 2);
                                if (kv != null && kv.length == 2 && kv[1].length() > 4) {
                                    if (kv[1].startsWith("http://") || kv[1].startsWith("https://")) {
                                        synonyms.addAll(urlTokens(new String[] {kv[1], zone}, false, includeTerm));
                                    } else if (kv[1].indexOf("@") > 0) {
                                        int atPos = kv[1].indexOf("@");
                                        synonyms.add(kv[1] + zone);
                                        if (atPos + 1 < kv[1].length()) {
                                            synonyms.add(kv[1].substring(atPos) + zone);
                                        }
                                    }
                                }
                            }
                        } catch (Throwable t) {
                            logger.warn("Exception caught when URLDecoding parameter, using encoded version: " + param, t);
                            synonyms.add(param + zone);
                        }
                    }

                }
            }

            // Decompose the url to find the path and then chop off the leading
            // bits to produce a series of tokens include sub-paths. Eventually
            // this should produce the filename referenced by the url.
            String url_path = lc_url;

            // trim fragpos, this should appear after the querypos, so we do
            // it first.
            if (fragpos > -1) {
                url_path = url_path.substring(0, fragpos);
            }

            // trim querypos that appears in the string prior to the fragpos
            if (querypos > -1 && querypos < url_path.length() && ((querypos <= fragpos) || fragpos < 0)) {
                url_path = url_path.substring(0, querypos);
            }

            // trim leading scheme
            if (schemepos > -1 && schemepos + 3 < url_path.length()) {
                url_path = url_path.substring(schemepos + 3);
            }

            // collapse multiple slashes.
            if (url_path.indexOf("//") > -1) {
                url_path = url_path.replaceAll("/+", "/");
            }

            // trim trailing slash.
            if (url_path.endsWith("/")) {
                url_path = url_path.substring(0, url_path.length() - 1);
            }

            // trim leading path segments, adding each as a synonym.
            int slashpos = url_path.indexOf("/");
            while (slashpos > -1 && (slashpos < (url_path.length() - 1))) {
                synonyms.add(url_path.substring(slashpos + 1) + zone);
                slashpos = url_path.indexOf("/", slashpos + 1);
            }

            // Index words from this url
            if (urlWordTokensEnabled) {
                getTokenWords(lc_url, zone, synonyms);
            }

            try {
                lc_url = urlDecode(lc_url);
            } catch (Throwable t) {
                logger.warn("Exception caught when URLDecoding url, using encoded version: " + lc_url, t);
            }

        } while (!lc_url.toString().equals(prevUrl.toString()) && ++loopCount <= maxUrlDecodes);

        return synonyms;
    }

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


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

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

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


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

        if (term[1] == null)
            term[1] = "";

        // Include the downcased term if it is different from the original
        // token or if the includeTerm flag is raised.
        String lctok = term[0].toLowerCase();
        if (!isStop(lctok) && (!term[0].equals(lctok) || includeTerm)) {
            synonyms.add(lctok + term[1]);
        }

        // Check term with diacritics stripped
        String stok = AccentFilter.strip(term[0]);
        if (!term[0].equals(stok) && !isStop(stok)) {
            // Check lowercase stripped term
            String lcstok = stok.toLowerCase();
            if (!isStop(lcstok)) {
                synonyms.add(lcstok + term[1]);
            }
        }

        // UNDERSCORE, ALPHANUM, NUM and other token types that arrive here
        // may have internal non-alpha characters.
        if (termWordTokensEnabled) {
            getTokenWords(lctok, term[1], synonyms);
        } else if (term[0].indexOf('_') > -1) {
            // UNDERSCORE is always word tokenized to preserve backwards compatibility
            getTokenWords(lctok, term[1], synonyms);
        }

        return synonyms;
    }

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

        if (term[1] == null)
            term[1] = "";

        // Include the downcased term if it is different from the original
        // token or if the includeTerm flag is raised.
        String lctok = term[0].toLowerCase();
        if (!isStop(lctok) && (!term[0].equals(lctok) || includeTerm)) {
            synonyms.add(lctok + term[1]);
        }

        // Check term with diacritics stripped
        String stok = AccentFilter.strip(term[0]);
        if (!term[0].equals(stok) && !isStop(stok)) {
            // Check lowercase stripped term
            String lcstok = stok.toLowerCase();
            if (!isStop(lcstok)) {
                synonyms.add(lcstok + term[1]);
            }
        }

        // UNDERSCORE, ALPHANUM, NUM and other token types that arrive here
        // may have internal non-alpha characters.
        if (termWordTokensEnabled) {
            getTokenWords(lctok, term[1], synonyms);
        } else if (term[0].indexOf('_') > -1) {
            // UNDERSCORE is always word tokenized to preserve backwards compatibility
            getTokenWords(lctok, term[1], synonyms);
        }

        return synonyms;
    }

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


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

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

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


    public void initializeEvent(final Configuration conf) throws IOException {
        // see if we have a data type override
        final String dataName = conf.get(Properties.DATA_NAME_OVERRIDE);
        if (dataName != null)
            conf.set(Properties.DATA_NAME, dataName);

        // In case the type registry is not already setup
        TypeRegistry.getInstance(conf);

        compressionCodecs = new CompressionCodecFactory(conf);

        helper = createHelper(conf);
        helper.setup(conf);

        // Get the event date field, its optional. If specified, get the format
        eventDateFieldName = conf.get(helper.getType().typeName() + Properties.EVENT_DATE_FIELD_NAME);

        if (!StringUtils.isEmpty(eventDateFieldName)) {
            String eventDateFieldFormat = conf.get(helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMAT);
            String[] eventDateFieldFormats = conf.getStrings(helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMATS);

            if (eventDateFieldFormat == null && eventDateFieldFormats == null) {
                throw new IllegalArgumentException("Neither " + helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMAT + " nor "
                                + helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMATS + " was specified");
            } else if (eventDateFieldFormat != null && eventDateFieldFormats != null) {
                throw new IllegalArgumentException("Both " + helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMAT + " and "
                                + helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMATS + " must not be specified, choose one");
            }

            if (eventDateFieldFormat != null) {
                formatter = new SimpleDateFormat(eventDateFieldFormat);
            }

            if (eventDateFieldFormats != null) { // getStrings will change 0 length strings to nulls
                formatters = new ArrayList<>(eventDateFieldFormats.length);
                for (String fmt : eventDateFieldFormats) {
                    formatters.add(new SimpleDateFormat(fmt));
                }
            }
        }

        initializeEventMarkingsHelper(conf, helper);

        final String[] uidFields = conf.getStrings(helper.getType().typeName() + Properties.EVENT_UID_FIELDS);
        if (uidFields != null)
            for (final String field : uidFields)
                uidOverrideFields.put(field, null);

        final String[] uuidFieldSet = conf.getStrings(helper.getType().typeName() + Properties.EVENT_UUID_FIELDS);
        if (uuidFieldSet != null)
            uuidFields = Sets.newHashSet(uuidFieldSet);

        if (Configurable.class.isAssignableFrom(event.getClass())) {
            ((Configurable) event).setConf(conf);
        }

        this.policyEnforcer = helper.getPolicyEnforcer();

        // Update the UID builder based on the configuration
        uidBuilder = UID.builder(conf);
    }

    public void initializeEvent(final Configuration conf) throws IOException {
        // see if we have a data type override
        final String dataName = conf.get(Properties.DATA_NAME_OVERRIDE);
        if (dataName != null)
            conf.set(Properties.DATA_NAME, dataName);

        // In case the type registry is not already setup
        TypeRegistry.getInstance(conf);

        compressionCodecs = new CompressionCodecFactory(conf);

        helper = createHelper(conf);
        helper.setup(conf);

        // Get the event date field, its optional. If specified, get the format
        eventDateFieldName = conf.get(helper.getType().typeName() + Properties.EVENT_DATE_FIELD_NAME);

        if (!StringUtils.isEmpty(eventDateFieldName)) {
            String eventDateFieldFormat = conf.get(helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMAT);
            String[] eventDateFieldFormats = conf.getStrings(helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMATS);

            if (eventDateFieldFormat == null && eventDateFieldFormats == null) {
                throw new IllegalArgumentException("Neither " + helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMAT + " nor "
                                + helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMATS + " was specified");
            } else if (eventDateFieldFormat != null && eventDateFieldFormats != null) {
                throw new IllegalArgumentException("Both " + helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMAT + " and "
                                + helper.getType().typeName() + Properties.EVENT_DATE_FIELD_FORMATS + " must not be specified, choose one");
            }

            if (eventDateFieldFormat != null) {
                formatter = new SimpleDateFormat(eventDateFieldFormat);
            }

            if (eventDateFieldFormats != null) { // getStrings will change 0 length strings to nulls
                formatters = new ArrayList<SimpleDateFormat>(eventDateFieldFormats.length);
                for (String fmt : eventDateFieldFormats) {
                    formatters.add(new SimpleDateFormat(fmt));
                }
            }
        }

        initializeEventMarkingsHelper(conf, helper);

        final String[] uidFields = conf.getStrings(helper.getType().typeName() + Properties.EVENT_UID_FIELDS);
        if (uidFields != null)
            for (final String field : uidFields)
                uidOverrideFields.put(field, null);

        final String[] uuidFieldSet = conf.getStrings(helper.getType().typeName() + Properties.EVENT_UUID_FIELDS);
        if (uuidFieldSet != null)
            uuidFields = Sets.newHashSet(uuidFieldSet);

        if (Configurable.class.isAssignableFrom(event.getClass())) {
            ((Configurable) event).setConf(conf);
        }

        this.policyEnforcer = helper.getPolicyEnforcer();

        // Update the UID builder based on the configuration
        uidBuilder = UID.builder(conf);
    }

Replace Generic With Diamond ArrayList<SimpleDateFormat> with ArrayList<> in method public initializeEvent(conf Configuration) : void from class datawave.ingest.input.reader.AbstractEventRecordReader


    protected void extractEventDate(final String fieldName, final String fieldValue) {
        if (formatters != null && formatter != null) {
            throw new IllegalStateException("Both 'formatter' and 'formatters' are set. Please define a single event date mechanism");
        } else if (formatters != null) {
            for (SimpleDateFormat format : formatters) {
                try {
                    event.setDate(format.parse(DateNormalizer.convertMicroseconds(fieldValue, format.toPattern())).getTime());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Parsed date from '" + fieldName + "' using formatter " + format.toPattern());
                    }
                    break;
                } catch (java.text.ParseException e) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Error parsing date from hash record using format " + format.toPattern(), e);
                    }
                }
            }
            if (event.getDate() == 0L) {
                List<String> patterns = new ArrayList<>(formatters.size());
                for (SimpleDateFormat formatter : formatters) {
                    patterns.add(formatter.toPattern());
                }
                logger.error("Unable to parse date '" + fieldValue + "' from field '" + fieldName + " using formatters " + patterns);
            }
        } else if (formatter != null) {
            try {
                event.setDate(formatter.parse(DateNormalizer.convertMicroseconds(fieldValue, formatter.toPattern())).getTime());
            } catch (java.text.ParseException e) {
                logger.error("Error parsing date from hash record", e);
            }
        } else {
            throw new IllegalArgumentException("No event data formatters are set");
        }
    }

    protected void extractEventDate(final String fieldName, final String fieldValue) {
        if (formatters != null && formatter != null) {
            throw new IllegalStateException("Both 'formatter' and 'formatters' are set. Please define a single event date mechanism");
        } else if (formatters != null) {
            for (SimpleDateFormat format : formatters) {
                try {
                    event.setDate(format.parse(DateNormalizer.convertMicroseconds(fieldValue, format.toPattern())).getTime());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Parsed date from '" + fieldName + "' using formatter " + format.toPattern());
                    }
                    break;
                } catch (java.text.ParseException e) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Error parsing date from hash record using format " + format.toPattern(), e);
                    }
                }
            }
            if (event.getDate() == 0L) {
                List<String> patterns = new ArrayList<String>(formatters.size());
                for (SimpleDateFormat formatter : formatters) {
                    patterns.add(formatter.toPattern());
                }
                logger.error("Unable to parse date '" + fieldValue + "' from field '" + fieldName + " using formatters " + patterns);
            }
        } else if (formatter != null) {
            try {
                event.setDate(formatter.parse(DateNormalizer.convertMicroseconds(fieldValue, formatter.toPattern())).getTime());
            } catch (java.text.ParseException e) {
                logger.error("Error parsing date from hash record", e);
            }
        } else {
            throw new IllegalArgumentException("No event data formatters are set");
        }
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method protected extractEventDate(fieldName String, fieldValue String) : void from class datawave.ingest.input.reader.AbstractEventRecordReader


    /**
     * Get the data type handlers for a given type name. This will also fill the dataTypeDiscardIntervalCache and the validators as a side effect.
     *
     * @return the data type handlers
     */
    private List<DataTypeHandler<K1>> loadDataType(String typeStr, Context context) {
        // Do not load the type twice
        if (!typeMap.containsKey(typeStr)) {

            typeMap.put(typeStr, new ArrayList<>());

            long myInterval = context.getConfiguration().getLong(typeStr + "." + DISCARD_INTERVAL, interval);

            dataTypeDiscardIntervalCache.put(typeStr, myInterval);

            log.info("Setting up type: " + typeStr + " with interval " + myInterval);

            if (!TypeRegistry.getTypeNames().contains(typeStr)) {
                log.warn("Attempted to load configuration for a type that does not exist in the registry: " + typeStr);
            } else {
                Type t = TypeRegistry.getType(typeStr);
                String fieldValidators = context.getConfiguration().get(typeStr + FieldValidator.FIELD_VALIDATOR_NAMES);

                if (fieldValidators != null) {
                    String[] validatorClasses = StringUtils.split(fieldValidators, ",");
                    for (String validatorClass : validatorClasses) {
                        try {
                            Class<? extends FieldValidator> clazz = Class.forName(validatorClass).asSubclass(FieldValidator.class);
                            FieldValidator validator = clazz.newInstance();
                            validator.init(t, context.getConfiguration());
                            validators.put(typeStr, validator);
                        } catch (ClassNotFoundException e) {
                            log.error("Error finding validator " + validatorClass, e);
                        } catch (InstantiationException | IllegalAccessException e) {
                            log.error("Error creating validator " + validatorClass, e);
                        }
                    }
                }

                String[] handlerClassNames = t.getDefaultDataTypeHandlers();

                if (handlerClassNames != null) {
                    for (String handlerClassName : handlerClassNames) {
                        log.info("Configuring handler: " + handlerClassName);
                        try {
                            @SuppressWarnings("unchecked")
                            Class<? extends DataTypeHandler<K1>> clazz = (Class<? extends DataTypeHandler<K1>>) Class.forName(handlerClassName);
                            DataTypeHandler<K1> h = clazz.newInstance();
                            // Create a counter initialized to zero for all handler types.
                            getCounter(context, IngestOutput.ROWS_CREATED.name(), h.getClass().getSimpleName()).increment(0);
                            // Trick here. Set the data.name parameter to type T, then call setup on the DataTypeHandler
                            Configuration clone = new Configuration(context.getConfiguration());
                            clone.set(DataTypeHelper.Properties.DATA_NAME, t.typeName());
                            // Use the StandaloneReporter and StandaloneTaskAttemptContext for the Handlers. Because the StandaloneTaskAttemptContext
                            // is a subclass of TaskInputOutputContext and TaskAttemptContext is not. We are using this to record the counters during
                            // processing. We will need to add the counters in the StandaloneReporter to the Map.Context in the close call.
                            // TaskAttemptContext newContext = new TaskAttemptContext(clone, context.getTaskAttemptID());
                            StandaloneTaskAttemptContext<K1,V1,K2,V2> newContext = new StandaloneTaskAttemptContext<>(clone, reporter);
                            h.setup(newContext);
                            typeMap.get(typeStr).add(h);
                        } catch (ClassNotFoundException e) {
                            log.error("Error finding DataTypeHandler " + handlerClassName, e);
                        } catch (InstantiationException | IllegalAccessException e) {
                            log.error("Error creating DataTypeHandler " + handlerClassName, e);
                        }
                    }
                }
            }
            log.info("EventMapper configured with the following handlers for " + typeStr + ": " + typeMap.get(typeStr));
        }

        return typeMap.get(typeStr);
    }

    /**
     * Get the data type handlers for a given type name. This will also fill the dataTypeDiscardIntervalCache and the validators as a side effect.
     *
     * @return the data type handlers
     */
    private List<DataTypeHandler<K1>> loadDataType(String typeStr, Context context) {
        // Do not load the type twice
        if (!typeMap.containsKey(typeStr)) {

            typeMap.put(typeStr, new ArrayList<DataTypeHandler<K1>>());

            long myInterval = context.getConfiguration().getLong(typeStr + "." + DISCARD_INTERVAL, interval);

            dataTypeDiscardIntervalCache.put(typeStr, myInterval);

            log.info("Setting up type: " + typeStr + " with interval " + myInterval);

            if (!TypeRegistry.getTypeNames().contains(typeStr)) {
                log.warn("Attempted to load configuration for a type that does not exist in the registry: " + typeStr);
            } else {
                Type t = TypeRegistry.getType(typeStr);
                String fieldValidators = context.getConfiguration().get(typeStr + FieldValidator.FIELD_VALIDATOR_NAMES);

                if (fieldValidators != null) {
                    String[] validatorClasses = StringUtils.split(fieldValidators, ",");
                    for (String validatorClass : validatorClasses) {
                        try {
                            Class<? extends FieldValidator> clazz = Class.forName(validatorClass).asSubclass(FieldValidator.class);
                            FieldValidator validator = clazz.newInstance();
                            validator.init(t, context.getConfiguration());
                            validators.put(typeStr, validator);
                        } catch (ClassNotFoundException e) {
                            log.error("Error finding validator " + validatorClass, e);
                        } catch (InstantiationException | IllegalAccessException e) {
                            log.error("Error creating validator " + validatorClass, e);
                        }
                    }
                }

                String[] handlerClassNames = t.getDefaultDataTypeHandlers();

                if (handlerClassNames != null) {
                    for (String handlerClassName : handlerClassNames) {
                        log.info("Configuring handler: " + handlerClassName);
                        try {
                            @SuppressWarnings("unchecked")
                            Class<? extends DataTypeHandler<K1>> clazz = (Class<? extends DataTypeHandler<K1>>) Class.forName(handlerClassName);
                            DataTypeHandler<K1> h = clazz.newInstance();
                            // Create a counter initialized to zero for all handler types.
                            getCounter(context, IngestOutput.ROWS_CREATED.name(), h.getClass().getSimpleName()).increment(0);
                            // Trick here. Set the data.name parameter to type T, then call setup on the DataTypeHandler
                            Configuration clone = new Configuration(context.getConfiguration());
                            clone.set(DataTypeHelper.Properties.DATA_NAME, t.typeName());
                            // Use the StandaloneReporter and StandaloneTaskAttemptContext for the Handlers. Because the StandaloneTaskAttemptContext
                            // is a subclass of TaskInputOutputContext and TaskAttemptContext is not. We are using this to record the counters during
                            // processing. We will need to add the counters in the StandaloneReporter to the Map.Context in the close call.
                            // TaskAttemptContext newContext = new TaskAttemptContext(clone, context.getTaskAttemptID());
                            StandaloneTaskAttemptContext<K1,V1,K2,V2> newContext = new StandaloneTaskAttemptContext<>(clone, reporter);
                            h.setup(newContext);
                            typeMap.get(typeStr).add(h);
                        } catch (ClassNotFoundException e) {
                            log.error("Error finding DataTypeHandler " + handlerClassName, e);
                        } catch (InstantiationException | IllegalAccessException e) {
                            log.error("Error creating DataTypeHandler " + handlerClassName, e);
                        }
                    }
                }
            }
            log.info("EventMapper configured with the following handlers for " + typeStr + ": " + typeMap.get(typeStr));
        }

        return typeMap.get(typeStr);
    }

Replace Generic With Diamond ArrayList<DataTypeHandler<K1>> with ArrayList<> in method private loadDataType(typeStr String, context Context) : List<DataTypeHandler<K1>> from class datawave.ingest.mapreduce.EventMapper


    public Set<String> getFields(Type dataType, String type) {
        Multimap<String,String> typeToFields = dataTypeToTypeToFields.get(dataType.typeName());
        if (typeToFields != null) {
            return Collections.unmodifiableSet(new HashSet<>(typeToFields.get(type)));
        } else {
            return Collections.emptySet();
        }
    }

    public Set<String> getFields(Type dataType, String type) {
        Multimap<String,String> typeToFields = dataTypeToTypeToFields.get(dataType.typeName());
        if (typeToFields != null) {
            return Collections.unmodifiableSet(new HashSet<String>(typeToFields.get(type)));
        } else {
            return Collections.emptySet();
        }
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public getFields(dataType Type, type String) : Set<String> from class datawave.ingest.mapreduce.handler.dateindex.DateIndexDataTypeHandler


    public Set<String> getFields(Type dataType) {
        Multimap<String,String> typeToFields = dataTypeToTypeToFields.get(dataType.typeName());
        if (typeToFields != null) {
            return Collections.unmodifiableSet(new HashSet<>(typeToFields.values()));
        } else {
            return Collections.emptySet();
        }
    }

    public Set<String> getFields(Type dataType) {
        Multimap<String,String> typeToFields = dataTypeToTypeToFields.get(dataType.typeName());
        if (typeToFields != null) {
            return Collections.unmodifiableSet(new HashSet<String>(typeToFields.values()));
        } else {
            return Collections.emptySet();
        }
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public getFields(dataType Type) : Set<String> from class datawave.ingest.mapreduce.handler.dateindex.DateIndexDataTypeHandler


    @Override
    public void setup(TaskAttemptContext context) {
        this.taskAttemptContext = context;
        this.conf = context.getConfiguration();
        this.shardIdFactory = new ShardIdFactory(conf);

        String tableName = conf.get(DATEINDEX_TNAME, null);
        if (null == tableName) {
            log.error(DATEINDEX_TNAME + " not specified, no date index will be created");
        } else {
            setDateIndexTableName(new Text(tableName));
        }

        this.dateIndexNumShards = conf.getInt(DATEINDEX_NUM_SHARDS, this.dateIndexNumShards);

        TypeRegistry registry = TypeRegistry.getInstance(conf);

        // instantiate the mapping of types to fields
        // now get the dates to be index for this datatype
        dataTypeToTypeToFields = new HashMap<>();
        for (Type dataType : registry.getTypes()) {
            Set<String> typeToFieldsSet = new HashSet<>();
            typeToFieldsSet.addAll(conf.getTrimmedStringCollection("all" + DATEINDEX_TYPE_TO_FIELDS));
            typeToFieldsSet.addAll(conf.getTrimmedStringCollection(dataType.typeName() + DATEINDEX_TYPE_TO_FIELDS));
            Multimap<String,String> typeToFields = HashMultimap.create();
            for (String typeToField : typeToFieldsSet) {
                String[] parts = StringUtils.split(typeToField, '=');
                if (parts.length != 2) {
                    throw new IllegalStateException("Improper date index type to field configuration: " + typeToField);
                }
                typeToFields.put(parts[0], parts[1]);
            }
            log.info(this.getClass().getSimpleName() + " configured for " + dataType.typeName() + ": " + typeToFields);
            dataTypeToTypeToFields.put(dataType.typeName(), typeToFields);
        }
    }

    @Override
    public void setup(TaskAttemptContext context) {
        this.taskAttemptContext = context;
        this.conf = context.getConfiguration();
        this.shardIdFactory = new ShardIdFactory(conf);

        String tableName = conf.get(DATEINDEX_TNAME, null);
        if (null == tableName) {
            log.error(DATEINDEX_TNAME + " not specified, no date index will be created");
        } else {
            setDateIndexTableName(new Text(tableName));
        }

        this.dateIndexNumShards = conf.getInt(DATEINDEX_NUM_SHARDS, this.dateIndexNumShards);

        TypeRegistry registry = TypeRegistry.getInstance(conf);

        // instantiate the mapping of types to fields
        // now get the dates to be index for this datatype
        dataTypeToTypeToFields = new HashMap<>();
        for (Type dataType : registry.getTypes()) {
            Set<String> typeToFieldsSet = new HashSet<String>();
            typeToFieldsSet.addAll(conf.getTrimmedStringCollection("all" + DATEINDEX_TYPE_TO_FIELDS));
            typeToFieldsSet.addAll(conf.getTrimmedStringCollection(dataType.typeName() + DATEINDEX_TYPE_TO_FIELDS));
            Multimap<String,String> typeToFields = HashMultimap.create();
            for (String typeToField : typeToFieldsSet) {
                String[] parts = StringUtils.split(typeToField, '=');
                if (parts.length != 2) {
                    throw new IllegalStateException("Improper date index type to field configuration: " + typeToField);
                }
                typeToFields.put(parts[0], parts[1]);
            }
            log.info(this.getClass().getSimpleName() + " configured for " + dataType.typeName() + ": " + typeToFields);
            dataTypeToTypeToFields.put(dataType.typeName(), typeToFields);
        }
    }

Replace Generic With Diamond HashSet<String> with HashSet<> in method public setup(context TaskAttemptContext) : void from class datawave.ingest.mapreduce.handler.dateindex.DateIndexDataTypeHandler


    public void setup(Configuration conf) {

        markingFunctions = MarkingFunctions.Factory.createMarkingFunctions();

        // This will fail if the TypeRegistry has not been initialized in the VM.
        TypeRegistry registry = TypeRegistry.getInstance(conf);

        // Grab the edge table name
        this.edgeTableName = ConfigurationHelper.isNull(conf, EDGE_TABLE_NAME, String.class);
        this.useStatsLogBloomFilter = conf.getBoolean(EDGE_STATS_LOG_USE_BLOOM, false);
        this.metadataTableName = ConfigurationHelper.isNull(conf, METADATA_TABLE_NAME, String.class);

        this.enableBlacklist = ConfigurationHelper.isNull(conf, EDGE_TABLE_BLACKIST_ENABLE, Boolean.class);
        this.enableMetadata = ConfigurationHelper.isNull(conf, EDGE_TABLE_METADATA_ENABLE, Boolean.class);

        setUpFailurePolicy = FailurePolicy.valueOf(conf.get(EDGE_SETUP_FAILURE_POLICY));
        processFailurePolicy = FailurePolicy.valueOf(conf.get(EDGE_PROCESS_FAILURE_POLICY));

        String springConfigFile = ConfigurationHelper.isNull(conf, EDGE_SPRING_CONFIG, String.class);
        futureDelta = ConfigurationHelper.isNull(conf, ACTIVITY_DATE_FUTURE_DELTA, Long.class);
        pastDelta = ConfigurationHelper.isNull(conf, ACTIVITY_DATE_PAST_DELTA, Long.class);

        evaluatePreconditions = Boolean.parseBoolean(conf.get(EVALUATE_PRECONDITIONS));
        includeAllEdges = Boolean.parseBoolean(conf.get(INCLUDE_ALL_EDGES));

        if (this.versioningCache == null) {
            this.versioningCache = new EdgeKeyVersioningCache(conf);
        }

        try {
            // Only one known edge key version so we simply grab the first one here

            // expected to be in the "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" format
            String startDate = versioningCache.getEdgeKeyVersionDateChange().entrySet().iterator().next().getValue();
            newFormatStartDate = DateNormalizer.parseDate(startDate, DateNormalizer.FORMAT_STRINGS).getTime();
            log.info("Edge key version change date set to: " + startDate);
        } catch (IOException e) {
            log.error("IO Exception could not get edge key version cache, will not generate edges!");
            if (setUpFailurePolicy == FailurePolicy.FAIL_JOB) {
                throw new RuntimeException("IO Exception could not get edge key version cache " + e.getMessage());
            } else {
                return; // no edges will be created but the ingest job will continue
            }
        } catch (ParseException e) {
            log.error("Unable to parse the switchover date will not generate edges!");
            if (setUpFailurePolicy == FailurePolicy.FAIL_JOB) {
                throw new RuntimeException("Protobufedge handler config not set correctly " + e.getMessage());
            } else {
                return; // no edges will be created but the ingest job will continue
            }
        } catch (NoSuchElementException e) {
            log.error("edge key version cache existed but was empty, will not generate edges");
            if (setUpFailurePolicy == FailurePolicy.FAIL_JOB) {
                throw new RuntimeException("Edge key versioning cache is empty " + e.getMessage());
            } else {
                return; // no edges will be created but the ingest job will continue
            }
        }

        // long term store edge definitions indexed by data type.
        /**
         * Parse and Store the Edge defs by data type
         */
        edges = new HashMap<>();
        ClassPathXmlApplicationContext ctx = null;
        try {
            ctx = new ClassPathXmlApplicationContext(ProtobufEdgeDataTypeHandler.class.getClassLoader().getResource(springConfigFile).toString());

            log.info("Got config on first try!");
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }

        Assert.notNull(ctx);

        registry.put(EDGE_DEFAULT_DATA_TYPE, null);

        // HashSet<String> edgeRelationships, collectionType;

        if (ctx.containsBean(EDGE_SPRING_RELATIONSHIPS) && ctx.containsBean(EDGE_SPRING_COLLECTIONS)) {
            edgeRelationships.addAll((HashSet<String>) ctx.getBean(EDGE_SPRING_RELATIONSHIPS));
            collectionType.addAll((HashSet<String>) ctx.getBean(EDGE_SPRING_COLLECTIONS));
        } else {
            log.error("Edge relationships and or collection types are not configured correctly. Cannot build edge definitions");
            if (setUpFailurePolicy == FailurePolicy.FAIL_JOB) {
                throw new RuntimeException("Missing some spring configurations");
            } else {
                return; // no edges will be created but the ingest job will continue
            }
        }

        for (Entry<String,Type> entry : registry.entrySet()) {
            if (ctx.containsBean(entry.getKey())) {
                EdgeDefinitionConfigurationHelper thing = (EdgeDefinitionConfigurationHelper) ctx.getBean(entry.getKey());

                // Always call init first before getting getting edge defs. This performs validation on the config file
                // and builds the edge pairs/groups
                thing.init(edgeRelationships, collectionType);

                edges.put(entry.getKey(), thing);
                if (thing.getEnrichmentTypeMappings() != null) {
                    edgeTypeLookup.put(entry.getKey(), thing.getEnrichmentTypeMappings());
                }
            }

            if (ctx.containsBean(entry.getKey() + EDGE_TABLE_BLACKLIST_VALUES)) {
                Set<String> values = (HashSet<String>) ctx.getBean(entry.getKey() + EDGE_TABLE_BLACKLIST_VALUES);
                blacklistValueLookup.put(entry.getKey(), new HashSet<>(values));
            }

            if (ctx.containsBean(entry.getKey() + EDGE_TABLE_BLACKLIST_FIELDS)) {
                Set<String> fields = (HashSet<String>) ctx.getBean(entry.getKey() + EDGE_TABLE_BLACKLIST_FIELDS);
                blacklistFieldLookup.put(entry.getKey(), new HashSet<>(fields));
            }

        }
        ctx.close();

        /*
         * The evaluate preconditions boolean determines whether or not we want to set up the Jexl Contexts to run preconditions the includeAllEdges boolean
         * determines whether we want the extra edge definitions from the preconditions included There are three scenarios: the first is you want to run and
         * evaluate preconditions. The evaluatePreconditions boolean will be set to true, the edges will be added, the jext contexts will be set up, and the
         * conditional edges will be evaluated.
         *
         * Second, you don't want to evaluate the conditional edges, but you want them included. The evaluatePreconditions boolean will be set to false so the
         * jext contexts are not set up, but the includeAllEdges boolean will be set to true.
         *
         * Third, you want neither of these done. Both booleans are set to false. The jexl context isn't set up and the conditional edges will be removed as to
         * not waste time evaluating edges where the conditions won't be met
         */
        if (evaluatePreconditions) {
            edgePreconditionContext = new EdgePreconditionJexlContext(edges);
            edgePreconditionEvaluation = new EdgePreconditionJexlEvaluation();
            edgePreconditionCacheHelper = new EdgePreconditionCacheHelper();
            scriptCache = edgePreconditionCacheHelper.createScriptCacheFromEdges(edges);
        } else if (!includeAllEdges) {

            // Else remove edges with a precondition. No conditional edge defs will be evaluated possibly resulting in fewer edges
            log.info("Removing conditional edge definitions, possibly resulting in fewer edges being created");
            removeEdgesWithPreconditions();
        }
        registry.remove(EDGE_DEFAULT_DATA_TYPE);

        // loop through edge definitions and collect any ones that have blacklisted fields
        if (this.enableBlacklist) {
            Map<String,Set<EdgeDefinition>> blacklistedEdges = new HashMap<>();
            for (String dType : edges.keySet()) {
                if (!blacklistedEdges.containsKey(dType)) {
                    blacklistedEdges.put(dType, new HashSet<>());
                }
                for (EdgeDefinition edgeDef : edges.get(dType).getEdges()) {
                    if (isBlacklistField(dType, edgeDef.getSourceFieldName()) || isBlacklistField(dType, edgeDef.getSinkFieldName())) {
                        blacklistedEdges.get(dType).add(edgeDef);
                        log.warn("Removing Edge Definition due to blacklisted Field: DataType: " + dType + " Definition: " + edgeDef.getSourceFieldName() + "-"
                                        + edgeDef.getSinkFieldName());
                    } else if (edgeDef.isEnrichmentEdge()) {
                        if (isBlacklistField(dType, edgeDef.getEnrichmentField())) {
                            blacklistedEdges.get(dType).add(edgeDef);
                        }
                    }
                }
            }
            // remove the blacklistedEdges
            int blacklistedFieldCount = 0;
            for (String dType : blacklistedEdges.keySet()) {
                for (EdgeDefinition edgeDef : blacklistedEdges.get(dType)) {
                    edges.get(dType).getEdges().remove(edgeDef);
                    blacklistedFieldCount++;
                }
            }
            if (blacklistedFieldCount > 0) {
                log.info("Removed " + blacklistedFieldCount + " edge definitions because they contain blacklisted fields.");
            }
        } else {
            log.info("Blacklisting of edges is disabled.");
        }

        log.info("Found edge definitions for " + edges.keySet().size() + " data types.");

        StringBuffer sb = new StringBuffer();
        sb.append("Data Types With Defined Edges: ");
        for (String t : edges.keySet()) {
            sb.append(t).append(" ");
        }
        log.info(sb.toString());
        log.info("ProtobufEdgeDataTypeHandler configured.");

    }

    public void setup(Configuration conf) {

        markingFunctions = MarkingFunctions.Factory.createMarkingFunctions();

        // This will fail if the TypeRegistry has not been initialized in the VM.
        TypeRegistry registry = TypeRegistry.getInstance(conf);

        // Grab the edge table name
        this.edgeTableName = ConfigurationHelper.isNull(conf, EDGE_TABLE_NAME, String.class);
        this.useStatsLogBloomFilter = conf.getBoolean(EDGE_STATS_LOG_USE_BLOOM, false);
        this.metadataTableName = ConfigurationHelper.isNull(conf, METADATA_TABLE_NAME, String.class);

        this.enableBlacklist = ConfigurationHelper.isNull(conf, EDGE_TABLE_BLACKIST_ENABLE, Boolean.class);
        this.enableMetadata = ConfigurationHelper.isNull(conf, EDGE_TABLE_METADATA_ENABLE, Boolean.class);

        setUpFailurePolicy = FailurePolicy.valueOf(conf.get(EDGE_SETUP_FAILURE_POLICY));
        processFailurePolicy = FailurePolicy.valueOf(conf.get(EDGE_PROCESS_FAILURE_POLICY));

        String springConfigFile = ConfigurationHelper.isNull(conf, EDGE_SPRING_CONFIG, String.class);
        futureDelta = ConfigurationHelper.isNull(conf, ACTIVITY_DATE_FUTURE_DELTA, Long.class);
        pastDelta = ConfigurationHelper.isNull(conf, ACTIVITY_DATE_PAST_DELTA, Long.class);

        evaluatePreconditions = Boolean.parseBoolean(conf.get(EVALUATE_PRECONDITIONS));
        includeAllEdges = Boolean.parseBoolean(conf.get(INCLUDE_ALL_EDGES));

        if (this.versioningCache == null) {
            this.versioningCache = new EdgeKeyVersioningCache(conf);
        }

        try {
            // Only one known edge key version so we simply grab the first one here

            // expected to be in the "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" format
            String startDate = versioningCache.getEdgeKeyVersionDateChange().entrySet().iterator().next().getValue();
            newFormatStartDate = DateNormalizer.parseDate(startDate, DateNormalizer.FORMAT_STRINGS).getTime();
            log.info("Edge key version change date set to: " + startDate);
        } catch (IOException e) {
            log.error("IO Exception could not get edge key version cache, will not generate edges!");
            if (setUpFailurePolicy == FailurePolicy.FAIL_JOB) {
                throw new RuntimeException("IO Exception could not get edge key version cache " + e.getMessage());
            } else {
                return; // no edges will be created but the ingest job will continue
            }
        } catch (ParseException e) {
            log.error("Unable to parse the switchover date will not generate edges!");
            if (setUpFailurePolicy == FailurePolicy.FAIL_JOB) {
                throw new RuntimeException("Protobufedge handler config not set correctly " + e.getMessage());
            } else {
                return; // no edges will be created but the ingest job will continue
            }
        } catch (NoSuchElementException e) {
            log.error("edge key version cache existed but was empty, will not generate edges");
            if (setUpFailurePolicy == FailurePolicy.FAIL_JOB) {
                throw new RuntimeException("Edge key versioning cache is empty " + e.getMessage());
            } else {
                return; // no edges will be created but the ingest job will continue
            }
        }

        // long term store edge definitions indexed by data type.
        /**
         * Parse and Store the Edge defs by data type
         */
        edges = new HashMap<>();
        ClassPathXmlApplicationContext ctx = null;
        try {
            ctx = new ClassPathXmlApplicationContext(ProtobufEdgeDataTypeHandler.class.getClassLoader().getResource(springConfigFile).toString());

            log.info("Got config on first try!");
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }

        Assert.notNull(ctx);

        registry.put(EDGE_DEFAULT_DATA_TYPE, null);

        // HashSet<String> edgeRelationships, collectionType;

        if (ctx.containsBean(EDGE_SPRING_RELATIONSHIPS) && ctx.containsBean(EDGE_SPRING_COLLECTIONS)) {
            edgeRelationships.addAll((HashSet<String>) ctx.getBean(EDGE_SPRING_RELATIONSHIPS));
            collectionType.addAll((HashSet<String>) ctx.getBean(EDGE_SPRING_COLLECTIONS));
        } else {
            log.error("Edge relationships and or collection types are not configured correctly. Cannot build edge definitions");
            if (setUpFailurePolicy == FailurePolicy.FAIL_JOB) {
                throw new RuntimeException("Missing some spring configurations");
            } else {
                return; // no edges will be created but the ingest job will continue
            }
        }

        for (Entry<String,Type> entry : registry.entrySet()) {
            if (ctx.containsBean(entry.getKey())) {
                EdgeDefinitionConfigurationHelper thing = (EdgeDefinitionConfigurationHelper) ctx.getBean(entry.getKey());

                // Always call init first before getting getting edge defs. This performs validation on the config file
                // and builds the edge pairs/groups
                thing.init(edgeRelationships, collectionType);

                edges.put(entry.getKey(), thing);
                if (thing.getEnrichmentTypeMappings() != null) {
                    edgeTypeLookup.put(entry.getKey(), thing.getEnrichmentTypeMappings());
                }
            }

            if (ctx.containsBean(entry.getKey() + EDGE_TABLE_BLACKLIST_VALUES)) {
                Set<String> values = (HashSet<String>) ctx.getBean(entry.getKey() + EDGE_TABLE_BLACKLIST_VALUES);
                blacklistValueLookup.put(entry.getKey(), new HashSet<>(values));
            }

            if (ctx.containsBean(entry.getKey() + EDGE_TABLE_BLACKLIST_FIELDS)) {
                Set<String> fields = (HashSet<String>) ctx.getBean(entry.getKey() + EDGE_TABLE_BLACKLIST_FIELDS);
                blacklistFieldLookup.put(entry.getKey(), new HashSet<>(fields));
            }

        }
        ctx.close();

        /*
         * The evaluate preconditions boolean determines whether or not we want to set up the Jexl Contexts to run preconditions the includeAllEdges boolean
         * determines whether we want the extra edge definitions from the preconditions included There are three scenarios: the first is you want to run and
         * evaluate preconditions. The evaluatePreconditions boolean will be set to true, the edges will be added, the jext contexts will be set up, and the
         * conditional edges will be evaluated.
         *
         * Second, you don't want to evaluate the conditional edges, but you want them included. The evaluatePreconditions boolean will be set to false so the
         * jext contexts are not set up, but the includeAllEdges boolean will be set to true.
         *
         * Third, you want neither of these done. Both booleans are set to false. The jexl context isn't set up and the conditional edges will be removed as to
         * not waste time evaluating edges where the conditions won't be met
         */
        if (evaluatePreconditions) {
            edgePreconditionContext = new EdgePreconditionJexlContext(edges);
            edgePreconditionEvaluation = new EdgePreconditionJexlEvaluation();
            edgePreconditionCacheHelper = new EdgePreconditionCacheHelper();
            scriptCache = edgePreconditionCacheHelper.createScriptCacheFromEdges(edges);
        } else if (!includeAllEdges) {

            // Else remove edges with a precondition. No conditional edge defs will be evaluated possibly resulting in fewer edges
            log.info("Removing conditional edge definitions, possibly resulting in fewer edges being created");
            removeEdgesWithPreconditions();
        }
        registry.remove(EDGE_DEFAULT_DATA_TYPE);

        // loop through edge definitions and collect any ones that have blacklisted fields
        if (this.enableBlacklist) {
            Map<String,Set<EdgeDefinition>> blacklistedEdges = new HashMap<>();
            for (String dType : edges.keySet()) {
                if (!blacklistedEdges.containsKey(dType)) {
                    blacklistedEdges.put(dType, new HashSet<EdgeDefinition>());
                }
                for (EdgeDefinition edgeDef : edges.get(dType).getEdges()) {
                    if (isBlacklistField(dType, edgeDef.getSourceFieldName()) || isBlacklistField(dType, edgeDef.getSinkFieldName())) {
                        blacklistedEdges.get(dType).add(edgeDef);
                        log.warn("Removing Edge Definition due to blacklisted Field: DataType: " + dType + " Definition: " + edgeDef.getSourceFieldName() + "-"
                                        + edgeDef.getSinkFieldName());
                    } else if (edgeDef.isEnrichmentEdge()) {
                        if (isBlacklistField(dType, edgeDef.getEnrichmentField())) {
                            blacklistedEdges.get(dType).add(edgeDef);
                        }
                    }
                }
            }
            // remove the blacklistedEdges
            int blacklistedFieldCount = 0;
            for (String dType : blacklistedEdges.keySet()) {
                for (EdgeDefinition edgeDef : blacklistedEdges.get(dType)) {
                    edges.get(dType).getEdges().remove(edgeDef);
                    blacklistedFieldCount++;
                }
            }
            if (blacklistedFieldCount > 0) {
                log.info("Removed " + blacklistedFieldCount + " edge definitions because they contain blacklisted fields.");
            }
        } else {
            log.info("Blacklisting of edges is disabled.");
        }

        log.info("Found edge definitions for " + edges.keySet().size() + " data types.");

        StringBuffer sb = new StringBuffer();
        sb.append("Data Types With Defined Edges: ");
        for (String t : edges.keySet()) {
            sb.append(t).append(" ");
        }
        log.info(sb.toString());
        log.info("ProtobufEdgeDataTypeHandler configured.");

    }

Replace Generic With Diamond HashSet<EdgeDefinition> with HashSet<> in method public setup(conf Configuration) : void from class datawave.ingest.mapreduce.handler.edge.ProtobufEdgeDataTypeHandler


    /**
     * When EVALUATE_PRECONDITIONS is false, remove edges with preconditions from consideration.
     */
    private void removeEdgesWithPreconditions() {
        Map<String,Set<EdgeDefinition>> preconditionEdges = new HashMap<>();
        for (String dType : edges.keySet()) {
            if (!preconditionEdges.containsKey(dType)) {
                preconditionEdges.put(dType, new HashSet<>());
            }
            for (EdgeDefinition edgeDef : edges.get(dType).getEdges()) {
                if (edgeDef.hasJexlPrecondition()) {
                    preconditionEdges.get(dType).add(edgeDef);
                }
            }
        }

        // remove the edges with preconditions
        int removedCount = 0;
        for (String dType : preconditionEdges.keySet()) {
            for (EdgeDefinition edgeDef : preconditionEdges.get(dType)) {
                edges.get(dType).getEdges().remove(edgeDef);
                removedCount++;
            }
        }
        if (log.isTraceEnabled()) {
            log.trace("Removed " + removedCount + " edges with preconditions prior to event processing.");
        }

    }

    /**
     * When EVALUATE_PRECONDITIONS is false, remove edges with preconditions from consideration.
     */
    private void removeEdgesWithPreconditions() {
        Map<String,Set<EdgeDefinition>> preconditionEdges = new HashMap<>();
        for (String dType : edges.keySet()) {
            if (!preconditionEdges.containsKey(dType)) {
                preconditionEdges.put(dType, new HashSet<EdgeDefinition>());
            }
            for (EdgeDefinition edgeDef : edges.get(dType).getEdges()) {
                if (edgeDef.hasJexlPrecondition()) {
                    preconditionEdges.get(dType).add(edgeDef);
                }
            }
        }

        // remove the edges with preconditions
        int removedCount = 0;
        for (String dType : preconditionEdges.keySet()) {
            for (EdgeDefinition edgeDef : preconditionEdges.get(dType)) {
                edges.get(dType).getEdges().remove(edgeDef);
                removedCount++;
            }
        }
        if (log.isTraceEnabled()) {
            log.trace("Removed " + removedCount + " edges with preconditions prior to event processing.");
        }

    }

Replace Generic With Diamond HashSet<EdgeDefinition> with HashSet<> in method private removeEdgesWithPreconditions() : void from class datawave.ingest.mapreduce.handler.edge.ProtobufEdgeDataTypeHandler


    /**
     * Given a {@link Configuration}, this method returns the required locality groups used by the edge table.
     */
    public static Map<String,Set<Text>> getLocalityGroups(Configuration conf) {

        // Edge table definition properties define either individual edges or groups of edges.
        // We create in each data-conf.xml file the ability to specify locality groups
        // These are specified by dataType.edge.table.locality.groups.
        // This does allow the condition for a colfam in one datatype to be specified
        // as a locality group, but not be specified as one in the other datatype
        // At this point that does not seem to be a problem because we are using
        // colfam to denote a logical mapping of the data elements. So if two datatypes
        // have the same colfam for an edge and one is used for a locality group
        // then the other one should most likely be as well.
        //
        // groupname:colfam
        //
        // NOTE: I can't find this being called. It is commented out in the EdgeIngestConfigHelper
        //
        Map<String,Set<Text>> locs = new HashMap<>();

        Pattern p = Pattern.compile("^.+\\.edge\\.table\\.locality\\.groups");

        for (Entry<String,String> confEntry : conf) {
            Matcher m = p.matcher(confEntry.getKey());
            if (m.matches()) {
                String parts[] = StringUtils.split(confEntry.getValue(), ',', false);
                for (String s : parts) {
                    String colfams[] = StringUtils.split(s, ':', false);
                    if (colfams.length > 1) {
                        if (!locs.containsKey(colfams[0])) {
                            locs.put(colfams[0], new HashSet<>());
                        }
                        for (int i = 1; i < colfams.length; i++) {
                            locs.get(colfams[0]).add(new Text(colfams[i]));
                        }
                    }
                }
            }
        }
        return locs;

    }

    /**
     * Given a {@link Configuration}, this method returns the required locality groups used by the edge table.
     */
    public static Map<String,Set<Text>> getLocalityGroups(Configuration conf) {

        // Edge table definition properties define either individual edges or groups of edges.
        // We create in each data-conf.xml file the ability to specify locality groups
        // These are specified by dataType.edge.table.locality.groups.
        // This does allow the condition for a colfam in one datatype to be specified
        // as a locality group, but not be specified as one in the other datatype
        // At this point that does not seem to be a problem because we are using
        // colfam to denote a logical mapping of the data elements. So if two datatypes
        // have the same colfam for an edge and one is used for a locality group
        // then the other one should most likely be as well.
        //
        // groupname:colfam
        //
        // NOTE: I can't find this being called. It is commented out in the EdgeIngestConfigHelper
        //
        Map<String,Set<Text>> locs = new HashMap<>();

        Pattern p = Pattern.compile("^.+\\.edge\\.table\\.locality\\.groups");

        for (Entry<String,String> confEntry : conf) {
            Matcher m = p.matcher(confEntry.getKey());
            if (m.matches()) {
                String parts[] = StringUtils.split(confEntry.getValue(), ',', false);
                for (String s : parts) {
                    String colfams[] = StringUtils.split(s, ':', false);
                    if (colfams.length > 1) {
                        if (!locs.containsKey(colfams[0])) {
                            locs.put(colfams[0], new HashSet<Text>());
                        }
                        for (int i = 1; i < colfams.length; i++) {
                            locs.get(colfams[0]).add(new Text(colfams[i]));
                        }
                    }
                }
            }
        }
        return locs;

    }

Replace Generic With Diamond HashSet<Text> with HashSet<> in method public getLocalityGroups(conf Configuration) : Map<String,Set<Text>> from class datawave.ingest.mapreduce.handler.edge.ProtobufEdgeDataTypeHandler


    @Override
    public String[] getTableNames(Configuration conf) {
        List<String> tableNames = new ArrayList<>();
        tableNames.add(ConfigurationHelper.isNull(conf, EDGE_TABLE_NAME, String.class));
        if (conf.getBoolean(EDGE_TABLE_METADATA_ENABLE, this.enableMetadata)) {
            tableNames.add(ConfigurationHelper.isNull(conf, METADATA_TABLE_NAME, String.class));
            if (LoadDateTableConfigHelper.isLoadDatesEnabled(conf)) {
                tableNames.add(LoadDateTableConfigHelper.getLoadDatesTableName(conf));
            }
        }
        return tableNames.toArray(new String[tableNames.size()]);
    }

    @Override
    public String[] getTableNames(Configuration conf) {
        List<String> tableNames = new ArrayList<String>();
        tableNames.add(ConfigurationHelper.isNull(conf, EDGE_TABLE_NAME, String.class));
        if (conf.getBoolean(EDGE_TABLE_METADATA_ENABLE, this.enableMetadata)) {
            tableNames.add(ConfigurationHelper.isNull(conf, METADATA_TABLE_NAME, String.class));
            if (LoadDateTableConfigHelper.isLoadDatesEnabled(conf)) {
                tableNames.add(LoadDateTableConfigHelper.getLoadDatesTableName(conf));
            }
        }
        return tableNames.toArray(new String[tableNames.size()]);
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public getTableNames(conf Configuration) : String[] from class datawave.ingest.mapreduce.handler.edge.ProtobufEdgeDataTypeHandler


    @Override
    public String[] getTableNames(final Configuration conf) {
        final List<String> tableNames = new ArrayList<>(2);

        final TypeRegistry registry = TypeRegistry.getInstance(conf);
        final String dataName = conf.get(DataTypeHelper.Properties.DATA_NAME_OVERRIDE, conf.get(DataTypeHelper.Properties.DATA_NAME));
        if (dataName != null && registry.containsKey(dataName)) {
            final Type type = registry.get(dataName);

            final String tableNamespace = conf.get(type.typeName() + GEOWAVE_NAMESPACE, null);
            final PrimaryIndex index = initIndex(conf.get(type.typeName() + GEOWAVE_INDEX_TYPE, null));

            if ((tableNamespace != null) && (index != null)) {
                tableNames.add(DataStoreUtils.getQualifiedTableName(tableNamespace, GeoWaveMetadata.METADATA_TABLE));
                tableNames.add(DataStoreUtils.getQualifiedTableName(tableNamespace, index.getId().getString()));
            }
        }
        return tableNames.toArray(new String[tableNames.size()]);
    }

    @Override
    public String[] getTableNames(final Configuration conf) {
        final List<String> tableNames = new ArrayList<String>(2);

        final TypeRegistry registry = TypeRegistry.getInstance(conf);
        final String dataName = conf.get(DataTypeHelper.Properties.DATA_NAME_OVERRIDE, conf.get(DataTypeHelper.Properties.DATA_NAME));
        if (dataName != null && registry.containsKey(dataName)) {
            final Type type = registry.get(dataName);

            final String tableNamespace = conf.get(type.typeName() + GEOWAVE_NAMESPACE, null);
            final PrimaryIndex index = initIndex(conf.get(type.typeName() + GEOWAVE_INDEX_TYPE, null));

            if ((tableNamespace != null) && (index != null)) {
                tableNames.add(DataStoreUtils.getQualifiedTableName(tableNamespace, GeoWaveMetadata.METADATA_TABLE));
                tableNames.add(DataStoreUtils.getQualifiedTableName(tableNamespace, index.getId().getString()));
            }
        }
        return tableNames.toArray(new String[tableNames.size()]);
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method public getTableNames(conf Configuration) : String[] from class datawave.ingest.mapreduce.handler.geowave.GeoWaveDataTypeHandler


    private Set<SimpleFeature> createSimpleFeatures(final IngestHelperInterface helper, final RawRecordContainer event,
                    final Multimap<String,NormalizedContentInterface> fields) throws ParseException {
        final Set<SimpleFeature> features = new HashSet<>();
        for (final SimpleFeature feature : eventToSimpleFeatures(helper, event, fields, builder, flattenGeometry))
            features.add(FeatureDataUtils.defaultCRSTransform(feature, originalType, reprojectedType, transform));
        return features;
    }

    private Set<SimpleFeature> createSimpleFeatures(final IngestHelperInterface helper, final RawRecordContainer event,
                    final Multimap<String,NormalizedContentInterface> fields) throws ParseException {
        final Set<SimpleFeature> features = new HashSet<SimpleFeature>();
        for (final SimpleFeature feature : eventToSimpleFeatures(helper, event, fields, builder, flattenGeometry))
            features.add(FeatureDataUtils.defaultCRSTransform(feature, originalType, reprojectedType, transform));
        return features;
    }

Replace Generic With Diamond HashSet<SimpleFeature> with HashSet<> in method private createSimpleFeatures(helper IngestHelperInterface, event RawRecordContainer, fields Multimap<String,NormalizedContentInterface>) : Set<SimpleFeature> from class datawave.ingest.mapreduce.handler.geowave.GeoWaveDataTypeHandler


    private List<KeyValue> entryToKeyValues(final SimpleFeature feature, final byte[] visibility) {
        final List<KeyValue> keyValues = new ArrayList<>();
        if (feature.getDefaultGeometry() != null) {
            final DataStoreEntryInfo ingestInfo = DataStoreUtils.getIngestInfo(dataAdapter, index, feature, new UniformVisibilityWriter<>(
                            new GlobalVisibilityHandler<>(StringUtils.stringFromBinary(visibility))));

            final List<DataStoreEntryInfo.FieldInfo<?>> fieldInfoList = DataStoreUtils.composeFlattenedFields(ingestInfo.getFieldInfo(), index.getIndexModel(),
                            dataAdapter);

            for (final ByteArrayId row : ingestInfo.getRowIds()) {
                for (final DataStoreEntryInfo.FieldInfo fieldInfo : fieldInfoList) {
                    final Key key = new Key(new Text(row.getBytes()), new Text(dataAdapter.getAdapterId().getBytes()), new Text(fieldInfo.getDataValue()
                                    .getId().getBytes()), new Text(fieldInfo.getVisibility()));

                    keyValues.add(new KeyValue(key, new Value(fieldInfo.getWrittenValue())));
                }
            }
        }
        return keyValues;
    }

    private List<KeyValue> entryToKeyValues(final SimpleFeature feature, final byte[] visibility) {
        final List<KeyValue> keyValues = new ArrayList<>();
        if (feature.getDefaultGeometry() != null) {
            final DataStoreEntryInfo ingestInfo = DataStoreUtils.getIngestInfo(dataAdapter, index, feature, new UniformVisibilityWriter<SimpleFeature>(
                            new GlobalVisibilityHandler<SimpleFeature,Object>(StringUtils.stringFromBinary(visibility))));

            final List<DataStoreEntryInfo.FieldInfo<?>> fieldInfoList = DataStoreUtils.composeFlattenedFields(ingestInfo.getFieldInfo(), index.getIndexModel(),
                            dataAdapter);

            for (final ByteArrayId row : ingestInfo.getRowIds()) {
                for (final DataStoreEntryInfo.FieldInfo fieldInfo : fieldInfoList) {
                    final Key key = new Key(new Text(row.getBytes()), new Text(dataAdapter.getAdapterId().getBytes()), new Text(fieldInfo.getDataValue()
                                    .getId().getBytes()), new Text(fieldInfo.getVisibility()));

                    keyValues.add(new KeyValue(key, new Value(fieldInfo.getWrittenValue())));
                }
            }
        }
        return keyValues;
    }

Replace Generic With Diamond UniformVisibilityWriter<SimpleFeature> with UniformVisibilityWriter<> in method private entryToKeyValues(feature SimpleFeature, visibility byte[]) : List<KeyValue> from class datawave.ingest.mapreduce.handler.geowave.GeoWaveDataTypeHandler


    private static <T> List<DataStoreEntryInfo.FieldInfo<?>> composeFlattenedFields(final List<DataStoreEntryInfo.FieldInfo<?>> originalList,
                    final PrimaryIndex index) {
        final List<DataStoreEntryInfo.FieldInfo<?>> retVal = new ArrayList<>();
        final Map<ByteArrayId,List<DataStoreEntryInfo.FieldInfo<?>>> vizToFieldMap = new HashMap<>();
        boolean sharedVisibility = false;
        // organize FieldInfos by unique visibility
        for (final DataStoreEntryInfo.FieldInfo<?> fieldInfo : originalList) {
            final ByteArrayId currViz = new ByteArrayId(fieldInfo.getVisibility());
            if (vizToFieldMap.containsKey(currViz)) {
                sharedVisibility = true;
                final List<DataStoreEntryInfo.FieldInfo<?>> listForViz = vizToFieldMap.get(currViz);
                final FieldReader<CommonIndexValue> fieldReader = index.getIndexModel().getReader(fieldInfo.getDataValue().getId());
                if (fieldReader != null) {
                    // put common index values up front
                    listForViz.add(0, fieldInfo);
                } else {
                    listForViz.add(fieldInfo);
                }
            } else {
                final List<DataStoreEntryInfo.FieldInfo<?>> listForViz = new ArrayList<>();
                listForViz.add(fieldInfo);
                vizToFieldMap.put(currViz, listForViz);
            }
        }
        if (!sharedVisibility) {
            return originalList;
        }
        for (final Entry<ByteArrayId,List<DataStoreEntryInfo.FieldInfo<?>>> entry : vizToFieldMap.entrySet()) {
            final List<byte[]> fieldInfoBytesList = new ArrayList<>();
            int totalLength = 0;
            for (final DataStoreEntryInfo.FieldInfo<?> fieldInfo : entry.getValue()) {
                final byte[] fieldIdBytes = fieldInfo.getDataValue().getId().getBytes();
                final ByteBuffer fieldInfoBytes = ByteBuffer.allocate(8 + fieldIdBytes.length + fieldInfo.getWrittenValue().length);
                fieldInfoBytes.putInt(fieldIdBytes.length);
                fieldInfoBytes.put(fieldIdBytes);
                fieldInfoBytes.putInt(fieldInfo.getWrittenValue().length);
                fieldInfoBytes.put(fieldInfo.getWrittenValue());
                fieldInfoBytesList.add(fieldInfoBytes.array());
                totalLength += fieldInfoBytes.array().length;
            }
            final ByteBuffer allFields = ByteBuffer.allocate(4 + totalLength);
            allFields.putInt(entry.getValue().size());
            for (final byte[] bytes : fieldInfoBytesList) {
                allFields.put(bytes);
            }
            final DataStoreEntryInfo.FieldInfo<?> composite = new DataStoreEntryInfo.FieldInfo<T>(new PersistentValue<>(COMPOSITE_CQ, null), // unnecessary
                            allFields.array(), entry.getKey().getBytes());
            retVal.add(composite);
        }
        return retVal;
    }

    private static <T> List<DataStoreEntryInfo.FieldInfo<?>> composeFlattenedFields(final List<DataStoreEntryInfo.FieldInfo<?>> originalList,
                    final PrimaryIndex index) {
        final List<DataStoreEntryInfo.FieldInfo<?>> retVal = new ArrayList<>();
        final Map<ByteArrayId,List<DataStoreEntryInfo.FieldInfo<?>>> vizToFieldMap = new HashMap<>();
        boolean sharedVisibility = false;
        // organize FieldInfos by unique visibility
        for (final DataStoreEntryInfo.FieldInfo<?> fieldInfo : originalList) {
            final ByteArrayId currViz = new ByteArrayId(fieldInfo.getVisibility());
            if (vizToFieldMap.containsKey(currViz)) {
                sharedVisibility = true;
                final List<DataStoreEntryInfo.FieldInfo<?>> listForViz = vizToFieldMap.get(currViz);
                final FieldReader<CommonIndexValue> fieldReader = index.getIndexModel().getReader(fieldInfo.getDataValue().getId());
                if (fieldReader != null) {
                    // put common index values up front
                    listForViz.add(0, fieldInfo);
                } else {
                    listForViz.add(fieldInfo);
                }
            } else {
                final List<DataStoreEntryInfo.FieldInfo<?>> listForViz = new ArrayList<>();
                listForViz.add(fieldInfo);
                vizToFieldMap.put(currViz, listForViz);
            }
        }
        if (!sharedVisibility) {
            return originalList;
        }
        for (final Entry<ByteArrayId,List<DataStoreEntryInfo.FieldInfo<?>>> entry : vizToFieldMap.entrySet()) {
            final List<byte[]> fieldInfoBytesList = new ArrayList<>();
            int totalLength = 0;
            for (final DataStoreEntryInfo.FieldInfo<?> fieldInfo : entry.getValue()) {
                final byte[] fieldIdBytes = fieldInfo.getDataValue().getId().getBytes();
                final ByteBuffer fieldInfoBytes = ByteBuffer.allocate(8 + fieldIdBytes.length + fieldInfo.getWrittenValue().length);
                fieldInfoBytes.putInt(fieldIdBytes.length);
                fieldInfoBytes.put(fieldIdBytes);
                fieldInfoBytes.putInt(fieldInfo.getWrittenValue().length);
                fieldInfoBytes.put(fieldInfo.getWrittenValue());
                fieldInfoBytesList.add(fieldInfoBytes.array());
                totalLength += fieldInfoBytes.array().length;
            }
            final ByteBuffer allFields = ByteBuffer.allocate(4 + totalLength);
            allFields.putInt(entry.getValue().size());
            for (final byte[] bytes : fieldInfoBytesList) {
                allFields.put(bytes);
            }
            final DataStoreEntryInfo.FieldInfo<?> composite = new DataStoreEntryInfo.FieldInfo<T>(new PersistentValue<T>(COMPOSITE_CQ, null), // unnecessary
                            allFields.array(), entry.getKey().getBytes());
            retVal.add(composite);
        }
        return retVal;
    }

Replace Generic With Diamond DataStoreEntryInfo.FieldInfo<T> with DataStoreEntryInfo.FieldInfo<T> in method private composeFlattenedFields(originalList List<DataStoreEntryInfo.FieldInfo<?>>, index PrimaryIndex) : List<DataStoreEntryInfo.FieldInfo<?>> from class datawave.ingest.mapreduce.handler.geowave.GeoWaveDataTypeHandler


    private List<Text> asListofTexts() {
        List<Text> result = new ArrayList<>(builders.size());
        for (StringBuilder builder : builders) {
            result.add(new Text(builder.toString()));
        }
        return result;
    }

    private List<Text> asListofTexts() {
        List<Text> result = new ArrayList<Text>(builders.size());
        for (StringBuilder builder : builders) {
            result.add(new Text(builder.toString()));
        }
        return result;
    }

Replace Generic With Diamond ArrayList<Text> with ArrayList<> in method private asListofTexts() : List<Text> from class datawave.ingest.mapreduce.handler.summary.MetricsSummaryFormatter


    private void resetFormattedFields(String prefix) {
        if (builders == null) {
            builders = new ArrayList<>();
        } else {
            builders.clear();
        }
        builders.add(new StringBuilder(DEFAULT_CAPACITY).append(prefix != null ? prefix : ""));
    }

    private void resetFormattedFields(String prefix) {
        if (builders == null) {
            builders = new ArrayList<StringBuilder>();
        } else {
            builders.clear();
        }
        builders.add(new StringBuilder(DEFAULT_CAPACITY).append(prefix != null ? prefix : ""));
    }

Replace Generic With Diamond ArrayList<StringBuilder> with ArrayList<> in method private resetFormattedFields(prefix String) : void from class datawave.ingest.mapreduce.handler.summary.MetricsSummaryFormatter


    private void createDelegatesForTables() throws ClassNotFoundException {
        tableOffsets = new HashMap<>();
        String commaSeparatedTableNames = conf.get(TABLE_NAMES_WITH_CUSTOM_PARTITIONERS);
        if (commaSeparatedTableNames == null) {
            log.info("No custom partitioners found");
            return;
        }
        try {
            ArrayList<Text> tableNames = getTableNames(commaSeparatedTableNames);
            partitionerCache.createAndCachePartitioners(tableNames);
            this.tableOffsets = new TablePartitionerOffsets(conf, tableNames, partitionerCache);
        } catch (Exception e) {
            throw new IllegalArgumentException("Problem with tableNames or their partitioner class names. " + commaSeparatedTableNames, e);
        }
    }

    private void createDelegatesForTables() throws ClassNotFoundException {
        tableOffsets = new HashMap<Text,Integer>();
        String commaSeparatedTableNames = conf.get(TABLE_NAMES_WITH_CUSTOM_PARTITIONERS);
        if (commaSeparatedTableNames == null) {
            log.info("No custom partitioners found");
            return;
        }
        try {
            ArrayList<Text> tableNames = getTableNames(commaSeparatedTableNames);
            partitionerCache.createAndCachePartitioners(tableNames);
            this.tableOffsets = new TablePartitionerOffsets(conf, tableNames, partitionerCache);
        } catch (Exception e) {
            throw new IllegalArgumentException("Problem with tableNames or their partitioner class names. " + commaSeparatedTableNames, e);
        }
    }

Replace Generic With Diamond HashMap<Text,Integer> with HashMap<> in method private createDelegatesForTables() : void from class datawave.ingest.mapreduce.job.DelegatingPartitioner


    /**
     * Output some verbose counters. Since the input is an iterable, this will cache the values in a list and return the new iterable.
     *
     * @param context
     * @param key
     * @param values
     */
    @SuppressWarnings("rawtypes")
    public static Iterable<Value> verboseCounters(TaskInputOutputContext context, String location, BulkIngestKey key, Iterable<Value> values) {
        List<Value> valueList = new ArrayList<>();
        for (Value value : values) {
            valueList.add(value);
            verboseCounters(context, location, key, value);
        }
        return valueList;
    }

    /**
     * Output some verbose counters. Since the input is an iterable, this will cache the values in a list and return the new iterable.
     *
     * @param context
     * @param key
     * @param values
     */
    @SuppressWarnings("rawtypes")
    public static Iterable<Value> verboseCounters(TaskInputOutputContext context, String location, BulkIngestKey key, Iterable<Value> values) {
        List<Value> valueList = new ArrayList<Value>();
        for (Value value : values) {
            valueList.add(value);
            verboseCounters(context, location, key, value);
        }
        return valueList;
    }

Replace Generic With Diamond ArrayList<Value> with ArrayList<> in method public verboseCounters(context TaskInputOutputContext, location String, key BulkIngestKey, values Iterable<Value>) : Iterable<Value> from class datawave.ingest.mapreduce.job.IngestJob


    /**
     */
    private int getAssignedPartition(String tableName, Text shardId) throws IOException {
        Map<Text,Integer> assignments = lazilyCreateAssignments(tableName);

        Integer partitionId = assignments.get(shardId);
        if (partitionId != null) {
            return partitionId;
        }
        // if the partitionId is not there, either shards were not created for the day
        // or not all shards were created for the day

        String missingShardStrategy = conf.get(MISSING_SHARD_STRATEGY_PROP, "hash");
        switch (missingShardStrategy) {
            case "hash":
                // only warn a few times per partitioner to avoid flooding the logs
                if (missingShardIdCount < 10) {
                    log.warn("shardId didn't have a partition assigned to it: " + shardId);
                    missingShardIdCount++;
                }
                return (shardId.hashCode() & Integer.MAX_VALUE);
            case "collapse":
                ArrayList<Text> keys = new ArrayList<>(assignments.keySet());
                Collections.sort(keys);
                int closestAssignment = Collections.binarySearch(keys, shardId);
                if (closestAssignment >= 0) {
                    // Should have found it earlier, but just in case go ahead and return it
                    log.warn("Something is screwy, found " + shardId + " on the second try");
                    return assignments.get(shardId);
                }
                // <tt>(-(<i>insertion point</i>) - 1)</tt> // insertion point in the index of the key greater
                Text shardString = keys.get(Math.abs(closestAssignment + 1));
                return assignments.get(shardString);
            default:
                throw new RuntimeException("Unsupported missing shard strategy " + MISSING_SHARD_STRATEGY_PROP + "=" + missingShardStrategy);
        }
    }

    /**
     */
    private int getAssignedPartition(String tableName, Text shardId) throws IOException {
        Map<Text,Integer> assignments = lazilyCreateAssignments(tableName);

        Integer partitionId = assignments.get(shardId);
        if (partitionId != null) {
            return partitionId;
        }
        // if the partitionId is not there, either shards were not created for the day
        // or not all shards were created for the day

        String missingShardStrategy = conf.get(MISSING_SHARD_STRATEGY_PROP, "hash");
        switch (missingShardStrategy) {
            case "hash":
                // only warn a few times per partitioner to avoid flooding the logs
                if (missingShardIdCount < 10) {
                    log.warn("shardId didn't have a partition assigned to it: " + shardId);
                    missingShardIdCount++;
                }
                return (shardId.hashCode() & Integer.MAX_VALUE);
            case "collapse":
                ArrayList<Text> keys = new ArrayList<Text>(assignments.keySet());
                Collections.sort(keys);
                int closestAssignment = Collections.binarySearch(keys, shardId);
                if (closestAssignment >= 0) {
                    // Should have found it earlier, but just in case go ahead and return it
                    log.warn("Something is screwy, found " + shardId + " on the second try");
                    return assignments.get(shardId);
                }
                // <tt>(-(<i>insertion point</i>) - 1)</tt> // insertion point in the index of the key greater
                Text shardString = keys.get(Math.abs(closestAssignment + 1));
                return assignments.get(shardString);
            default:
                throw new RuntimeException("Unsupported missing shard strategy " + MISSING_SHARD_STRATEGY_PROP + "=" + missingShardStrategy);
        }
    }

Replace Generic With Diamond ArrayList<Text> with ArrayList<> in method private getAssignedPartition(tableName String, shardId Text) : int from class datawave.ingest.mapreduce.partition.BalancedShardPartitioner


    /**
     * hashCode of the tserver name
     *
     * Read in the sequence file (that was created at job startup) that contains a list of shard IDs and the corresponding tablet server to which that shard is
     * assigned. The hash is a simple hashCode of the location string.
     */
    private Map<Text,Integer> getShardHashes(String tableName) throws IOException {
        if (this.shardHashes == null) {
            this.shardHashes = new HashMap<>();
        }

        if (null == this.shardHashes.get(tableName)) {
            Map<Text,Integer> hashedForTable = new HashMap<>();

            for (Map.Entry<Text,String> entry : ShardedTableMapFile.getShardIdToLocations(conf, tableName).entrySet()) {
                hashedForTable.put(entry.getKey(), entry.getValue().toString().hashCode());
            }

            this.shardHashes.put(tableName, hashedForTable);
        }

        return this.shardHashes.get(tableName);
    }

    /**
     * hashCode of the tserver name
     *
     * Read in the sequence file (that was created at job startup) that contains a list of shard IDs and the corresponding tablet server to which that shard is
     * assigned. The hash is a simple hashCode of the location string.
     */
    private Map<Text,Integer> getShardHashes(String tableName) throws IOException {
        if (this.shardHashes == null) {
            this.shardHashes = new HashMap<>();
        }

        if (null == this.shardHashes.get(tableName)) {
            Map<Text,Integer> hashedForTable = new HashMap<Text,Integer>();

            for (Map.Entry<Text,String> entry : ShardedTableMapFile.getShardIdToLocations(conf, tableName).entrySet()) {
                hashedForTable.put(entry.getKey(), entry.getValue().toString().hashCode());
            }

            this.shardHashes.put(tableName, hashedForTable);
        }

        return this.shardHashes.get(tableName);
    }

Replace Generic With Diamond HashMap<Text,Integer> with HashMap<> in method private getShardHashes(tableName String) : Map<Text,Integer> from class datawave.ingest.mapreduce.partition.TabletLocationHashPartitioner


    /**
     * Sorts the tserver locations for all the shard ids. Each shardId is assigned a number which corresponds to where its tserver is found in that sorted list.
     * sort by most recent shard id, tserver
     *
     * suggested change: sort by most recent day's locations first, not by location id
     *
     * Read in the sequence file (that was created at job startup) that contains a list of shard IDs and the corresponding tablet server to which that shard is
     * assigned. The location is a number generated by adding the tuples of the location ip address and port.
     */
    private Map<Text,Integer> getShardLocations(String tableName) throws IOException {
        if (this.shardLocations == null) {
            this.shardLocations = new HashMap<>();
        }

        if (null == this.shardLocations.get(tableName)) {
            Map<Text,String> shards = ShardedTableMapFile.getShardIdToLocations(conf, tableName);

            // now sort the locations
            SortedSet<String> locations = new TreeSet<>();
            locations.addAll(shards.values());

            ArrayList<String> locList = new ArrayList<>(locations);
            HashMap<Text,Integer> localShardLocations = new HashMap<>();
            for (Map.Entry<Text,String> entry : shards.entrySet()) {
                localShardLocations.put(entry.getKey(), locList.indexOf(entry.getValue()));
            }

            this.shardLocations.put(tableName, localShardLocations);
        }

        return this.shardLocations.get(tableName);
    }

    /**
     * Sorts the tserver locations for all the shard ids. Each shardId is assigned a number which corresponds to where its tserver is found in that sorted list.
     * sort by most recent shard id, tserver
     *
     * suggested change: sort by most recent day's locations first, not by location id
     *
     * Read in the sequence file (that was created at job startup) that contains a list of shard IDs and the corresponding tablet server to which that shard is
     * assigned. The location is a number generated by adding the tuples of the location ip address and port.
     */
    private Map<Text,Integer> getShardLocations(String tableName) throws IOException {
        if (this.shardLocations == null) {
            this.shardLocations = new HashMap<>();
        }

        if (null == this.shardLocations.get(tableName)) {
            Map<Text,String> shards = ShardedTableMapFile.getShardIdToLocations(conf, tableName);

            // now sort the locations
            SortedSet<String> locations = new TreeSet<>();
            locations.addAll(shards.values());

            ArrayList<String> locList = new ArrayList<String>(locations);
            HashMap<Text,Integer> localShardLocations = new HashMap<>();
            for (Map.Entry<Text,String> entry : shards.entrySet()) {
                localShardLocations.put(entry.getKey(), locList.indexOf(entry.getValue()));
            }

            this.shardLocations.put(tableName, localShardLocations);
        }

        return this.shardLocations.get(tableName);
    }

Replace Generic With Diamond ArrayList<String> with ArrayList<> in method private getShardLocations(tableName String) : Map<Text,Integer> from class datawave.ingest.mapreduce.partition.TabletLocationNamePartitioner