while (st.hasMoreTokens()) {
            String keyword = st.nextToken().trim().toLowerCase();
            if (!(keyword.equals(JAVAEE_FULL) || keyword.equals(JAVAEE_KEYWORD) || keyword.equals(JAVAEE_WEB) || keyword.equals(JAVAEE_WEB_KEYWORD))) {
                result.add(keyword);
                debugit("added the following keyword to result:  " + keyword);
            } else {
                debugit("not adding keyword (" + keyword + ") to result");
            }
        }

package com.sun.ts.tests.signaturetest.javaee;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import com.sun.javatest.Status;
import com.sun.ts.lib.util.TestUtil;
import com.sun.ts.tests.signaturetest.SigTestEE;

/**
 * The JavaEESigTest class provides signature tests for the Java EE TCK. This
 * class extends SigTestEE which contains the signature test code. This class is
 * responsible for providing implementations of the abstract method defined in
 * SigTestEE, namely the getPackages method.
 *
 * The EE7 signature tests are to be run in 4 possible modes: (1) full/classic
 * profile (only covers REQUIRED Technologys for this profile) (2) full/classic
 * profile + OPTIONAL technologies (eg , jaxr, etc) (3)
 * web profile (only covers REQUIRED Technologys for this profile) (4) web
 * profile + OPTIONAL technologies (eg connector, jacc, jaxr, etc)
 *
 * The ts.jte's javaee.level property is used to specify these 4 modes of
 * sigtest control. The two basic profile modes (full and web profile) are
 * simple enough. The 2nd and 4th modes takes a bit more explaining. A typical
 * entry for this 4th mode could be something like the following:
 * javaee.level=web connector jacc For this scenario, we would run sigtests for
 * all technologies that are required in the web profile + connector + jacc. So
 * the 2nd and 4th modes are used if you wish to test OPTIONAL technologies
 * along with the REQUIRED technologies within the standard profiles of
 * javaee/full profile or web profile.
 *
 * For JavaEE7, there are 3 optional technologies called out in the EE 7 spec in
 * table EE.6-1: JAXR 1.0 , and Java EE Deployment 1.2. (There is
 * also an optional part of EJB 3.2 (optional part is Entity Beans and EJB QL)
 * BUT while these parts of the EJB are optional, EJB 3.2 MUST have ALL API's
 * that fulfill sigtest requirements. This means that ALL of EJB 3.2 must pass
 * sigtests even though parts of EJB 3.2 (e.g. QL and ENtity Benas) are
 * optional.
 *
 * The list of optional technologies that could be tested along with Java EE 7
 * are: jaxr
 *
 * The incomplete list of OPTIONAL/ADDITIONAL technologies which could be tested
 * along with the web profile are: jms javamail connector jaspic jacc
 * jaxrs - optional technology in EE 7 jaxr - optional technology
 * in EE 7
 */
public class JavaEESigTest extends SigTestEE {

    public static final String JAVAEE_FULL = "full";

    public static final String JAVAEE_KEYWORD = "javaee";

    public static final String JAVAEE_WEB = "web";

    public static final String JAVAEE_WEB_KEYWORD = "javaee_web_profile";

    public static final String KEYWORD_JAVAEE = "ejb interceptors caj jms wsmd javamail" + " cdi di beanval persistence jaxb saaj jaxws connector" + " jacc jaspic jsonp jta el servlet jsf jaxrs websocket batch concurrency jsonb securityapi";

    public static final String KEYWORD_WEB = "caj ejb persistence el jsf jsonp jsp servlet jta jaxrs cdi di beanval interceptors websocket jsonb securityapi";

    public static final ArrayList<String> KEYWORD_JAVAEE_FULL_OPTIONAL_TECHS = new ArrayList<String>();

    public static final ArrayList<String> KEYWORD_WEB_FULL_OPTIONAL_TECHS = new ArrayList<String>(Arrays.asList("batch", "connector", "jaxws", "jaxb", "jms", "javamail", "jacc", "jaspic", "wsmd"));

    enum Containers {

        ejb, servlet, jsp, appclient
    }

    public static final Map<Containers, Map<String, String[]>> CONTAINER_PACKAGE_MAPS;

    static {
        Map<Containers, Map<String, String[]>> tempMap = new EnumMap<Containers, Map<String, String[]>>(Containers.class);
        Map EJB_MAP = new HashMap<String, String[]>();
        Map SERVLET_MAP = new HashMap<String, String[]>();
        Map JSP_MAP = new HashMap<String, String[]>();
        Map APPCLIENT_MAP = new HashMap<String, String[]>();
        // These need to be filled in properly. If one map is a subset of
        // another map we can use putAll to add one map to the other.
        // So maybe populate appclient first then add it to the EJB map
        // then do EJB then add it to JSP then set JSP to SERVLET.
        APPCLIENT_MAP.put("ejb", new String[] { "jakarta.ejb", "jakarta.ejb.spi", "jakarta.ejb.embeddable", "jakarta.interceptor", "javax.rmi" });
        APPCLIENT_MAP.put("interceptors", new String[] { "jakarta.interceptor" });
        APPCLIENT_MAP.put("caj", new String[] { "jakarta.annotation", "jakarta.annotation.security", "jakarta.annotation.sql" });
        APPCLIENT_MAP.put("jms", new String[] { "jakarta.jms" });
        APPCLIENT_MAP.put("javamail", new String[] { "jakarta.mail", "jakarta.mail.event", "jakarta.mail.internet", "jakarta.mail.search", "jakarta.mail.util" });
        APPCLIENT_MAP.put("persistence", new String[] { "jakarta.persistence", "jakarta.persistence.spi", "jakarta.persistence.criteria", "jakarta.persistence.metamodel" });
        // note: cdi API's actually utilize two different base packages and
        // so will require two different sigfiles.
        APPCLIENT_MAP.put("cdi", new String[] { "jakarta.decorator", "jakarta.enterprise.context", "jakarta.enterprise.context.control", "jakarta.enterprise.context.spi", "jakarta.enterprise.event", "jakarta.enterprise.inject", "jakarta.enterprise.inject.spi", "jakarta.enterprise.inject.literal", "jakarta.enterprise.inject.spi.configurator", "jakarta.enterprise.util" });
        APPCLIENT_MAP.put("beanval", new String[] { "jakarta.validation", "jakarta.validation.bootstrap", "jakarta.validation.constraints", "jakarta.validation.groups", "jakarta.validation.metadata", "jakarta.validation.constraintvalidation", "jakarta.validation.executable", "jakarta.validation.spi", "jakarta.validation.valueextraction" });
        APPCLIENT_MAP.put("di", new String[] { "jakarta.inject" });
        APPCLIENT_MAP.put("jsonp", new String[] { "jakarta.json", "jakarta.json.spi", "jakarta.json.stream" });
        APPCLIENT_MAP.put("jsonb", new String[] { "jakarta.json.bind", "jakarta.json.bind.adapter", "jakarta.json.bind.annotation", "jakarta.json.bind.config", "jakarta.json.bind.serializer", "jakarta.json.bind.spi" });
        EJB_MAP.putAll(APPCLIENT_MAP);
        EJB_MAP.put("connector", new String[] { "jakarta.resource", "jakarta.resource.cci", "jakarta.resource.spi", "jakarta.resource.spi.work", "jakarta.resource.spi.endpoint", "jakarta.resource.spi.security" });
        EJB_MAP.put("jacc", new String[] { "jakarta.security.jacc" });
        EJB_MAP.put("jaspic", new String[] { "jakarta.security.auth.message", "jakarta.security.auth.message.callback", "jakarta.security.auth.message.config", "jakarta.security.auth.message.module" });
        EJB_MAP.put("jta", new String[] { "jakarta.transaction" });
        EJB_MAP.put("batch", new String[] { "jakarta.batch.api", "jakarta.batch.api.chunk", "jakarta.batch.api.chunk.listener", "jakarta.batch.api.listener", "jakarta.batch.api.partition", "jakarta.batch.operations", "jakarta.batch.runtime", "jakarta.batch.runtime.context" });
        EJB_MAP.put("concurrency", new String[] { "jakarta.enterprise.concurrent" });
        EJB_MAP.put("securityapi", new String[] { "jakarta.security.enterprise", "jakarta.security.enterprise.authentication.mechanism.http", "jakarta.security.enterprise.credential", "jakarta.security.enterprise.identitystore" });
        SERVLET_MAP.putAll(EJB_MAP);
        SERVLET_MAP.put("el", new String[] { "jakarta.el" });
        SERVLET_MAP.put("servlet", new String[] { "jakarta.servlet", "jakarta.servlet.annotation", "jakarta.servlet.descriptor", "jakarta.servlet.http", "jakarta.servlet.jsp", "jakarta.servlet.jsp.el", "jakarta.servlet.jsp.jstl.core", "jakarta.servlet.jsp.jstl.fmt", "jakarta.servlet.jsp.jstl.sql", "jakarta.servlet.jsp.jstl.tlv", "jakarta.servlet.jsp.tagext" });
        SERVLET_MAP.put("jsf", new String[] { "jakarta.faces", "jakarta.faces.application", "jakarta.faces.annotation", "jakarta.faces.component", "jakarta.faces.bean", "jakarta.faces.flow", "jakarta.faces.flow.builder", "jakarta.faces.component.behavior", "jakarta.faces.component.html", "jakarta.faces.component.visit", "jakarta.faces.component.search", "jakarta.faces.context", "jakarta.faces.convert", "jakarta.faces.el", "jakarta.faces.event", "jakarta.faces.lifecycle", "jakarta.faces.model", "jakarta.faces.push", "jakarta.faces.render", "jakarta.faces.validator", "jakarta.faces.view", "jakarta.faces.view.facelets", "jakarta.faces.webapp" });
        SERVLET_MAP.put("jaxrs", new String[] { "jakarta.ws.rs", "jakarta.ws.rs.core", "jakarta.ws.rs.ext", "jakarta.ws.rs.client", "jakarta.ws.rs.container", "jakarta.ws.rs.sse" });
        SERVLET_MAP.put("websocket", new String[] { "jakarta.websocket", "jakarta.websocket.server" });
        JSP_MAP = SERVLET_MAP;
        tempMap.put(Containers.ejb, Collections.unmodifiableMap(EJB_MAP));
        tempMap.put(Containers.servlet, Collections.unmodifiableMap(SERVLET_MAP));
        tempMap.put(Containers.jsp, Collections.unmodifiableMap(JSP_MAP));
        tempMap.put(Containers.appclient, Collections.unmodifiableMap(APPCLIENT_MAP));
        CONTAINER_PACKAGE_MAPS = Collections.unmodifiableMap(tempMap);
    }

    // end static block
    /* Instance Variables */
    private boolean isFullEEProfile = true;

    private String level;

    private String otherTechnologyKeywords = null;

    private void debugit(String str) {
        TestUtil.logTrace(str);
    }

    /**
     * Set the current level, either web profile or full EE. If isFullEEProfile is
     * false it must be web since there are only two valid values, full and web.
     * It is possible that the javaee.level in the ts.jte is set to web +
     * <some_additional_technologies> so we want to make sure that the string is
     * parsed appropriately.
     */
    private void setLevel() {
        level = testInfo.getJavaeeLevel().toLowerCase();
        // The javaee.level should be a string and could contain the following
        // possible entries:
        // 4. anything else we cant reconcile will default to "full" behavior.
        debugit("in setLevel()");
        debugit("javaee.level = " + level);
        if (level.contains(JAVAEE_FULL)) {
            // if the javaee.level contains "full" or some variant string
            // such as "blarg + full" then we will assume it is "full"
            isFullEEProfile = true;
            debugit("isFullEEProfile = true");
            otherTechnologyKeywords = level.replace(JAVAEE_FULL, "");
        } else if (level.contains(JAVAEE_WEB)) {
            // if here, we have web profile. we need to check for
            // the additional technologies that might be specified in
            // the (ts.jte) javaee.level propery) javaee.level additional
            // props would be specified as: javaee.level = web foo1 foo2 ...
            isFullEEProfile = false;
            debugit("isFullEEProfile = false");
            otherTechnologyKeywords = level.replace(JAVAEE_WEB, "");
        } else {
            // if our level did not contain "full" or "web" assume "full"
            System.err.println("ERROR level set to \"" + level + "\"");
            System.err.println("\t level must be set to " + JAVAEE_FULL + " or " + JAVAEE_WEB);
            System.err.println("Tests will run assuming level:  " + JAVAEE_FULL);
            isFullEEProfile = true;
            debugit("level is indeterminate so setting isFullEEProfile = true");
        }
        debugit("JavaEESigTest.ssetLevel():  otherTechnologyKeywords = " + otherTechnologyKeywords);
    }

    /**
     * This method uses the ts.jte's javaee.level property to find the terminal
     * keywords that make up the web or full keywords, depending on the current
     * javaee.level. In other words, the full and web profiles are aggregate
     * keywords. This method determines the terminal keywords that make up those
     * aggregate keywords.
     *
     * The returned result is a set of keywords that serve as keys into the maps
     * above where each keyword represents a set of pacakages for a given
     * techonology (eg connector, jacc, etc)
     */
    private Set<String> resolveAggregateKeywords() throws IOException {
        String tsHome = testInfo.getTSHome();
        Set<String> result = new HashSet<String>();
        String strKeywords;
        if (isFullEEProfile) {
            // get javaee keyword
            strKeywords = KEYWORD_JAVAEE;
        } else {
            // assume web profile so get javaee_web_profile keyword
            strKeywords = KEYWORD_WEB;
        }
        if (otherTechnologyKeywords != null) {
            strKeywords = strKeywords + " " + otherTechnologyKeywords;
        }
        List terminals = getTerminals(strKeywords);
        result.addAll(terminals);
        debugit("JavaEESigTest.resolveAggregateKeywords(): strKeywords = " + strKeywords);
        return result;
    }

    private List<String> getTerminals(String s) {
        List<String> result = new ArrayList<String>();
        StringTokenizer st = new StringTokenizer(s, " \t\n\r\f,");

        return result;
    }

    @Override
    protected ArrayList<String> getUnlistedOptionalPackages() {
        ArrayList unlistedOptPkgs = new ArrayList<String>();
        ArrayList unlistedKeywords = new ArrayList<String>();
        debugit("Enterred getUnlistedOptionalPackages()");
        // get list of technology keywords specified in (ts.jte) javaee.level
        // property
        if (isFullEEProfile) {
            unlistedKeywords = cloneArrayList(KEYWORD_JAVAEE_FULL_OPTIONAL_TECHS);
            if (otherTechnologyKeywords == null) {
                // this could be null if no optional technologies were listed in which
                // case we want all optional technology keywords
                // so don't remove ANYTHING from our list of unlistedKeywords to search
                debugit("No Optional Technology Keywords found in ts.jte's javaee.level property.");
            } else {
                // we have some optional technologies that were listed in the (ts.jte)
                // javaee.level
                // so be sure to remove any of these from the list of
                debugit("Optional Technology Keywords found in ts.jte's javaee.level property: " + otherTechnologyKeywords);
                otherTechnologyKeywords = otherTechnologyKeywords.trim();
                String[] otherTechKeywords = otherTechnologyKeywords.split(" ");
                for (int ii = 0; ii < otherTechKeywords.length; ii++) {
                    unlistedKeywords.remove(otherTechKeywords[ii]);
                }
            }
        } else {
            // assume web profile
            unlistedKeywords = cloneArrayList(KEYWORD_WEB_FULL_OPTIONAL_TECHS);
            if (otherTechnologyKeywords == null) {
                // this could be null if no optional technologies were listed in which
                // case we want all the optional technology keywords (relevant to web
                // so don't remove ANYTHING from our list of unlistedKeywords to search
                debugit("No Optional Technology Keywords found in ts.jte's javaee.level property.");
            } else {
                // we have some optional technologies that were listed in the (ts.jte)
                // javaee.level
                // so be sure to remove any of these from the list of
                debugit("Optional Technology Keywords found in ts.jte's javaee.level property: " + otherTechnologyKeywords);
                otherTechnologyKeywords = otherTechnologyKeywords.trim();
                String[] otherTechKeywords = otherTechnologyKeywords.split(" ");
                for (int ii = 0; ii < otherTechKeywords.length; ii++) {
                    unlistedKeywords.remove(otherTechKeywords[ii]);
                }
            }
        }
        // once we know which keywords (for optional technology areas) are not
        // explicitly
        // listed for testing, we will take those and get the packages for them and
        for (int ii = 0; ii < unlistedKeywords.size(); ii++) {
            // loop thru list of optional technology keywords
            debugit("getting packages for Optional Technology Keyword == " + unlistedKeywords.get(ii));
            for (Containers cc : Containers.values()) {
                // loop thru each container looking for matching technology keyword
                Map<String, String[]> containerMap = CONTAINER_PACKAGE_MAPS.get(cc);
                if (containerMap.containsKey(unlistedKeywords.get(ii))) {
                    // see if the container/vehicle contains the optional tech keyword,
                    // if so, then add the packages for that keyword
                    debugit("Container: " + cc + "  contains packages for Optional Technolgoy of: " + unlistedKeywords.get(ii));
                    String[] pkgs = containerMap.get(unlistedKeywords.get(ii));
                    for (String otPkg : pkgs) {
                        unlistedOptPkgs.add(otPkg);
                    }
                    break;
                }
            }
        }
        debugit("getUnlistedOptionalPackages(): returning the following unlistedOptPkgs: " + unlistedOptPkgs.toString());
        return unlistedOptPkgs;
    }

    private ArrayList<String> cloneArrayList(ArrayList<String> listToBeCloned) {
        ArrayList<String> returnVal = new ArrayList<String>(listToBeCloned.size());
        for (String str : listToBeCloned) {
            returnVal.add(new String(str));
        }
        return returnVal;
    }

    /**
     * ** Abstract Method Implementations **
     */
    /**
     * Returns a list of strings where each string represents a package name. Each
     * package name will have it's signature tested by the signature test
     * framework.
     *
     * @param vehicleName
     *          The name of the JavaEE container where the signature tests should
     *          be conducted.
     * @return String[] The names of the packages whose signatures should be
     *         verified.
     */
    protected String[] getPackages(String vehicleName) {
        Set<String> packages = new HashSet<String>();
        Containers vehicle = Containers.valueOf(vehicleName);
        Set<String> keywords = null;
        debugit("vehicleName = " + vehicleName);
        // set the level instance variable to web or full
        setLevel();
        try {
            // get keywords that make up web or full profile
            keywords = resolveAggregateKeywords();
        } catch (IOException ioe) {
            // something happened with the keyword.properties file
        }
        dumpKeywords(keywords);
        Map<String, String[]> vehicleMap = CONTAINER_PACKAGE_MAPS.get(vehicle);
        dumpMap(vehicle, vehicleMap);
        for (String keyword : keywords) {
            if (vehicleMap.containsKey(keyword)) {
                packages.addAll(Arrays.asList(vehicleMap.get(keyword)));
            }
        }
        dumpPackages(vehicle, packages);
        return packages.toArray(new String[packages.size()]);
    }

    // Debugging fun
    private void dumpKeywords(Set<String> words) {
        debugit("Level is set to \"" + level + "\"");
        debugit("\tKeywords:");
        for (String s : words) {
            debugit("\t\t" + s);
        }
        debugit("// dumpKeywords *****");
    }

    private void dumpMap(Containers vehicle, Map<String, String[]> packages) {
        debugit("Vehicle is set to \"" + vehicle + "\"");
        for (String s : packages.keySet()) {
            if (packages != null) {
                String[] pkgs = packages.get(s);
                String outStr = s + " -> ";
                for (int ii = 0; ii < pkgs.length; ii++) {
                    outStr += pkgs[ii] + " ";
                }
                debugit(outStr);
            } else {
                debugit(s + " ->  no packages ");
            }
        }
        debugit("// dumpMap *****");
    }

    private void dumpPackages(Containers vehicle, Set<String> packages) {
        debugit("Vehicle is set to \"" + vehicle + "\"");
        if (packages != null) {
            String outStr = "";
            for (Iterator i = packages.iterator(); i.hasNext(); ) {
                String item = (String) i.next();
                outStr += item + " ";
            }
            debugit(outStr);
        } else {
            debugit("no packages found");
        }
        debugit("// dumpPackages *****");
    }

    /*
   * Initial entry point for JavaTest.
   */
    public static void main(String[] args) {
        JavaEESigTest theTests = new JavaEESigTest();
        Status s = theTests.run(args, System.out, System.err);
        s.exit();
    }
    /*
   * @class.setup_props: sigTestClasspath, Location of JavaEE jar files;
   * ts_home, The base path of this TCK; javaee.level, current EE level defined
   * in ts.jte web or full; optional.tech.packages.to.ignore, for excluding
   * certain packages that may exist in Optional technologies;
   * jtaJarClasspath, The Location of the JTA API jar file;
   */
    // XXX current.keywords does not seem to be in the props instance
    /*
   * @testName: signatureTest
   *
   * @assertion: A JavaEE platform must implement the required classes and and
   * APIs specified in the JavaEE Platform Specification.
   *
   * @test_Strategy: Using reflection, gather the implementation specific
   * classes and APIs. Compare these results with the expected (required)
   * classes and APIs.
   */
    /*
   * Call the parent class's cleanup method.
   */
}
// end class CTSSigTest


while (iterator.hasNext()) {
            Map.Entry<String, LocalizeResource> entry = iterator.next();
            if (moreFile == null) {
                moreFile = adder.withLocalFiles().add(entry.getKey(), entry.getValue().getURI(), entry.getValue().isArchive());
            } else {
                moreFile = moreFile.add(entry.getKey(), entry.getValue().getURI(), entry.getValue().isArchive());
            }
        }

package io.cdap.cdap.data.runtime.main;

import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import io.cdap.cdap.common.conf.CConfiguration;
import io.cdap.cdap.common.conf.Constants;
import io.cdap.cdap.common.lang.jar.BundleJarUtil;
import io.cdap.cdap.common.twill.AbortOnTimeoutEventHandler;
import io.cdap.cdap.common.utils.DirUtils;
import io.cdap.cdap.explore.service.ExploreServiceUtils;
import io.cdap.cdap.hive.ExploreUtils;
import io.cdap.cdap.internal.app.runtime.batch.distributed.MapReduceContainerHelper;
import io.cdap.cdap.internal.app.runtime.distributed.LocalizeResource;
import io.cdap.cdap.logging.LoggingUtil;
import io.cdap.cdap.spi.hbase.HBaseDDLExecutor;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.twill.api.ResourceSpecification;
import org.apache.twill.api.TwillApplication;
import org.apache.twill.api.TwillSpecification;
import org.apache.twill.api.TwillSpecification.Builder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * TwillApplication wrapper for Master Services running in YARN.
 */
public class MasterTwillApplication implements TwillApplication {

    private static final Logger LOG = LoggerFactory.getLogger(MasterTwillApplication.class);

    private static final String NAME = Constants.Service.MASTER_SERVICES;

    private static final String CCONF_NAME = "cConf.xml";

    private static final String HCONF_NAME = "hConf.xml";

    // A map from service name to cConf configuration key prefix for service specific container configuration
    // They are not necessarily the same (e.g. "transaction" vs "data.tx").
    // We follow the same naming prefix for configuring containers' memory/vcores.
    private static final Map<String, String> ALL_SERVICES = ImmutableMap.<String, String>builder().put(Constants.Service.MESSAGING_SERVICE, "messaging.").put(Constants.Service.TRANSACTION, "data.tx.").put(Constants.Service.DATASET_EXECUTOR, "dataset.executor.").put(Constants.Service.LOGSAVER, "log.saver.").put(Constants.Service.METRICS_PROCESSOR, "metrics.processor.").put(Constants.Service.METRICS, "metrics.").put(Constants.Service.EXPLORE_HTTP_USER_SERVICE, "explore.executor.").build();

    private final CConfiguration cConf;

    private final Map<String, Integer> instanceCountMap;

    private final Map<String, Map<String, LocalizeResource>> runnableLocalizeResources;

    MasterTwillApplication(CConfiguration cConf, Map<String, Integer> instanceCountMap) {
        this.cConf = cConf;
        this.instanceCountMap = instanceCountMap;
        Map<String, Map<String, LocalizeResource>> runnableLocalizeResources = new HashMap<>();
        for (String service : ALL_SERVICES.keySet()) {
            runnableLocalizeResources.put(service, new HashMap<>());
        }
        this.runnableLocalizeResources = runnableLocalizeResources;
    }

    /**
     * Prepares the resources that need to be localized to service containers.
     *
     * @param tempDir a temporary directory for creating files to be localized
     * @param hConf the hadoop configuration
     * @return a list of extra classpath that need to be added to each container.
     * @throws IOException if failed to prepare localize resources
     */
    List<String> prepareLocalizeResource(Path tempDir, Configuration hConf) throws IOException {
        CConfiguration containerCConf = CConfiguration.copy(cConf);
        containerCConf.set(Constants.CFG_LOCAL_DATA_DIR, "data");
        List<String> extraClassPath = new ArrayList<>();
        prepareLogSaverResources(tempDir, containerCConf, runnableLocalizeResources.get(Constants.Service.LOGSAVER), extraClassPath);
        prepareHBaseDDLExecutorResources(tempDir, containerCConf);
        if (cConf.getBoolean(Constants.Explore.EXPLORE_ENABLED)) {
            prepareExploreResources(tempDir, hConf, runnableLocalizeResources.get(Constants.Service.EXPLORE_HTTP_USER_SERVICE), extraClassPath);
        }
        Path cConfPath = saveCConf(containerCConf, Files.createTempFile(tempDir, "cConf", ".xml"));
        Path hConfPath = saveHConf(hConf, Files.createTempFile(tempDir, "hConf", ".xml"));
        for (String service : ALL_SERVICES.keySet()) {
            Map<String, LocalizeResource> localizeResources = runnableLocalizeResources.get(service);
            localizeResources.put(CCONF_NAME, new LocalizeResource(cConfPath.toFile(), false));
            localizeResources.put(HCONF_NAME, new LocalizeResource(hConfPath.toFile(), false));
        }
        return extraClassPath;
    }

    /**
     * Returns a map from runnable name to configuration prefixes.
     */
    Map<String, String> getRunnableConfigPrefixes() {
        return ALL_SERVICES;
    }

    @Override
    public TwillSpecification configure() {
        // It is always present in cdap-default.xml
        final long noContainerTimeout = cConf.getLong(Constants.CFG_TWILL_NO_CONTAINER_TIMEOUT, Long.MAX_VALUE);
        TwillSpecification.Builder.RunnableSetter runnableSetter = addMessaging(addDatasetOpExecutor(addLogSaverService(addMetricsProcessor(addMetricsService(TwillSpecification.Builder.with().setName(NAME).withRunnable())))));
        if (cConf.getBoolean(Constants.Transaction.TX_ENABLED)) {
            runnableSetter = addTransactionService(runnableSetter);
        }
        if (cConf.getBoolean(Constants.Explore.EXPLORE_ENABLED)) {
            LOG.info("Adding explore runnable.");
            runnableSetter = addExploreService(runnableSetter);
        } else {
            LOG.info("Explore module disabled - will not launch explore runnable.");
        }
        return runnableSetter.withOrder().begin(Constants.Service.MESSAGING_SERVICE, Constants.Service.TRANSACTION, Constants.Service.DATASET_EXECUTOR).withEventHandler(new AbortOnTimeoutEventHandler(noContainerTimeout)).build();
    }

    private Builder.RunnableSetter addLogSaverService(Builder.MoreRunnable builder) {
        ResourceSpecification resourceSpec = createResourceSpecification(Constants.LogSaver.NUM_CORES, Constants.LogSaver.MEMORY_MB, Constants.Service.LOGSAVER);
        return addResources(Constants.Service.LOGSAVER, builder.add(new LogSaverTwillRunnable(Constants.Service.LOGSAVER, CCONF_NAME, HCONF_NAME), resourceSpec));
    }

    private Builder.RunnableSetter addMetricsProcessor(Builder.MoreRunnable builder) {
        ResourceSpecification resourceSpec = createResourceSpecification(Constants.MetricsProcessor.NUM_CORES, Constants.MetricsProcessor.MEMORY_MB, Constants.Service.METRICS_PROCESSOR);
        return addResources(Constants.Service.METRICS_PROCESSOR, builder.add(new MetricsProcessorTwillRunnable(Constants.Service.METRICS_PROCESSOR, CCONF_NAME, HCONF_NAME), resourceSpec));
    }

    private Builder.RunnableSetter addMetricsService(Builder.MoreRunnable builder) {
        ResourceSpecification resourceSpec = createResourceSpecification(Constants.Metrics.NUM_CORES, Constants.Metrics.MEMORY_MB, Constants.Service.METRICS);
        return addResources(Constants.Service.METRICS, builder.add(new MetricsTwillRunnable(Constants.Service.METRICS, CCONF_NAME, HCONF_NAME), resourceSpec));
    }

    private Builder.RunnableSetter addTransactionService(Builder.MoreRunnable builder) {
        ResourceSpecification resourceSpec = createResourceSpecification(Constants.Transaction.Container.NUM_CORES, Constants.Transaction.Container.MEMORY_MB, Constants.Service.TRANSACTION);
        return addResources(Constants.Service.TRANSACTION, builder.add(new TransactionServiceTwillRunnable(Constants.Service.TRANSACTION, CCONF_NAME, HCONF_NAME), resourceSpec));
    }

    private Builder.RunnableSetter addDatasetOpExecutor(Builder.MoreRunnable builder) {
        ResourceSpecification resourceSpec = createResourceSpecification(Constants.Dataset.Executor.CONTAINER_VIRTUAL_CORES, Constants.Dataset.Executor.CONTAINER_MEMORY_MB, Constants.Service.DATASET_EXECUTOR);
        return addResources(Constants.Service.DATASET_EXECUTOR, builder.add(new DatasetOpExecutorServerTwillRunnable(Constants.Service.DATASET_EXECUTOR, CCONF_NAME, HCONF_NAME), resourceSpec));
    }

    private Builder.RunnableSetter addExploreService(Builder.MoreRunnable builder) {
        ResourceSpecification resourceSpec = createResourceSpecification(Constants.Explore.CONTAINER_VIRTUAL_CORES, Constants.Explore.CONTAINER_MEMORY_MB, Constants.Service.EXPLORE_HTTP_USER_SERVICE);
        return addResources(Constants.Service.EXPLORE_HTTP_USER_SERVICE, builder.add(new ExploreServiceTwillRunnable(Constants.Service.EXPLORE_HTTP_USER_SERVICE, CCONF_NAME, HCONF_NAME), resourceSpec));
    }

    private Builder.RunnableSetter addMessaging(Builder.MoreRunnable builder) {
        ResourceSpecification resourceSpec = createResourceSpecification(Constants.MessagingSystem.CONTAINER_VIRTUAL_CORES, Constants.MessagingSystem.CONTAINER_MEMORY_MB, Constants.Service.MESSAGING_SERVICE);
        return addResources(Constants.Service.MESSAGING_SERVICE, builder.add(new MessagingServiceTwillRunnable(Constants.Service.MESSAGING_SERVICE, CCONF_NAME, HCONF_NAME), resourceSpec));
    }

    /**
     * Creates a {@link ResourceSpecification} based on the given configuration keys.
     */
    private ResourceSpecification createResourceSpecification(String vCoresKey, String memoryKey, String instancesKey) {
        int vCores = cConf.getInt(vCoresKey);
        int memory = cConf.getInt(memoryKey);
        int instances = instanceCountMap.get(instancesKey);
        Preconditions.checkArgument(vCores > 0, "Number of virtual cores must be > 0 for property %s", vCoresKey);
        Preconditions.checkArgument(memory > 0, "Memory size must be > 0 for property %s", memoryKey);
        Preconditions.checkArgument(instances > 0, "Number of instances must be > 0 for property %s", instancesKey);
        return ResourceSpecification.Builder.with().setVirtualCores(vCores).setMemory(memory, ResourceSpecification.SizeUnit.MEGA).setInstances(instances).build();
    }

    /**
     * Adds localize resources for the given service.
     */
    private Builder.RunnableSetter addResources(String service, Builder.RuntimeSpecificationAdder adder) {
        Map<String, LocalizeResource> localizeResources = runnableLocalizeResources.get(service);
        Iterator<Map.Entry<String, LocalizeResource>> iterator = localizeResources.entrySet().iterator();
        TwillSpecification.Builder.MoreFile moreFile = null;

        return moreFile == null ? adder.noLocalFiles() : moreFile.apply();
    }

    /**
     * Serializes the given {@link CConfiguration} to the give file.
     */
    private Path saveCConf(CConfiguration cConf, Path file) throws IOException {
        try (Writer writer = Files.newBufferedWriter(file, Charsets.UTF_8)) {
            cConf.writeXml(writer);
        }
        return file;
    }

    /**
     * Serializes the given {@link Configuration} to the give file.
     */
    private Path saveHConf(Configuration conf, Path file) throws IOException {
        try (Writer writer = Files.newBufferedWriter(file, Charsets.UTF_8)) {
            conf.writeXml(writer);
        }
        return file;
    }

    /**
     * Prepares resources that need to be localized to the log saver container.
     */
    private void prepareLogSaverResources(Path tempDir, CConfiguration containerCConf, Map<String, LocalizeResource> localizeResources, Collection<String> extraClassPath) throws IOException {
        String configJarName = "log.config.jar";
        String libJarName = "log.lib.jar";
        // Localize log config files
        List<File> configFiles = DirUtils.listFiles(new File(cConf.get(Constants.Logging.PIPELINE_CONFIG_DIR)), "xml");
        if (!configFiles.isEmpty()) {
            Path configJar = Files.createTempFile(tempDir, "log.config", ".jar");
            try (JarOutputStream jarOutput = new JarOutputStream(Files.newOutputStream(configJar))) {
                for (File configFile : configFiles) {
                    jarOutput.putNextEntry(new JarEntry(configFile.getName()));
                    Files.copy(configFile.toPath(), jarOutput);
                    jarOutput.closeEntry();
                }
            }
            localizeResources.put(configJarName, new LocalizeResource(configJar.toUri(), true));
        }
        // It's ok to set to a non-existing directory in case there is no config files
        containerCConf.set(Constants.Logging.PIPELINE_CONFIG_DIR, configJarName);
        // Localize log lib jars
        // First collect jars under each of the configured lib directory
        List<File> libJars = LoggingUtil.getExtensionJars(cConf);
        if (!libJars.isEmpty()) {
            Path libJar = Files.createTempFile("log.lib", ".jar");
            try (JarOutputStream jarOutput = new JarOutputStream(Files.newOutputStream(libJar))) {
                for (File jarFile : libJars) {
                    jarOutput.putNextEntry(new JarEntry(jarFile.getName()));
                    Files.copy(jarFile.toPath(), jarOutput);
                    jarOutput.closeEntry();
                    // Add the log lib jar to the container classpath
                    extraClassPath.add(libJarName + File.separator + jarFile.getName());
                }
            }
            localizeResources.put(libJarName, new LocalizeResource(libJar.toUri(), true));
        }
        // Set it to empty value since we don't use this in the container.
        // All jars are already added as part of container classpath.
        containerCConf.set(Constants.Logging.PIPELINE_LIBRARY_DIR, "");
    }

    /**
     * Prepares resources to be localized to the explore container.
     */
    private void prepareExploreResources(Path tempDir, Configuration hConf, Map<String, LocalizeResource> localizeResources, Collection<String> extraClassPath) throws IOException {
        // Find the jars in the yarn application classpath
        String yarnAppClassPath = Joiner.on(File.pathSeparatorChar).join(hConf.getTrimmedStrings(YarnConfiguration.YARN_APPLICATION_CLASSPATH, YarnConfiguration.DEFAULT_YARN_APPLICATION_CLASSPATH));
        final Set<File> yarnAppJarFiles = new LinkedHashSet<>();
        Iterables.addAll(yarnAppJarFiles, ExploreUtils.getClasspathJarFiles(yarnAppClassPath));
        // Filter out jar files that are already in the yarn application classpath as those,
        // are already available in the Explore container.
        Iterable<File> exploreFiles = Iterables.filter(ExploreUtils.getExploreClasspathJarFiles("tgz", "gz"), new Predicate<File>() {

            @Override
            public boolean apply(File file) {
                return !yarnAppJarFiles.contains(file);
            }
        });
        // Create a zip file that contains all explore jar files.
        // Upload and localizing one big file is fast than many small one.
        Path exploreArchive = Files.createTempFile(tempDir, "explore.archive", ".zip");
        Set<String> addedJar = new HashSet<>();
        try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(exploreArchive))) {
            zos.setLevel(Deflater.NO_COMPRESSION);
            for (File file : exploreFiles) {
                if (file.getName().endsWith(".tgz") || file.getName().endsWith(".gz")) {
                    // It's an archive, hence localize it archive so that it will be expanded to a directory on the container
                    localizeResources.put(file.getName(), new LocalizeResource(file, true));
                    // Includes the expanded directory, jars under that directory and jars under the "lib" to classpath
                    extraClassPath.add(file.getName());
                    extraClassPath.add(file.getName() + "/*");
                    extraClassPath.add(file.getName() + "/lib/*");
                } else {
                    // For jar file, add it to explore archive
                    File targetFile = tempDir.resolve(System.currentTimeMillis() + "-" + file.getName()).toFile();
                    File resultFile = ExploreServiceUtils.patchHiveClasses(file, targetFile);
                    if (resultFile == targetFile) {
                        LOG.info("Rewritten HiveAuthFactory from jar file {} to jar file {}", file, resultFile);
                    }
                    // don't add duplicate jar
                    if (addedJar.add(resultFile.getName())) {
                        zos.putNextEntry(new ZipEntry(resultFile.getName()));
                        Files.copy(resultFile.toPath(), zos);
                        extraClassPath.add(ExploreServiceTwillRunnable.EXPLORE_ARCHIVE_NAME + File.separator + resultFile.getName());
                    }
                }
            }
        }
        if (!addedJar.isEmpty()) {
            localizeResources.put(ExploreServiceTwillRunnable.EXPLORE_ARCHIVE_NAME, new LocalizeResource(exploreArchive.toFile(), true));
        }
        // Explore also depends on MR, hence adding MR jars to the classpath.
        // Depending on how the cluster is configured, we might need to localize the MR framework tgz as well.
        MapReduceContainerHelper.localizeFramework(hConf, localizeResources);
        MapReduceContainerHelper.addMapReduceClassPath(hConf, extraClassPath);
        LOG.trace("Jars in extra classpath after adding jars in explore classpath: {}", extraClassPath);
    }

    /**
     * Prepares the {@link HBaseDDLExecutor} implementation for localization.
     */
    private void prepareHBaseDDLExecutorResources(Path tempDir, CConfiguration cConf) throws IOException {
        String ddlExecutorExtensionDir = cConf.get(Constants.HBaseDDLExecutor.EXTENSIONS_DIR);
        if (ddlExecutorExtensionDir == null) {
            // Nothing to localize
            return;
        }
        final File target = new File(tempDir.toFile(), "hbaseddlext.jar");
        BundleJarUtil.createJar(new File(ddlExecutorExtensionDir), target);
        for (String service : ALL_SERVICES.keySet()) {
            Map<String, LocalizeResource> localizeResourceMap = runnableLocalizeResources.get(service);
            localizeResourceMap.put(target.getName(), new LocalizeResource(target, true));
        }
        cConf.set(Constants.HBaseDDLExecutor.EXTENSIONS_DIR, target.getName());
    }
}


switch(i) {
            case 1000:
                return Retry;
            case 1001:
                return Stop;
            default:
                return Retry;
        }

package com.jd.binlog.exception;

/**
 * operation Type for error code
 */
public enum OperationType {

    // retry 重试
    Retry(1000),
    // stop no need to retry
    Stop(1001);

    private final int id;

    OperationType(int i) {
        this.id = i;
    }

    /**
     * take the number into operation tp
     * @param i
     * @return
     */
    public static OperationType valueOf(int i) {


switch(position) {
                case 0:
                    mFragmentManager.beginTransaction().show(mContactOperationFragment).hide(mSystemMessageFragment).commit();
                    break;
                case 1:
                    mFragmentManager.beginTransaction().show(mSystemMessageFragment).hide(mContactOperationFragment).commit();
                    break;
            }

package com.yzx.chat.module.contact.view;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.ViewGroup;
import com.yzx.chat.R;
import com.yzx.chat.base.BaseCompatActivity;
import com.yzx.chat.util.AndroidHelper;
import com.yzx.chat.widget.view.SegmentedControlView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentManager;

public class NotificationMessageActivity extends BaseCompatActivity {

    public static void startActivity(Context context) {
        Intent intent = new Intent(context, NotificationMessageActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        context.startActivity(intent);
    }

    private SegmentedControlView mSegmentedControlView;

    private ContactOperationFragment mContactOperationFragment;

    private SystemMessageFragment mSystemMessageFragment;

    private Toolbar mToolbar;

    private FragmentManager mFragmentManager;

    @Override
    protected int getLayoutID() {
        return R.layout.activity_notification_message;
    }

    @Override
    protected void init(Bundle savedInstanceState) {
        mToolbar = findViewById(R.id.Default_mToolbar);
        mSegmentedControlView = new SegmentedControlView(this);
        mContactOperationFragment = new ContactOperationFragment();
        mSystemMessageFragment = new SystemMessageFragment();
        mFragmentManager = getSupportFragmentManager();
    }

    @Override
    protected void setup(Bundle savedInstanceState) {
        setDisplayHomeAsUpEnabled(true);
        setTitle(null);
        int paddingLeftRight = (int) AndroidHelper.dip2px(10);
        int paddingTopBottom = (int) AndroidHelper.dip2px(5);
        mSegmentedControlView.setItems(getResources().getStringArray(R.array.NotificationMessageActivity_Subtitle)).setColors(Color.WHITE, ContextCompat.getColor(this, R.color.colorAccent)).setTextSize(AndroidHelper.sp2px(14)).setItemPadding(paddingLeftRight, paddingTopBottom, paddingLeftRight, paddingTopBottom).setRadius(AndroidHelper.dip2px(4)).setDefaultSelectedPosition(0).setOnSelectionChangedListener(mOnSelectedChangedListener).update();
        mToolbar.addView(mSegmentedControlView, new Toolbar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
        mFragmentManager.beginTransaction().add(R.id.NotificationMessageActivity_mFlContent, mContactOperationFragment).add(R.id.NotificationMessageActivity_mFlContent, mSystemMessageFragment).hide(mSystemMessageFragment).commit();
    }

    private final SegmentedControlView.OnSelectedChangedListener mOnSelectedChangedListener = new SegmentedControlView.OnSelectedChangedListener() {

        @Override
        public void onSelected(int position, String text) {


while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }

/*! ******************************************************************************
 *
 * Pentaho Data Integration
 *
 *
 *******************************************************************************
 *
 *
 ******************************************************************************/
package org.pentaho.di.ui.job.entries.talendjobexec;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.vfs.KettleVFS;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.job.JobMeta;
import org.pentaho.di.job.entries.talendjobexec.JobEntryTalendJobExec;
import org.pentaho.di.job.entry.JobEntryDialogInterface;
import org.pentaho.di.job.entry.JobEntryInterface;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.ui.core.gui.WindowProperty;
import org.pentaho.di.ui.core.widget.TextVar;
import org.pentaho.di.ui.job.dialog.JobDialog;
import org.pentaho.di.ui.job.entry.JobEntryDialog;
import org.pentaho.di.ui.spoon.Spoon;
import org.pentaho.di.ui.trans.step.BaseStepDialog;
import org.pentaho.vfs.ui.VfsFileChooserDialog;

/**
 * This dialog allows you to edit the SQL job entry settings. (select the connection and the sql script to be executed)
 *
 * @author Matt
 * @since 19-06-2003
 */
public class JobEntryTalendJobExecDialog extends JobEntryDialog implements JobEntryDialogInterface {

    // for i18n purposes, needed by Translator2!!
    private static Class<?> PKG = JobEntryTalendJobExec.class;

    private static final String[] EXTENSIONS = new String[] { "*.ZIP;*.zip", "*" };

    private static final String[] FILETYPES = new String[] { BaseMessages.getString(PKG, "JobEntryTalendJobExec.Filetype.ZIP"), BaseMessages.getString(PKG, "JobEntryTalendJobExec.Filetype.All") };

    private Label wlName;

    private Text wName;

    private FormData fdlName, fdName;

    private Label wlFilename;

    private Button wbFilename;

    private TextVar wFilename;

    private FormData fdlFilename, fdbFilename, fdFilename;

    private Button wOK, wCancel;

    private Listener lsOK, lsCancel;

    private JobEntryTalendJobExec jobEntry;

    private Shell shell;

    private SelectionAdapter lsDef;

    private boolean changed;

    private TextVar wClassName;

    public JobEntryTalendJobExecDialog(Shell parent, JobEntryInterface jobEntryInt, Repository rep, JobMeta jobMeta) {
        super(parent, jobEntryInt, rep, jobMeta);
        jobEntry = (JobEntryTalendJobExec) jobEntryInt;
        if (this.jobEntry.getName() == null) {
            this.jobEntry.setName(BaseMessages.getString(PKG, "JobEntryTalendJobExec.Name.Default"));
        }
    }

    public JobEntryInterface open() {
        Shell parent = getParent();
        Display display = parent.getDisplay();
        shell = new Shell(parent, props.getJobsDialogStyle());
        props.setLook(shell);
        JobDialog.setShellImage(shell, jobEntry);
        ModifyListener lsMod = new ModifyListener() {

            public void modifyText(ModifyEvent e) {
                jobEntry.setChanged();
            }
        };
        changed = jobEntry.hasChanged();
        FormLayout formLayout = new FormLayout();
        formLayout.marginWidth = Const.FORM_MARGIN;
        formLayout.marginHeight = Const.FORM_MARGIN;
        shell.setLayout(formLayout);
        shell.setText(BaseMessages.getString(PKG, "JobEntryTalendJobExec.Title"));
        int middle = props.getMiddlePct();
        int margin = Const.MARGIN;
        // Filename line
        wlName = new Label(shell, SWT.RIGHT);
        wlName.setText(BaseMessages.getString(PKG, "JobEntryTalendJobExec.Name.Label"));
        props.setLook(wlName);
        fdlName = new FormData();
        fdlName.left = new FormAttachment(0, 0);
        fdlName.right = new FormAttachment(middle, -margin);
        fdlName.top = new FormAttachment(0, margin);
        wlName.setLayoutData(fdlName);
        wName = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
        props.setLook(wName);
        wName.addModifyListener(lsMod);
        fdName = new FormData();
        fdName.left = new FormAttachment(middle, 0);
        fdName.top = new FormAttachment(0, margin);
        fdName.right = new FormAttachment(100, 0);
        wName.setLayoutData(fdName);
        Control lastControl = wName;
        // Filename line
        wlFilename = new Label(shell, SWT.RIGHT);
        wlFilename.setText(BaseMessages.getString(PKG, "JobEntryTalendJobExec.Filename.Label"));
        props.setLook(wlFilename);
        fdlFilename = new FormData();
        fdlFilename.left = new FormAttachment(0, 0);
        fdlFilename.top = new FormAttachment(lastControl, margin);
        fdlFilename.right = new FormAttachment(middle, -margin);
        wlFilename.setLayoutData(fdlFilename);
        wbFilename = new Button(shell, SWT.PUSH | SWT.CENTER);
        props.setLook(wbFilename);
        wbFilename.setText(BaseMessages.getString(PKG, "System.Button.Browse"));
        fdbFilename = new FormData();
        fdbFilename.right = new FormAttachment(100, 0);
        fdbFilename.top = new FormAttachment(lastControl, 0);
        wbFilename.setLayoutData(fdbFilename);
        wFilename = new TextVar(jobMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
        props.setLook(wFilename);
        wFilename.addModifyListener(lsMod);
        fdFilename = new FormData();
        fdFilename.left = new FormAttachment(middle, 0);
        fdFilename.top = new FormAttachment(lastControl, margin);
        fdFilename.right = new FormAttachment(wbFilename, -margin);
        wFilename.setLayoutData(fdFilename);
        // Whenever something changes, set the tooltip to the expanded version:
        wFilename.addModifyListener(new ModifyListener() {

            public void modifyText(ModifyEvent e) {
                wFilename.setToolTipText(jobMeta.environmentSubstitute(wFilename.getText()));
            }
        });
        wbFilename.addSelectionListener(new SelectionAdapter() {

            public void widgetSelected(SelectionEvent e) {
                try {
                    FileObject fileName = null;
                    try {
                        String curFile = wFilename.getText();
                        if (curFile.trim().length() > 0) {
                            fileName = KettleVFS.getInstance().getFileSystemManager().resolveFile(jobMeta.environmentSubstitute(wFilename.getText()));
                        } else {
                            fileName = KettleVFS.getInstance().getFileSystemManager().resolveFile(Const.getUserHomeDirectory());
                        }
                    } catch (FileSystemException ex) {
                        fileName = KettleVFS.getInstance().getFileSystemManager().resolveFile(Const.getUserHomeDirectory());
                    }
                    VfsFileChooserDialog vfsFileChooser = Spoon.getInstance().getVfsFileChooserDialog(fileName.getParent(), fileName);
                    FileObject selected = vfsFileChooser.open(shell, null, EXTENSIONS, FILETYPES, VfsFileChooserDialog.VFS_DIALOG_OPEN_FILE);
                    wFilename.setText(selected != null ? selected.getURL().toString() : Const.EMPTY_STRING);
                } catch (FileSystemException ex) {
                    ex.printStackTrace();
                }
            }
        });
        lastControl = wFilename;
        // Filename line
        Label wlClassName = new Label(shell, SWT.RIGHT);
        wlClassName.setText(BaseMessages.getString(PKG, "JobEntryTalendJobExec.ClassName.Label"));
        props.setLook(wlClassName);
        FormData fdlClassName = new FormData();
        fdlClassName.left = new FormAttachment(0, 0);
        fdlClassName.right = new FormAttachment(middle, -margin);
        fdlClassName.top = new FormAttachment(lastControl, margin);
        wlClassName.setLayoutData(fdlClassName);
        wClassName = new TextVar(jobMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
        wClassName.setToolTipText(BaseMessages.getString(PKG, "JobEntryTalendJobExec.ClassName.Tooltip"));
        props.setLook(wClassName);
        wClassName.addModifyListener(lsMod);
        FormData fdClassName = new FormData();
        fdClassName.left = new FormAttachment(middle, 0);
        fdClassName.top = new FormAttachment(lastControl, margin);
        fdClassName.right = new FormAttachment(100, 0);
        wClassName.setLayoutData(fdClassName);
        lastControl = wClassName;
        wOK = new Button(shell, SWT.PUSH);
        wOK.setText(BaseMessages.getString(PKG, "System.Button.OK"));
        FormData fd = new FormData();
        fd.right = new FormAttachment(50, -10);
        fd.bottom = new FormAttachment(100, 0);
        fd.width = 100;
        wOK.setLayoutData(fd);
        wCancel = new Button(shell, SWT.PUSH);
        wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel"));
        fd = new FormData();
        fd.left = new FormAttachment(50, 10);
        fd.bottom = new FormAttachment(100, 0);
        fd.width = 100;
        wCancel.setLayoutData(fd);
        BaseStepDialog.positionBottomButtons(shell, new Button[] { wOK, wCancel }, margin, wClassName);
        // Add listeners
        lsCancel = new Listener() {

            public void handleEvent(Event e) {
                cancel();
            }
        };
        lsOK = new Listener() {

            public void handleEvent(Event e) {
                ok();
            }
        };
        wCancel.addListener(SWT.Selection, lsCancel);
        wOK.addListener(SWT.Selection, lsOK);
        lsDef = new SelectionAdapter() {

            public void widgetDefaultSelected(SelectionEvent e) {
                ok();
            }
        };
        wName.addSelectionListener(lsDef);
        wFilename.addSelectionListener(lsDef);
        // Detect X or ALT-F4 or something that kills this window...
        shell.addShellListener(new ShellAdapter() {

            public void shellClosed(ShellEvent e) {
                cancel();
            }
        });
        getData();
        BaseStepDialog.setSize(shell);
        shell.open();
        props.setDialogSize(shell, "JobEntryTalendJobExec.DialogSize");

        return jobEntry;
    }

    public void dispose() {
        WindowProperty winprop = new WindowProperty(shell);
        props.setScreen(winprop);
        shell.dispose();
    }

    /**
     * Copy information from the meta-data input to the dialog fields.
     */
    public void getData() {
        wFilename.setText(Const.NVL(jobEntry.getFilename(), ""));
        wClassName.setText(Const.NVL(jobEntry.getClassName(), ""));
        wName.setText(Const.NVL(jobEntry.getName(), ""));
        wName.selectAll();
        wName.setFocus();
    }

    private void cancel() {
        jobEntry.setChanged(changed);
        jobEntry = null;
        dispose();
    }

    private void ok() {
        if (Utils.isEmpty(wName.getText())) {
            MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
            mb.setText(BaseMessages.getString(PKG, "System.StepJobEntryNameMissing.Title"));
            mb.setMessage(BaseMessages.getString(PKG, "System.JobEntryNameMissing.Msg"));
            mb.open();
            return;
        }
        jobEntry.setName(wName.getText());
        jobEntry.setFilename(wFilename.getText());
        jobEntry.setClassName(wClassName.getText());
        dispose();
    }

    public boolean evaluates() {
        return true;
    }

    public boolean isUnconditional() {
        return false;
    }
}


while ((numRead = reader.read(buffer, 0, buffer.length)) != -1) {
                sb.append(buffer, 0, numRead);
            }

/*
 * All rights reserved.
 *
 *
 * NASA World Wind Java (WWJ) also contains the following 3rd party Open Source
 * software:
 *
 *
 * A complete listing of 3rd Party software notices and licenses included in
 * NASA World Wind Java (WWJ)  can be found in the WorldWindJava-v2.2 3rd-party
 * notices and licenses PDF found in code directory.
 */
package gov.nasa.worldwindx.examples;

import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.layers.Earth.UTMBaseGraticuleLayer;
import gov.nasa.worldwind.layers.Earth.*;
import gov.nasa.worldwind.util.Logging;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileWriter;

/**
 * @author dcollins
 * @version $Id: MGRSAttributesPanel.java 1171 2013-02-11 21:45:02Z dcollins $
 */
@SuppressWarnings("unchecked")
public class MGRSAttributesPanel extends JPanel {

    // Logical components.
    private final MGRSGraticuleLayer layer;

    // UI components.
    private JList itemList;

    private JComboBox maxResolutionComboBox;

    private JButton saveStateButton;

    private JButton loadStateButton;

    private JPanel cardPanel;

    private CardLayout cardLayout;

    private Map<String, Component> graticuleAttribPanelMap = new HashMap<String, Component>();

    // Helper properties.
    private boolean ignoreLayerEvents = false;

    private boolean ignoreUIEvents = false;

    private String[] ALL_GRATICULE_TYPES = new String[] { UTMBaseGraticuleLayer.GRATICULE_UTM, MGRSGraticuleLayer.GRATICULE_UTM_GRID, MGRSGraticuleLayer.GRATICULE_100000M, MGRSGraticuleLayer.GRATICULE_10000M, MGRSGraticuleLayer.GRATICULE_1000M, MGRSGraticuleLayer.GRATICULE_100M, MGRSGraticuleLayer.GRATICULE_10M, MGRSGraticuleLayer.GRATICULE_1M };

    private String[] MGRS_GRATICULE_TYPES = new String[] { MGRSGraticuleLayer.GRATICULE_UTM_GRID, MGRSGraticuleLayer.GRATICULE_100000M, MGRSGraticuleLayer.GRATICULE_10000M, MGRSGraticuleLayer.GRATICULE_1000M, MGRSGraticuleLayer.GRATICULE_100M, MGRSGraticuleLayer.GRATICULE_10M, MGRSGraticuleLayer.GRATICULE_1M };

    public MGRSAttributesPanel(MGRSGraticuleLayer mgrsGraticuleLayer) {
        if (mgrsGraticuleLayer == null) {
            String message = Logging.getMessage("nullValue.LayerIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        this.layer = mgrsGraticuleLayer;
        this.layer.addPropertyChangeListener(new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent event) {
                onLayerPropertyChanged(event);
            }
        });
        init();
    }

    private void init() {
        // Initialize UI components.
        makeComponents();
        // Initialize UI layout.
        layoutComponents();
        // Update UI state to reflect the current layer state.
        updateComponents();
        String selectedType = MGRSGraticuleLayer.GRATICULE_UTM_GRID;
        this.itemList.setSelectedValue(selectedType, true);
        this.cardLayout.show(this.cardPanel, selectedType);
    }

    public final MGRSGraticuleLayer getLayer() {
        return this.layer;
    }

    public static JDialog showDialog(Component component, String title, MGRSGraticuleLayer mgrsGraticuleLayer) {
        if (mgrsGraticuleLayer == null) {
            String message = Logging.getMessage("nullValue.LayerIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        JDialog dialog;
        if (component != null && component instanceof Dialog) {
            dialog = new JDialog((Dialog) component);
        } else if (component != null && component instanceof Frame) {
            dialog = new JDialog((Frame) component);
        } else {
            dialog = new JDialog();
        }
        if (title != null) {
            dialog.setTitle(title);
        }
        MGRSAttributesPanel panel = new MGRSAttributesPanel(mgrsGraticuleLayer);
        dialog.getContentPane().setLayout(new BorderLayout());
        dialog.getContentPane().add(panel, BorderLayout.CENTER);
        dialog.pack();
        dialog.setVisible(true);
        return dialog;
    }

    public String getSelectedGraticule() {
        Object selectedValue = this.itemList.getSelectedValue();
        return selectedValue != null ? selectedValue.toString() : null;
    }

    public void setSelectedGraticule(String graticuleType) {
        if (graticuleType == null) {
            String message = Logging.getMessage("nullValue.StringIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        this.itemList.setSelectedValue(graticuleType, true);
        this.cardLayout.show(this.cardPanel, graticuleType);
    }

    private void onListSelectionChanged(ListSelectionEvent event) {
        if (event != null) {
            Object selectedValue = this.itemList.getSelectedValue();
            this.cardLayout.show(this.cardPanel, selectedValue.toString());
        }
    }

    private void onMaxResolutionChanged(ActionEvent event) {
        if (event != null) {
            if (!this.ignoreUIEvents) {
                updateLayer();
            }
        }
    }

    private void onSaveStatePressed(ActionEvent event) {
        if (event == null)
            return;
        JFileChooser fc = new JFileChooser();
        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int resultVal = fc.showSaveDialog(this);
        if (resultVal != JFileChooser.APPROVE_OPTION)
            return;
        File file = fc.getSelectedFile();
        if (file == null)
            return;
        try {
            String stateInXml = this.layer.getRestorableState();
            saveString(stateInXml, file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void onLoadStatePressed(ActionEvent event) {
        if (event == null)
            return;
        JFileChooser fc = new JFileChooser();
        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int resultVal = fc.showOpenDialog(this);
        if (resultVal != JFileChooser.APPROVE_OPTION)
            return;
        File file = fc.getSelectedFile();
        if (file == null)
            return;
        try {
            String stateInXml = loadString(file);
            this.layer.restoreState(stateInXml);
            this.layer.firePropertyChange(AVKey.LAYER, null, this.layer);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void onPanelStateChanged(PropertyChangeEvent event, String graticuleType) {
        if (event != null && graticuleType != null) {
            if (!this.ignoreUIEvents) {
                if (event.getPropertyName().equals(GraticuleAttributesPanel.LINE_COLOR_PROPERTY) || event.getPropertyName().equals(GraticuleAttributesPanel.LINE_WIDTH_PROPERTY) || event.getPropertyName().equals(GraticuleAttributesPanel.LINE_STYLE_PROPERTY) || event.getPropertyName().equals(GraticuleAttributesPanel.LABEL_ENABLED_PROPERTY) || event.getPropertyName().equals(GraticuleAttributesPanel.LABEL_COLOR_PROPERTY) || event.getPropertyName().equals(GraticuleAttributesPanel.LABEL_FONT_PROPERTY)) {
                    updateLayer();
                }
            }
        }
    }

    private void updateLayer() {
        this.ignoreLayerEvents = true;
        try {
            if (this.layer != null) {
                this.layer.setMaximumGraticuleResolution(this.maxResolutionComboBox.getSelectedItem().toString());
                for (Map.Entry<String, Component> entry : this.graticuleAttribPanelMap.entrySet()) {
                    if (entry.getKey() != null && entry.getValue() != null) {
                        if (entry.getValue() instanceof GraticuleAttributesPanel) {
                            updateLayerState((GraticuleAttributesPanel) entry.getValue(), entry.getKey());
                        }
                    }
                }
            }
        } finally {
            this.ignoreLayerEvents = false;
        }
    }

    private void updateLayerState(GraticuleAttributesPanel attributesPanel, String graticuleType) {
        if (this.layer != null && attributesPanel != null && graticuleType != null) {
            this.layer.setGraticuleLineColor(attributesPanel.getSelectedLineColor(), graticuleType);
            this.layer.setGraticuleLineWidth(attributesPanel.getSelectedLineWidth(), graticuleType);
            this.layer.setGraticuleLineStyle(attributesPanel.getSelectedLineStyle(), graticuleType);
            this.layer.setDrawLabels(attributesPanel.isLabelEnableSelected(), graticuleType);
            this.layer.setLabelColor(attributesPanel.getSelectedLabelColor(), graticuleType);
            this.layer.setLabelFont(attributesPanel.getSelectedLabelFont(), graticuleType);
            this.layer.firePropertyChange(AVKey.LAYER, null, this.layer);
        }
    }

    private void onLayerPropertyChanged(PropertyChangeEvent event) {
        if (event != null) {
            if (!this.ignoreLayerEvents) {
                updateComponents();
            }
        }
    }

    private void updateComponents() {
        this.ignoreUIEvents = true;
        try {
            if (this.layer != null) {
                this.maxResolutionComboBox.setSelectedItem(layer.getMaximumGraticuleResolution());
            }
            for (Map.Entry<String, Component> entry : this.graticuleAttribPanelMap.entrySet()) {
                if (entry.getKey() != null && entry.getValue() != null) {
                    if (entry.getValue() instanceof GraticuleAttributesPanel) {
                        updatePanelState((GraticuleAttributesPanel) entry.getValue(), entry.getKey());
                    }
                }
            }
        } finally {
            this.ignoreUIEvents = false;
        }
    }

    private void updatePanelState(GraticuleAttributesPanel panel, String graticuleType) {
        if (this.layer != null && panel != null && graticuleType != null) {
            panel.setSelectedLineColor(this.layer.getGraticuleLineColor(graticuleType));
            panel.setSelectedLineWidth(this.layer.getGraticuleLineWidth(graticuleType));
            panel.setSelectedLineStyle(this.layer.getGraticuleLineStyle(graticuleType));
            panel.setLabelEnableSelected(this.layer.isDrawLabels(graticuleType));
            panel.setSelectedLabelColor(this.layer.getLabelColor(graticuleType));
            panel.setSelectedLabelFont(this.layer.getLabelFont(graticuleType));
        }
    }

    private static String loadString(File file) throws IOException {
        String s = null;
        FileReader reader = null;
        try {
            reader = new FileReader(file);
            StringBuilder sb = new StringBuilder();
            int numRead;
            char[] buffer = new char[2048];

            s = sb.toString();
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return s;
    }

    private static void saveString(String s, File file) throws IOException {
        FileWriter writer = null;
        try {
            if (s != null && file != null) {
                writer = new FileWriter(file);
                writer.write(s);
            }
        } finally {
            try {
                if (writer != null)
                    writer.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void makeComponents() {
        this.itemList = new JList(ALL_GRATICULE_TYPES);
        this.itemList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        ListCellRenderer originalRenderer = this.itemList.getCellRenderer();
        this.itemList.setCellRenderer(new GraticuleTypeListRenderer(originalRenderer, null));
        this.itemList.addListSelectionListener(new ListSelectionListener() {

            public void valueChanged(ListSelectionEvent event) {
                onListSelectionChanged(event);
            }
        });
        this.saveStateButton = new JButton("Save State");
        this.saveStateButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent event) {
                onSaveStatePressed(event);
            }
        });
        this.loadStateButton = new JButton("Load State");
        this.loadStateButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent event) {
                onLoadStatePressed(event);
            }
        });
        this.maxResolutionComboBox = new JComboBox(MGRS_GRATICULE_TYPES);
        originalRenderer = this.maxResolutionComboBox.getRenderer();
        this.maxResolutionComboBox.setRenderer(new GraticuleTypeListRenderer(originalRenderer, null));
        this.maxResolutionComboBox.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent event) {
                onMaxResolutionChanged(event);
            }
        });
        this.cardLayout = new CardLayout();
        this.cardPanel = new JPanel();
        this.cardPanel.setLayout(this.cardLayout);
        for (String type : ALL_GRATICULE_TYPES) {
            Component panel = makeGraticulePanel(type);
            this.graticuleAttribPanelMap.put(type, panel);
        }
    }

    private Component makeGraticulePanel(final String graticuleType) {
        if (graticuleType == null) {
            String message = Logging.getMessage("nullValue.StringIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        GraticuleAttributesPanel panel = new GraticuleAttributesPanel();
        panel.addPropertyChangeListener(new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent event) {
                onPanelStateChanged(event, graticuleType);
            }
        });
        return panel;
    }

    private void layoutComponents() {
        setLayout(new BorderLayout());
        // ---------- Graticule Item List ----------//
        {
            Box box = Box.createVerticalBox();
            box.setBorder(new EmptyBorder(30, 20, 20, 5));
            JScrollPane itemScrollPane = new JScrollPane(this.itemList);
            itemScrollPane.setAlignmentX(Component.LEFT_ALIGNMENT);
            box.add(itemScrollPane);
            box.add(Box.createVerticalStrut(20));
            JLabel label = new JLabel("Maximum Resolution");
            label.setAlignmentX(Component.LEFT_ALIGNMENT);
            box.add(label);
            this.maxResolutionComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
            box.add(this.maxResolutionComboBox);
            box.add(Box.createVerticalStrut(20));
            this.saveStateButton.setAlignmentX(Component.LEFT_ALIGNMENT);
            box.add(this.saveStateButton);
            this.loadStateButton.setAlignmentX(Component.LEFT_ALIGNMENT);
            box.add(this.loadStateButton);
            box.add(Box.createVerticalGlue());
            add(box, BorderLayout.WEST);
        }
        // ---------- Graticule Card Panel ----------//
        {
            this.cardPanel.setBorder(new EmptyBorder(30, 5, 20, 20));
            for (Map.Entry<String, Component> entry : this.graticuleAttribPanelMap.entrySet()) {
                if (entry.getKey() != null && entry.getValue() != null) {
                    this.cardPanel.add(entry.getValue(), entry.getKey());
                }
            }
            add(this.cardPanel, BorderLayout.CENTER);
        }
    }

    private static String getGraticuleLabel(String graticuleType) {
        String labelText = null;
        if (UTMBaseGraticuleLayer.GRATICULE_UTM.equals(graticuleType))
            labelText = "Global UTM";
        else if (MGRSGraticuleLayer.GRATICULE_UTM_GRID.equals(graticuleType))
            labelText = "UTM Grid";
        else if (MGRSGraticuleLayer.GRATICULE_100000M.equals(graticuleType))
            labelText = "100km";
        else if (MGRSGraticuleLayer.GRATICULE_10000M.equals(graticuleType))
            labelText = "10km";
        else if (MGRSGraticuleLayer.GRATICULE_1000M.equals(graticuleType))
            labelText = "1km";
        else if (MGRSGraticuleLayer.GRATICULE_100M.equals(graticuleType))
            labelText = "100m";
        else if (MGRSGraticuleLayer.GRATICULE_10M.equals(graticuleType))
            labelText = "10m";
        else if (MGRSGraticuleLayer.GRATICULE_1M.equals(graticuleType))
            labelText = "1m";
        return labelText;
    }

    @SuppressWarnings({ "UnusedDeclaration" })
    private Icon getIcon(String path) {
        Icon icon = null;
        try {
            URL url = getClass().getResource(path);
            if (url != null) {
                icon = new ImageIcon(url);
            }
        } catch (Exception e) {
            String message = "Exception while loading icon";
            Logging.logger().log(java.util.logging.Level.WARNING, message, e);
        }
        return icon;
    }

    @SuppressWarnings("unchecked")
    private static class GraticuleTypeListRenderer implements ListCellRenderer {

        private ListCellRenderer delegate;

        private Icon icon;

        public GraticuleTypeListRenderer(ListCellRenderer delegate, Icon icon) {
            this.delegate = delegate;
            this.icon = icon;
        }

        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Component c = this.delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (c != null && c instanceof JLabel) {
                JLabel label = (JLabel) c;
                Font font = label.getFont();
                if (font != null) {
                    label.setFont(font.deriveFont(Font.BOLD));
                }
                if (this.icon != null) {
                    label.setIcon(this.icon);
                }
                if (value != null && value instanceof String) {
                    String graticuleType = (String) value;
                    String labelText = getGraticuleLabel(graticuleType);
                    label.setText(labelText);
                }
            }
            return c;
        }
    }
}


switch(atom.getAtomicNumber()) {
            // F
            case 9:
            // Cl
            case 17:
            // Br
            case 35:
            case // I
            53:
                return true;
            default:
                return false;
        }

/*
 * Note: I adapted this fingerprint from Yap Chun Wei's PaDEL source code, which can be found here:
 * http://example.com
 *
 * Author: Lyle D. Burgoon, Ph.D. (example@nnthink.com)
 *
 *
 */
package org.openscience.cdk.fingerprint;

import org.openscience.cdk.config.Elements;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.graph.AllPairsShortestPaths;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Generates an atom pair 2D fingerprint as implemented in PaDEL given an  {@link IAtomContainer}, that
 * extends the {@link Fingerprinter}.
 *
 * @author Lyle Burgoon (lyle.d.burgoon@usace.army.mil)
 * @cdk.created 2018-02-05
 * @cdk.keyword fingerprint
 * @cdk.keyword similarity
 * @cdk.module fingerprint
 * @cdk.githash
 * @see org.openscience.cdk.fingerprint.Fingerprinter
 */
public class AtomPairs2DFingerprinter extends AbstractFingerprinter implements IFingerprinter {

    private static final int MAX_DISTANCE = 10;

    private static final String[] atypes = { "C", "N", "O", "S", "P", "F", "Cl", "Br", "I", "B", "Si", "X" };

    private final Map<String, Integer> pathToBit = new HashMap<>();

    private final Map<Integer, String> bitToPath = new HashMap<>();

    public AtomPairs2DFingerprinter() {
        for (int dist = 1; dist <= MAX_DISTANCE; dist++) {
            for (int i = 0; i < atypes.length; i++) {
                for (int j = i; j < atypes.length; j++) {
                    final String key_name = dist + "_" + atypes[i] + "_" + atypes[j];
                    pathToBit.put(key_name, pathToBit.size());
                    bitToPath.put(bitToPath.size(), key_name);
                }
            }
        }
    }

    @Override
    public int getSize() {
        return pathToBit.size();
    }

    /**
     * Checks if an atom is a halogen
     * @param atom
     * @return
     */
    private static boolean isHalogen(final IAtom atom) {

    }

    /**
     * Atoms that we are using in the fingerprint
     * @param atom
     * @return
     */
    private static boolean include(final IAtom atom) {
        switch(atom.getAtomicNumber()) {
            // B
            case 5:
            // C
            case 6:
            // N
            case 7:
            // O
            case 8:
            // Si
            case 14:
            // P
            case 15:
            // S
            case 16:
            // F
            case 9:
            // Cl
            case 17:
            // Br
            case 35:
            case // I
            53:
                return true;
            default:
                return false;
        }
    }

    /**
     * Creates the fingerprint name which is used as a key in our hashes
     * @param dist
     * @param a
     * @param b
     * @return
     */
    private static String encodePath(int dist, IAtom a, IAtom b) {
        return dist + "_" + a.getSymbol() + "_" + b.getSymbol();
    }

    /**
     * Encodes name for halogen paths
     * @param dist
     * @param a
     * @param b
     * @return
     */
    private static String encodeHalPath(int dist, IAtom a, IAtom b) {
        return dist + "_" + (isHalogen(a) ? "X" : a.getSymbol()) + "_" + (isHalogen(b) ? "X" : b.getSymbol());
    }

    /**
     * This performs the calculations used to generate the fingerprint
     * @param paths
     * @param mol
     */
    private void calculate(List<String> paths, IAtomContainer mol) {
        AllPairsShortestPaths apsp = new AllPairsShortestPaths(mol);
        int numAtoms = mol.getAtomCount();
        for (int i = 0; i < numAtoms; i++) {
            if (!include(mol.getAtom(i)))
                continue;
            for (int j = i + 1; j < numAtoms; j++) {
                if (!include(mol.getAtom(j)))
                    continue;
                final int dist = apsp.from(i).distanceTo(j);
                if (dist > MAX_DISTANCE)
                    continue;
                final IAtom beg = mol.getAtom(i);
                final IAtom end = mol.getAtom(j);
                paths.add(encodePath(dist, beg, end));
                paths.add(encodePath(dist, end, beg));
                if (isHalogen(mol.getAtom(i)) || isHalogen(mol.getAtom(j))) {
                    paths.add(encodeHalPath(dist, beg, end));
                    paths.add(encodeHalPath(dist, end, beg));
                }
            }
        }
    }

    @Override
    public IBitFingerprint getBitFingerprint(IAtomContainer container) throws CDKException {
        BitSet fp = new BitSet(pathToBit.size());
        List<String> paths = new ArrayList<>();
        calculate(paths, container);
        for (String path : paths) {
            if (!pathToBit.containsKey(path))
                continue;
            fp.set(pathToBit.get(path));
        }
        return new BitSetFingerprint(fp);
    }

    @Override
    public Map<String, Integer> getRawFingerprint(IAtomContainer mol) throws CDKException {
        Map<String, Integer> raw = new HashMap<>();
        List<String> paths = new ArrayList<>();
        calculate(paths, mol);
        Collections.sort(paths);
        int count = 0;
        String prev = null;
        for (String path : paths) {
            if (prev == null || !path.equals(prev)) {
                if (count > 0)
                    raw.put(prev, count);
                count = 1;
                prev = path;
            } else {
                ++count;
            }
        }
        if (count > 0)
            raw.put(prev, count);
        return raw;
    }

    @Override
    public ICountFingerprint getCountFingerprint(IAtomContainer mol) throws CDKException {
        final Map<String, Integer> raw = getRawFingerprint(mol);
        final List<String> keys = new ArrayList<>(raw.keySet());
        return new ICountFingerprint() {

            @Override
            public long size() {
                return pathToBit.size();
            }

            @Override
            public int numOfPopulatedbins() {
                return keys.size();
            }

            @Override
            public int getCount(int index) {
                return raw.get(keys.get(index));
            }

            @Override
            public int getHash(int index) {
                return pathToBit.get(keys.get(index));
            }

            @Override
            public void merge(ICountFingerprint fp) {
            }

            @Override
            public void setBehaveAsBitFingerprint(boolean behaveAsBitFingerprint) {
            }

            @Override
            public boolean hasHash(int hash) {
                return bitToPath.containsKey(hash);
            }

            @Override
            public int getCountForHash(int hash) {
                return raw.get(bitToPath.get(hash));
            }
        };
    }
}


while (li < llst.size() && ri < rlst.size()) {
            E le = llst.get(li);
            E re = rlst.get(ri);
            if (getComparator().compare(le, re) <= 0) {
                resultList.add(le);
                li++;
            } else {
                resultList.add(re);
                ri++;
            }
        }

package com.alibaba.cobar.client.merger;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import com.alibaba.cobar.client.support.utils.CollectionUtils;

/**
 * This merger implementation is mainly for situations that the original
 * sub-result lists are all in order.

 * In this situation, we only need to do the 2nd part of merge-sort algorithm to
 * sort all of the sub-result lists.

 *
 * @author fujohnwang
 * @since 1.0
 * @param <E>
 */
public class ConcurrentSortMerger<E> implements IMerger<List<E>, List<E>>, InitializingBean, DisposableBean {

    private boolean usingDefaultExecutor = false;

    private ExecutorService executor;

    private Comparator<E> comparator;

    public List<E> merge(List<List<E>> entities) {
        List<E> resultList = new ArrayList<E>();
        if (CollectionUtils.isNotEmpty(entities)) {
            if (entities.size() == 1) {
                resultList.addAll(entities.get(0));
            } else {
                List<List<E>> partialResult = new ArrayList<List<E>>();
                int pairs = entities.size() / 2;
                List<Future<List<E>>> futures = new ArrayList<Future<List<E>>>();
                for (int i = 0; i < pairs; i++) {
                    final List<E> llst = entities.get(i * 2);
                    final List<E> rlst = entities.get(i * 2 + 1);
                    futures.add(getExecutor().submit(new Callable<List<E>>() {

                        public List<E> call() throws Exception {
                            return partialSortMerge(llst, rlst);
                        }
                    }));
                }
                for (Future<List<E>> f : futures) {
                    try {
                        partialResult.add(f.get());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    }
                }
                if (entities.size() % 2 == 1) {
                    partialResult.add(entities.get(pairs * 2));
                }
                resultList.addAll(merge(partialResult));
            }
        }
        return resultList;
    }

    protected List<E> partialSortMerge(List<E> llst, List<E> rlst) {
        List<E> resultList = new ArrayList<E>();
        int li = 0, ri = 0;

        if (li < llst.size()) {
            resultList.addAll(llst.subList(li, llst.size()));
        }
        if (ri < rlst.size()) {
            resultList.addAll(rlst.subList(ri, rlst.size()));
        }
        return resultList;
    }

    public void setExecutor(ExecutorService executor) {
        this.executor = executor;
    }

    public ExecutorService getExecutor() {
        return executor;
    }

    public void afterPropertiesSet() throws Exception {
        if (getComparator() == null) {
            throw new IllegalArgumentException("you must provide a comparator for us to compare the element for merge.");
        }
        if (getExecutor() == null) {
            setExecutor(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()));
            usingDefaultExecutor = true;
        }
    }

    public void destroy() throws Exception {
        if (usingDefaultExecutor) {
            getExecutor().shutdown();
        }
    }

    public void setComparator(Comparator<E> comparator) {
        this.comparator = comparator;
    }

    public Comparator<E> getComparator() {
        return comparator;
    }
}