public class GraphMerger {
    
    boolean allowUndo = false;
    
    
    public GraphMerger(boolean allowUndo_) {
        allowUndo = allowUndo_;
    }
    public GraphMerger() {
        
    }
    /**
     * 
     * @param graph_01
     * @param graph_02
     * @param restrictionList
     * @param vocabulary
     * @param similarityThreshold
     * @return 
     */
    public DirectedGraph<Object, Edge> Merging(
            DirectedGraph<Object, Edge> graph_01, 
            DirectedGraph<Object, Edge> graph_02, 
            Map<String, AttributeErrorMargin> restrictionList,
            Vocabulary vocabulary,
            float similarityThreshold) {
        
        GraphMatching combiner = new GraphMatching(restrictionList, vocabulary.getVocabulary(), similarityThreshold);
        return MergeGraphs(graph_01, graph_02, combiner);
    }
    
    /**
     * 
     * @param graph_01
     * @param graph_02
     * @param restrictionList
     * @param vocabulary
     * @param similarityThreshold
     * @param defaultError
     * @return 
     */
    public DirectedGraph<Object, Edge> Merging(
            DirectedGraph<Object, Edge> graph_01, 
            DirectedGraph<Object, Edge> graph_02, 
            Map<String, AttributeErrorMargin> restrictionList,
            Vocabulary vocabulary,
            float similarityThreshold, String defaultError) {
        
        GraphMatching combiner = new GraphMatching(restrictionList, vocabulary.getVocabulary(), similarityThreshold, defaultError);
        return MergeGraphs(graph_01, graph_02, combiner);
    }
    
    /**
     * 
     * @param graph_01
     * @param graph_02
     * @param restrictionList
     * @param vocabulary
     * @param similarityThreshold
     * @param defaultError
     * @return 
     */
    public DirectedGraph<Object, Edge> Merging(
            DirectedGraph<Object, Edge> graph_01, 
            DirectedGraph<Object, Edge> graph_02, 
            Map<String, AttributeErrorMargin> restrictionList,
             Map<String, String> vocabulary,
            float similarityThreshold, String defaultError) {
        
        GraphMatching combiner = new GraphMatching(restrictionList, vocabulary, similarityThreshold, defaultError);
        return MergeGraphs(graph_01, graph_02, combiner);
    }
    
    /**
     * 
     * @param graph_01
     * @param graph_02
     * @param restrictionList
     * @param vocabulary
     * @param similarityThreshold
     * @param defaultError
     * @param defaultWeight
     * @return 
     */
    public DirectedGraph<Object, Edge> Merging(
            DirectedGraph<Object, Edge> graph_01, 
            DirectedGraph<Object, Edge> graph_02, 
            Map<String, AttributeErrorMargin> restrictionList,
             Map<String, String> vocabulary,
            float similarityThreshold, String defaultError, float defaultWeight) {
        
        GraphMatching combiner = new GraphMatching(restrictionList, vocabulary, similarityThreshold, defaultError, defaultWeight);
        return MergeGraphs(graph_01, graph_02, combiner);
    }
    
    /**
     * 
     * @param graph_01
     * @param graph_02
     * @param restrictionList
     * @param similarityThreshold
     * @param defaultError
     * @return 
     */
    public DirectedGraph<Object, Edge> Merging(
            DirectedGraph<Object, Edge> graph_01, 
            DirectedGraph<Object, Edge> graph_02, 
            Map<String, AttributeErrorMargin> restrictionList, 
            float similarityThreshold, String defaultError) {
        
        GraphMatching combiner = new GraphMatching(restrictionList, similarityThreshold, defaultError);
        return MergeGraphs(graph_01, graph_02, combiner);
    }
    
    /**
     * 
     * @param graph_01
     * @param graph_02
     * @param restrictionList
     * @param similarityThreshold
     * @return 
     */
    public DirectedGraph<Object, Edge> Merging(
            DirectedGraph<Object, Edge> graph_01, 
            DirectedGraph<Object, Edge> graph_02, 
            Map<String, AttributeErrorMargin> restrictionList, 
            float similarityThreshold) {
        
        GraphMatching combiner = new GraphMatching(restrictionList, similarityThreshold);
        return MergeGraphs(graph_01, graph_02, combiner);
    }
    
    /**
     * 
     * @param graph_01
     * @param graph_02
     * @param combiner
     * @return 
     */
    private DirectedGraph<Object, Edge> MergeGraphs(
            DirectedGraph<Object, Edge> graph_01, 
            DirectedGraph<Object, Edge> graph_02, 
            GraphMatching combiner) {
        // Correct IDs
//        Utils.updateVertexIDs(graph_01, graph01);
//        Utils.updateVertexIDs(graph_02, graph02);
//        Utils.updateEdgeIDs(graph_01, graph01);
//        Utils.updateEdgeIDs(graph_02, graph02);
        Utils.NormalizeTime(graph_01, true);
        Utils.NormalizeTime(graph_02, true);
        
        // Matching Heuristic
        MatchingHeuristic heuristic = new SimpleHeuristic(allowUndo);
        heuristic.MatchGraphs(graph_01, graph_02, combiner);
        
        if(allowUndo)
            return combiner.CG();
        else {
        // After matching all vertices
            combiner.addVertices(graph_01.getVertices());
            combiner.addVertices(graph_02.getVertices());
            Collection<Edge> updatedG1edges = combiner.updateEdges(graph_01.getEdges());
            Collection<Edge> updatedG2edges = combiner.updateEdges(graph_02.getEdges());
            combiner.addEdges(updatedG1edges);
            combiner.addEdges(updatedG2edges);
            return combiner.getCombinedGraph();
        }
    }
} public class Edge extends GraphObject {

    private String id;
    private Object source;
    private Object target;
    private final String type;           // Edge type (prov edges)
    //used to hide this edge when collapsing a group of edges
    private boolean hide;
    private Color defaultColor = new Color(0, 0, 255);
    private String influenceName = "Influence";

    /**
     * Constructor for testing purposes since it construct a mostly blank edge
     *
     * @param id is the edge ID
     * @param target is the target vertex
     * @param source is the source vertex
     */
    public Edge(String id, Object target, Object source) {
        this.id = id;
        this.source = source;
        this.target = target;
        this.type = "";
        hide = false;
        this.attributes = new HashMap<>();
        GraphAttribute att = new GraphAttribute(influenceName, "", "");
        this.attributes.put(att.getName(), att);
        if (!this.hasAttribute(VariableNames.edgeHiddenAttribute)) {
            GraphAttribute hide = new GraphAttribute(VariableNames.edgeHiddenAttribute, "false", "");
            this.attributes.put(hide.getName(), hide);
        } else {
            hide = Boolean.parseBoolean(this.getAttributeValue(VariableNames.edgeHiddenAttribute));
        }
//        this.attributes.putAll(attributes);
        setLabel("");
    }

    public Edge(String id, String type, Object target, Object source) {
        this.id = id;
        this.source = source;
        this.target = target;
        this.type = type;
        hide = false;
        this.attributes = new HashMap<>();
        GraphAttribute att = new GraphAttribute(influenceName, "", "");
        this.attributes.put(att.getName(), att);
        if (!this.hasAttribute(VariableNames.edgeHiddenAttribute)) {
            GraphAttribute hide = new GraphAttribute(VariableNames.edgeHiddenAttribute, "false", "");
            this.attributes.put(hide.getName(), hide);
        } else {
            hide = Boolean.parseBoolean(this.getAttributeValue(VariableNames.edgeHiddenAttribute));
        }
//        this.attributes.putAll(attributes);
        setLabel(type);
    }

    /**
     * Constructor
     *
     * @param id
     * @param type
     * @param value
     * @param label
     * @param attributes
     * @param target
     * @param source
     */
    public Edge(String id, String type, String value,
            String label, Map<String, GraphAttribute> attributes, Object target, Object source) {
        this.id = id;
        this.source = source;
        this.target = target;
        this.type = type;
        hide = false;
        this.attributes = new HashMap<>(attributes);
        GraphAttribute att = new GraphAttribute(influenceName, value, "");
        this.attributes.put(att.getName(), att);
        if (!this.hasAttribute(VariableNames.edgeHiddenAttribute)) {
            GraphAttribute hide = new GraphAttribute(VariableNames.edgeHiddenAttribute, "false", "");
            this.attributes.put(hide.getName(), hide);
        } else {
            hide = Boolean.parseBoolean(this.getAttributeValue(VariableNames.edgeHiddenAttribute));
        }
        setLabel(label);
    }

    /**
     * Constructor without extra attributes
     *
     * @param id
     * @param type
     * @param value
     * @param label
     * @param target
     * @param source
     */
    public Edge(String id, String type, String label, String value, Object target, Object source) {
        this.id = id;
        this.source = source;
        this.target = target;
        this.type = type;
//        hide = false;
        this.attributes = new HashMap<>();
        GraphAttribute att = new GraphAttribute(influenceName, value, "");
        this.attributes.put(att.getName(), att);
        if (!this.hasAttribute(VariableNames.edgeHiddenAttribute)) {
            GraphAttribute hide = new GraphAttribute(VariableNames.edgeHiddenAttribute, "false", "");
            this.attributes.put(hide.getName(), hide);
        } else {
            hide = Boolean.parseBoolean(this.getAttributeValue(VariableNames.edgeHiddenAttribute));
        }
        setLabel(label);
//        if (label.equalsIgnoreCase("") || label == null || "-".equals(label) || label.equalsIgnoreCase("Neutral")) {
//            setLabel("Neutral");
//            value = "0";
//        }

    }

    /**
     * Constructor without influence value, label, type (type=influence) and no
     * extra attribute
     *
     * @param id Edge's ID
     * @deprecated Used only on outdated TSVReader
     * @param target Vertex target
     * @param source Vertex source
     * @param influence Influence value and name (i.e. "+9 damage")
     */
    public Edge(String id, Object target, Object source, String influence) {
        this.id = id;
        this.source = source;
        this.target = target;
        influence = "0";
        this.type = getLabel();
        hide = false;
        this.attributes = new HashMap<>();
        GraphAttribute att = new GraphAttribute(influenceName, influence, "");
        this.attributes.put(att.getName(), att);
        GraphAttribute hide = new GraphAttribute(VariableNames.edgeHiddenAttribute, "false", "");
        this.attributes.put(hide.getName(), hide);
        if (influence.equalsIgnoreCase("")) {
            setLabel("Neutral");
        } else {
            setLabel(influence);
        }
    }

    /**
     * Return Edge id
     *
     * @return
     */
    public String getID() {
        return id;
    }

    /**
     * Set the edge ID
     *
     * @param t is the new value
     */
    public void setID(String t) {
        id = t;
    }

    /**
     * Method to get the edge source
     *
     * @return vertex source
     */
    public Object getSource() {
        return source;
    }

    /**
     * Set the edge's source
     *
     * @param t is the new source
     */
    public void setSource(Object t) {
        source = t;
    }

    /**
     * Method to get the edge target
     *
     * @return vertex target
     */
    public Object getTarget() {
        return target;
    }

    /**
     * Set the edge's target/destionation
     *
     * @param t is the new target
     */
    public void setTarget(Object t) {
        target = t;
    }

    /**
     * Method for returning the edge's numeric value (converted from String)
     *
     * @return (float) edge influence value
     */
    public float getValue() {
        if (Utils.tryParseDouble(this.getAttributeValue(influenceName))) {
            return Float.parseFloat(this.getAttributeValue(influenceName));
        } else if (Utils.tryParseDouble(this.getAttributeValue(influenceName).split(" ")[0])) {
            return Float.parseFloat(this.getAttributeValue(influenceName).split(" ")[0]);
        } else {
            return 0;
        }
    }

    /**
     * Returns the edge's value as the original String instead of converting to
     * numeric
     *
     * @return
     */
    public String getStringValue() {
        return this.getAttributeValue(influenceName);
    }

    /**
     * Updates the edge's value
     *
     * @param t is the string with the new value
     */
    public void setValue(String t) {
        this.getAttribute(influenceName).setValue(t);
    }

    /**
     * Method for returning the edge type
     *
     * @return
     */
    public String getType() {
        return this.type;
    }

    /**
     * Method to get the edge influence + value
     *
     * @param nGraphs is the number of different graphFiles values
     * @return (String) influence
     */
    public String getEdgeTooltip(int nGraphs) {
        return "<br>ID: " + this.id
                + "<br>Label: " + getLabel()
                + "<br>"
                + "<br>Type: " + getType()
                + "<br>Frequency: " + getFrequency(nGraphs)
                + "<br>" + printAttributes();
    }

    /**
     * Method to check if the edge is hidden (due to collapses)
     *
     * @return (boolean) if the edge is hidden or not
     */
    public boolean isHidden() {
        return hide;
//        return Boolean.parseBoolean(this.attributes.get(VariableNames.edgeHiddenAttribute).getValue());
    }

    /**
     * Method to set the hide parameter
     *
     * @param t (boolean) Hide = t
     */
    public void setHide(boolean t) {
        hide = t;
        GraphAttribute hide = new GraphAttribute(VariableNames.edgeHiddenAttribute, Boolean.toString(t), "");
        this.attributes.put(hide.getName(), hide);
    }

//    public String getHide() {
//        return this.attributes.get(VariableNames.edgeHiddenAttribute).getValue();
//    }
    /**
     * Method to check if the edge is of the neutral type (Empty influence or
     * value equals zero
     *
     * @return (boolean) is neutral or not
     */
    public boolean isNeutral() {
        return (getLabel().equalsIgnoreCase(""))
                || (getLabel().isEmpty())
                || (getLabel().equalsIgnoreCase("Neutral"));
    }

    /**
     * Method to override JUNG's default toString method
     *
     * @return edge details
     */
    @Override
    public String toString() {
        String font = VariableNames.FontConfiguration;
        if (getLabel().isEmpty()) {
            return font + this.type;
        } else if (getLabel().equals(this.type)) {
            return font + this.type;
        } else {
            return font + this.type + " (" + getLabel() + ")";
        }
    }

    private Color defaultColor() {
        if (this.getLabel().contains("Crash")) {
            return new Color(204, 0, 204);
        }
        if (((Vertex) this.getTarget()).getTime() < 100) {
            return Color.RED;
        } else if (((Vertex) this.getTarget()).getTime() < 180) {
            return Color.GREEN;
        } else {
            return Color.BLUE;
        }
//        return defaultColor;
    }

    /**
     * Method to get the edge color (red, black, or green), defined by value
     *
     * @param variables
     * @return
     */
    public Color getColor(Variables variables) {
        //TODO Refactor this method
        if (variables.isEdgeColorByMarkovIn) {
            if (!this.getAttributeValue(VariableNames.MarkovIn).equals(VariableNames.UnknownValue)) {
                return (Color) TrafficLight.splittedTrafficLight(Float.valueOf(this.getAttributeValue(VariableNames.MarkovIn)), 0, 1, false);
            } else {
                return defaultColor;
            }
        } else if (variables.isEdgeColorByMarkovOut) {
            if (!this.getAttributeValue(VariableNames.MarkovOut).equals(VariableNames.UnknownValue)) {
                return (Color) TrafficLight.splittedTrafficLight(Float.valueOf(this.getAttributeValue(VariableNames.MarkovOut)), 0, 1, false);
            } else {
                return defaultColor;
            }
        } else if (variables.isEdgeColorByGraphs) {
            String[] graphs = getAttributeValues(VariableNames.GraphFile);
            return TrafficLight.getGrayscaleColor(graphs.length, variables.numberOfGraphs);
        } else if (variables.isEdgeColorByValue) {
            float v = getValue();
            if (v == 0) {
                return defaultColor;
            } else {
                EdgeType et = null;
                if (variables.config.edgeTypes.containsKey(this.getLabel())) {
                    et = variables.config.edgeTypes.get(this.getLabel());
                } else if (variables.config.edgeTypes.containsKey(this.getType())) {
                    et = variables.config.edgeTypes.get(this.getType());
                }
                double min = et.min;
                double max = et.max;
                min = Math.min(min, 510);
                max = Math.max(max, 0);
                return (Color) TrafficLight.splittedTrafficLight(v, min, max, et.isInverted);
            }
        } else { // By Type
            if (variables.config.edgeTypes.containsKey(this.getType())) {
                return variables.config.edgeTypes.get(this.getType()).edgeColor;
            }
        }
        return defaultColor;
    }

    /**
     * Method used during the collapse of edges. This method defines if the
     * collapsed edge influence value will be the sum of the edges values or the
     * average
     *
     * @param variables
     * @return (boolean) Return true if influence from collapsed edges are
     * added. Return false if average
     */
    public boolean addInfluence(Variables variables) {
        EdgeType et = null;
        if (variables.config.edgeTypes.containsKey(this.getLabel())) {
            et = variables.config.edgeTypes.get(this.getLabel());
        } else if (variables.config.edgeTypes.containsKey(this.getType())) {
            et = variables.config.edgeTypes.get(this.getType());
        }
        if (et != null) {
            if (et.collapse.equalsIgnoreCase("AVERAGE")) {
                return false;
            }
        }

//        for (EdgeType edgetype : variables.config.edgetype) {
//            if (this.getType().contains(edgetype.type)) {
//                if (edgetype.collapse.equalsIgnoreCase("AVERAGE")) {
//                    return false;
//                }
//            }
//        }
        return true;
    }

    /**
     * Function to merge two edges
     *
     * @param edge is the edge that we want to merge with
     * @return the updated edge after merging with "edge"
     */
    public Edge merge(Edge edge, String mergeCode) {
        if (this.getType().equalsIgnoreCase(edge.getType())) {
            this.updateAllAttributes(edge.getAttributes());
            // We have a problem here when merging many graphs: StringBuilder.append(StringBuilder.java:132) java.lang.OutOfMemoryError: Java heap space
//            this.id = this.id + ", " + edge.id; 
            this.id = this.id + " ";
            if (!this.getLabel().contains(edge.getLabel())) {
                this.setLabel(this.getLabel() + ", " + edge.getLabel());
            }
            edge.setHide(true);
            GraphAttribute merged = new GraphAttribute(VariableNames.MergedEdgeAttribute, mergeCode, "");
            this.addAttribute(merged);
            GraphAttribute hide = new GraphAttribute(VariableNames.edgeHiddenAttribute, "false", "");
            this.addAttribute(hide);
        }
        return this;
    }

//    /**
//     * Method that calculates the edge frequency and returns a human-readable value (String)
//     * @param nGraphs is the total number of existing graphs used during the merge
//     * @return the edge's frequency between 0% and 100%
//     */
//    public String getEdgeFrequency(float nGraphs) {
//        if(this.hasAttribute(VariableNames.GraphFile)) {
//            float frequency = ((float) this.getAttributeValues(VariableNames.GraphFile).length / (float)nGraphs) * 100;
//            return String.format("%.02f", frequency) + "%";
//        } else
//            return "Frequency Unavailable";
//    }
//    
//    /**
//     * Method that calculates the edge frequency and returns the probability between 0 and 1
//     * @param nGraphs is the total number of existing graphs used during the merge
//     * @return the edge's frequency
//     */
//    public float getEdgeFrequencyValue(float nGraphs) {
//        if(this.hasAttribute(VariableNames.GraphFile)) {
//            return ((float) this.getAttributeValues(VariableNames.GraphFile).length / (float)nGraphs);
//        } else
//            return 0;
//    }
} public static void PanCameraToFirstVertex(Variables variables) {
    Vertex first = (Vertex) variables.graph.getVertices().iterator().next();
    variables.view.getGraphLayout();
    Point2D q = variables.view.getGraphLayout().transform(first);
    Point2D lvc
            = variables.view.getRenderContext().getMultiLayerTransformer().inverseTransform(variables.view.getCenter());
    final double dx = (lvc.getX() - q.getX());
    final double dy = (lvc.getY() - q.getY());
    variables.view.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).translate(dx, dy);
} public class GraphFrame extends javax.swing.JFrame {

    Variables variables = new Variables();

    /**
     * Creates new form GraphFrame
     * @param graph 
     */
    public GraphFrame() {
        variables = new Variables();
        System.out.println("Graph: " + BasePath.getBasePathForClass(GuiRun.class) + variables.demo);
        File graphFile = new File(BasePath.getBasePathForClass(GuiRun.class) + variables.demo);
        DirectedGraph<Object, Edge> graph = GuiReadFile.getGraph(graphFile);
        initComponents();
        GuiInitialization.initGraphComponent(variables, graph, this, Layouts, 
                displayAgentLabelButton.getState(), 
                displayActivityLabelButton.getState(), 
                displayEntityLabelButton.getState(), 
                displayTimeLabel.getState(), 
                displayID.getState());       
    }
    
    public GraphFrame(DirectedGraph<Object, Edge> graph) {
        variables = new Variables();
        initComponents();
        GuiInitialization.initGraphComponent(variables, graph, this, Layouts, 
                displayAgentLabelButton.getState(), 
                displayActivityLabelButton.getState(), 
                displayEntityLabelButton.getState(), 
                displayTimeLabel.getState(), 
                displayID.getState());       
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setNewLabelDialogBox = new javax.swing.JDialog();
        jLabel8 = new javax.swing.JLabel();
        newVertexLabelTextBox = new javax.swing.JTextField();
        setNewLabelConfirmButton = new javax.swing.JButton();
        setNewLabelCancelButton = new javax.swing.JButton();
        fileChooser = new javax.swing.JFileChooser();
        searchVertexIDDialogBox = new javax.swing.JDialog();
        jLabel9 = new javax.swing.JLabel();
        vertexIDTextField = new javax.swing.JTextField();
        searchVertexIDButton = new javax.swing.JButton();
        cancelSearchVertexButton = new javax.swing.JButton();
        debugDialogBox = new javax.swing.JDialog();
        jLabel11 = new javax.swing.JLabel();
        selectedTrialComboBox = new javax.swing.JComboBox<>();
        jLabel12 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        correctTrialsList = new javax.swing.JList<>();
        confirmDebuggingButton = new javax.swing.JButton();
        cancelDebugButton = new javax.swing.JButton();
        considerEntityVerticesButton = new javax.swing.JRadioButton();
        considerAgentVerticesButton = new javax.swing.JRadioButton();
        considerActivityVerticesButton = new javax.swing.JRadioButton();
        jLabel14 = new javax.swing.JLabel();
        tooltipDialogBox = new javax.swing.JDialog();
        jLabel10 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        tooltipWindowTextPane = new javax.swing.JTextPane();
        closeTooltipWindowButton = new javax.swing.JButton();
        selectWorkingTrialsDialogBox = new javax.swing.JDialog();
        jScrollPane3 = new javax.swing.JScrollPane();
        listWorkingTrials = new javax.swing.JList<>();
        jLabel13 = new javax.swing.JLabel();
        confirmWorkingTrialsButton = new javax.swing.JButton();
        cancelWorkingTrialsButton = new javax.swing.JButton();
        VertexStroke = new javax.swing.ButtonGroup();
        ToolMenu = new javax.swing.JPanel();
        CollapseAgent = new javax.swing.JButton();
        Reset = new javax.swing.JButton();
        Expand = new javax.swing.JButton();
        Collapse = new javax.swing.JButton();
        MouseModes = new javax.swing.JComboBox();
        DisplayEdges = new javax.swing.JLabel();
        EdgeLineShapeSelection = new javax.swing.JComboBox();
        StatusFilterBox = new javax.swing.JComboBox();
        AttributeStatus = new javax.swing.JLabel();
        EdgeStyle = new javax.swing.JLabel();
        MouseModeLabel = new javax.swing.JLabel();
        EdgeTypes = new javax.swing.JScrollPane();
        edgeFilterList = new javax.swing.JList();
        Layouts = new javax.swing.JComboBox();
        GraphLayout = new javax.swing.JLabel();
        SimilarityInference = new javax.swing.JButton();
        FilterVertexMinValue = new javax.swing.JTextField();
        FilterVertexMaxValue = new javax.swing.JTextField();
        TemporalFilterToggle = new javax.swing.JToggleButton();
        jButton1 = new javax.swing.JButton();
        VertexLabels = new javax.swing.JScrollPane();
        vertexFilterList = new javax.swing.JList();
        DisplayVertices = new javax.swing.JLabel();
        dbscanEpsilon = new javax.swing.JTextField();
        isSTDeps = new javax.swing.JCheckBox();
        simEpsilon = new javax.swing.JTextField();
        simStdSize = new javax.swing.JTextField();
        simStdInc = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        vertexShapeComboBox = new javax.swing.JComboBox<>();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        vertexShapeBasedOnAttribute = new javax.swing.JTextField();
        layoutAttributeName_X_Text = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        layoutAttributeName_Y_Text = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        DeleteSelectedVerticesButton = new javax.swing.JButton();
        UndoDeletionButton = new javax.swing.JButton();
        PanToGraphButton = new javax.swing.JButton();
        isAndOperatorButton = new javax.swing.JCheckBox();
        MenuBar = new javax.swing.JMenuBar();
        FileMenu = new javax.swing.JMenu();
        OpenConfig = new javax.swing.JMenuItem();
        OpenGraph = new javax.swing.JMenuItem();
        exportGraphPROVNButton = new javax.swing.JMenuItem();
        exportGraphXMLButton = new javax.swing.JMenuItem();
        exportCollapsedGraphXML = new javax.swing.JMenuItem();
        exportDisplayedGraphXML = new javax.swing.JMenuItem();
        Exit = new javax.swing.JMenuItem();
        jMenu7 = new javax.swing.JMenu();
        RenameVertexLabelMenuButton = new javax.swing.JMenuItem();
        linkActivitiesButton = new javax.swing.JMenuItem();
        SearchVertexMenuButton = new javax.swing.JMenuItem();
        jMenu1 = new javax.swing.JMenu();
        autoDetectEdgesCheckBox = new javax.swing.JCheckBoxMenuItem();
        autoDetectAttributeCheckBox = new javax.swing.JCheckBoxMenuItem();
        allowVariableLayoutButton = new javax.swing.JCheckBoxMenuItem();
        displayEdgeTextButton = new javax.swing.JMenu();
        jMenu10 = new javax.swing.JMenu();
        displayID = new javax.swing.JCheckBoxMenuItem();
        displayTimeLabel = new javax.swing.JCheckBoxMenuItem();
        displayActivityLabelButton = new javax.swing.JCheckBoxMenuItem();
        displayAgentLabelButton = new javax.swing.JCheckBoxMenuItem();
        displayEntityLabelButton = new javax.swing.JCheckBoxMenuItem();
        jMenu11 = new javax.swing.JMenu();
        displayIDButton = new javax.swing.JCheckBoxMenuItem();
        displayEdgeLabel = new javax.swing.JCheckBoxMenuItem();
        displayEdgeType = new javax.swing.JCheckBoxMenuItem();
        edgeFrequencyButton = new javax.swing.JCheckBoxMenuItem();
        ShowEdgePathProbabilityButton = new javax.swing.JCheckBoxMenuItem();
        jMenu6 = new javax.swing.JMenu();
        hideAgentVerticesButton = new javax.swing.JCheckBoxMenuItem();
        hideEntityVerticesButton = new javax.swing.JCheckBoxMenuItem();
        hideLonelyVerticesButton = new javax.swing.JCheckBoxMenuItem();
        hideMergedVerticesButton = new javax.swing.JCheckBoxMenuItem();
        hideAgentEdgesButton = new javax.swing.JCheckBoxMenuItem();
        jMenu2 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        mergeGraphButtom = new javax.swing.JMenuItem();
        allowMergeUndoButtom = new javax.swing.JCheckBoxMenuItem();
        jMenu3 = new javax.swing.JMenu();
        temporalNanosecondsButton = new javax.swing.JCheckBoxMenuItem();
        temporalMicrosecondsButton = new javax.swing.JCheckBoxMenuItem();
        temporalMillisecondsButton = new javax.swing.JCheckBoxMenuItem();
        temporalSecondsButton = new javax.swing.JCheckBoxMenuItem();
        temporalMinutesButton = new javax.swing.JCheckBoxMenuItem();
        temporalHoursButton = new javax.swing.JCheckBoxMenuItem();
        temporalDaysButton = new javax.swing.JCheckBoxMenuItem();
        temporalWeeksButton = new javax.swing.JCheckBoxMenuItem();
        jMenu4 = new javax.swing.JMenu();
        doDerivateButton = new javax.swing.JCheckBoxMenuItem();
        removeOutliersButton = new javax.swing.JCheckBoxMenuItem();
        jMenu8 = new javax.swing.JMenu();
        jMenu5 = new javax.swing.JMenu();
        updateErrorButton = new javax.swing.JCheckBoxMenuItem();
        verifyWithinClusterButton = new javax.swing.JCheckBoxMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();
        attributeDisplaySimConfig = new javax.swing.JRadioButtonMenuItem();
        similarityConsiderNeighborsButton = new javax.swing.JCheckBoxMenuItem();
        CollapseAllAgentsButton = new javax.swing.JMenuItem();
        jMenu12 = new javax.swing.JMenu();
        debugTrialMenuItem = new javax.swing.JMenuItem();
        findNodesFrequencyButton = new javax.swing.JMenuItem();
        computeMarkovChainButton = new javax.swing.JMenuItem();
        jMenu13 = new javax.swing.JMenu();
        findPathButton = new javax.swing.JMenuItem();
        jMenu9 = new javax.swing.JMenu();
        PerformanceAAButton = new javax.swing.JCheckBoxMenuItem();
        PerformanceArrowHeadsButton = new javax.swing.JCheckBoxMenuItem();
        PaintInvisibleVerticesButton = new javax.swing.JCheckBoxMenuItem();
        jMenu14 = new javax.swing.JMenu();
        isEdgeColorByType = new javax.swing.JCheckBoxMenuItem();
        isColorByEdgeValueButton = new javax.swing.JCheckBoxMenuItem();
        EdgeColorGraphsButtom = new javax.swing.JCheckBoxMenuItem();
        EdgeColorMarkovInButtom = new javax.swing.JCheckBoxMenuItem();
        EdgeColorMarkovOutButtom = new javax.swing.JCheckBoxMenuItem();
        EdgeStrokeByValueButton = new javax.swing.JCheckBoxMenuItem();
        EdgeStrokeByGraphButton = new javax.swing.JCheckBoxMenuItem();
        EdgeStrokeByMarkovinButton = new javax.swing.JCheckBoxMenuItem();
        EdgeStrokeByMarkovoutButton = new javax.swing.JCheckBoxMenuItem();
        EdgeStrokeDefaultButton = new javax.swing.JCheckBoxMenuItem();
        jMenu15 = new javax.swing.JMenu();
        vertexBorderByGraphButton = new javax.swing.JCheckBoxMenuItem();
        vertexStrokeDefault = new javax.swing.JRadioButtonMenuItem();
        vertexStrokeGraphFile = new javax.swing.JRadioButtonMenuItem();
        vertexStrokeLabel = new javax.swing.JRadioButtonMenuItem();
        vertexStrokeOutlier = new javax.swing.JRadioButtonMenuItem();

        setNewLabelDialogBox.setAlwaysOnTop(true);
        setNewLabelDialogBox.setMinimumSize(new java.awt.Dimension(257, 153));

        jLabel8.setText("Type the new Label for selected Vertices");

        setNewLabelConfirmButton.setText("OK");
        setNewLabelConfirmButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                setNewLabelConfirmButtonActionPerformed(evt);
            }
        });

        setNewLabelCancelButton.setText("Cancel");
        setNewLabelCancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                setNewLabelCancelButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout setNewLabelDialogBoxLayout = new javax.swing.GroupLayout(setNewLabelDialogBox.getContentPane());
        setNewLabelDialogBox.getContentPane().setLayout(setNewLabelDialogBoxLayout);
        setNewLabelDialogBoxLayout.setHorizontalGroup(
            setNewLabelDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(setNewLabelDialogBoxLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(setNewLabelDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(newVertexLabelTextBox)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, setNewLabelDialogBoxLayout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(setNewLabelConfirmButton, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(setNewLabelCancelButton)
                        .addGap(11, 11, 11)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        setNewLabelDialogBoxLayout.setVerticalGroup(
            setNewLabelDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(setNewLabelDialogBoxLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel8)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(newVertexLabelTextBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(setNewLabelDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(setNewLabelConfirmButton)
                    .addComponent(setNewLabelCancelButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        fileChooser.setCurrentDirectory(new java.io.File("C:\\Kohwalter\\GitHub\\prov-viewer\\src\\main\\resources"));
        fileChooser.setDialogTitle("This is my open dialog");

        searchVertexIDDialogBox.setAlwaysOnTop(true);
        searchVertexIDDialogBox.setMinimumSize(new java.awt.Dimension(175, 140));

        jLabel9.setText("Type the Vertex ID");

        searchVertexIDButton.setText("Search");
        searchVertexIDButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchVertexIDButtonActionPerformed(evt);
            }
        });

        cancelSearchVertexButton.setText("Cancel");
        cancelSearchVertexButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelSearchVertexButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout searchVertexIDDialogBoxLayout = new javax.swing.GroupLayout(searchVertexIDDialogBox.getContentPane());
        searchVertexIDDialogBox.getContentPane().setLayout(searchVertexIDDialogBoxLayout);
        searchVertexIDDialogBoxLayout.setHorizontalGroup(
            searchVertexIDDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(searchVertexIDDialogBoxLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(searchVertexIDDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(searchVertexIDDialogBoxLayout.createSequentialGroup()
                        .addComponent(searchVertexIDButton, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cancelSearchVertexButton))
                    .addComponent(vertexIDTextField)
                    .addComponent(jLabel9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        searchVertexIDDialogBoxLayout.setVerticalGroup(
            searchVertexIDDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(searchVertexIDDialogBoxLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel9)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(vertexIDTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(searchVertexIDDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(searchVertexIDButton)
                    .addComponent(cancelSearchVertexButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        debugDialogBox.setAlwaysOnTop(true);
        debugDialogBox.setMinimumSize(new java.awt.Dimension(358, 450));

        jLabel11.setText("Select the trial for debugging");

        selectedTrialComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        jLabel12.setText("Select the trials that worked");

        correctTrialsList.setModel(new javax.swing.AbstractListModel<String>() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public String getElementAt(int i) { return strings[i]; }
        });
        jScrollPane1.setViewportView(correctTrialsList);

        confirmDebuggingButton.setText("OK");
        confirmDebuggingButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                confirmDebuggingButtonActionPerformed(evt);
            }
        });

        cancelDebugButton.setText("Cancel");
        cancelDebugButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelDebugButtonActionPerformed(evt);
            }
        });

        considerEntityVerticesButton.setText("Entity");

        considerAgentVerticesButton.setText("Agent");

        considerActivityVerticesButton.setText("Activity");

        jLabel14.setText("Consider the following types:");

        javax.swing.GroupLayout debugDialogBoxLayout = new javax.swing.GroupLayout(debugDialogBox.getContentPane());
        debugDialogBox.getContentPane().setLayout(debugDialogBoxLayout);
        debugDialogBoxLayout.setHorizontalGroup(
            debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(debugDialogBoxLayout.createSequentialGroup()
                .addGroup(debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addGroup(debugDialogBoxLayout.createSequentialGroup()
                            .addContainerGap()
                            .addGroup(debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(jLabel11, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(selectedTrialComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, debugDialogBoxLayout.createSequentialGroup()
                            .addComponent(confirmDebuggingButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(cancelDebugButton, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGap(11, 11, 11)))
                    .addGroup(debugDialogBoxLayout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(considerEntityVerticesButton)
                            .addComponent(considerAgentVerticesButton)
                            .addComponent(considerActivityVerticesButton)
                            .addComponent(jLabel14))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel12, javax.swing.GroupLayout.Alignment.TRAILING))
                .addContainerGap())
        );
        debugDialogBoxLayout.setVerticalGroup(
            debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(debugDialogBoxLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel11)
                    .addComponent(jLabel12))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(debugDialogBoxLayout.createSequentialGroup()
                        .addComponent(selectedTrialComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jLabel14)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(considerActivityVerticesButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(considerAgentVerticesButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(considerEntityVerticesButton)
                        .addGap(18, 18, 18)
                        .addGroup(debugDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(confirmDebuggingButton)
                            .addComponent(cancelDebugButton)))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 363, Short.MAX_VALUE))
                .addContainerGap())
        );

        tooltipDialogBox.setAlwaysOnTop(true);
        tooltipDialogBox.setMinimumSize(new java.awt.Dimension(311, 356));

        jLabel10.setText("Tooltip");

        jScrollPane2.setViewportView(tooltipWindowTextPane);

        closeTooltipWindowButton.setText("Close");
        closeTooltipWindowButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeTooltipWindowButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout tooltipDialogBoxLayout = new javax.swing.GroupLayout(tooltipDialogBox.getContentPane());
        tooltipDialogBox.getContentPane().setLayout(tooltipDialogBoxLayout);
        tooltipDialogBoxLayout.setHorizontalGroup(
            tooltipDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(tooltipDialogBoxLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel10)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(tooltipDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(tooltipDialogBoxLayout.createSequentialGroup()
                        .addComponent(closeTooltipWindowButton)
                        .addGap(0, 318, Short.MAX_VALUE))
                    .addComponent(jScrollPane2))
                .addContainerGap())
        );
        tooltipDialogBoxLayout.setVerticalGroup(
            tooltipDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(tooltipDialogBoxLayout.createSequentialGroup()
                .addGroup(tooltipDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(tooltipDialogBoxLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jLabel10)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(tooltipDialogBoxLayout.createSequentialGroup()
                        .addGap(24, 24, 24)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 239, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
                .addComponent(closeTooltipWindowButton)
                .addContainerGap())
        );

        selectWorkingTrialsDialogBox.setAlwaysOnTop(true);
        selectWorkingTrialsDialogBox.setMinimumSize(new java.awt.Dimension(173, 492));

        listWorkingTrials.setModel(new javax.swing.AbstractListModel<String>() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public String getElementAt(int i) { return strings[i]; }
        });
        jScrollPane3.setViewportView(listWorkingTrials);

        jLabel13.setText("Select the working Trials");

        confirmWorkingTrialsButton.setText("OK");
        confirmWorkingTrialsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                confirmWorkingTrialsButtonActionPerformed(evt);
            }
        });

        cancelWorkingTrialsButton.setText("Cancel");
        cancelWorkingTrialsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelWorkingTrialsButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout selectWorkingTrialsDialogBoxLayout = new javax.swing.GroupLayout(selectWorkingTrialsDialogBox.getContentPane());
        selectWorkingTrialsDialogBox.getContentPane().setLayout(selectWorkingTrialsDialogBoxLayout);
        selectWorkingTrialsDialogBoxLayout.setHorizontalGroup(
            selectWorkingTrialsDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(selectWorkingTrialsDialogBoxLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(selectWorkingTrialsDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 149, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(selectWorkingTrialsDialogBoxLayout.createSequentialGroup()
                        .addComponent(confirmWorkingTrialsButton, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cancelWorkingTrialsButton))
                    .addComponent(jLabel13))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        selectWorkingTrialsDialogBoxLayout.setVerticalGroup(
            selectWorkingTrialsDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, selectWorkingTrialsDialogBoxLayout.createSequentialGroup()
                .addComponent(jLabel13)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 384, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(selectWorkingTrialsDialogBoxLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelWorkingTrialsButton)
                    .addComponent(confirmWorkingTrialsButton))
                .addContainerGap())
        );

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Prov Viewer");
        setMinimumSize(new java.awt.Dimension(1255, 800));

        ToolMenu.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        CollapseAgent.setText("CollapseAgent");
        CollapseAgent.setToolTipText("Collapse all vertices from each agent");
        CollapseAgent.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CollapseAgentActionPerformed(evt);
            }
        });

        Reset.setText("Reset");
        Reset.setToolTipText("Reset the graph to the original format");
        Reset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ResetActionPerformed(evt);
            }
        });

        Expand.setText("Expand");
        Expand.setToolTipText("Remove the collapse from the selected vertex");
        Expand.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ExpandActionPerformed(evt);
            }
        });

        Collapse.setText("Collapse");
        Collapse.setToolTipText("Collapse selected vertices");
        Collapse.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CollapseActionPerformed(evt);
            }
        });

        MouseModes.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Transforming", "Picking" }));
        MouseModes.setToolTipText("Change the mouse function to select (Picking) or moving (Transforming)");
        MouseModes.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                MouseModesActionPerformed(evt);
            }
        });

        DisplayEdges.setText("Display Edge");
        DisplayEdges.setToolTipText("Edge filter: Display only the edges with selected labels");

        EdgeLineShapeSelection.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "QuadCurve", "Line" }));
        EdgeLineShapeSelection.setToolTipText("Change the edge's line format");
        EdgeLineShapeSelection.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EdgeLineShapeSelectionActionPerformed(evt);
            }
        });

        StatusFilterBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Default", "Morale", "Stamina", "Hours", "Weekend", "Credits", "Role" }));
        StatusFilterBox.setToolTipText("Change vertex coloring to evaluate the selected attribute");
        StatusFilterBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                StatusFilterBoxActionPerformed(evt);
            }
        });

        AttributeStatus.setText("Attribute Status");

        EdgeStyle.setText("Edge Style");

        MouseModeLabel.setText("Mouse Mode");

        edgeFilterList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        edgeFilterList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                edgeFilterListValueChanged(evt);
            }
        });
        EdgeTypes.setViewportView(edgeFilterList);

        Layouts.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Timeline", "Timeline (Graphs)", "One Dimensional", "One Dimensional (Variant)", "Two Dimensional", "Hierarchy", "Temporal", "Spatial", "List", "ProvCircle", "ProvCircle2", "Circle", "FR", "FR2", "ISOM", "KK", "Spring", "Dag" }));
        Layouts.setToolTipText("Change the graph layout");
        Layouts.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                LayoutsActionPerformed(evt);
            }
        });

        GraphLayout.setText("Graph Layout");

        SimilarityInference.setText("Similarity Collapse");
        SimilarityInference.setToolTipText("Collapse vertices using the Similarity Algorithm Make sure to load the configuration file before collapsing or selecting the \"Attribute Status Config\" option in the \"Similarity Collapse\" menu");
        SimilarityInference.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SimilarityInferenceActionPerformed(evt);
            }
        });

        FilterVertexMinValue.setText("0");
        FilterVertexMinValue.setToolTipText("Filter vertices by time (min value)");
        FilterVertexMinValue.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FilterVertexMinValueActionPerformed(evt);
            }
        });

        FilterVertexMaxValue.setText("100");
        FilterVertexMaxValue.setToolTipText("Filter vertices by time (max value)");
        FilterVertexMaxValue.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                FilterVertexMaxValueActionPerformed(evt);
            }
        });

        TemporalFilterToggle.setText("Temporal Filter");
        TemporalFilterToggle.setToolTipText("Hide vertices outside the range below using the selected temporal scale (zero represents the lowest timestamp in the graph) or XMLGregorianCalendar format");
        TemporalFilterToggle.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                TemporalFilterToggleActionPerformed(evt);
            }
        });

        jButton1.setText("DBSCAN");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        vertexFilterList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "All Vertices", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        vertexFilterList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                vertexFilterListValueChanged(evt);
            }
        });
        VertexLabels.setViewportView(vertexFilterList);

        DisplayVertices.setText("Display Vertices");
        DisplayVertices.setToolTipText("<html>Vertex filter: Display only the vertices with selected attributes's values \n<br><b>AttributeNAME</b>: <b>VALUE </b>\n<br>If <b>VALUE</b> is not specified, then it will only consider if the vertex has the attribute. \n<br>If <b>VALUE</b> is specified, then it will only consider if the vertex has the attribute with the specified value");

        dbscanEpsilon.setText("0.5");
        dbscanEpsilon.setToolTipText("DBSCAN Epsilon Value");
        dbscanEpsilon.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                dbscanEpsilonActionPerformed(evt);
            }
        });

        isSTDeps.setText("Use STD eps");
        isSTDeps.setToolTipText("Define if the Eps will use the defined value or multiply the value to the std of the selected attribute");
        isSTDeps.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                isSTDepsActionPerformed(evt);
            }
        });

        simEpsilon.setText("2.0");
        simEpsilon.setToolTipText("Defines the epsilon for the similarty algorithms (Float)");
        simEpsilon.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                simEpsilonActionPerformed(evt);
            }
        });

        simStdSize.setText("1");
        simStdSize.setToolTipText("Defines the minimim cluster size (before havings its own epsilon) for the similarty algorithms (Integer) and is used when VE is selected");

        simStdInc.setText("1.0");
        simStdInc.setToolTipText("Defines the epsilon multiplier used before reaching the minimum cluster size for the similarty algorithms (Float) and is used when VE is selected");

        jLabel1.setText("STD Epsilon");
        jLabel1.setToolTipText("Defines the eps value for the similarity algorithm");

        jLabel2.setText("Cluster Size");
        jLabel2.setToolTipText("Defines the minimum cluster size to be considered independent (used when VE is true)");

        jLabel3.setText("Eps Increase");
        jLabel3.setToolTipText("Defines the epsilon increase before reaching the minimum cluster size (used when VE is true)");

        vertexShapeComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Default", "Summarized", "Graphs", "Attribute" }));
        vertexShapeComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                vertexShapeComboBoxActionPerformed(evt);
            }
        });

        jLabel4.setText("Vertex Shape");

        jLabel5.setText("Vertex Attribute");

        vertexShapeBasedOnAttribute.setText("Timestamp");
        vertexShapeBasedOnAttribute.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                vertexShapeBasedOnAttributeActionPerformed(evt);
            }
        });

        layoutAttributeName_X_Text.setText("Timestamp");
        layoutAttributeName_X_Text.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                layoutAttributeName_X_TextActionPerformed(evt);
            }
        });

        jLabel6.setText("Layout X coord");

        layoutAttributeName_Y_Text.setText("Timestamp");
        layoutAttributeName_Y_Text.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                layoutAttributeName_Y_TextActionPerformed(evt);
            }
        });

        jLabel7.setText("Layout Y coord");

        DeleteSelectedVerticesButton.setText("Delete");
        DeleteSelectedVerticesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DeleteSelectedVerticesButtonActionPerformed(evt);
            }
        });

        UndoDeletionButton.setText("Undo");
        UndoDeletionButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                UndoDeletionButtonActionPerformed(evt);
            }
        });

        PanToGraphButton.setText("Pan");
        PanToGraphButton.setToolTipText("Pan the View to the Graph");
        PanToGraphButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PanToGraphButtonActionPerformed(evt);
            }
        });

        isAndOperatorButton.setText("AND Operator");
        isAndOperatorButton.setToolTipText("<html>Mark if you want to use the <b>AND</b> operator instead of <b>OR</b> to compose the Vertex Filter\n<br><b>AND</b>: Vertex will only show if all the selected items are <b>TRUE</b>\n<br><b>OR</b>: Vertex will only show if at least one of the selected items are <b>TRUE</b>");
        isAndOperatorButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                isAndOperatorButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout ToolMenuLayout = new javax.swing.GroupLayout(ToolMenu);
        ToolMenu.setLayout(ToolMenuLayout);
        ToolMenuLayout.setHorizontalGroup(
            ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ToolMenuLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(vertexShapeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel4)
                    .addComponent(jLabel5)
                    .addComponent(vertexShapeBasedOnAttribute)
                    .addGroup(ToolMenuLayout.createSequentialGroup()
                        .addComponent(UndoDeletionButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(PanToGraphButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(DisplayEdges, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(EdgeTypes, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(VertexLabels)
                    .addGroup(ToolMenuLayout.createSequentialGroup()
                        .addComponent(DisplayVertices, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(isAndOperatorButton)))
                .addGap(18, 18, Short.MAX_VALUE)
                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(CollapseAgent, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(Collapse, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(Expand, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(Reset, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(DeleteSelectedVerticesButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(ToolMenuLayout.createSequentialGroup()
                        .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(simStdSize)
                            .addComponent(simEpsilon, javax.swing.GroupLayout.DEFAULT_SIZE, 40, Short.MAX_VALUE)
                            .addComponent(simStdInc))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2)
                            .addComponent(jLabel3)))
                    .addGroup(ToolMenuLayout.createSequentialGroup()
                        .addComponent(jButton1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(dbscanEpsilon, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(SimilarityInference))
                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(ToolMenuLayout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, ToolMenuLayout.createSequentialGroup()
                                .addComponent(FilterVertexMinValue, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(FilterVertexMaxValue))
                            .addComponent(AttributeStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(StatusFilterBox, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(TemporalFilterToggle, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))
                    .addGroup(ToolMenuLayout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(isSTDeps)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(GraphLayout, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(MouseModeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(EdgeStyle, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jLabel7))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(layoutAttributeName_Y_Text)
                    .addComponent(layoutAttributeName_X_Text)
                    .addComponent(MouseModes, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(Layouts, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(EdgeLineShapeSelection, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(574, 574, 574))
        );
        ToolMenuLayout.setVerticalGroup(
            ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ToolMenuLayout.createSequentialGroup()
                .addGap(5, 5, 5)
                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(ToolMenuLayout.createSequentialGroup()
                        .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(ToolMenuLayout.createSequentialGroup()
                                .addGap(30, 30, 30)
                                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(Collapse)
                                    .addComponent(StatusFilterBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(simEpsilon, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jLabel1))
                                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(Expand)
                                    .addComponent(TemporalFilterToggle)
                                    .addComponent(simStdSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jLabel2)
                                    .addComponent(layoutAttributeName_X_Text, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jLabel6)))
                            .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(CollapseAgent)
                                .addComponent(AttributeStatus)
                                .addComponent(SimilarityInference))
                            .addGroup(ToolMenuLayout.createSequentialGroup()
                                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(MouseModes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(MouseModeLabel))
                                .addGap(4, 4, 4)
                                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(Layouts, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(GraphLayout))))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(FilterVertexMinValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(FilterVertexMaxValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(simStdInc, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(DeleteSelectedVerticesButton))
                            .addComponent(jLabel3)
                            .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(layoutAttributeName_Y_Text, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabel7)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jButton1)
                                .addComponent(dbscanEpsilon, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(isSTDeps)
                                .addComponent(Reset))
                            .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(EdgeLineShapeSelection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(EdgeStyle)))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(ToolMenuLayout.createSequentialGroup()
                        .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(DisplayEdges)
                            .addComponent(DisplayVertices)
                            .addComponent(jLabel4)
                            .addComponent(isAndOperatorButton))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(ToolMenuLayout.createSequentialGroup()
                                .addComponent(vertexShapeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabel5)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(vertexShapeBasedOnAttribute, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addGroup(ToolMenuLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(UndoDeletionButton)
                                    .addComponent(PanToGraphButton)))
                            .addComponent(EdgeTypes, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                            .addComponent(VertexLabels, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))))
                .addContainerGap())
        );

        getContentPane().add(ToolMenu, java.awt.BorderLayout.PAGE_END);

        FileMenu.setText("File");

        OpenConfig.setText("Open Config File");
        OpenConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OpenConfigActionPerformed(evt);
            }
        });
        FileMenu.add(OpenConfig);

        OpenGraph.setText("Open Graph File");
        OpenGraph.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OpenGraphActionPerformed(evt);
            }
        });
        FileMenu.add(OpenGraph);

        exportGraphPROVNButton.setText("Export Graph (Prov-N)");
        exportGraphPROVNButton.setToolTipText("<html>Export the original graph (or the resulting merged graph) in Prov-N format.\n<br><b>Warning: Data loss is possible due to the format's restrictions</b>");
        exportGraphPROVNButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportGraphPROVNButtonActionPerformed(evt);
            }
        });
        FileMenu.add(exportGraphPROVNButton);

        exportGraphXMLButton.setText("Export Graph (XML)");
        exportGraphXMLButton.setToolTipText("Export the original graph (or the resulted merged graph) in Prov Viewer's xml format");
        exportGraphXMLButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportGraphXMLButtonActionPerformed(evt);
            }
        });
        FileMenu.add(exportGraphXMLButton);

        exportCollapsedGraphXML.setText("Export Collapsed Graph (XML)");
        exportCollapsedGraphXML.setToolTipText("Export the collapsed graph (with all filters disabled) in Prov Viewer's xml format");
        exportCollapsedGraphXML.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportCollapsedGraphXMLActionPerformed(evt);
            }
        });
        FileMenu.add(exportCollapsedGraphXML);

        exportDisplayedGraphXML.setText("Export Displayed Graph (XML)");
        exportDisplayedGraphXML.setToolTipText("<html>Export the current displayed graph (as it is being shown) in Prov Viewer's xml format\n<br><b>Warning: Hidden information will be lost</b>");
        exportDisplayedGraphXML.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportDisplayedGraphXMLActionPerformed(evt);
            }
        });
        FileMenu.add(exportDisplayedGraphXML);

        Exit.setText("Exit");
        Exit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ExitActionPerformed(evt);
            }
        });
        FileMenu.add(Exit);

        MenuBar.add(FileMenu);

        jMenu7.setText("Edit");

        RenameVertexLabelMenuButton.setText("Rename Vertex Label");
        RenameVertexLabelMenuButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RenameVertexLabelMenuButtonActionPerformed(evt);
            }
        });
        jMenu7.add(RenameVertexLabelMenuButton);

        linkActivitiesButton.setText("Link Activities");
        linkActivitiesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                linkActivitiesButtonActionPerformed(evt);
            }
        });
        jMenu7.add(linkActivitiesButton);

        SearchVertexMenuButton.setText("Search Vertex");
        SearchVertexMenuButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SearchVertexMenuButtonActionPerformed(evt);
            }
        });
        jMenu7.add(SearchVertexMenuButton);

        MenuBar.add(jMenu7);

        jMenu1.setText("Options");

        autoDetectEdgesCheckBox.setText("Auto Detect Edges");
        autoDetectEdgesCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                autoDetectEdgesCheckBoxActionPerformed(evt);
            }
        });
        jMenu1.add(autoDetectEdgesCheckBox);

        autoDetectAttributeCheckBox.setText("Auto Detect Vertex Attributes");
        autoDetectAttributeCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                autoDetectAttributeCheckBoxActionPerformed(evt);
            }
        });
        jMenu1.add(autoDetectAttributeCheckBox);

        allowVariableLayoutButton.setText("Dynamic Layouts");
        allowVariableLayoutButton.setToolTipText("Layouts will adapt upon refresh based on the graph currently being displayed");
        allowVariableLayoutButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                allowVariableLayoutButtonActionPerformed(evt);
            }
        });
        jMenu1.add(allowVariableLayoutButton);

        MenuBar.add(jMenu1);

        displayEdgeTextButton.setText("Display");

        jMenu10.setText("Vertex");

        displayID.setText("Display ID");
        displayID.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                displayIDActionPerformed(evt);
            }
        });
        jMenu10.add(displayID);

        displayTimeLabel.setText("Display Time");
        displayTimeLabel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                displayTimeLabelActionPerformed(evt);
            }
        });
        jMenu10.add(displayTimeLabel);

        displayActivityLabelButton.setText("Display Activity Label");
        displayActivityLabelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                displayActivityLabelButtonActionPerformed(evt);
            }
        });
        jMenu10.add(displayActivityLabelButton);

        displayAgentLabelButton.setText("Display Agent Label");
        displayAgentLabelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                displayAgentLabelButtonActionPerformed(evt);
            }
        });
        jMenu10.add(displayAgentLabelButton);

        displayEntityLabelButton.setText("Display Entity Label");
        displayEntityLabelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                displayEntityLabelButtonActionPerformed(evt);
            }
        });
        jMenu10.add(displayEntityLabelButton);

        displayEdgeTextButton.add(jMenu10);

        jMenu11.setText("Edge");

        displayIDButton.setText("Display ID");
        displayIDButton.setToolTipText("Display the Edge's ID");
        displayIDButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                displayIDButtonActionPerformed(evt);
            }
        });
        jMenu11.add(displayIDButton);

        displayEdgeLabel.setText("Display Label");
        displayEdgeLabel.setToolTipText("Display Edge's Label. Can be combined with Type");
        displayEdgeLabel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                displayEdgeLabelActionPerformed(evt);
            }
        });
        jMenu11.add(displayEdgeLabel);

        displayEdgeType.setText("Display Type");
        displayEdgeType.setToolTipText("Display the edge's Type. Can be combined with Label");
        displayEdgeType.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                displayEdgeTypeActionPerformed(evt);
            }
        });
        jMenu11.add(displayEdgeType);

        edgeFrequencyButton.setText("Display Frequency");
        edgeFrequencyButton.setToolTipText("Display the Edge Probability based on the number of graphs it belongs compared to the total number of graphs");
        edgeFrequencyButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                edgeFrequencyButtonActionPerformed(evt);
            }
        });
        jMenu11.add(edgeFrequencyButton);

        ShowEdgePathProbabilityButton.setText("Display Path Probability");
        ShowEdgePathProbabilityButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ShowEdgePathProbabilityButtonActionPerformed(evt);
            }
        });
        jMenu11.add(ShowEdgePathProbabilityButton);

        displayEdgeTextButton.add(jMenu11);

        MenuBar.add(displayEdgeTextButton);

        jMenu6.setText("Hide");

        hideAgentVerticesButton.setText("Agent Vertices");
        hideAgentVerticesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hideAgentVerticesButtonActionPerformed(evt);
            }
        });
        jMenu6.add(hideAgentVerticesButton);

        hideEntityVerticesButton.setText("Entity Vertices");
        hideEntityVerticesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hideEntityVerticesButtonActionPerformed(evt);
            }
        });
        jMenu6.add(hideEntityVerticesButton);

        hideLonelyVerticesButton.setText("Lonely Vertices");
        hideLonelyVerticesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hideLonelyVerticesButtonActionPerformed(evt);
            }
        });
        jMenu6.add(hideLonelyVerticesButton);

        hideMergedVerticesButton.setText("Common Vertices from All Graphs");
        hideMergedVerticesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hideMergedVerticesButtonActionPerformed(evt);
            }
        });
        jMenu6.add(hideMergedVerticesButton);

        hideAgentEdgesButton.setText("Agent Edges");
        hideAgentEdgesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hideAgentEdgesButtonActionPerformed(evt);
            }
        });
        jMenu6.add(hideAgentEdgesButton);

        MenuBar.add(jMenu6);

        jMenu2.setText("Merge");

        jMenuItem1.setText("Merge Configuration");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        jMenu2.add(jMenuItem1);

        mergeGraphButtom.setText("Merge Graph With...");
        mergeGraphButtom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mergeGraphButtomActionPerformed(evt);
            }
        });
        jMenu2.add(mergeGraphButtom);

        allowMergeUndoButtom.setText("Allow to Undo Merge");
        allowMergeUndoButtom.setToolTipText("<html>\nIf selected, then graph merging will be treated as normal collases. This generate bigger files due to multiple collapses and is considerable slower.  \n<br>\nIf unselected, then graph merging will replace merged vertices with a new vertex. This is a faster process and uses less space\n</html>");
        allowMergeUndoButtom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                allowMergeUndoButtomActionPerformed(evt);
            }
        });
        jMenu2.add(allowMergeUndoButtom);

        MenuBar.add(jMenu2);

        jMenu3.setText("Temporal Scale");

        temporalNanosecondsButton.setText("Nanoseconds");
        temporalNanosecondsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                temporalNanosecondsButtonActionPerformed(evt);
            }
        });
        jMenu3.add(temporalNanosecondsButton);

        temporalMicrosecondsButton.setText("Microseconds");
        temporalMicrosecondsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                temporalMicrosecondsButtonActionPerformed(evt);
            }
        });
        jMenu3.add(temporalMicrosecondsButton);

        temporalMillisecondsButton.setSelected(true);
        temporalMillisecondsButton.setText("Milliseconds");
        temporalMillisecondsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                temporalMillisecondsButtonActionPerformed(evt);
            }
        });
        jMenu3.add(temporalMillisecondsButton);

        temporalSecondsButton.setText("Seconds");
        temporalSecondsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                temporalSecondsButtonActionPerformed(evt);
            }
        });
        jMenu3.add(temporalSecondsButton);

        temporalMinutesButton.setText("Minutes");
        temporalMinutesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                temporalMinutesButtonActionPerformed(evt);
            }
        });
        jMenu3.add(temporalMinutesButton);

        temporalHoursButton.setText("Hours");
        temporalHoursButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                temporalHoursButtonActionPerformed(evt);
            }
        });
        jMenu3.add(temporalHoursButton);

        temporalDaysButton.setText("Days");
        temporalDaysButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                temporalDaysButtonActionPerformed(evt);
            }
        });
        jMenu3.add(temporalDaysButton);

        temporalWeeksButton.setText("Week");
        temporalWeeksButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                temporalWeeksButtonActionPerformed(evt);
            }
        });
        jMenu3.add(temporalWeeksButton);

        MenuBar.add(jMenu3);

        jMenu4.setText("Color Scheme");

        doDerivateButton.setText("Derivative");
        doDerivateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                doDerivateButtonActionPerformed(evt);
            }
        });
        jMenu4.add(doDerivateButton);

        removeOutliersButton.setText("Remove Outliers");
        removeOutliersButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeOutliersButtonActionPerformed(evt);
            }
        });
        jMenu4.add(removeOutliersButton);

        MenuBar.add(jMenu4);

        jMenu8.setText("Collapse");

        jMenu5.setText("Similarity Collapse");

        updateErrorButton.setText("Variable Epsilon (VE)");
        updateErrorButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateErrorButtonActionPerformed(evt);
            }
        });
        jMenu5.add(updateErrorButton);

        verifyWithinClusterButton.setSelected(true);
        verifyWithinClusterButton.setText("Inter-cluster verification (IC)");
        verifyWithinClusterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                verifyWithinClusterButtonActionPerformed(evt);
            }
        });
        jMenu5.add(verifyWithinClusterButton);

        jMenuItem2.setText("Similarity Configuration");
        jMenuItem2.setToolTipText("Loads the configuration file for the Similarity Collapse");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        jMenu5.add(jMenuItem2);

        attributeDisplaySimConfig.setSelected(true);
        attributeDisplaySimConfig.setText("Use Attribute Status Config");
        attributeDisplaySimConfig.setToolTipText("Will use the current attribute display schema being used to color the vertices for the similarity algorithm, evaluating only the displayed attribute");
        attributeDisplaySimConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                attributeDisplaySimConfigActionPerformed(evt);
            }
        });
        jMenu5.add(attributeDisplaySimConfig);

        similarityConsiderNeighborsButton.setSelected(true);
        similarityConsiderNeighborsButton.setText("Consider only Neighbors");
        similarityConsiderNeighborsButton.setToolTipText("The neighborhood will be based on the graph's links (edges) if selected. Otherwise all vertices will be considered neighbors (used for clustering disconsidering the edges)");
        similarityConsiderNeighborsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                similarityConsiderNeighborsButtonActionPerformed(evt);
            }
        });
        jMenu5.add(similarityConsiderNeighborsButton);

        jMenu8.add(jMenu5);

        CollapseAllAgentsButton.setText("Collapse All Agents");
        CollapseAllAgentsButton.setToolTipText("Collapse all the vertices from each Agent");
        CollapseAllAgentsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CollapseAllAgentsButtonActionPerformed(evt);
            }
        });
        jMenu8.add(CollapseAllAgentsButton);

        MenuBar.add(jMenu8);

        jMenu12.setText("Debugging<Prototype>");

        debugTrialMenuItem.setText("Debug Trial");
        debugTrialMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                debugTrialMenuItemActionPerformed(evt);
            }
        });
        jMenu12.add(debugTrialMenuItem);

        findNodesFrequencyButton.setText("Find Frequency");
        findNodesFrequencyButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                findNodesFrequencyButtonActionPerformed(evt);
            }
        });
        jMenu12.add(findNodesFrequencyButton);

        computeMarkovChainButton.setText("Markov Chain");
        computeMarkovChainButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                computeMarkovChainButtonActionPerformed(evt);
            }
        });
        jMenu12.add(computeMarkovChainButton);

        MenuBar.add(jMenu12);

        jMenu13.setText("Pathing");

        findPathButton.setText("Find Path between two Selected Vertices");
        findPathButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                findPathButtonActionPerformed(evt);
            }
        });
        jMenu13.add(findPathButton);

        MenuBar.add(jMenu13);

        jMenu9.setText("Performance");

        PerformanceAAButton.setSelected(true);
        PerformanceAAButton.setText("Anti aliasing");
        PerformanceAAButton.setToolTipText("Enable/Disable anti-aliasing");
        PerformanceAAButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PerformanceAAButtonActionPerformed(evt);
            }
        });
        jMenu9.add(PerformanceAAButton);

        PerformanceArrowHeadsButton.setSelected(true);
        PerformanceArrowHeadsButton.setText("Show Edge ArrowHeads");
        PerformanceArrowHeadsButton.setToolTipText("Show/Hide edge arrowheads");
        PerformanceArrowHeadsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PerformanceArrowHeadsButtonActionPerformed(evt);
            }
        });
        jMenu9.add(PerformanceArrowHeadsButton);

        PaintInvisibleVerticesButton.setSelected(true);
        PaintInvisibleVerticesButton.setText("Paint invisible Vertices");
        PaintInvisibleVerticesButton.setToolTipText("Paint/Hide vertices outside the current viewport");
        PaintInvisibleVerticesButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PaintInvisibleVerticesButtonActionPerformed(evt);
            }
        });
        jMenu9.add(PaintInvisibleVerticesButton);

        MenuBar.add(jMenu9);

        jMenu14.setText("Edge");

        isEdgeColorByType.setText("Edge Color based on its Type");
        isEdgeColorByType.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                isEdgeColorByTypeActionPerformed(evt);
            }
        });
        jMenu14.add(isEdgeColorByType);

        isColorByEdgeValueButton.setSelected(true);
        isColorByEdgeValueButton.setText("Edge Color based on its Value");
        isColorByEdgeValueButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                isColorByEdgeValueButtonActionPerformed(evt);
            }
        });
        jMenu14.add(isColorByEdgeValueButton);

        EdgeColorGraphsButtom.setText("Edge Color based on Graphs");
        EdgeColorGraphsButtom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EdgeColorGraphsButtomActionPerformed(evt);
            }
        });
        jMenu14.add(EdgeColorGraphsButtom);

        EdgeColorMarkovInButtom.setText("Edge Color based on Markov In");
        EdgeColorMarkovInButtom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EdgeColorMarkovInButtomActionPerformed(evt);
            }
        });
        jMenu14.add(EdgeColorMarkovInButtom);

        EdgeColorMarkovOutButtom.setText("Edge Color based on Markov Out");
        EdgeColorMarkovOutButtom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EdgeColorMarkovOutButtomActionPerformed(evt);
            }
        });
        jMenu14.add(EdgeColorMarkovOutButtom);

        EdgeStrokeByValueButton.setSelected(true);
        EdgeStrokeByValueButton.setText("Edge Size based on Value");
        EdgeStrokeByValueButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EdgeStrokeByValueButtonActionPerformed(evt);
            }
        });
        jMenu14.add(EdgeStrokeByValueButton);

        EdgeStrokeByGraphButton.setText("Edge Size based on Graphs");
        EdgeStrokeByGraphButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EdgeStrokeByGraphButtonActionPerformed(evt);
            }
        });
        jMenu14.add(EdgeStrokeByGraphButton);

        EdgeStrokeByMarkovinButton.setText("Edge Size based on Markov In");
        EdgeStrokeByMarkovinButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EdgeStrokeByMarkovinButtonActionPerformed(evt);
            }
        });
        jMenu14.add(EdgeStrokeByMarkovinButton);

        EdgeStrokeByMarkovoutButton.setText("Edge Size based on Markov Out");
        EdgeStrokeByMarkovoutButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EdgeStrokeByMarkovoutButtonActionPerformed(evt);
            }
        });
        jMenu14.add(EdgeStrokeByMarkovoutButton);

        EdgeStrokeDefaultButton.setText("Default Edge Size");
        EdgeStrokeDefaultButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                EdgeStrokeDefaultButtonActionPerformed(evt);
            }
        });
        jMenu14.add(EdgeStrokeDefaultButton);

        MenuBar.add(jMenu14);

        jMenu15.setText("Vertex");

        vertexBorderByGraphButton.setText("Vertex Border Color based on GraphFile");
        vertexBorderByGraphButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                vertexBorderByGraphButtonActionPerformed(evt);
            }
        });
        jMenu15.add(vertexBorderByGraphButton);

        VertexStroke.add(vertexStrokeDefault);
        vertexStrokeDefault.setSelected(true);
        vertexStrokeDefault.setText("Default Stroke");
        vertexStrokeDefault.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                vertexStrokeDefaultActionPerformed(evt);
            }
        });
        jMenu15.add(vertexStrokeDefault);

        VertexStroke.add(vertexStrokeGraphFile);
        vertexStrokeGraphFile.setText("Stroke by GraphFile");
        vertexStrokeGraphFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                vertexStrokeGraphFileActionPerformed(evt);
            }
        });
        jMenu15.add(vertexStrokeGraphFile);

        VertexStroke.add(vertexStrokeLabel);
        vertexStrokeLabel.setText("Stroke by Label");
        vertexStrokeLabel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                vertexStrokeLabelActionPerformed(evt);
            }
        });
        jMenu15.add(vertexStrokeLabel);

        VertexStroke.add(vertexStrokeOutlier);
        vertexStrokeOutlier.setText("Stroke by Outlier");
        vertexStrokeOutlier.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                vertexStrokeOutlierActionPerformed(evt);
            }
        });
        jMenu15.add(vertexStrokeOutlier);

        MenuBar.add(jMenu15);

        setJMenuBar(MenuBar);

        setSize(new java.awt.Dimension(1189, 784));
        setLocationRelativeTo(null);
    }// </editor-fold>//GEN-END:initComponents
    /**
     * ================================================
     * Expand Button
     * ================================================
     */
    private void ExpandActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ExpandActionPerformed
        GuiButtons.Expand(variables);
    }//GEN-LAST:event_ExpandActionPerformed
    /**
     * ================================================
     * Collapse Button
     * ================================================
     */
    private void CollapseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CollapseActionPerformed
        GuiButtons.Collapse(variables);
    }//GEN-LAST:event_CollapseActionPerformed
    /**
     * ================================================
     * Reset Button
     * ================================================
     */
    private void ResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ResetActionPerformed
        GuiButtons.Reset(variables);
    }//GEN-LAST:event_ResetActionPerformed
    /**
     * ================================================
     * Select Mouse mode Button
     * ================================================
     */
    private void MouseModesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MouseModesActionPerformed
        GuiButtons.MouseModes(variables.mouse, MouseModes);
    }//GEN-LAST:event_MouseModesActionPerformed
    /**
     * ================================================
     * Collapse Agent's processes
     * ================================================
     */
    private void CollapseAgentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CollapseAgentActionPerformed
        GuiButtons.CollapseAgent(variables);
    }//GEN-LAST:event_CollapseAgentActionPerformed

   /**
         * ================================================
         * Edge Shape: Make it to be a line instead of quadratic curves
         * ================================================
         */
    private void EdgeLineShapeSelectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EdgeLineShapeSelectionActionPerformed
        GuiButtons.EdgeLineMode(EdgeLineShapeSelection, variables);
    }//GEN-LAST:event_EdgeLineShapeSelectionActionPerformed

    /**
         * ================================================
         * Status Filter box
         * ================================================
         */
    private void StatusFilterBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_StatusFilterBoxActionPerformed
        GuiButtons.StatusFilter(variables);
    }//GEN-LAST:event_StatusFilterBoxActionPerformed

   
    private void edgeFilterListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_edgeFilterListValueChanged
        GuiButtons.Filter(variables);
    }//GEN-LAST:event_edgeFilterListValueChanged

    private void LayoutsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_LayoutsActionPerformed
        GuiButtons.LayoutSelection(variables, Layouts);
    }//GEN-LAST:event_LayoutsActionPerformed

    private void OpenConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OpenConfigActionPerformed
        GuiReadFile.openConfigFile(variables, fileChooser, this, Layouts);
    }//GEN-LAST:event_OpenConfigActionPerformed

    private void ExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ExitActionPerformed
        GuiButtons.Exit();
    }//GEN-LAST:event_ExitActionPerformed

    private void OpenGraphActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OpenGraphActionPerformed
        GuiReadFile.openGraphFile(variables, fileChooser, this, Layouts);
    }//GEN-LAST:event_OpenGraphActionPerformed

    private void SimilarityInferenceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SimilarityInferenceActionPerformed
        GuiInference.SimilarityCollapse(variables, updateErrorButton.getState(), verifyWithinClusterButton.getState());
    }//GEN-LAST:event_SimilarityInferenceActionPerformed

    private void FilterVertexMaxValueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FilterVertexMaxValueActionPerformed
        // TODO add your handling code here:
        if(TemporalFilterToggle.isSelected())
            GuiButtons.Filter(variables);
    }//GEN-LAST:event_FilterVertexMaxValueActionPerformed

    private void FilterVertexMinValueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FilterVertexMinValueActionPerformed
        // TODO add your handling code here:
        if(TemporalFilterToggle.isSelected())
            GuiButtons.Filter(variables);
    }//GEN-LAST:event_FilterVertexMinValueActionPerformed

    private void TemporalFilterToggleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_TemporalFilterToggleActionPerformed
        // TODO add your handling code here:
        GuiButtons.Filter(variables);
    }//GEN-LAST:event_TemporalFilterToggleActionPerformed

    private void autoDetectEdgesCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_autoDetectEdgesCheckBoxActionPerformed
        // TODO add your handling code here:
        GuiButtons.AutoDetectEdge(variables, autoDetectEdgesCheckBox.getState());
    }//GEN-LAST:event_autoDetectEdgesCheckBoxActionPerformed

    private void autoDetectAttributeCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_autoDetectAttributeCheckBoxActionPerformed
        // TODO add your handling code here:
        GuiButtons.AutoDetectVertexModes(variables, autoDetectAttributeCheckBox.getState());
    }//GEN-LAST:event_autoDetectAttributeCheckBoxActionPerformed

    private void displayEntityLabelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_displayEntityLabelButtonActionPerformed
        // TODO add your handling code here:
        displayID.setSelected(false);
        GuiButtons.VertexLabel(variables, displayAgentLabelButton.getState(), displayActivityLabelButton.getState(), displayEntityLabelButton.getState(), displayTimeLabel.getState(), displayID.getState());
    }//GEN-LAST:event_displayEntityLabelButtonActionPerformed

    private void displayActivityLabelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_displayActivityLabelButtonActionPerformed
        // TODO add your handling code here:
        displayID.setSelected(false);
        GuiButtons.VertexLabel(variables, displayAgentLabelButton.getState(), displayActivityLabelButton.getState(), displayEntityLabelButton.getState(), displayTimeLabel.getState(), displayID.getState());
    }//GEN-LAST:event_displayActivityLabelButtonActionPerformed

    private void displayAgentLabelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_displayAgentLabelButtonActionPerformed
        // TODO add your handling code here:
        displayID.setSelected(false);
        GuiButtons.VertexLabel(variables, displayAgentLabelButton.getState(), displayActivityLabelButton.getState(), displayEntityLabelButton.getState(), displayTimeLabel.getState(), displayID.getState());
    }//GEN-LAST:event_displayAgentLabelButtonActionPerformed

    private void displayTimeLabelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_displayTimeLabelActionPerformed
        // TODO add your handling code here:
        displayID.setSelected(false);
        GuiButtons.VertexLabel(variables, displayAgentLabelButton.getState(), displayActivityLabelButton.getState(), displayEntityLabelButton.getState(), displayTimeLabel.getState(), displayID.getState());
    }//GEN-LAST:event_displayTimeLabelActionPerformed

    private void mergeGraphButtomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mergeGraphButtomActionPerformed
        // TODO add your handling code here:
        GuiReadFile.MergeGraph(variables, fileChooser, this, Layouts);
    }//GEN-LAST:event_mergeGraphButtomActionPerformed

    private void exportGraphPROVNButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportGraphPROVNButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.ExportGraphPROVN(variables);
    }//GEN-LAST:event_exportGraphPROVNButtonActionPerformed

    private void temporalMillisecondsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_temporalMillisecondsButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.TemporalLayoutGranularity("milliseconds", variables, false, false, true, false, false, false, 
                false, false, Layouts, temporalNanosecondsButton, temporalMicrosecondsButton, temporalMillisecondsButton, 
                temporalSecondsButton, temporalMinutesButton, temporalHoursButton, 
                temporalDaysButton, temporalWeeksButton);        
    }//GEN-LAST:event_temporalMillisecondsButtonActionPerformed

    private void temporalHoursButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_temporalHoursButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.TemporalLayoutGranularity("hours", variables, false, false, false, false, false, true, 
                false, false, Layouts, temporalNanosecondsButton, temporalMicrosecondsButton, temporalMillisecondsButton, 
                temporalSecondsButton, temporalMinutesButton, temporalHoursButton, 
                temporalDaysButton, temporalWeeksButton);
    }//GEN-LAST:event_temporalHoursButtonActionPerformed

    private void temporalDaysButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_temporalDaysButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.TemporalLayoutGranularity("days", variables, false, false, false, false, false, false, 
                true, false, Layouts, temporalNanosecondsButton, temporalMicrosecondsButton, temporalMillisecondsButton, 
                temporalSecondsButton, temporalMinutesButton, temporalHoursButton, 
                temporalDaysButton, temporalWeeksButton);
    }//GEN-LAST:event_temporalDaysButtonActionPerformed

    private void temporalWeeksButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_temporalWeeksButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.TemporalLayoutGranularity("weeks", variables, false, false, false, false, false, false, 
                false, true, Layouts, temporalNanosecondsButton, temporalMicrosecondsButton, temporalMillisecondsButton, 
                temporalSecondsButton, temporalMinutesButton, temporalHoursButton, 
                temporalDaysButton, temporalWeeksButton);
    }//GEN-LAST:event_temporalWeeksButtonActionPerformed

    private void temporalMinutesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_temporalMinutesButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.TemporalLayoutGranularity("minutes", variables, false, false, false, false, true, false, 
                false, false, Layouts, temporalNanosecondsButton, temporalMicrosecondsButton, temporalMillisecondsButton, 
                temporalSecondsButton, temporalMinutesButton, temporalHoursButton, 
                temporalDaysButton, temporalWeeksButton);
    }//GEN-LAST:event_temporalMinutesButtonActionPerformed

    private void doDerivateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_doDerivateButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.derivateScheme(variables, doDerivateButton.getState());
    }//GEN-LAST:event_doDerivateButtonActionPerformed

    private void removeOutliersButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeOutliersButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.removeOutliersDerivateScheme(variables, removeOutliersButton.getState());
    }//GEN-LAST:event_removeOutliersButtonActionPerformed

    private void displayIDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_displayIDActionPerformed
        // TODO add your handling code here:
        displayAgentLabelButton.setSelected(false);
        displayEntityLabelButton.setSelected(false);
        displayActivityLabelButton.setSelected(false);
        displayTimeLabel.setSelected(false);
        GuiButtons.VertexLabel(variables, displayAgentLabelButton.getState(), displayActivityLabelButton.getState(), displayEntityLabelButton.getState(), displayTimeLabel.getState(), displayID.getState());
    }//GEN-LAST:event_displayIDActionPerformed

    private void verifyWithinClusterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_verifyWithinClusterButtonActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_verifyWithinClusterButtonActionPerformed

    private void updateErrorButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateErrorButtonActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_updateErrorButtonActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        // TODO add your handling code here:
        GuiInference.DBSCANCollapse(variables);
    }//GEN-LAST:event_jButton1ActionPerformed

    private void vertexFilterListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_vertexFilterListValueChanged
//        GuiButtons.Filter(variables);
        GuiButtons.Filter(variables);
    }//GEN-LAST:event_vertexFilterListValueChanged

    private void dbscanEpsilonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dbscanEpsilonActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_dbscanEpsilonActionPerformed

    private void simEpsilonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_simEpsilonActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_simEpsilonActionPerformed

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        // TODO add your handling code here:
        GuiReadFile.loadMergeConfiguration(variables, fileChooser, this);
    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
        // TODO add your handling code here:
        GuiReadFile.loadSimilarityConfiguration(variables, fileChooser, this);
    }//GEN-LAST:event_jMenuItem2ActionPerformed

    private void temporalMicrosecondsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_temporalMicrosecondsButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.TemporalLayoutGranularity("microseconds", variables, false, true, false, false, false, false, 
                false, false, Layouts, temporalNanosecondsButton, temporalMicrosecondsButton, temporalMillisecondsButton, 
                temporalSecondsButton, temporalMinutesButton, temporalHoursButton, 
                temporalDaysButton, temporalWeeksButton);  
    }//GEN-LAST:event_temporalMicrosecondsButtonActionPerformed

    private void temporalSecondsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_temporalSecondsButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.TemporalLayoutGranularity("seconds", variables, false, false, false, true, false, false, 
                false, false, Layouts, temporalNanosecondsButton, temporalMicrosecondsButton, temporalMillisecondsButton, 
                temporalSecondsButton, temporalMinutesButton, temporalHoursButton, 
                temporalDaysButton, temporalWeeksButton);  
    }//GEN-LAST:event_temporalSecondsButtonActionPerformed

    private void temporalNanosecondsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_temporalNanosecondsButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.TemporalLayoutGranularity("nanoseconds", variables, true, false, false, false, false, false, 
                false, false, Layouts, temporalNanosecondsButton, temporalMicrosecondsButton, temporalMillisecondsButton, 
                temporalSecondsButton, temporalMinutesButton, temporalHoursButton, 
                temporalDaysButton, temporalWeeksButton);  
    }//GEN-LAST:event_temporalNanosecondsButtonActionPerformed

    private void attributeDisplaySimConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_attributeDisplaySimConfigActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_attributeDisplaySimConfigActionPerformed

    private void isEdgeColorByTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_isEdgeColorByTypeActionPerformed
        GuiButtons.EdgeColorConfiguration(variables, true, false, false, false, false, isEdgeColorByType, isColorByEdgeValueButton, EdgeColorGraphsButtom, EdgeColorMarkovInButtom, EdgeColorMarkovOutButtom);
    }//GEN-LAST:event_isEdgeColorByTypeActionPerformed

    private void EdgeStrokeByValueButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EdgeStrokeByValueButtonActionPerformed
        GuiButtons.EdgeStrokeConfiguration(variables, true, false, false, false, false, EdgeStrokeByValueButton, EdgeStrokeByGraphButton, EdgeStrokeByMarkovinButton, EdgeStrokeByMarkovoutButton, EdgeStrokeDefaultButton);
    }//GEN-LAST:event_EdgeStrokeByValueButtonActionPerformed

    private void displayEdgeLabelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_displayEdgeLabelActionPerformed
        // TODO add your handling code here:
        edgeFrequencyButton.setSelected(false);
        ShowEdgePathProbabilityButton.setSelected(false);
        displayIDButton.setSelected(false);
        GuiButtons.EdgeTextDisplay(variables, displayIDButton.isSelected(), displayEdgeLabel.isSelected(), displayEdgeType.isSelected(), edgeFrequencyButton.isSelected(),ShowEdgePathProbabilityButton.isSelected());
    }//GEN-LAST:event_displayEdgeLabelActionPerformed

    private void hideAgentVerticesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideAgentVerticesButtonActionPerformed
        GuiButtons.Filter(variables);
    }//GEN-LAST:event_hideAgentVerticesButtonActionPerformed

    private void hideEntityVerticesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideEntityVerticesButtonActionPerformed
        GuiButtons.Filter(variables);
    }//GEN-LAST:event_hideEntityVerticesButtonActionPerformed

    private void hideLonelyVerticesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideLonelyVerticesButtonActionPerformed
        GuiButtons.Filter(variables);
    }//GEN-LAST:event_hideLonelyVerticesButtonActionPerformed

    private void hideAgentEdgesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideAgentEdgesButtonActionPerformed
        GuiButtons.Filter(variables);
    }//GEN-LAST:event_hideAgentEdgesButtonActionPerformed

    private void vertexShapeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_vertexShapeComboBoxActionPerformed
        GuiButtons.selectVertexShape(variables, (String) vertexShapeComboBox.getSelectedItem(), vertexShapeBasedOnAttribute.getText());
    }//GEN-LAST:event_vertexShapeComboBoxActionPerformed

    private void vertexShapeBasedOnAttributeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_vertexShapeBasedOnAttributeActionPerformed
        GuiButtons.selectVertexShape(variables, (String) vertexShapeComboBox.getSelectedItem(), vertexShapeBasedOnAttribute.getText());
    }//GEN-LAST:event_vertexShapeBasedOnAttributeActionPerformed

    private void layoutAttributeName_X_TextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_layoutAttributeName_X_TextActionPerformed
        // TODO add your handling code here:
        variables.layout_attribute_X = layoutAttributeName_X_Text.getText();
    }//GEN-LAST:event_layoutAttributeName_X_TextActionPerformed

    private void layoutAttributeName_Y_TextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_layoutAttributeName_Y_TextActionPerformed
        // TODO add your handling code here:
        variables.layout_attribute_Y = layoutAttributeName_Y_Text.getText();
    }//GEN-LAST:event_layoutAttributeName_Y_TextActionPerformed

    private void isColorByEdgeValueButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_isColorByEdgeValueButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.EdgeColorConfiguration(variables, false, true, false, false, false, isEdgeColorByType, isColorByEdgeValueButton, EdgeColorGraphsButtom, EdgeColorMarkovInButtom, EdgeColorMarkovOutButtom);
    }//GEN-LAST:event_isColorByEdgeValueButtonActionPerformed

    private void hideMergedVerticesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideMergedVerticesButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.Filter(variables);
    }//GEN-LAST:event_hideMergedVerticesButtonActionPerformed

    private void allowVariableLayoutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allowVariableLayoutButtonActionPerformed
        // TODO add your handling code here:
//        variables.allowVariableLayout = allowVariableLayoutButton.getState();
        GuiButtons.setVariableLayouts(variables, allowVariableLayoutButton.getState(), Layouts);
    }//GEN-LAST:event_allowVariableLayoutButtonActionPerformed

    private void vertexBorderByGraphButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_vertexBorderByGraphButtonActionPerformed
        // TODO add your handling code here:
//        variables.vertexBorderByGraphs = vertexBorderByGraphButton.getState();
//        variables.view.repaint();
    }//GEN-LAST:event_vertexBorderByGraphButtonActionPerformed

    private void similarityConsiderNeighborsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_similarityConsiderNeighborsButtonActionPerformed
        // TODO add your handling code here:
        variables.considerOnlyNeighborsSimilarityCollapse = similarityConsiderNeighborsButton.getState();
    }//GEN-LAST:event_similarityConsiderNeighborsButtonActionPerformed

    private void DeleteSelectedVerticesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DeleteSelectedVerticesButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.Delete(variables);
    }//GEN-LAST:event_DeleteSelectedVerticesButtonActionPerformed

    private void UndoDeletionButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_UndoDeletionButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.UndoDeletion(variables);
    }//GEN-LAST:event_UndoDeletionButtonActionPerformed

    private void setNewLabelConfirmButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_setNewLabelConfirmButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.UpdateVertexLabel(newVertexLabelTextBox.getText(), variables);
        setNewLabelDialogBox.setVisible(false);
    }//GEN-LAST:event_setNewLabelConfirmButtonActionPerformed

    private void PanToGraphButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PanToGraphButtonActionPerformed
        // TODO add your handling code here:
        GuiFunctions.PanCameraToFirstVertex(variables);
    }//GEN-LAST:event_PanToGraphButtonActionPerformed

    private void setNewLabelCancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_setNewLabelCancelButtonActionPerformed
        // TODO add your handling code here:
        setNewLabelDialogBox.setVisible(false);
    }//GEN-LAST:event_setNewLabelCancelButtonActionPerformed

    private void RenameVertexLabelMenuButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RenameVertexLabelMenuButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.ShowVertexRenameLabelWindow(setNewLabelDialogBox);
    }//GEN-LAST:event_RenameVertexLabelMenuButtonActionPerformed

    private void CollapseAllAgentsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CollapseAllAgentsButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.CollapseAllAgents(variables);
    }//GEN-LAST:event_CollapseAllAgentsButtonActionPerformed

    private void linkActivitiesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_linkActivitiesButtonActionPerformed
        // TODO add your handling code here:
        GuiFunctions.AddChronologicalEdgesLinkingActivities(variables);
    }//GEN-LAST:event_linkActivitiesButtonActionPerformed

    private void PerformanceAAButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PerformanceAAButtonActionPerformed
        // TODO add your handling code here:
        if(!PerformanceAAButton.getState())
            variables.jungPerformance.DisableAntialiasing(variables.view);
        else
            variables.jungPerformance.EnableAntialiasing(variables.view);
        variables.view.repaint();
    }//GEN-LAST:event_PerformanceAAButtonActionPerformed

    private void PerformanceArrowHeadsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PerformanceArrowHeadsButtonActionPerformed
        // TODO add your handling code here:
        if(!PerformanceArrowHeadsButton.getState())
            variables.jungPerformance.OmitArrowHeads(variables.view);
        else
            variables.jungPerformance.EnableArrowHeads(variables.view);
        variables.view.repaint();
    }//GEN-LAST:event_PerformanceArrowHeadsButtonActionPerformed

    private void PaintInvisibleVerticesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PaintInvisibleVerticesButtonActionPerformed
        // TODO add your handling code here:
        
        if(!PaintInvisibleVerticesButton.getState())
            variables.jungPerformance.doNotPaintInvisibleVertices(variables.view);
        else
            variables.jungPerformance.PaintInvisibleVertices(variables.view);
        variables.view.repaint();
    }//GEN-LAST:event_PaintInvisibleVerticesButtonActionPerformed

    private void edgeFrequencyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_edgeFrequencyButtonActionPerformed
        // TODO add your handling code here:
        displayEdgeLabel.setSelected(false);
        displayEdgeType.setSelected(false);
        ShowEdgePathProbabilityButton.setSelected(false);
        displayIDButton.setSelected(false);
        GuiButtons.EdgeTextDisplay(variables, displayIDButton.isSelected(), displayEdgeLabel.isSelected(), displayEdgeType.isSelected(), edgeFrequencyButton.isSelected(), ShowEdgePathProbabilityButton.isSelected());
    }//GEN-LAST:event_edgeFrequencyButtonActionPerformed

    private void ShowEdgePathProbabilityButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ShowEdgePathProbabilityButtonActionPerformed
        // TODO add your handling code here:
        displayEdgeLabel.setSelected(false);
        displayEdgeType.setSelected(false);
        edgeFrequencyButton.setSelected(false);
        displayIDButton.setSelected(false);
        GuiButtons.EdgeTextDisplay(variables, displayIDButton.isSelected(), displayEdgeLabel.isSelected(), displayEdgeType.isSelected(), edgeFrequencyButton.isSelected(), ShowEdgePathProbabilityButton.isSelected());
    }//GEN-LAST:event_ShowEdgePathProbabilityButtonActionPerformed

    private void displayEdgeTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_displayEdgeTypeActionPerformed
        // TODO add your handling code here:
        edgeFrequencyButton.setSelected(false);
        ShowEdgePathProbabilityButton.setSelected(false);
        displayIDButton.setSelected(false);
        GuiButtons.EdgeTextDisplay(variables, displayIDButton.isSelected(), displayEdgeLabel.isSelected(), displayEdgeType.isSelected(), edgeFrequencyButton.isSelected(), ShowEdgePathProbabilityButton.isSelected());
    }//GEN-LAST:event_displayEdgeTypeActionPerformed

    private void exportGraphXMLButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportGraphXMLButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.ExportGraphXML(variables.graph.getVertices(), variables.graph.getEdges(), "Export_Original_Graph_XML");
    }//GEN-LAST:event_exportGraphXMLButtonActionPerformed

    private void exportCollapsedGraphXMLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportCollapsedGraphXMLActionPerformed
        // TODO add your handling code here:
        GuiButtons.ExportCollapsedGraphXML(variables);
    }//GEN-LAST:event_exportCollapsedGraphXMLActionPerformed

    private void exportDisplayedGraphXMLActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportDisplayedGraphXMLActionPerformed
        // TODO add your handling code here:
        GuiButtons.ExportDisplayedGraphXML(variables);
    }//GEN-LAST:event_exportDisplayedGraphXMLActionPerformed

    private void isSTDepsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_isSTDepsActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_isSTDepsActionPerformed

    private void isAndOperatorButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_isAndOperatorButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.Filter(variables);
    }//GEN-LAST:event_isAndOperatorButtonActionPerformed

    private void displayIDButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_displayIDButtonActionPerformed
        // TODO add your handling code here:
        displayEdgeLabel.setSelected(false);
        displayEdgeType.setSelected(false);
        edgeFrequencyButton.setSelected(false);
        ShowEdgePathProbabilityButton.setSelected(false);
        GuiButtons.EdgeTextDisplay(variables, displayIDButton.isSelected(), displayEdgeLabel.isSelected(), displayEdgeType.isSelected(), edgeFrequencyButton.isSelected(), ShowEdgePathProbabilityButton.isSelected());
    }//GEN-LAST:event_displayIDButtonActionPerformed

    private void findPathButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_findPathButtonActionPerformed
        // TODO add your handling code here:
//        float probability = GuiFunctions.FindPath(variables);
        tooltipDialogBox.setVisible(true);
//        String tooltip = "The probability of taking this path, linking the selected source to the destination is: " + probability * 100.0f + " %";
        tooltipWindowTextPane.setText(GuiFunctions.ComputePath(variables));
    }//GEN-LAST:event_findPathButtonActionPerformed

    private void SearchVertexMenuButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SearchVertexMenuButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.ShowVertexSearchWindow(searchVertexIDDialogBox);
    }//GEN-LAST:event_SearchVertexMenuButtonActionPerformed

    private void searchVertexIDButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchVertexIDButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.SearchVertexByID(vertexIDTextField.getText(), variables);
        searchVertexIDDialogBox.setVisible(false);
    }//GEN-LAST:event_searchVertexIDButtonActionPerformed

    private void cancelSearchVertexButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelSearchVertexButtonActionPerformed
        // TODO add your handling code here:
        searchVertexIDDialogBox.setVisible(false);
    }//GEN-LAST:event_cancelSearchVertexButtonActionPerformed

    private void confirmDebuggingButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_confirmDebuggingButtonActionPerformed
        // TODO add your handling code here:
        ProvDebugger.debugTrial(variables, selectedTrialComboBox.getSelectedItem().toString(), correctTrialsList.getSelectedValuesList(), 
                considerActivityVerticesButton.isSelected(), considerAgentVerticesButton.isSelected(), considerEntityVerticesButton.isSelected());
        debugDialogBox.setVisible(false);
    }//GEN-LAST:event_confirmDebuggingButtonActionPerformed

    private void cancelDebugButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelDebugButtonActionPerformed
        // TODO add your handling code here:
        debugDialogBox.setVisible(false);
    }//GEN-LAST:event_cancelDebugButtonActionPerformed

    private void debugTrialMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_debugTrialMenuItemActionPerformed
        // TODO add your handling code here:
        String[] types = new String[variables.graphNames.size()];
        int i = 0;
        for (String s : variables.graphNames) {
            types[i] = s;
            i++;
        }
        Arrays.sort(types);
        correctTrialsList.setListData(types);
        selectedTrialComboBox.setModel(
                new DefaultComboBoxModel(types));
        debugDialogBox.setVisible(true);
    }//GEN-LAST:event_debugTrialMenuItemActionPerformed

    private void closeTooltipWindowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeTooltipWindowButtonActionPerformed
        // TODO add your handling code here:
        tooltipDialogBox.setVisible(false);
    }//GEN-LAST:event_closeTooltipWindowButtonActionPerformed

    private void findNodesFrequencyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_findNodesFrequencyButtonActionPerformed
        // TODO add your handling code here:
        
        String[] types = new String[variables.graphNames.size()];
        int i = 0;
        for (String s : variables.graphNames) {
            types[i] = s;
            i++;
        }
        Arrays.sort(types);
        listWorkingTrials.setListData(types);
        selectWorkingTrialsDialogBox.setVisible(true);
    }//GEN-LAST:event_findNodesFrequencyButtonActionPerformed

    private void confirmWorkingTrialsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_confirmWorkingTrialsButtonActionPerformed
        // TODO add your handling code here:
         Map<String, String> result = GuiFunctions.FindFrequencyOfNodes(variables, listWorkingTrials.getSelectedValuesList());
        tooltipDialogBox.setVisible(true);
        String tooltip = result.get("Selected") + "\n"
                + "Related to failing:" + "\n" + result.get("Support_NOTOK") + " \n" + result.get("Confidence_NOTOK")+ " \n" + result.get("Lift_NOTOK")
                + " \n" + " \n" + "Related to succeeding:" + "\n" + result.get("Support_OK") + " \n" + result.get("Confidence_OK")+ " \n" + result.get("Lift_OK");
        tooltipWindowTextPane.setText(tooltip);
        selectWorkingTrialsDialogBox.setVisible(false);
    }//GEN-LAST:event_confirmWorkingTrialsButtonActionPerformed

    private void cancelWorkingTrialsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelWorkingTrialsButtonActionPerformed
        // TODO add your handling code here:
        selectWorkingTrialsDialogBox.setVisible(false);
    }//GEN-LAST:event_cancelWorkingTrialsButtonActionPerformed

    private void allowMergeUndoButtomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allowMergeUndoButtomActionPerformed
        // TODO add your handling code here:
        variables.allowMergeUndo = allowMergeUndoButtom.isSelected();
    }//GEN-LAST:event_allowMergeUndoButtomActionPerformed

    private void computeMarkovChainButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_computeMarkovChainButtonActionPerformed
        // TODO add your handling code here:
        GuiButtons.ComputeMarkov(variables);
    }//GEN-LAST:event_computeMarkovChainButtonActionPerformed

    private void EdgeColorMarkovInButtomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EdgeColorMarkovInButtomActionPerformed
        GuiButtons.EdgeColorConfiguration(variables, false, false, false, true, false, isEdgeColorByType, isColorByEdgeValueButton, EdgeColorGraphsButtom, EdgeColorMarkovInButtom, EdgeColorMarkovOutButtom);
    }//GEN-LAST:event_EdgeColorMarkovInButtomActionPerformed

    private void EdgeColorMarkovOutButtomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EdgeColorMarkovOutButtomActionPerformed
        GuiButtons.EdgeColorConfiguration(variables, false, false, false, false, true, isEdgeColorByType, isColorByEdgeValueButton, EdgeColorGraphsButtom, EdgeColorMarkovInButtom, EdgeColorMarkovOutButtom);
    }//GEN-LAST:event_EdgeColorMarkovOutButtomActionPerformed

    private void EdgeColorGraphsButtomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EdgeColorGraphsButtomActionPerformed
        GuiButtons.EdgeColorConfiguration(variables, false, false, true, false, false, isEdgeColorByType, isColorByEdgeValueButton, EdgeColorGraphsButtom, EdgeColorMarkovInButtom, EdgeColorMarkovOutButtom);
    }//GEN-LAST:event_EdgeColorGraphsButtomActionPerformed

    private void EdgeStrokeByGraphButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EdgeStrokeByGraphButtonActionPerformed
        GuiButtons.EdgeStrokeConfiguration(variables, false, true, false, false, false, EdgeStrokeByValueButton, EdgeStrokeByGraphButton, EdgeStrokeByMarkovinButton, EdgeStrokeByMarkovoutButton, EdgeStrokeDefaultButton);
    }//GEN-LAST:event_EdgeStrokeByGraphButtonActionPerformed

    private void EdgeStrokeByMarkovinButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EdgeStrokeByMarkovinButtonActionPerformed
        GuiButtons.EdgeStrokeConfiguration(variables, false, false, true, false, false, EdgeStrokeByValueButton, EdgeStrokeByGraphButton, EdgeStrokeByMarkovinButton, EdgeStrokeByMarkovoutButton, EdgeStrokeDefaultButton);
    }//GEN-LAST:event_EdgeStrokeByMarkovinButtonActionPerformed

    private void EdgeStrokeByMarkovoutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EdgeStrokeByMarkovoutButtonActionPerformed
        GuiButtons.EdgeStrokeConfiguration(variables, false, false, false, true, false, EdgeStrokeByValueButton, EdgeStrokeByGraphButton, EdgeStrokeByMarkovinButton, EdgeStrokeByMarkovoutButton, EdgeStrokeDefaultButton);
    }//GEN-LAST:event_EdgeStrokeByMarkovoutButtonActionPerformed

    private void EdgeStrokeDefaultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_EdgeStrokeDefaultButtonActionPerformed
        GuiButtons.EdgeStrokeConfiguration(variables, false, false, false, false, true, EdgeStrokeByValueButton, EdgeStrokeByGraphButton, EdgeStrokeByMarkovinButton, EdgeStrokeByMarkovoutButton, EdgeStrokeDefaultButton);
    }//GEN-LAST:event_EdgeStrokeDefaultButtonActionPerformed

    private void vertexStrokeGraphFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_vertexStrokeGraphFileActionPerformed
        variables.vertexBorderByGraphs = vertexStrokeGraphFile.isSelected();
        variables.highlightVertexOutliers = vertexStrokeOutlier.isSelected();
        variables.vertexBorderByLabel = vertexStrokeLabel.isSelected();
        variables.view.repaint();
        
    }//GEN-LAST:event_vertexStrokeGraphFileActionPerformed

    private void vertexStrokeOutlierActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_vertexStrokeOutlierActionPerformed
        variables.highlightVertexOutliers = vertexStrokeOutlier.isSelected();
        variables.view.repaint();
    }//GEN-LAST:event_vertexStrokeOutlierActionPerformed

    private void vertexStrokeDefaultActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_vertexStrokeDefaultActionPerformed
        variables.vertexBorderByGraphs = vertexStrokeGraphFile.isSelected();
        variables.highlightVertexOutliers = vertexStrokeOutlier.isSelected();
        variables.vertexBorderByLabel = vertexStrokeLabel.isSelected();
        variables.view.repaint();
    }//GEN-LAST:event_vertexStrokeDefaultActionPerformed

    private void vertexStrokeLabelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_vertexStrokeLabelActionPerformed
        variables.vertexBorderByGraphs = vertexStrokeGraphFile.isSelected();
        variables.highlightVertexOutliers = vertexStrokeOutlier.isSelected();
        variables.vertexBorderByLabel = vertexStrokeLabel.isSelected();
        variables.view.repaint();
    }//GEN-LAST:event_vertexStrokeLabelActionPerformed
   
    /**
     * Main
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional)">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    
                }
            }
        } catch (ClassNotFoundException ex) {
                Logger.getLogger(GraphFrame.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                Logger.getLogger(GraphFrame.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(GraphFrame.class.getName()).log(Level.SEVERE, null, ex);
            } catch (UnsupportedLookAndFeelException ex) {
                Logger.getLogger(GraphFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
//        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
//            java.util.logging.Logger.getLogger(GraphFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//        }
        //</editor-fold>

        GuiRun.Run();
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel AttributeStatus;
    private javax.swing.JButton Collapse;
    private javax.swing.JButton CollapseAgent;
    private javax.swing.JMenuItem CollapseAllAgentsButton;
    private javax.swing.JButton DeleteSelectedVerticesButton;
    private javax.swing.JLabel DisplayEdges;
    private javax.swing.JLabel DisplayVertices;
    private javax.swing.JCheckBoxMenuItem EdgeColorGraphsButtom;
    private javax.swing.JCheckBoxMenuItem EdgeColorMarkovInButtom;
    private javax.swing.JCheckBoxMenuItem EdgeColorMarkovOutButtom;
    private javax.swing.JComboBox EdgeLineShapeSelection;
    private javax.swing.JCheckBoxMenuItem EdgeStrokeByGraphButton;
    private javax.swing.JCheckBoxMenuItem EdgeStrokeByMarkovinButton;
    private javax.swing.JCheckBoxMenuItem EdgeStrokeByMarkovoutButton;
    public static javax.swing.JCheckBoxMenuItem EdgeStrokeByValueButton;
    private javax.swing.JCheckBoxMenuItem EdgeStrokeDefaultButton;
    private javax.swing.JLabel EdgeStyle;
    private javax.swing.JScrollPane EdgeTypes;
    private javax.swing.JMenuItem Exit;
    private javax.swing.JButton Expand;
    private javax.swing.JMenu FileMenu;
    public static javax.swing.JTextField FilterVertexMaxValue;
    public static javax.swing.JTextField FilterVertexMinValue;
    private javax.swing.JLabel GraphLayout;
    private javax.swing.JComboBox Layouts;
    private javax.swing.JMenuBar MenuBar;
    private javax.swing.JLabel MouseModeLabel;
    private javax.swing.JComboBox MouseModes;
    private javax.swing.JMenuItem OpenConfig;
    private javax.swing.JMenuItem OpenGraph;
    private javax.swing.JCheckBoxMenuItem PaintInvisibleVerticesButton;
    private javax.swing.JButton PanToGraphButton;
    private javax.swing.JCheckBoxMenuItem PerformanceAAButton;
    private javax.swing.JCheckBoxMenuItem PerformanceArrowHeadsButton;
    private javax.swing.JMenuItem RenameVertexLabelMenuButton;
    private javax.swing.JButton Reset;
    private javax.swing.JMenuItem SearchVertexMenuButton;
    private javax.swing.JCheckBoxMenuItem ShowEdgePathProbabilityButton;
    private javax.swing.JButton SimilarityInference;
    public static javax.swing.JComboBox StatusFilterBox;
    public static javax.swing.JToggleButton TemporalFilterToggle;
    private javax.swing.JPanel ToolMenu;
    private javax.swing.JButton UndoDeletionButton;
    private javax.swing.JScrollPane VertexLabels;
    private javax.swing.ButtonGroup VertexStroke;
    private javax.swing.JCheckBoxMenuItem allowMergeUndoButtom;
    private javax.swing.JCheckBoxMenuItem allowVariableLayoutButton;
    public static javax.swing.JRadioButtonMenuItem attributeDisplaySimConfig;
    private javax.swing.JCheckBoxMenuItem autoDetectAttributeCheckBox;
    private javax.swing.JCheckBoxMenuItem autoDetectEdgesCheckBox;
    private javax.swing.JButton cancelDebugButton;
    private javax.swing.JButton cancelSearchVertexButton;
    private javax.swing.JButton cancelWorkingTrialsButton;
    private javax.swing.JButton closeTooltipWindowButton;
    private javax.swing.JMenuItem computeMarkovChainButton;
    private javax.swing.JButton confirmDebuggingButton;
    private javax.swing.JButton confirmWorkingTrialsButton;
    private javax.swing.JRadioButton considerActivityVerticesButton;
    private javax.swing.JRadioButton considerAgentVerticesButton;
    private javax.swing.JRadioButton considerEntityVerticesButton;
    private static javax.swing.JList<String> correctTrialsList;
    public static javax.swing.JTextField dbscanEpsilon;
    private javax.swing.JDialog debugDialogBox;
    private javax.swing.JMenuItem debugTrialMenuItem;
    private javax.swing.JCheckBoxMenuItem displayActivityLabelButton;
    private javax.swing.JCheckBoxMenuItem displayAgentLabelButton;
    private javax.swing.JCheckBoxMenuItem displayEdgeLabel;
    private javax.swing.JMenu displayEdgeTextButton;
    private javax.swing.JCheckBoxMenuItem displayEdgeType;
    private javax.swing.JCheckBoxMenuItem displayEntityLabelButton;
    private javax.swing.JCheckBoxMenuItem displayID;
    private javax.swing.JCheckBoxMenuItem displayIDButton;
    private javax.swing.JCheckBoxMenuItem displayTimeLabel;
    private javax.swing.JCheckBoxMenuItem doDerivateButton;
    public static javax.swing.JList edgeFilterList;
    private javax.swing.JCheckBoxMenuItem edgeFrequencyButton;
    private javax.swing.JMenuItem exportCollapsedGraphXML;
    private javax.swing.JMenuItem exportDisplayedGraphXML;
    private javax.swing.JMenuItem exportGraphPROVNButton;
    private javax.swing.JMenuItem exportGraphXMLButton;
    private javax.swing.JFileChooser fileChooser;
    private javax.swing.JMenuItem findNodesFrequencyButton;
    private javax.swing.JMenuItem findPathButton;
    public static javax.swing.JCheckBoxMenuItem hideAgentEdgesButton;
    public static javax.swing.JCheckBoxMenuItem hideAgentVerticesButton;
    public static javax.swing.JCheckBoxMenuItem hideEntityVerticesButton;
    public static javax.swing.JCheckBoxMenuItem hideLonelyVerticesButton;
    public static javax.swing.JCheckBoxMenuItem hideMergedVerticesButton;
    public static javax.swing.JCheckBox isAndOperatorButton;
    private javax.swing.JCheckBoxMenuItem isColorByEdgeValueButton;
    public static javax.swing.JCheckBoxMenuItem isEdgeColorByType;
    public static javax.swing.JCheckBox isSTDeps;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu10;
    private javax.swing.JMenu jMenu11;
    private javax.swing.JMenu jMenu12;
    private javax.swing.JMenu jMenu13;
    private javax.swing.JMenu jMenu14;
    private javax.swing.JMenu jMenu15;
    private javax.swing.JMenu jMenu2;
    public static javax.swing.JMenu jMenu3;
    public static javax.swing.JMenu jMenu4;
    private javax.swing.JMenu jMenu5;
    private javax.swing.JMenu jMenu6;
    private javax.swing.JMenu jMenu7;
    private javax.swing.JMenu jMenu8;
    private javax.swing.JMenu jMenu9;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JTextField layoutAttributeName_X_Text;
    private javax.swing.JTextField layoutAttributeName_Y_Text;
    private javax.swing.JMenuItem linkActivitiesButton;
    private javax.swing.JList<String> listWorkingTrials;
    private javax.swing.JMenuItem mergeGraphButtom;
    private javax.swing.JTextField newVertexLabelTextBox;
    public static javax.swing.JCheckBoxMenuItem removeOutliersButton;
    private javax.swing.JButton searchVertexIDButton;
    private javax.swing.JDialog searchVertexIDDialogBox;
    private javax.swing.JDialog selectWorkingTrialsDialogBox;
    private static javax.swing.JComboBox<String> selectedTrialComboBox;
    private javax.swing.JButton setNewLabelCancelButton;
    private javax.swing.JButton setNewLabelConfirmButton;
    private javax.swing.JDialog setNewLabelDialogBox;
    public static javax.swing.JTextField simEpsilon;
    public static javax.swing.JTextField simStdInc;
    public static javax.swing.JTextField simStdSize;
    private javax.swing.JCheckBoxMenuItem similarityConsiderNeighborsButton;
    public static javax.swing.JCheckBoxMenuItem temporalDaysButton;
    public static javax.swing.JCheckBoxMenuItem temporalHoursButton;
    public static javax.swing.JCheckBoxMenuItem temporalMicrosecondsButton;
    public static javax.swing.JCheckBoxMenuItem temporalMillisecondsButton;
    public static javax.swing.JCheckBoxMenuItem temporalMinutesButton;
    public static javax.swing.JCheckBoxMenuItem temporalNanosecondsButton;
    public static javax.swing.JCheckBoxMenuItem temporalSecondsButton;
    public static javax.swing.JCheckBoxMenuItem temporalWeeksButton;
    private javax.swing.JDialog tooltipDialogBox;
    private javax.swing.JTextPane tooltipWindowTextPane;
    private javax.swing.JCheckBoxMenuItem updateErrorButton;
    private javax.swing.JCheckBoxMenuItem verifyWithinClusterButton;
    private javax.swing.JCheckBoxMenuItem vertexBorderByGraphButton;
    public static javax.swing.JList vertexFilterList;
    private javax.swing.JTextField vertexIDTextField;
    private javax.swing.JTextField vertexShapeBasedOnAttribute;
    public static javax.swing.JComboBox<String> vertexShapeComboBox;
    private javax.swing.JRadioButtonMenuItem vertexStrokeDefault;
    private javax.swing.JRadioButtonMenuItem vertexStrokeGraphFile;
    private javax.swing.JRadioButtonMenuItem vertexStrokeLabel;
    private javax.swing.JRadioButtonMenuItem vertexStrokeOutlier;
    // End of variables declaration//GEN-END:variables
} public class SimilarityConfig {
    
    private Map<String, AttributeErrorMargin> restrictionList; // List of errors for each specified attribute, including their weights. Otherwise the default weight is 1
    private String defaultError; // Default value error if not specified anywhere
    private float defaultWeight; // Default weight if not specified anywhere
    private float similarityThreshold; // Used to define if two vertices are similar. The similarity result will need to be highter than the similarityThreshold
    private AttributeErrorMargin epsilon; // Auxiliary variable used in this class
    private Vocabulary vocabulary; // The vocabulary that contains string synonyms
    
    public Map<String, AttributeErrorMargin> getRestrictionList() {
        return restrictionList;
    }
    
    public float getSimilarityThreshold() {
        return similarityThreshold;
    }
    
    public String getDefaultError() {
        return defaultError;
    }
    
    public float getDefaultWeight() {
        return defaultWeight;
    }
    
    public Map<String, String> getVocabulary() {
        return vocabulary.getVocabulary();
    }
    
    public Vocabulary returnVocabulary() {
        return vocabulary;
    }
    
    public void readFile(File fXmlFile) {
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);
            doc.getDocumentElement().normalize();
            NodeList nList;
            
            restrictionList = new HashMap<>();
            vocabulary = new Vocabulary();
            defaultError = "0";
            
            epsilon = new AttributeErrorMargin(VariableNames.CollapsedVertexActivityAttribute, "", 0);
            restrictionList.put(VariableNames.CollapsedVertexActivityAttribute, epsilon);
            epsilon = new AttributeErrorMargin(VariableNames.CollapsedVertexAgentAttribute, "", 0);
            restrictionList.put(VariableNames.CollapsedVertexAgentAttribute, epsilon);
            epsilon = new AttributeErrorMargin(VariableNames.CollapsedVertexEntityAttribute, "", 0);
            restrictionList.put(VariableNames.CollapsedVertexEntityAttribute, epsilon);
            epsilon = new AttributeErrorMargin(VariableNames.similarityAttribute, "", 0);
            restrictionList.put(VariableNames.similarityAttribute, epsilon);
            epsilon = new AttributeErrorMargin(VariableNames.GraphFile, "", 0);
            restrictionList.put(VariableNames.GraphFile, epsilon);
                    
            nList = doc.getElementsByTagName("default_error");
            defaultError = nList.item(0).getTextContent();
            nList = doc.getElementsByTagName("default_weight");
            defaultWeight = Float.parseFloat(nList.item(0).getTextContent());
            nList = doc.getElementsByTagName("similarityThreshold");
            similarityThreshold = Float.parseFloat(nList.item(0).getTextContent());
            
            nList = doc.getElementsByTagName("attributeErrorList");
            for (int temp = 0; temp < nList.getLength(); temp++) {
                Node nNode = nList.item(temp);
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    String name;
                    String value;
                    float weight;
                    Element eElement = (Element) nNode;
                    name = eElement.getElementsByTagName("name").item(0).getTextContent();
                    value = eElement.getElementsByTagName("value").item(0).getTextContent();
                    weight = Float.parseFloat(eElement.getElementsByTagName("weight").item(0).getTextContent());
                    epsilon = new AttributeErrorMargin(name, value, weight);
                    restrictionList.put(name, epsilon);
                    
                    // Populate the Vocabulary
                    // Detection: Check if there is a comma since it separates the words
                    if(value.contains(",")) {
                        // So we have a list of strings for the vocabulary
                        vocabulary.addVocabulary(value);
                    }
                }
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
} public class VariableNames {
    public static String CollapsedVertexAgentAttribute = "Agents";
    public static String CollapsedVertexActivityAttribute = "Activities";
    public static String CollapsedVertexEntityAttribute = "Entities";
    public static String GraphFile = "GraphFile";
    public static String FilterAllEdges = "All Edges";
    public static String ChronologicalEdge = "Chronological";
    public static String FilterAllVertices = "(All Vertices)";
    public static String MouseModePicking = "Picking";
    public static String MouseModeTransforming = "Transforming";
    public static String EdgeModeQuadCurve = "QuadCurve";
    public static String EdgeModeLine = "Line";
    public static String FontConfiguration = "<html><font face=\"verdana\", size=\"6\", color=\"yellow\">";
    public static String SummarizedLabelString = " (Summarized)";
    public static String DefaultVertexPainter = "Prov";
    public static String EdgeTooltipFontConfiguration = "<html><font size=\"4\">";
    public static String UnknownValue = "Unknown";
    public static String time = "Timestamp";
    public static String edgeHiddenAttribute = "Hide";
    public static String vertexNewSource = "NewSource";
    public static String vertexNewTarget = "NewTarget";
    public static String similarityAttribute = "Similarity";
    
    public static String layout_timeline = "Timeline";
    public static String layout_circle = "Circle";
    public static String layout_hierarchy = "Hierarchy";
    public static String layout_provcircle2 = "ProvCircle2";
    public static String layout_list = "List";
    public static String layout_Two_Dimensional = "Two Dimensional";
    public static String layout_ISOM = "ISOM";
    public static String layout_provcircle = "ProvCircle";
    public static String layout_kk = "KK";
    public static String layout_spring = "Spring";
    public static String layout_temporal = "Temporal";
    public static String layout_fr2 = "FR2";
    public static String layout_dag = "DAG";
    public static String layout_One_Dimensional = "One Dimensional";
    public static String layout_One_Dimensional_2 = "One Dimensional (Variant)";
    public static String layout_timeline_graphs = "Timeline (Graphs)";
    public static String layout_spatial = "Spatial";
    public static String layout_fr = "FR";
    public static String layout_test = "Test";
    
    public static Color AgentColor = new Color(254, 211, 127);
    public static Color ActivityColor = new Color(159, 177, 252);
    public static Color EntityColor = new Color(255, 252, 135);
    public static String MergedEdgeAttribute = "Merged_Edge";
    public static String Frequency = "Frequency";
    public static String MarkovIn = "MarkovIn";
    public static String MarkovOut = "MarkovOut";
    public static String label = "Label";
    public static String MarkovLayout = "Markov Layout";
    public static String MarkovInLayout = "MarkovInLayout";
    public static String MarkovOutLayout = "MarkovOutLayout";
} public class UnityReader extends XMLReader {

    boolean isProvenanceGraph;
    boolean hackLabelPathAndFile = false;
    boolean hackSplitFilePath = false;

    public UnityReader(File fXmlFile) throws URISyntaxException, IOException {
        super(fXmlFile);
    }

    /**
     * Method to read the file
     */
    @Override
    public void readFile() {
        readHeader();
    }
    
    /**
     * Method to read the attributes from the graph object (can be either an
     * edge or a vertex)
     *
     * @param element
     * @param attributes
     */
    public void readAttribute(Element element, Map<String, GraphAttribute> attributes) {
        NodeList attributesList = element.getElementsByTagName("attributes");
        if (attributesList.getLength() > 0) {
            Node nNode = attributesList.item(0);
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                NodeList aList = ((Element) nNode).getElementsByTagName("attribute");
                boolean hasGraphFile = false;
                for (int i = 0; i < aList.getLength(); i++) {
                    Node nAttributeNode = aList.item(i);
                    Element eElement = (Element) nAttributeNode;
                    GraphAttribute att;
                    if (eElement.getElementsByTagName("name").item(0).getTextContent().equalsIgnoreCase("GraphFile")) {
                        hasGraphFile = true;
                    }
                    if (hackSplitFilePath) {
                        if (eElement.getElementsByTagName("name").item(0).getTextContent().equalsIgnoreCase("Path")) {
                            Collection<GraphAttribute> mPath = new ArrayList<>();
                            String[] paths = eElement.getElementsByTagName("value").item(0).getTextContent().split("/");
                            int j = 0;
                            for (String s : paths) {
                                mPath.add(new GraphAttribute("Path_#" + j, s, file.getName()));
                                j++;
                            }
                            for (GraphAttribute ga : mPath) {
                                attributes.put(ga.getName(), ga);
                            }
                        }
                    }
                    
                    if (eElement.getElementsByTagName("originalValues").item(0) != null) {
                        Node valuesList = eElement.getElementsByTagName("originalValues").item(0);
                        Element e = (Element) valuesList;
                        Map<String, String> oValues = new HashMap<>();
                        for (int j = 0; j < Integer.valueOf(eElement.getElementsByTagName("quantity").item(0).getTextContent()); j++) {
                            if(e.getElementsByTagName("originalValue").item(j) != null) {
                                String ov = e.getElementsByTagName("originalValue").item(j).getTextContent();
                                String[] v = ov.split(", ");
                                if(v.length >= 2)
                                    oValues.put(v[0], v[1]);
                                else if (v.length != 0)
                                    oValues.put(v[0], "-");
                                else
                                    oValues.put("-", "-");
                            }
                        }
                        att = new GraphAttribute(eElement.getElementsByTagName("name").item(0).getTextContent(),
                                eElement.getElementsByTagName("value").item(0).getTextContent(),
                                eElement.getElementsByTagName("min").item(0).getTextContent(),
                                eElement.getElementsByTagName("max").item(0).getTextContent(), oValues);
                    } else {
                        att = new GraphAttribute(eElement.getElementsByTagName("name").item(0).getTextContent(),
                                eElement.getElementsByTagName("value").item(0).getTextContent(), file.getName());
                    }
                    attributes.put(att.getName(), att);
                }
                if (!hasGraphFile) {
                    GraphAttribute att = new GraphAttribute(VariableNames.GraphFile, file.getName(), file.getName());
                    attributes.put(att.getName(), att);
                }
            }
        } else {
            GraphAttribute att = new GraphAttribute(VariableNames.GraphFile, file.getName(), file.getName());
            attributes.put(att.getName(), att);
        }
    }

    /**
     * Method that reads the file Header and then the vertex and edge lists (Graph)
     */
    public void readHeader() {
        isProvenanceGraph = true;
        NodeList nList;
        nList = doc.getElementsByTagName("edgesRightToLeft");
        if (nList != null && nList.getLength() > 0 && !nList.item(0).getTextContent().equalsIgnoreCase("")) {
            isProvenanceGraph = Boolean.parseBoolean(nList.item(0).getTextContent());
        }
        NodeList vList = doc.getElementsByTagName("vertex");
        NodeList eList = doc.getElementsByTagName("edge");
        readGraph(vList, eList, nodes, edges);
    }

    public void readGraph(NodeList vList, NodeList eList, Map<String, Vertex> vertices, Collection<Edge> edges) {
        readVertices(vList, vertices);
        readEdges(eList, edges, vertices);
    }

    /**
     * Method to read a vertex
     * @param nList
     * @param vertices
     */
    public void readVertices(NodeList nList, Map<String, Vertex> vertices) {
        for (int temp = 0; temp < nList.getLength(); temp++) {
            Node nNode = nList.item(temp);
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                Element eElement = (Element) nNode;
                String id = eElement.getElementsByTagName("ID").item(0).getTextContent();
                String type = eElement.getElementsByTagName("type").item(0).getTextContent();
                String label = eElement.getElementsByTagName("label").item(0).getTextContent();
                String date = eElement.getElementsByTagName("date").item(0).getTextContent();

                Map<String, GraphAttribute> attributes = new HashMap<>();
                readAttribute(eElement, attributes);

                GraphAttribute path = null;
                GraphAttribute fileName = null;
                if (hackLabelPathAndFile) {
                    String[] folders = label.split("/");
                    String filePath = label.replace(folders[folders.length - 1], "");
                    String fn = folders[folders.length - 1];
                    path = new GraphAttribute("Path", filePath, file.getName());
                    fileName = new GraphAttribute("FileName", fn, file.getName());
                    if (type.equalsIgnoreCase("Entity")) {
                        label = fn;
                    }
                    if (type.equalsIgnoreCase("Activity")) {
                        label = label.split(":")[0];
                    }
                }
                Vertex node;
                if (type.equalsIgnoreCase("Activity")) {
                    node = new ActivityVertex(id, label, date);
                } else if (type.equalsIgnoreCase("Entity")) {
                    node = new EntityVertex(id, label, date);
                } else if (type.equalsIgnoreCase("Agent")) {
                    node = new AgentVertex(id, label, date);
                } else {
                    node = new GraphVertex(id, label, date);
                }
//                readAttribute(eElement, node);
                if (hackLabelPathAndFile) {
                    if (node instanceof EntityVertex) {
                        node.addAttribute(path);
                        node.addAttribute(fileName);
                    }
                }
                node.addAllAttributes(attributes);
//                System.out.println("Reading vertex: " + id);
                if (node instanceof GraphVertex) {
//                    System.out.println("Its a GraphVertex!");
                    NodeList graph = eElement.getElementsByTagName("Graph");
                    Node gNode = graph.item(0);
                    Element graphElement = (Element) gNode;
                    NodeList collapsedVertices = graphElement.getElementsByTagName("collapsedvertices");
                    NodeList collapsedEdged = graphElement.getElementsByTagName("collapsededges");
                    Node cVertexNode = collapsedVertices.item(0);
                    Node cEdgeNode = collapsedEdged.item(collapsedEdged.getLength() - 1);
                    if (cVertexNode.getNodeType() == Node.ELEMENT_NODE) {
                        Element cVertexElement = (Element) cVertexNode;
                        Element cEdgeElement = (Element) cEdgeNode;
//                        NodeList vList = cVertexElement.getElementsByTagName("collapsedvertex");
//                        NodeList eList = cEdgeElement.getElementsByTagName("collapsededge");
                        NodeList vList = cVertexElement.getChildNodes();
                        NodeList eList = cEdgeElement.getChildNodes();
                        Map<String, Vertex> cv = new HashMap<>();
                        Collection<Edge> ce = new ArrayList<>();
                        readGraph(vList, eList, cv, ce);
                        ((GraphVertex) node).setClusterGraph(ce, cv);
                    }
//                    System.out.println("Finished Reading GraphVertex!");
                }
                vertices.put(node.getID(), node);
            }
        }
    }

    /**
     * Method to read an edge
     */
    public void readEdges(NodeList nList, Collection<Edge> edges, Map<String, Vertex> vertices) {
//        System.out.println("Edge list size: " + nList.getLength());
        for (int temp = 0; temp < nList.getLength(); temp++) {
            Node nNode = nList.item(temp);
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                Element eElement = (Element) nNode;
                String id = eElement.getElementsByTagName("ID").item(0).getTextContent();
                String type = eElement.getElementsByTagName("type").item(0).getTextContent();
                String label = eElement.getElementsByTagName("label").item(0).getTextContent();
                String value = eElement.getElementsByTagName("value").item(0).getTextContent();
                String source = eElement.getElementsByTagName("sourceID").item(0).getTextContent();
                String target = eElement.getElementsByTagName("targetID").item(0).getTextContent();
                Edge edge;
                Map<String, GraphAttribute> attributes = new HashMap<>();
                readAttribute(eElement, attributes);
                String newSource = "Null";
                String newTarget = "Null";
                if (attributes.containsKey(VariableNames.vertexNewSource)) {
                    newSource = attributes.get(VariableNames.vertexNewSource).getValue();
                }
                if (attributes.containsKey(VariableNames.vertexNewTarget)) {
                    newTarget = attributes.get(VariableNames.vertexNewTarget).getValue();
                }
                if ((vertices.containsKey(source) || vertices.containsKey(newSource)) && (vertices.containsKey(target) || vertices.containsKey(newTarget))) {
                    Vertex vs;
                    Vertex vt;
                    vs = findNode(source, vertices);
                    vt = findNode(target, vertices);

                    if (isProvenanceGraph) {
                        edge = new Edge(id, type, label, value, vt, vs);
                    }
                    else {
                        edge = new Edge(id, type, label, value, vs, vt);
                    }
                    edge.addAllAttributes(attributes);
                    edges.add(edge);
                } else {
                    System.out.println("Not possible!");
                    System.out.println("ID: " + id);
                    System.out.println("source: " + source);
                    System.out.println("target: " + target);
                    System.out.println("NewSource: " + newSource);
                    System.out.println("NewTarget: " + newTarget);
                }
            }
        }
    }

    /**
     * Method to find the original Vertex 
     * @param ID is the vertex ID we are looking for
     * @param vertices is the map that contains the vertices with the Key being the vertex's ID
     * @return the vertex
     */
    private Vertex findNode(String ID, Map<String, Vertex> vertices) {
        if (vertices.containsKey(ID)) {
            return vertices.get(ID);
        } else {
            for(String ids : vertices.keySet()) {
                if(ids.contains(ID)) { // It might have. Lets break it down to make sure it has the Source
                    String currentID = ids.replace("[", ""); // Remove the GraphVertex ID brankets
                    currentID = currentID.replace("]", "");
                    currentID = currentID.replace(" ", ""); // Remove spaces
                    String[] subIDs = currentID.split(","); // Split each ID that composes the GraphVertex
                    for(String i : subIDs) { // Lets check if each individual ID is the original Source
                        if(i.equalsIgnoreCase(ID)) { // If true then the original vertex is inside this GraphVertex
                            GraphVertex v = (GraphVertex) vertices.get(ids); // We got the GraphVertex, now need to explore it
                            return findNode(v.clusterGraph, ID);
                        }
                    }
                }
            }
        }
        return null;
    }
    
    /**
     * Method to find the vertex inside a GraphVertex
     * @param clusterGraph is the GraphVertex's clustergraph
     * @param ID is the vertex's ID that we are looking for
     * @return the vertex
     */
    private Vertex findNode(Graph clusterGraph, String ID) {
        Vertex found = null;
        for(Object v : clusterGraph.getVertices()) {
            if(((Vertex)v).getID().equalsIgnoreCase(ID))
                return (Vertex) v;
            else if(v instanceof GraphVertex)
                found = findNode(((GraphVertex)v).clusterGraph, ID);
        }
        return found;
    }
    
    /**
     * Method that returns 
     * @param id
     * @return 
     */
    public Vertex getNewPointer(String id) {
        return nodes.get(id);
    }
} public class Variables extends Object {

    public String mergingWithGraphPath;
    public String originalGraphPath = "demo";
    public Markov markov = new Markov();

//    public static String demo = File.separator + "Graph" + File.separator + "Merge_Test.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "AngryBots_3_Merge.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "Angry_Robots.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "Graph_to_Merge_01.xml";
//    public String configDemo = File.separator + "Config" + File.separator + "Angry_Robots_config.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "Angry_Robots_paperCIG.xml";

    public static String demo = "Graph" + File.separator + "Car_Tutorial.xml";   
    public String configDemo = "Config" + File.separator + "Car_Tutorial_config.xml";
//    
//    public static String demo = File.separator + "Graph" + File.separator + "MorphWing2.xml";
//    public String configDemo = "Config" + File.separator + "Morph_config.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "rio_city_bus_example.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "bus_linha5.xml";
//    public String configDemo = File.separator + "Config" + File.separator + "rio_de_janeiro_cidade_config.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "input.xml";
//    public String configDemo = File.separator + "Config" + File.separator + "config.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "Test" + File.separator + "prov-dm-example1.prov-asn";
//    public static String demo = File.separator + "Graph" + File.separator + "test" + File.separator + "example-blog1.provn";
//    public static String demo = File.separator + "Graph" + File.separator + "workflow_trial_0.xml";
//    public String configDemo = File.separator + "Config" + File.separator + "PROV_config.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "2D_Provenance.xml";
//    public String configDemo = File.separator + "Config" + File.separator + "2D_Tower_Defense_config.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "map.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "graph_features_example.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "graph1.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "graph2.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "Gradient.xml";
//    public String configDemo = File.separator + "Config" + File.separator + "map_config.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "program_prov_example.xml";
//    public String configDemo = File.separator + "Config" + File.separator + "prog_example_config.xml";  
//    public static String demo = File.separator + "Graph" + File.separator + "Car_Tutorial.xml";
//    public String configDemo = File.separator + "Config" + File.separator + "Noise_config.xml";
//    public static String demo = File.separator + "Graph" + File.separator + "bash-count.xml"; 
//    public String configDemo = File.separator + "Config" + File.separator + "Reprozip_config.xml";
    public GuiBackground guiBackground = new GuiBackground();
    public VisualizationViewer<Object, Edge> view;
    public Layout<Object, Edge> layout;
    public GraphCollapser gCollapser;
    public DirectedGraph<Object, Edge> graph;
    public DirectedGraph<Object, Edge> collapsedGraph;
    public Config config = new Config();
    public boolean filterCredits = false;
    public boolean initConfig = false;
    public final Set exclusions = new HashSet();
    public boolean initLayout = true;
    public Filters filter = new Filters();
    public boolean prologIsInitialized = false;
    public File file;
    public DefaultModalGraphMouse mouse = new DefaultModalGraphMouse();
    public Collapser collapser = new Collapser();
    public boolean initialGraph = true;
    public SimilarityConfig mergeConfig;
    public SimilarityConfig similarityConfig;
    public boolean considerOnlyNeighborsSimilarityCollapse = true;

    public String selectedTimeScale = config.timeScale;
    public boolean doDerivate = false;
    public boolean removeDerivateOutliers = false;
    public boolean changedOutliersOption = false;

    public ImproveJUNGPerformance jungPerformance = new ImproveJUNGPerformance();
    public String layout_attribute_X = "Timestamp";
    public String layout_attribute_Y = "Timestamp";
    public int numberOfGraphs = 1;
    public Collection<String> graphNames;
    public boolean highlightVertexOutliers = true;
    public boolean vertexBorderByGraphs = false;
    public boolean vertexBorderByLabel = false;
    public ThresholdValues outliersThresholds;
    public boolean allowVariableLayout = false;
    public int edgeAlpha = 25;

    public Stack<StackElementUndoDeletion> undoDeletion = new Stack();

    public boolean allowMergeUndo = false;
    public boolean isEdgeColorByMarkovIn = false;
    public boolean isEdgeColorByMarkovOut = false;
    public boolean isEdgeColorByGraphs = false;
    public boolean isEdgeColorByType = false;
    public boolean isEdgeColorByValue = true;
    
    public boolean isEdgeStrokeByValue = true;
    public boolean isEdgeStrokeByGraph = false;
    public boolean isEdgeStrokeByMarkovIn = false;
    public boolean isEdgeStrokeByMarkovOut = false;
    public boolean isEdgeStrokeDefault = false;

    /**
     * Method that updates the number of graphs that comprises the current graph
     * Should be called everytime after a graph is loaded: File Open / Merge
     * Graph
     */
    public void updateNumberOfGraphs() {
        graphNames = Utils.DetectAllPossibleValuesFromAttribute(graph.getVertices(), VariableNames.GraphFile);
        numberOfGraphs = graphNames.size();
        this.config.detectGraphVisualizationModes(this.graphNames);
        this.config.addGraphFileVertexFilter(this.graphNames);
    }

    /**
     * Return the max value between 2 values
     *
     * @param type (String) Edge type to be analyzed
     * @param value (Float) Current max value
     * @param edge (Edge) Second value is extracted from this edge, if the
     * influence type is the same
     * @return max value between value and edge.getValue
     */
    public float CompareMax(float value, Edge edge) {
        value = Math.max(value, edge.getValue());
        return value;
    }

    /**
     * Return the min value between 2 values
     *
     * @param type (String) Edge type to be analyzed
     * @param value (Float) Current max value
     * @param edge (Edge) Second value is extracted from this edge, if the
     * influence type is the same
     * @return max value between value and edge.getValue
     */
    public float CompareMin(float value, Edge edge) {
        value = Math.min(value, edge.getValue());
        return value;
    }

    /**
     * Return the added value between 2 values
     *
     * @param type (String) Edge type to be analyzed
     * @param value (Float[]) Current value
     * @param edge (Edge) Second value is extracted from this edge, if the
     * influence type is the same
     * @return added value between value and edge.getValue
     */
    public float Add(float value, Edge edge) {
        value += Math.abs(edge.getValue());
        return value;
    }

    /**
     * Return the average value
     *
     * @param value (Float[]) Current value and counter
     * @param average (Boolean) To compute the average or not
     * @return average value between value and edge.getValue
     */
    public float[] Average(float[] value, String average) {
        if (average.equalsIgnoreCase("MEAN")) {
            value[0] = value[0] / (value[1] - 1);
        }
        return value;
    }

    /**
     * Return the new value
     *
     * @param etype
     * @param type (String) Edge type to be analyzed
     * @param edge (Edge) Second value is extracted from this edge, if the
     * influence type is the same
     * @param max (Boolean) To compute the max between values or to add values
     * @return value, according to the operation, between value and
     * edge.getValue
     */
    public EdgeType ComputeValue(EdgeType etype, Edge edge) {
        etype.max = CompareMax(etype.max, edge);
        etype.min = CompareMin(etype.min, edge);
        etype.count++;
        etype.total = Add(etype.total, edge);
        return etype;
    }

    /**
     * Find max values for each edge type. Used for edge width.
     *
     */
    public void ComputeEdgeTypeValues() {
        Collection<Edge> edges = this.graph.getEdges();
        for (Edge edge : edges) {
            if (this.config.edgeTypes.containsKey(edge.getLabel())) {
                EdgeType et = this.config.edgeTypes.get(edge.getLabel());
                ComputeValue(et, edge);
            } else if (this.config.edgeTypes.containsKey(edge.getType())) {
                EdgeType et = this.config.edgeTypes.get(edge.getType());
                ComputeValue(et, edge);
            }
        }
        GraphFrame.edgeFilterList.setSelectedIndex(0);
    }

    public void newLayout(String layout) {
        DirectedGraph<Object, Edge> displayGraph;
        if (this.layout != null && this.allowVariableLayout) {
            displayGraph = (DirectedGraph<Object, Edge>) this.layout.getGraph();
        } else {
            displayGraph = this.graph;
        }
        if (layout.equalsIgnoreCase(VariableNames.layout_circle)) {
            this.layout = new CircleLayout<>(displayGraph);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_fr)) {
            this.layout = new FRLayout<>(displayGraph);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_fr2)) {
            this.layout = new FRLayout2<>(displayGraph);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_ISOM)) {
            this.layout = new ISOMLayout<>(displayGraph);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_kk)) {
            this.layout = new KKLayout<>(displayGraph);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_spring)) {
            this.layout = new SpringLayout<>(displayGraph);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_dag)) {
            this.layout = new DAGLayout<>(displayGraph);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_temporal)) {
            this.layout = new Temporal_Layout<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_spatial)) {
            this.layout = new Spatial_Layout<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_timeline)) {
            this.layout = new Timeline_Layout<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_timeline_graphs)) {
            this.layout = new TimelineGraphs_Layout<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_One_Dimensional)) {
            this.layout = new OneDimensional_Layout<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_One_Dimensional_2)) {
            this.layout = new OneDimensional_Layout_Ordered<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_Two_Dimensional)) {
            this.layout = new TwoDimensional_Layout<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_provcircle)) {
            this.layout = new ProvCircleLayout<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_provcircle2)) {
            this.layout = new ProvCircleLayout2<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_list)) {
            this.layout = new ListLayout<>(displayGraph, this);
        } else if (layout.equalsIgnoreCase(VariableNames.layout_hierarchy)) {
            this.layout = new Hierarchy_Layout_2<>(displayGraph, this);
        } else {
            this.layout = new Timeline_Layout<>(displayGraph, this);
        }
    }

    public void initGraphCollapser() {
        gCollapser = new GraphCollapser(this.graph, this.config.considerEdgeLabelForMerge);
    }

    /**
     * Method to set the parameters for Highlighting the outliers during a
     * display mode The actual highlighting happnes at GuiFunctions Stroke
     * method
     *
     * @param attribute is the attribute that we are using to display the values
     */
    public void highlightOutliers(String attribute) {
        if (this.highlightVertexOutliers) {
            ArrayList<Double> values = GraphUtils.getAttributeValuesFromVertices(this.graph, attribute);
            if (!values.isEmpty() && values.size() > 5) {
                this.outliersThresholds = Utils.calculateOutliers(values, attribute);
            } else {
                this.outliersThresholds = new ThresholdValues("", 0, 0);
                this.highlightVertexOutliers = false;
            }
        }
    }
} public abstract class InputReader {
    Map<String, Vertex> nodes;
    Collection<Edge> edges;
    File file;
    /**
     * Return edges
     *
     * @return
     */
    public Collection<Edge> getEdges() {
        return edges;
    }

    /**
     * Return vertices
     *
     * @return
     */
    public Collection<Vertex> getNodes() {
        return nodes.values();
    }

    public InputReader(File f){
        if (! f.canRead()) {
            throw new IllegalArgumentException("Invalid file: " + f);
        }
        file = f;
        nodes = new HashMap<>();
        edges = new ArrayList<>();
    }
    
//    public void addEdge(String id, String influence, String type, String value, String label, Map<String, Attribute> attributes, String target, String source)
//    {
//        Edge edge = new Edge(id, influence, type, value, label, attributes, nodes.get(target), nodes.get(source));
//        edges.add(edge);
//    }
    
    /**
     *  Method to create and add an edge
     * @param id
     * @param type
     * @param label
     * @param value
     * @param target
     * @param source 
     */
    public void addEdge(String id, String type, String label, String value, String target, String source)
    {
        //AddEdge(id, type, label, value, target, source);
        Edge edge = new Edge(id, type, label, value, nodes.get(target), nodes.get(source));
        edges.add(edge);
    }
    /**
     * Method to add an edge
     * @param edge: the edge to be added
     */
    public void addEdge(Edge edge)
    {
        edges.add(edge);
    }
    
    /**
     * Method to add Vertex to the Map
     * @param node 
     */
    public void addNode(Vertex node)
    {
        nodes.put(node.getID(), node);
    }
    
    /**
     * Abstract method to read a XML file depending on the XML-Schema
     */
    public abstract void readFile()throws URISyntaxException, IOException;

} public class PROVNReader extends InputReader {

    int edgeOptionalID = 0;

    public PROVNReader(File f) throws URISyntaxException, IOException {
        super(f);
    }

    public void readFile() throws URISyntaxException, IOException {
        BufferedReader br = new BufferedReader(new FileReader(file));
        try {
            String line = br.readLine();

//            Vertex node = new AgentVertex("Unknown Agent", "Unknown Agent", "");
//            addNode(node);
//            node = new ActivityVertex("Unknown Activity", "Unknown Activity", "");
//            addNode(node);
//            node = new EntityVertex("Unknown Entity", "Unknown Entity", "");
//            addNode(node);

            while (line != null) {
                Read(line);
                line = br.readLine();
            }
        } finally {
            br.close();
        }

    }

    public void Read(String line) {
        String[] elements;
        String[] statement;
        String[] attributes;
        String[] optionalAttributes = null;

        line = line.replace(")", "");
        line = line.replace(" ", "");
        line = line.replace("\t", "");
        line = line.replace("]", "");
//        line = line.replace("'", "");
        elements = line.split("\\(");
        if (elements.length > 1) {
            statement = elements[1].split("\\[");
            attributes = statement[0].split(",");

            if (statement.length > 1) {
                optionalAttributes = statement[1].split(",");
            }

            if (elements[0].contains("entity")) {
                readEntity(attributes, optionalAttributes);
            }
            if (elements[0].contains("activity")) {
                readActivity(attributes, optionalAttributes);
            }
            if (elements[0].contains("agent")) {
                readAgent(attributes, optionalAttributes);
            }
            if (elements[0].contains("wasGeneratedBy")) {
                readGeneration(attributes, optionalAttributes);
            }
            if (elements[0].contains("used")) {
                readUsage(attributes, optionalAttributes);
            }
            if (elements[0].contains("wasInformedBy")) {
                readCommunication(attributes, optionalAttributes);
            }
            if (elements[0].contains("wasStartedBy")) {
                readStart(attributes, optionalAttributes);
            }
            if (elements[0].contains("wasEndedBy")) {
                readEnd(attributes, optionalAttributes);
            }
            if (elements[0].contains("wasInvalidatedBy")) {
                readInvalidation(attributes, optionalAttributes);
            }
            if (elements[0].contains("wasDerivedFrom")) { //Revision, Quotation, Primary Source from PROV-N
                readDerivation(attributes, optionalAttributes);
            }
//            if(elements[0].contains("wasDerivedFrom")){ //Revision from PROV-N
//                readRevision(attributes, optionalAttributes);
//            }
//            if(elements[0].contains("wasDerivedFrom")){ //Quotation from PROV-N
//                readQuotation(attributes, optionalAttributes);
//            }
//            if(elements[0].contains("wasDerivedFrom")){ //Primary Source from PROV-N
//                readPrimarySource(attributes, optionalAttributes);
//            }
            if (elements[0].contains("wasAttributedTo")) {
                readAttribution(attributes, optionalAttributes);
            }
            if (elements[0].contains("wasAssociatedWith")) {
                readAssociation(attributes, optionalAttributes);
            }
            if (elements[0].contains("actedOnBehalfOf")) {
                readDelegation(attributes, optionalAttributes);
            }
            if (elements[0].contains("wasInfluencedBy")) {
                readInfluence(attributes, optionalAttributes);
            }
        }
    }

    public void readEntity(String[] attributes, String[] optionalAttributes) {
        Vertex node;
        String id = attributes[0];
        node = new EntityVertex(id, id, "");
        readAttributes(node, optionalAttributes);
        addNode(node);
    }

    public void readActivity(String[] attributes, String[] optionalAttributes) {
        Vertex node;
        String id = attributes[0];
        node = new ActivityVertex(id, id, "");
        if (attributes.length > 1) {
            String startTime = attributes[1];

            GraphAttribute optAtt = new GraphAttribute("startTime", startTime, file.getName());
            node.addAttribute(optAtt);
            GraphAttribute time = new GraphAttribute("Timestamp", startTime, file.getName());
            node.addAttribute(time);
//            node.setTime(startTime);
        }
        if (attributes.length > 2) {
            String endTime = attributes[2];
            GraphAttribute optAtt = new GraphAttribute("endTime", endTime, file.getName());
            node.addAttribute(optAtt);
        }
        readAttributes(node, optionalAttributes);
        addNode(node);
    }

    public void readAgent(String[] attributes, String[] optionalAttributes) {
        Vertex node;
        String id = attributes[0];
        node = new AgentVertex(id, id, "");
        readAttributes(node, optionalAttributes);
        addNode(node);
    }

    public void readGeneration(String[] attributes, String[] optionalAttributes) {
        Edge edge;
        String id = null;
        String entity = "-";
        String activity = "-";
        String time;

        if (attributes.length == 3) {
            id = getEdgeID(attributes[0], id);
            entity = getEdge1stAttribute(attributes[0], entity);
            activity = attributes[1];
            time = attributes[2];
        } else {
            id = getEdgeID(attributes[0], id);
            entity = getEdge1stAttribute(attributes[0], entity);
            time = "";
        }
        activity = testPointer(activity, "Activity");
        entity = testPointer(entity, "Entity");

        edge = new Edge(id, "wasGeneratedBy", "-", "-", nodes.get(activity), nodes.get(entity));
        GraphAttribute optAtt = new GraphAttribute("time", time, file.getName());
        edge.addAttribute(optAtt);

        readAttributes(edge, optionalAttributes);
        addEdge(edge);

    }

    public void readUsage(String[] attributes, String[] optionalAttributes) {
        Edge edge;
        String id = null;
        String activity = "-";
        String entity = "-";
        String time;

        if (attributes.length == 3) {
            id = getEdgeID(attributes[0], id);
            activity = getEdge1stAttribute(attributes[0], activity);
            entity = attributes[1];
            time = attributes[2];
        } else {
            id = getEdgeID(attributes[0], id);
            activity = getEdge1stAttribute(attributes[0], activity);
            time = "-";
        }
        activity = testPointer(activity, "Activity");
        entity = testPointer(entity, "Entity");

        edge = new Edge(id, "used", "-", "-", nodes.get(entity), nodes.get(activity));
        GraphAttribute optAtt = new GraphAttribute("time", time, file.getName());
        edge.addAttribute(optAtt);

        readAttributes(edge, optionalAttributes);
        addEdge(edge);
    }

    public void readCommunication(String[] attributes, String[] optionalAttributes) {
        Edge edge;
        String id = null;
        String informed = "-";
        String informant = "-";

        id = getEdgeID(attributes[0], id);
        informed = getEdge1stAttribute(attributes[0], informed);
        informant = attributes[1];

        informed = testPointer(informed, "Activity");
        informant = testPointer(informant, "Activity");

        edge = new Edge(id, "wasInformedBy", "-", "-", nodes.get(informant), nodes.get(informed));

        readAttributes(edge, optionalAttributes);
        addEdge(edge);
    }

    public void readStart(String[] attributes, String[] optionalAttributes) {
        starterOrEnder(attributes, optionalAttributes, "wasStartedBy");
    }

    public void readEnd(String[] attributes, String[] optionalAttributes) {
        starterOrEnder(attributes, optionalAttributes, "wasEndedBy");
    }

    public void starterOrEnder(String[] attributes, String[] optionalAttributes, String type) {
        Edge edge;
        String id = null;
        String activity = "-";
        String trigger = "-";
        String starterOrEnder = "-";
        String time;
        
        if (attributes.length == 4) {
            id = getEdgeID(attributes[0], id);
            activity = getEdge1stAttribute(attributes[0], activity);
            trigger = attributes[1];
            starterOrEnder = attributes[2];
            time = attributes[3];
        } else {
            id = getEdgeID(attributes[0], id);
            activity = getEdge1stAttribute(attributes[0], activity);
            time = "";
        }

        starterOrEnder = testPointer(starterOrEnder, "Activity");
        activity = testPointer(activity, "Activity");

        edge = new Edge(id, type, "-", "-", nodes.get(starterOrEnder), nodes.get(activity));

        GraphAttribute optAtt = new GraphAttribute("trigger", trigger, file.getName());
        edge.addAttribute(optAtt);

        optAtt = new GraphAttribute(type, starterOrEnder, file.getName());
        edge.addAttribute(optAtt);

        optAtt = new GraphAttribute("time", time, file.getName());
        edge.addAttribute(optAtt);

        readAttributes(edge, optionalAttributes);
        addEdge(edge);
//        }
//        else {
//            edge = new Edge(id + "_trigger", type, "-", "-", nodes.get(trigger), nodes.get(activity));
//            GraphAttribute optAtt = new GraphAttribute("time", time);
//            edge.addAttribute(optAtt);
//
//            readAttributes(edge, optionalAttributes);
//            addEdge(edge);
//            
//            edge = new Edge(id + "_generated", type, "-", "-", nodes.get(starterOrEnder), nodes.get(trigger));
//            optAtt = new GraphAttribute("time", time);
//            edge.addAttribute(optAtt);
//
//            readAttributes(edge, optionalAttributes);
//            addEdge(edge);
//        }
    }

    public void readInvalidation(String[] attributes, String[] optionalAttributes) {
        Edge edge;
        String id = null;
        String entity = "-";
        String activity = "-";
        String time;

        id = getEdgeID(attributes[0], id);
        entity = getEdge1stAttribute(attributes[0], entity);
        activity = attributes[1];
        time = attributes[2];

        entity = testPointer(entity, "Entity");
        activity = testPointer(activity, "Activity");

        edge = new Edge(id, "wasInvalidatedBy", "-", "-", nodes.get(activity), nodes.get(entity));
        GraphAttribute optAtt = new GraphAttribute("time", time, file.getName());
        edge.addAttribute(optAtt);

        readAttributes(edge, optionalAttributes);
        addEdge(edge);
    }

    public void readDerivation(String[] attributes, String[] optionalAttributes) {
        Edge edge;
        String id = null;
        String generatedEntity = null;
        String usedEntity;
        String activity = "-";
        String generation = "-";
        String usage = "-";
        if (attributes.length == 5) {
            id = getEdgeID(attributes[0], id);
            generatedEntity = getEdge1stAttribute(attributes[0], generatedEntity);
            usedEntity = attributes[1];
            activity = attributes[2];
            generation = attributes[3];
            usage = attributes[4];
        } else {
            id = getEdgeID(attributes[0], id);
            generatedEntity = getEdge1stAttribute(attributes[0], generatedEntity);
            usedEntity = attributes[1];
        }

        usedEntity = testPointer(usedEntity, "Entity");
        generatedEntity = testPointer(generatedEntity, "Entity");

        edge = new Edge(id, "wasDerivedFrom", "-", "-", nodes.get(usedEntity), nodes.get(generatedEntity));

        GraphAttribute optAtt = new GraphAttribute("activity", activity, file.getName());
        edge.addAttribute(optAtt);

        optAtt = new GraphAttribute("generation", generation, file.getName());
        edge.addAttribute(optAtt);

        optAtt = new GraphAttribute("usage", usage, file.getName());
        edge.addAttribute(optAtt);

        readAttributes(edge, optionalAttributes);
        addEdge(edge);

//        if (generation != null && !generation.matches("-") && activity != null && !activity.matches("-")) {
//            edge = new Edge(generation, "wasGeneratedBy", "-", "-", nodes.get(activity), nodes.get(generatedEntity));
//            readAttributes(edge, optionalAttributes);
//            addEdge(edge);
//
//            edge = new Edge(usage, "used", "-", "-", nodes.get(usedEntity), nodes.get(activity));
//            readAttributes(edge, optionalAttributes);
//            addEdge(edge);
//        }
    }

    public void readRevision(String[] attributes, String[] optionalAttributes) {
        readGeneration(attributes, optionalAttributes);
    }

    public void readQuotation(String[] attributes, String[] optionalAttributes) {
        readGeneration(attributes, optionalAttributes);
    }

    public void readPrimarySource(String[] attributes, String[] optionalAttributes) {
        readGeneration(attributes, optionalAttributes);
    }

    public void readAttribution(String[] attributes, String[] optionalAttributes) {
        Edge edge;
        String id = null;
        String entity = "-";
        String agent;

        id = getEdgeID(attributes[0], id);
        entity = getEdge1stAttribute(attributes[0], entity);
        agent = attributes[1];

        entity = testPointer(entity, "Entity");
        agent = testPointer(agent, "Agent");

        edge = new Edge(id, "wasAttributedTo", "-", "-", nodes.get(agent), nodes.get(entity));

        readAttributes(edge, optionalAttributes);
        addEdge(edge);
    }

    public void readAssociation(String[] attributes, String[] optionalAttributes) {
        Edge edge;
        String id = null;
        String activity = "-";
        String agent;
        String plan = "-";
        boolean hasPlan = false;

        id = getEdgeID(attributes[0], id);
        activity = getEdge1stAttribute(attributes[0], activity);
        agent = attributes[1];

        if (attributes.length == 3) {
            plan = attributes[2];
            if (!plan.contentEquals("-")) {
                hasPlan = true;
            }
        }

        activity = testPointer(activity, "Activity");
        agent = testPointer(agent, "Agent");
        
        edge = new Edge(id, "wasAssociatedWith", "-", "-", nodes.get(agent), nodes.get(activity));

        GraphAttribute optAtt = new GraphAttribute("plan", plan, file.getName());
        edge.addAttribute(optAtt);

        readAttributes(edge, optionalAttributes);
        addEdge(edge);

        if (hasPlan) {
//            Vertex node = new EntityVertex(plan, plan, "");
//            GraphAttribute optAtt = new GraphAttribute("prov:type", "prov:Plan");
//            addNode(node);
            plan = testPointer(plan, "Entity");
            edge = new Edge(id, "wasAssociatedWith(Plan)", "-", "-", nodes.get(plan), nodes.get(agent));
            readAttributes(edge, optionalAttributes);
            addEdge(edge);
        }
    }

    public void readDelegation(String[] attributes, String[] optionalAttributes) {
        Edge edge;
        String id = null;
        String delegate = "-";
        String responsible;
        String activity = "-";

        id = getEdgeID(attributes[0], id);
        delegate = getEdge1stAttribute(attributes[0], delegate);
        responsible = attributes[1];

        if (attributes.length == 3) {
            activity = attributes[2];
        }

        delegate = testPointer(delegate, "Agent");
        responsible = testPointer(responsible, "Agent");

        edge = new Edge(id, "actedOnBehalfOf", "-", "-", nodes.get(delegate), nodes.get(responsible));

        GraphAttribute optAtt = new GraphAttribute("activity", activity, file.getName());
        edge.addAttribute(optAtt);

        readAttributes(edge, optionalAttributes);
        addEdge(edge);

        if (activity != null && !activity.matches("-")) {
            edge = new Edge(id, "actedOnBehalfOf(Activity)", "-", "-", nodes.get(activity), nodes.get(responsible));
            readAttributes(edge, optionalAttributes);
            addEdge(edge);
        }
    }

    public void readInfluence(String[] attributes, String[] optionalAttributes) {
        Edge edge;
        String id = null;
        String influencee = "-";
        String influencer;

        id = getEdgeID(attributes[0], id);
        influencee = getEdge1stAttribute(attributes[0], influencee);
        influencer = attributes[1];

        influencee = testPointer(influencee, "Entity");
        influencer = testPointer(influencer, "Entity");

        edge = new Edge(id, "wasInfluencedBy", "-", "-", nodes.get(influencer), nodes.get(influencee));

        readAttributes(edge, optionalAttributes);
        addEdge(edge);
    }

    public void readAlternate(String[] attributes, String[] optionalAttributes) {
        alternateOrSpecializationOrMembership(attributes, optionalAttributes, "alternateOf");
    }

    public void readSpecialization(String[] attributes, String[] optionalAttributes) {
        alternateOrSpecializationOrMembership(attributes, optionalAttributes, "specializationOf");
    }

    public void readMembership(String[] attributes, String[] optionalAttributes) {
        alternateOrSpecializationOrMembership(attributes, optionalAttributes, "hadMember");
    }

    public void alternateOrSpecializationOrMembership(String[] attributes, String[] optionalAttributes, String type) {
        Edge edge;
        String id = null;
        String alternate1 = "-";
        String alternate2;

        id = "Edge_" + edgeOptionalID;
        edgeOptionalID++;
        alternate2 = attributes[1];

        alternate1 = testPointer(alternate1, "Entity");
        alternate2 = testPointer(alternate2, "Entity");

        edge = new Edge(id, type, "-", "-", nodes.get(alternate2), nodes.get(alternate1));

        readAttributes(edge, optionalAttributes);
        addEdge(edge);
    }

    public void readAttributes(GraphObject obj, String[] attributes) {
        boolean hasGraphFile = false;
        if (attributes != null) {
            for (String attList1 : attributes) {
                String[] att = attList1.split("=");
                if (att.length > 1) {
                    if (att[0].equalsIgnoreCase("prov:label")) {
                        obj.setLabel(att[1]);
                    } else if ((obj instanceof Edge) && (att[0].contains("value"))) {
                        ((Edge) obj).setValue(att[1]);
                    }
                    if(att[0].equalsIgnoreCase("GraphFile")) {
                        hasGraphFile = true;
                    }
                    GraphAttribute optAtt = new GraphAttribute(att[0], att[1], file.getName());
                    obj.addAttribute(optAtt);
                }
            }
        }
        if (!hasGraphFile) {
            GraphAttribute graphFileAtt = new GraphAttribute(VariableNames.GraphFile, file.getName(), file.getName());
            obj.addAttribute(graphFileAtt);
        }
    }

    public String getEdgeID(String attribute, String id) {
        String[] att = attribute.split(";");
        if (att.length == 2) {
            if (att[0].equalsIgnoreCase("-")) {
                id = "Edge_" + edgeOptionalID;
                edgeOptionalID++;
            } else {
                id = att[0];
            }
        } else {
            id = "Edge_" + edgeOptionalID;
            edgeOptionalID++;
        }
        return id;
    }

    public String getEdge1stAttribute(String attribute, String attr) {
        String[] att = attribute.split(";");
        if (att.length == 2) {
            attr = att[1];
        } else {
            attr = att[0];
        }
        return attr;
    }

    /**
     * Function to verify if the pointers were initialized or informed
     *
     * @param pointer: Is the edge's source or target
     * @param type: Is the type of the vertex we are trying to verify. This is
     * used to create the correct vertex type when the pointer was not
     * initialized
     * @return the pointer
     */
    public String testPointer(String pointer, String type) {
        if (nodes.get(pointer) == null) {
            if (pointer.contentEquals("-")) {
                if(type.contentEquals("Entity")) {
                    pointer = "Unknown Entity";
                    Vertex node = new EntityVertex("Unknown Entity", "Unknown Entity", "");
                    addNode(node);
                }
                else if(type.contentEquals("Agent")) {
                    pointer = "Unknown Agent";
                    Vertex node = new AgentVertex("Unknown Agent", "Unknown Agent", "");
                    addNode(node);
                }
                else if(type.contentEquals("Activity")) {
                    pointer = "Unknown Activity";
                    Vertex node = new ActivityVertex("Unknown Activity", "Unknown Activity", "");
                    addNode(node);
                }
            } else if (pointer == null) {
                pointer = "Unknown";
            } else if (pointer.isEmpty()) {
                pointer = "Unknown";
            } else if (!pointer.isEmpty()) {
                if (type.equals("Agent")) {
                    Vertex node = new AgentVertex(pointer, "Not Initialized", "");
                    addNode(node);
                } else if (type.equals("Activity")) {
                    Vertex node = new ActivityVertex(pointer, "Not Initialized", "");
                    addNode(node);
                } else {
                    Vertex node = new EntityVertex(pointer, "Not Initialized", "");
                    addNode(node);
                }
            } else {
                pointer = "Unknown";
            }
        }
        return pointer;
    }
} public class Utils {

    Color[] colors = new Color[17];

    public static Color getColor(int i) {
        int size = 25; // Array max position + 1
        int index = i % size;
        Color[] colors = new Color[size];
        colors[0] = new Color(0, 0, 0); // Black
        colors[1] = new Color(0, 0, 255); // Blue
        colors[2] = new Color(153, 153, 0); // Yellow-Mostard
        colors[3] = new Color(0, 255, 255); // Cyan/Aqua
        colors[4] = new Color(255, 0, 255); // Magenta
        colors[5] = new Color(128, 128, 128); // Gray
        colors[6] = new Color(128, 0, 0); // Brown / Maroon
        colors[7] = new Color(128, 128, 0); // olive
        colors[8] = new Color(210, 105, 30); // Chocolate
        colors[9] = new Color(0, 0, 128); // Navy
        colors[10] = new Color(255, 128, 128); // Pink
        colors[11] = new Color(255, 128, 0); // Orange
        colors[12] = new Color(192, 192, 192); // Silver / Light-Gray
        colors[13] = new Color(70, 130, 180); // Steel blue
        colors[14] = new Color(184, 134, 11); // Dark golden rod
        // Similar colors...
        colors[15] = new Color(0, 128, 128); // Teal
        colors[16] = new Color(0, 128, 0); // Green
        colors[17] = new Color(255, 0, 0); // Red
        colors[18] = new Color(0, 255, 0); // Lime/Green
        colors[19] = new Color(245, 245, 220); // Beige
        colors[20] = new Color(128, 0, 128); // Purple
        colors[21] = new Color(218,112,214); // Orchid
        colors[22] = new Color(210,105,30); // Chocolate
        colors[23] = new Color(240,255,255); // Azure
        colors[24] = new Color(255,20,147); // Deep-Pink

        return colors[index];
    }

    /**
     * Method to check if it is possible to parse the value to double
     *
     * @param value desired to be parsed to double
     * @return boolean
     */
    public static boolean tryParseDouble(String value) {
        value = value.replace(" ", "");
        value = value.replace(",", ".");
        if (value.isEmpty()) {
            return false;
        } else if (value == null) {
            return false;
        } else if (value.equalsIgnoreCase("")) {
            return false;
        } else if (value.equalsIgnoreCase("NaN")) {
            return false;
        } else {
            try {
                String v = new BigDecimal(value).toPlainString();
                Double.parseDouble(v);
                return true;
            } catch (NumberFormatException nfe) {
                return false;
            }
        }

    }

    /**
     * Function that verifies if it is possible to convert the String to a double
     *
     * @param value is the String to be verified
     * @return true if it is possible to convert to a double
     */
    public static double convertStringToDouble(String value) {
        value = value.replace(" ", "");
        value = value.replace(",", ".");
        String v;
        if(value.contains("Infinity")) {
            return Double.POSITIVE_INFINITY;
        } else {
            v = new BigDecimal(value.trim()).toPlainString();
            return Double.valueOf(v);
        }
        
        
    }

    /**
     * Function that verifies if it is possible to convert the String to a double
     *
     * @param value is the String to be verified
     * @return true if it is possible to convert to a double
     */
    public static double convertDouble(String value) {
        value = value.replace(" ", "");
        return Double.parseDouble(value);
    }

    /**
     * Function that verifies if it is possible to convert the String to an
     * integer
     *
     * @param value is the String to be verified
     * @return true if it is possible to convert to an integer
     */
    public static boolean tryParseInt(String value) {
        value = value.replace(" ", "");
        try {
            Integer.valueOf(value);
            return true;
        } catch (NumberFormatException nfe) {
            return false;
        }
    }

    /**
     * Function to convert a String to an Int value
     *
     * @param value is the String to be converted
     * @return the int value of the string
     */
    public static int convertInt(String value) {
        value = value.replace(" ", "");
        return Integer.valueOf(value);
    }

    /**
     * Function to convert a String to an Int value, rounding it
     *
     * @param value is the String to be converted
     * @return the rounded int value of the string
     */
    public static double roundToInt(String value) {
        value = value.replace(" ", "");
        return Math.round(convertStringToDouble(value));
    }

    /**
     * Function to compare two doubles with an epsilon margin of error
     *
     * @param f1 is the first double
     * @param f2 is the second double
     * @param epsilon is the margin of error for the comparison
     * @return true if doubles are equals within the epsilon error margin
     */
//    public static boolean DoubleEqualTo(double f1, double f2, double epsilon) {
//        return Math.abs(f1 - f2) <= epsilon;
//    }

    public static boolean DoubleEqualTo(double f1, double f2, double epsilon) {
        return Math.abs(f1 - f2) <= epsilon;
    }

    public static boolean DoubleSimilar(double f1, double f2, double epsilon) {
        double max = Math.max(f1, f2);
        double min = Math.min(f1, f2);

        return min + Math.abs(max * epsilon) >= max;
    }
    
    public static boolean DoubleLesserThan(double f1, double f2, double epsilon) {
        if (Double.compare(f1, f2) < 0)
            return true;
        else
            return false;
    }

    /**
     * Clamp function to clamp the value between min and max
     *
     * @param min is the minimal accepted value
     * @param max is the maximum accepted value
     * @param value is the value to be clamped between min and max
     * @return clamped value
     */
    public static double clamp(double min, double max, double value) {
        return Math.max(min, Math.min(max, value));
    }

    /**
     * Method to convert a string to XMLGregorianCalendar
     *
     * @param time is the desired date in the "yyyy-MM-dd'T'HH:mm:ss"
     * @return the converted XMLGregorian Date
     */
    public static XMLGregorianCalendar stringToXMLGregorianCalendar(String time) {
        try {
            XMLGregorianCalendar result;
            Date date;
            SimpleDateFormat simpleDateFormat;
            GregorianCalendar gregorianCalendar;

            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            date = simpleDateFormat.parse(time);
            gregorianCalendar
                    = (GregorianCalendar) GregorianCalendar.getInstance();
            gregorianCalendar.setTime(date);
            result = DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar);
//            System.out.println("Date: " + result.toString());
            return result;
        } catch (ParseException ex) {
            Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
        } catch (DatatypeConfigurationException ex) {
            Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    /**
     * Function that verifies if it is possible to convert the String to Date
     *
     * @param value is the String to be verified
     * @return true if it is possible to convert to Date
     */
    public static boolean tryParseDate(String value) {
//        System.out.println("tryParseDate: " + value);
        if (value.isEmpty()) {
            return false;
        } else if (value == null) {
            return false;
        } else if (value.equalsIgnoreCase("")) {
            return false;
        } else if (value.equalsIgnoreCase("NaN")) {
            return false;
        }
        try {
            SimpleDateFormat simpleDateFormat;
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            simpleDateFormat.parse(value);
            return true;
        } catch (ParseException ex) {
            return false;
        }
    }

    /**
     * Convert a Date in the format of a string to double
     *
     * @param d1 is the string to be converted
     * @return the value in Double for the date
     */
    public static long convertStringDateToLong(String d1) {
        // Try to convert to date format and return how many milliseconds have passed since January 1, 1970, 00:00:00 GMT
        try {
            Date date;
            SimpleDateFormat simpleDateFormat;
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            date = simpleDateFormat.parse(d1);
            return date.getTime();
        } catch (ParseException ex) {
            Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
        }
        return 0;
    }

    /**
     * Method to return the median of a numeric array
     *
     * @param l is the array
     * @param start
     * @param end
     * @return the median
     */
    public static String median(Object[] l, int start, int end) {
        if (end - start > 1) {
            int middle = (end - start) / 2; //l.length / 2;
            middle = middle + start;
            boolean isString = false;
            double[] v = new double[l.length];
            int i = 0;
            for (Object s : l) {
                if (tryParseDouble((String) s)) {
                    v[i++] = convertStringToDouble((String) s);
                } else {
                    isString = true;
                }

            }
            if (!isString) {
                Arrays.sort(v);
                if ((end - start) % 2 == 0) {
                    double left = v[middle - 1];
                    double right = v[middle];
                    return String.valueOf((left + right) / 2);
                } else {
                    return String.valueOf(v[middle]);
                }
            } else {
                Arrays.sort(l);
                return (String) l[middle];
            }
        } else {
            return (String) l[start];
        }
    }

    /**
     * Retrieve the quartile value from an array
     *
     * @param values THe array of data
     * @param lowerPercent The percent cut off. For the lower quartile use 25,
     * for the upper-quartile use 75
     * @return
     */
    public static String quartile(Object[] values, int lowerPercent) {

        if (values == null || values.length == 0) {
            throw new IllegalArgumentException("The data array either is null or does not contain any data.");
        }
        int start, end;
        if (lowerPercent == 1) {
            start = 0;
            end = values.length / 2;
        } else {
            if ((values.length % 2) == 0) {
                start = (values.length / 2);
            } else {
                start = (values.length / 2) + 1;
            }
            end = values.length;
        }

        return median(values, start, end);
    }

    /**
     * Method to remove the infinity numbers from an arrayList
     *
     * @param allNumbers is the arrayList of double
     * @return the same arrayList without the infinity numbers
     */
    public static ArrayList<Double> removeInfinity(ArrayList<Double> allNumbers) {
        ArrayList<Double> normalNumbers = new ArrayList<>();
        for (double number : allNumbers) {
            if ((number != Double.NEGATIVE_INFINITY) && (number != Double.POSITIVE_INFINITY)) {
                normalNumbers.add(number);
            }
        }
        return normalNumbers;
    }

    /**
     * Method to remove outliers from a list
     *
     * @param allNumbers is the arrayList of double
     * @param att
     * @return the same arrayList without the outliers
     */
    public static ArrayList<Double> removeOutLierAnalysis(ArrayList<Double> allNumbers, String att) {
        if (allNumbers.isEmpty()) {
            return null;
        }
        ArrayList<Double> normalNumbers = new ArrayList<>();

        ThresholdValues thresholds = calculateOutliers(allNumbers, att);

        for (double number : allNumbers) {
            if ((thresholds.lowerThreshold <= number) && (number <= thresholds.upperThreshold)) {
                normalNumbers.add(number);
            }
        }

        return normalNumbers;
    }
    
    /**
     * Method to calculate the upper and lower outliers thresholds from a sequence of numbers
     * @param allNumbers contains the numbers
     * @param att
     * @return the lower and upper thresholds for outlier detection
     */
    public static ThresholdValues calculateOutliers(ArrayList<Double> allNumbers, String att) {
        Collections.sort(allNumbers);
        double q1;
        double q3;
        if (allNumbers.size() % 2 == 0) {
            int position;
//            mean = (allNumbers.get(position) + allNumbers.get(position - 1)) * 0.5;
            position = (int) (allNumbers.size() * 0.25);
            q1 = (allNumbers.get(position) + allNumbers.get(position - 1)) * 0.5f;
            position = (int) (allNumbers.size() * 0.75);
            q3 = (allNumbers.get(position) + allNumbers.get(position - 1)) * 0.5f;
        } else {
            int position;
//            mean = allNumbers.get(position);
            position = (int) (allNumbers.size() * 0.25);
            q1 = allNumbers.get(position);
            position = (int) (allNumbers.size() * 0.75);
            q3 = allNumbers.get(position);
        }
        double iqr = q3 - q1;
        double lowerThreshold = q1 - iqr * 1.5f;
        double upperThreshold = q3 + iqr * 1.5f;
        return new ThresholdValues(att, lowerThreshold, upperThreshold);
    }

    /**
     * Method to compute the standard deviation
     *
     * @param list is the list of double values
     * @return the stdev
     */
    public static double stdev(Double[] list) {
        double mean;
        mean = mean(list);
        return stdev(list, mean);
    }

    /**
     * Method to compute the standard deviation when the mean is already known
     *
     * @param list is the list of double values
     * @param mean is the known mean of the list
     * @return the stdev
     */
    public static double stdev(Double[] list, double mean) {
        double num = 0.0f;
        double numi;
        double deno = 0.0f;

        for (Double list1 : list) {
            numi = (double) Math.pow(list1 - mean, 2);
            num += numi;
            deno = list.length - 1;
        }

        double stdevResult = (double) Math.sqrt(num / deno);

//        double v = (double) ((int) stdevResult * 10000) * 0.0001f;
        return stdevResult;
    }

    /**
     * Computes the standard deviation for the attribute
     *
     * @param vertices the list of vertices
     * @param attribute the attribute in which we want to calculate the standard
     * deviation
     * @return the standard deviation
     */
    public static double std(Collection<Object> vertices, String attribute) {
        ArrayList<Double> values = new ArrayList<>();
        for (Object v1 : vertices) {
            double val = ((Vertex) v1).getAttributeValueDouble(attribute);
                if (!(val != val)) {
                    values.add(val);
                }
            }
        Double[] doubleArray = new Double[values.size()];
        doubleArray = Utils.listToDoubleArray(values);
        return stdev(doubleArray);
    }

    /**
     * Method to compute the mean of a list
     *
     * @param list is the list
     * @return the mean of the list
     */
    public static double mean(Double[] list) {
        double mean;
        double sum = 0.0F;
        for (Double list1 : list) {
            sum += list1;
        }
        mean = sum / list.length;

        return mean;
    }

    /**
     * Method to find the minimum value of a list
     *
     * @param list is the list of values
     * @return the minimum value of the list
     */
    public static double minimumValue(Double[] list) {
        double min = Double.POSITIVE_INFINITY;
        for (Double list1 : list) {
            min = Math.min(min, list1);
        }

        return min;
    }

    /**
     * Method to find the maximum value of a list
     *
     * @param list is the list of values
     * @return the maximum value of the list
     */
    public static double maximumValue(Double[] list) {
        double max = Double.NEGATIVE_INFINITY;
        for (Double list1 : list) {
            max = Math.max(max, list1);
        }
        return max;
    }
    
    /**
     * Method to find the maximum value in the graph from an attribute
     * @param nodes is the list of vertices
     * @param attribute is the attribute that we want to find the maximum value
     * @return the maximum value of attribute
     */
    public static double findMaximumAttributeValue(Collection<Object> nodes, String attribute) {
        double max = Double.NEGATIVE_INFINITY;
        for (Object node : nodes) {
            if (!((Vertex) node).getAttributeValue(attribute).contentEquals("Unknown")) {
                max = Math.max(max, ((Vertex) node).getAttributeValueDouble(attribute));
            }
        }
        return max;
    }

    /**
     * Method to convert a list of objects to an arraylist of double
     *
     * @param values is the list of objects to be convertable
     * @return the arraylist of double
     */
    public static Double[] listToDoubleArray(ArrayList<Double> values) {
        Double[] doubleArray = new Double[values.size()];
        int i = 0;
        for (Double f : values) {
            doubleArray[i++] = (f != null ? f : Double.NaN);
        }
        return doubleArray;
    }

    /**
     * Method to clone a graph
     *
     * @param graph The graph to be cloned
     * @return a clone of the graph
     */
    public static DirectedGraph<Object, Edge> copyGraph(DirectedGraph<Object, Edge> graph) {
        DirectedGraph<Object, Edge> clone = new DirectedSparseMultigraph<>();
        for (Edge e : graph.getEdges()) {
            clone.addEdge(e, e.getSource(), e.getTarget());
        }

        return clone;
    }

    /**
     * Function to convert the timestamp to different time scales
     *
     * @param timeFormat is the original timestamp scale used in the graph XML
     * @param time is the time we want to convert
     * @param timeScale is the current timescale being used
     * @return the converted value
     */
    public static long convertTime(String timeFormat, double time, String timeScale) {
        TimeUnit t;
        if(time == -1)
            return (long) time;
        // Convert the number to a lower scale being used to avoid losing the decimals
        switch (timeFormat) {
            case "nanoseconds":
                t = TimeUnit.NANOSECONDS;
                break;
            case "microseconds":
                t = TimeUnit.MICROSECONDS;
                break;
            case "milliseconds":
                t = TimeUnit.MILLISECONDS;
                break;
            case "seconds":
                t = TimeUnit.SECONDS;
                break;
            case "minutes":
                t = TimeUnit.MINUTES;
                break;
            case "hours":
                t = TimeUnit.HOURS;
                break;
            case "days":
                t = TimeUnit.DAYS;
                break;
            case "weeks":
                t = TimeUnit.DAYS;
                time = time / 7;
                break;
            default:
                t = TimeUnit.NANOSECONDS;
                break;
        }
        switch (timeScale) {
            case "nanoseconds":
                return t.toNanos((long) time);
            case "microseconds":
                return t.toMicros((long) time);
            case "milliseconds":
                return t.toMillis((long) time);
            case "seconds":
                return t.toSeconds((long) time);
            case "minutes":
                return t.toMinutes((long) time);
            case "hours":
                return t.toHours((long) time);
            case "days":
                return t.toDays((long) time);
            case "weeks":
                return (int) t.toDays((long) time) / 7;
            default:
                return (long) time;
        }
    }
    
        /**
     * Method to normalize vertex's timestamps to start from 0
     * @param graph
     * @param overwriteTime
     */
    public static void NormalizeTime(DirectedGraph<Object, Edge> graph, boolean overwriteTime) {
        Collection<Object> vertices = graph.getVertices();
        double minTime = Double.POSITIVE_INFINITY;
        for (Object v : vertices) {
            if (((Vertex) v).getTime() != -1) {
                minTime = Math.min(minTime, ((Vertex) v).getTime());
            }
        }
        // Normalize time
        for (Object v : vertices) {
            if (((Vertex) v).getTime() >= 0) {
                double normalized = ((Vertex) v).getTime() - minTime;
                ((Vertex) v).setNormalizedTime(normalized);
                if (overwriteTime && minTime != 0) {
                    ((Vertex) v).setTime(Double.toString(normalized));
                }
            } else {
                ((Vertex) v).setNormalizedTime(-1);
            }
        }
    }
    
    /**
     * Method to detect all values for the ATTRIBUTE that appears in the graph
     * @param vertices
     * @param attribute
     * @return 
     */
    public static Collection<String> DetectAllPossibleValuesFromAttribute(Collection<Object> vertices, String attribute) {
        Map<String, String> attributeList = new HashMap<>();
        for (Object v : vertices) {
            String value = ((Vertex) v).getAttributeValue(attribute);
            if(!value.contains("Unknown")) {
                String[] values = value.split(", ");
                for(String s : values) {
                    attributeList.put(s, s);
                }
            }
        }
        return attributeList.values();
    }
    
    /**
     * Method that determines if the provided attribute is a timestamp/date/time type of attribute
     * @param attribute the attribute we want to check
     * @return TRUE if it is Time/Timestamp/Date or FALSE if not
     */
    public static boolean isItTime(String attribute) {
        if(attribute.equalsIgnoreCase("Time"))         {
            return true;
        }
        if(attribute.equalsIgnoreCase("Timestamp")) {
            return true;
        }
        if(attribute.equalsIgnoreCase("Date")) {
            return true;
        }
        return false;
    }
    
    /**
     * Method to return a comparator that compares two vertices based on their timestamps
     * @return the comparator
     */
    public static Comparator getVertexTimeComparator() {
        Comparator comparator = new Comparator<Object>() {
            @Override
            public int compare(Object c1, Object c2) {
                    double c1t = ((Vertex) c1).getTime();
                    double c2t = ((Vertex) c2).getTime();
                    if (c1t != c2t) {
                        return Double.compare(c1t, c2t);
                    } else {
                        return ((Vertex) c2).getNodeType().compareTo(((Vertex) c1).getNodeType());
                    }
                    //TODO make agent lose priority to appear after the activity
            }
        };
        return comparator;
    }
    
    /**
     * Generic comparator
     * @param attribute Is the attribute that we want to sort
     * @return the comparator for the given attribute
     */
    public static Comparator getVertexAttributeComparator(final String attribute) {
        Comparator comparator = new Comparator<Object>() {
            @Override
            public int compare(Object c1, Object c2) {
                    long c1t = 0;
                    long c2t = 0;
                    if(!tryParseDouble(((Vertex) c1).getAttributeValue(attribute))){
                        String c1v = ((Vertex) c1).getAttributeValue(attribute);
                        String c2v = ((Vertex) c2).getAttributeValue(attribute);
                        int result = c1v.compareTo(c2v);
                        if(result == 0) {
                            return untieVertexAttributeComparator(c1, c2);
                        }
                        else
                            return result;
                    } else {
                        c1t = (long) (((Vertex) c1).getAttributeValueDouble(attribute) * 1000);
                        c2t = (long) (((Vertex) c2).getAttributeValueDouble(attribute)* 1000);
                    }
                    if (c1t != c2t) {
                        return Long.compare(c1t, c2t);
                    } else {
                        return untieVertexAttributeComparator(c1, c2);
//                        return ((Vertex) c1).getNodeType().compareTo(((Vertex) c2).getNodeType());
                    }
            }
        };
        return comparator;
    }
    
    private static int untieVertexAttributeComparator(Object c1, Object c2) {
        if((((Vertex) c1).getNodeType() != null) && (((Vertex) c2).getNodeType() != null)){
            if((((Vertex) c1).getNodeType().equalsIgnoreCase("Agent")) && !(((Vertex) c2).getNodeType().equalsIgnoreCase("Agent")))
                return -1;
            else if((((Vertex) c2).getNodeType().equalsIgnoreCase("Agent")) && !(((Vertex) c1).getNodeType().equalsIgnoreCase("Agent")))
                return 1;
            else if((((Vertex) c1).getNodeType().equalsIgnoreCase("Activity")) && !(((Vertex) c2).getNodeType().equalsIgnoreCase("Activity")))
                return -1;
            else if((((Vertex) c2).getNodeType().equalsIgnoreCase("Activity")) && !(((Vertex) c1).getNodeType().equalsIgnoreCase("Activity")))
                return 1;
            else if((((Vertex) c1).getNodeType().equalsIgnoreCase("Entity")) && !(((Vertex) c2).getNodeType().equalsIgnoreCase("Entity")))
                return 1;
            else if((((Vertex) c2).getNodeType().equalsIgnoreCase("Entity")) && !(((Vertex) c1).getNodeType().equalsIgnoreCase("Entity")))
                return -1;
            else
                return 0;
        }
        else
            return 0;
    }
    
    /**
     * Method to determine if the string has a minus sign in the beginning
     * @param s is the string that we want to know if it has a minus sign
     * @return TRUE if it has a minus sign and FALSE if it does not have it
     */
    public static boolean getMinusSign(String s) {
        String sign = s.substring(0, 1);
        boolean isReverse = false;
        
        if("-".equals(sign)) {
            isReverse = true;
        }
        return isReverse;
    }
    
    /**
     * Method to remove the minus sign in the beginning of the string (if it has it)
     * @param s the string that we want to remove the minus sign
     * @return the string without the minus sign
     */
    public static String removeMinusSign(String s) {
        String sign = s.substring(0, 1);
        if("-".equals(sign)) {
            return s.substring(1);
        }
        return s;
    }
    
    
    /**
     * Method to decide if the current edge should be highlighted or not
     * @param e the edge we are evaluating
     * @param variables location that has the view variable so we can select the vertices and edges that were marked by the user
     * @return true if the edge should be highlighted and false if not
     */
    public static boolean edgeHighlighted(Edge e, Variables variables){
        PickedState<Object> picked_state = variables.view.getPickedVertexState();
        PickedState<Edge> edge_picked_state = variables.view.getPickedEdgeState();
        if(!picked_state.getPicked().isEmpty() || !edge_picked_state.getPicked().isEmpty()) {
            if (!picked_state.getPicked().isEmpty()) {
                for (Object v : picked_state.getPicked()) {
                    if (e.getSource().equals(v)) {
                        return true;
                    } else if (e.getTarget().equals(v)) {
                        return true;
                    }
                }
            }
            if (!edge_picked_state.getPicked().isEmpty()) {
                for (Object v : edge_picked_state.getPicked()) {
                    if (e.equals(v)) {
                        return true;
                    }
                }
            }
            return false;
        }
        return true;
    }
} public abstract class Vertex extends GraphObject {

    private String id;                              // prov:id
    private double normalizedTime;
//    private String time;                            // prov:startTime
                                                    // Refactor for datetime type
    private String timeFormat;
    private String timeScale;
    private String timeLabel = "Timestamp";
    
    /**
     * Constructor without attributes
     * Using this constructor, attributes must be added later
     * 
     * @param id vertex unique ID
     * @param label HUman readable name
     * @param time Time-related value. Used for temporal layouts
     */
    public Vertex(String id, String label, String time) {
        this.id = id;
//        this.time = time;
        GraphAttribute t = new GraphAttribute(timeLabel, time, "");
        this.attributes = new HashMap<>();
        this.attributes.put(t.getName(), t);
        setLabel(label);
        timeFormat = "nanoseconds";
        timeScale = "nanoseconds";
    }
    
    /**
     * Constructor with attributes
     * @param id
     * @param label
     * @param time
     * @param attributes 
     */
    public Vertex(String id, String label, String time, Map<String, GraphAttribute> attributes) {
        this.id = id;
        this.attributes = new HashMap<>();
        this.attributes.putAll(attributes);
        GraphAttribute t = new GraphAttribute(timeLabel, time, "");
        this.attributes.put(t.getName(), t);
        setLabel(label);
        timeFormat = "nanoseconds";
        timeScale = "nanoseconds";
    }

    /**
     * Return the vertex ID
     *
     * @return (String) id
     */
    public String getID() {
        return id;
    }
    
    /**
     * Set vertex ID
     * @param t is the new ID
     */
    public void setID(String t) {
        id = t;
    }
    
    public void setNormalizedTime(double t) {
        this.normalizedTime = t;
    }
    
    public double getNormalizedTime() {
        return this.normalizedTime;
    }
    
    /**
     * Method for returning the vertex name (not type) from the sub-classes.
     * i.e. Agent Vertex name = Kohwalter
     *
     * @return (String) name
     */
    
    /**
     * Method for returning the vertex day (if any)
     *
     * @return (int) date
     */
    public double getTime() {    
//        String[] day = this.time.split(":");
        String time = this.attributes.get(timeLabel).getAverageValue();
        if(Utils.tryParseDouble(time))
            return (Double.parseDouble(time));
        else if(Utils.tryParseDate(time))
        {
            double milliseconds =  Utils.convertStringDateToLong(time);
            return milliseconds;
        }
        else
            return -1;
    }
    public long getMinTime() {    
        String time = this.attributes.get(timeLabel).getMin();
        if(Utils.tryParseDouble(time))
            return (long) ((Double.parseDouble(time))*1000);
        else if(Utils.tryParseDate(time))
        {
            long milliseconds = Utils.convertStringDateToLong(time);
            return milliseconds;
        }
        else
            return -1;
    }
    
    /**
     * Method to get the value of the variable time 
     * @return time
     */
    public String getTimeString() {    
        return this.attributes.get(timeLabel).getAverageValue();
    }
    
    /**
     * Method to set the value of the variable time
     * @param t is the new value
     */
    public void setTime(String t){
        GraphAttribute time = new GraphAttribute(timeLabel, t, "Normalized");
        this.attributes.put(timeLabel, time);
    }

    
    /**
     * (Optional) Method for returning the day of the week instead of the day's
     * number.
     *
     * @return (String) the day of the week (mon, tue, wed, ...)
     */
    public String getDayName() {
        String[] day = this.attributes.get(timeLabel).getAverageValue().split(":");
        return day[1];
    }
    
    /**
     * This overrides the default JUNG method for displaying information
     *
     * @return (String) id
     */
    @Override
    public String toString() {
        return this.getNodeType() + "<br> "
                + "<br>ID: " + this.id + "<br>"
                + "<b>Label: " + getLabel() + "</b>"
                + " <br>" + printTime()
                + " <br>"
                + " <br>" + printAttributes();
    }
    
    public String getTooltip(int nGraphs) {
        return this.getNodeType() + "<br> "
                + "<br>ID: " + this.id + "<br>"
                + "<b>Label: " + getLabel() + "</b>"
                + " <br>" + printTime()
                + "<br>Frequency: " + getFrequency(nGraphs)
                + " <br>"
                + " <br>" + printAttributes();
    }
    public String printTime()
    {
        double nt = this.getTime();
        return "Timestamp: " + Utils.convertTime(timeFormat, nt, timeScale) + " (" + timeScale + ")";
    }
    
    public void setTimeScalePrint(String timeFormat, String timeScale) {
        this.timeFormat = timeFormat;
        this.timeScale = timeScale;
    }

    /**
     * Method to return the attribute value (not necessarily a number)
     * If the attribute does not exist, returns "Unknown"
     * @param attribute
     * @return 
     */
    @Override
    public String getAttributeValue(String attribute) {
        if(attribute.equalsIgnoreCase("Label")) {
            return getLabel();
        }
        GraphAttribute aux = attributes.get(attribute);
        if(aux != null) {
            return aux.getAverageValue();
        }
        else {
            return deltaAttributeValue(attribute);
//            return "Unknown";
        }
    }
    
    /**
     * Method to return the values in an attribute that were separated by a comma
     * @param attribute is the attribute that we want to get the values
     * @return an array with the values
     */
    @Override
    public String[] getAttributeValues(String attribute) {
        String values = this.getAttributeValue(attribute);
        return values.split(", ");
    }
    
    /**
     * Method to return the attribute value as float
     * @param attribute
     * @return 
     */
    public double getAttributeValueDouble(String attribute) {
        if(isItTime(attribute)) {
            return (double)getNormalizedTime();
        }
        if(attributes.get(attribute) == null) {
            return deltaAttributeDoubleValue(attribute);
        }
        return getAttDoubleValue(attribute);
    }
    
    
    
    /**
     * Method that gets both attributes in the string and subtracts them. I.e.: First_Attribute - Second_Attribute
     * @param attribute must be a string with both atributes separared by " - ". Example: "First_Attribute - Second_Attribute"
     * @return the delta
     */
    private double deltaAttributeDoubleValue(String attribute) {
        String[] atts = attribute.split(" - ");
        if(atts.length == 2)
            return getAttDoubleValue(atts[0]) - getAttDoubleValue(atts[1]);
        else
            return Double.NaN;
    }
    
    /**
     * Method that returns the delta from the two attributes or Unknown if any attribute is invalid
     * @param attribute must be a string with both atributes separared by " - ". Example: "First_Attribute - Second_Attribute"
     * @return the delta as a String
     */
    private String deltaAttributeValue(String attribute) {
        if(attribute.equalsIgnoreCase("Label")) {
            return getLabel();
        }
        if(isItTime(attribute)) {
            return String.valueOf(getTime());
        }
        
        String[] atts = attribute.split(" - ");
        if(atts.length == 2) {
            if(VariableNames.UnknownValue.equals(getAttributeValue(atts[0])) || VariableNames.UnknownValue.equals(getAttributeValue(atts[1]))) return VariableNames.UnknownValue;
            else {
                String delta = Double.toString(getAttDoubleValue(atts[0]) - getAttDoubleValue(atts[1]));
                return delta;
            }
        }
        else
            return VariableNames.UnknownValue;
    }
    
    /**
     * Method that returns the float value of the attribute. If it is not convertable, then it returns Float.NaN
     * @param attribute the attribute that we want to get the value from
     * @return the float value or Float.NaN if it is not possible to convert to float
     */
    private double getAttDoubleValue(String attribute) {
        if(isItTime(attribute)) {
            return (double)getNormalizedTime();
        }
        if(attributes.get(attribute) != null) {
            if(Utils.tryParseDouble(attributes.get(attribute).getAverageValue())) {
                return Utils.convertStringToDouble(attributes.get(attribute).getAverageValue());
            }
            else {
                
                return Double.NaN;
            }
        }
        else {
            return Double.NaN;
        }
    }
    

    /**
     * Method for getting the vertex border size
     *
     * @deprecated use VertexStroke class instead
     * @param width Define the border width
     * @return (Stroke) returns the new vertex border width
     */
    public Stroke getStroke(float width) {
        float dash[] = null;
        final Stroke nodeStroke = new BasicStroke(width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);
        return nodeStroke;
    }

    /**
     * Method for defining the vertex color
     *
     * @return (Paint) vertex color
     */
    public abstract Paint getColor();

    /**
     * Method used to identify the vertex type
     *
     * 
     * @return (String) vertex type
     */
    public abstract String getNodeType();

}
import br.uff.ic.graphmatching.GraphMerger;
import br.uff.ic.utility.graph.Edge;
import static br.uff.ic.provviewer.GUI.GuiFunctions.PanCameraToFirstVertex;
import br.uff.ic.provviewer.GraphFrame;
import br.uff.ic.provviewer.Input.SimilarityConfig;
import br.uff.ic.provviewer.VariableNames;
import br.uff.ic.utility.IO.UnityReader;
import br.uff.ic.provviewer.Variables;
import br.uff.ic.utility.IO.InputReader;
import br.uff.ic.utility.IO.PROVNReader;
import br.uff.ic.utility.Utils;
import br.uff.ic.utility.graph.Vertex;
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import org.apache.commons.io.FilenameUtils;
/*
 * The MIT License
 *
 * Copyright 2017 Kohwalter.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package br.uff.ic.provviewer.GUI;


/**
 * Class to read the graph and config files from the GUI button (File open)
 * @author Kohwalter
 */
public class GuiReadFile {

    /**
     * Method to read the graph from the XML file
     * @param graphFile is the XML file with the graph information
     * @return 
     */
    public static DirectedGraph<Object, Edge> getGraph(File graphFile) {
        DirectedGraph<Object, Edge> g = new DirectedSparseMultigraph<>();
        Map<String, Object> vertices = new HashMap<>();
        try {
            String extension = FilenameUtils.getExtension(graphFile.toPath().toString());
            InputReader fileReader;
            if(extension.equalsIgnoreCase("xml"))
                fileReader = new UnityReader(graphFile);
            else
                fileReader = new PROVNReader(graphFile);
                
            fileReader.readFile();
            
            for (Edge edge : fileReader.getEdges()) {
                if(edge.hasAttribute(VariableNames.vertexNewTarget) || edge.hasAttribute(VariableNames.vertexNewSource)) {
                    if(fileReader instanceof UnityReader) {
                        Object newTarget = edge.getTarget();
                        Object newSource = edge.getSource();
                        if(edge.hasAttribute(VariableNames.vertexNewTarget)) {
                            newTarget = ((UnityReader)fileReader).getNewPointer(edge.getAttributeValue(VariableNames.vertexNewTarget));
                        }
                        if(edge.hasAttribute(VariableNames.vertexNewSource)) {
                            newSource = ((UnityReader)fileReader).getNewPointer(edge.getAttributeValue(VariableNames.vertexNewSource));
                        }
//                        System.out.println("newSourceID: " + edge.getAttributeValue("NewSource"));
//                        System.out.println("newTargetID: " + edge.getAttributeValue("NewTarget"));
//                        System.out.println("newSource: " + ((Vertex)newSource).getID());
//                        System.out.println("newTarget: " + ((Vertex)newTarget).getID());
                        g.addEdge(edge, newSource, newTarget);
                        vertices.put(((Vertex)newSource).getID(), newSource);
                        vertices.put(((Vertex)newTarget).getID(), newTarget);
                    }
                } else {
                    g.addEdge(edge, edge.getSource(), edge.getTarget());
                    vertices.put(((Vertex)edge.getSource()).getID(), edge.getSource());
                    vertices.put(((Vertex)edge.getTarget()).getID(), edge.getTarget());
                }
            }
            // Adds vertices that had no edge connecting then
            for(Vertex v : fileReader.getNodes()) {
                if(!vertices.containsKey(v.getID()))
                    g.addVertex(v);
            }
            
        } catch (URISyntaxException ex) {
            Logger.getLogger(GraphFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(GraphFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
        return g;
    }

    /**
     * Method to read the XML configuration file
     * @param variables
     * @param fileChooser is the file chooser from the interface
     * @param graphFrame is the tool's main frame
     * @param Layouts
     */
    public static void openConfigFile(Variables variables, JFileChooser fileChooser, JFrame graphFrame, JComboBox Layouts) {