Repository: workcraft/workcraft
Issue: Selected non-leaf items without Checkbox are added to the checked list in TreeWindow component

To reproduce open _Parallel composition_ (or _N-way conformation_) dialog and select Workspace or External item. When Run button is clicked the composition process is interrupted with a null-pointer exception. This happens because the selected non-leaf item is interpreted as a path to  a work file, even though it does not have an associated check-box.

Changed files:
MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutputPersistencyOutputHandler.java
MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatCscConflictResolutionOutputHandler.java
MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationOutputHandler.java
MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatTask.java
MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutput.java
MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationNwayTask.java
WorkcraftCore/src/org/workcraft/gui/trees/TreeWindow.java
StgPlugin/src/org/workcraft/plugins/stg/StgUtils.java
MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationTask.java

diff --git a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationNwayTask.java b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationNwayTask.java
index 56f648611..013fea9aa 100644
--- a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationNwayTask.java
+++ b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationNwayTask.java
@@ -95,7 +95,6 @@ public class MpsatConformationNwayTask implements Task<MpsatChainOutput> {
             // Generating .g for the whole system (model and environment)
             File stgFile = new File(directory, StgUtils.SYSTEM_FILE_PREFIX + stgFileExtension);
             File detailFile = new File(directory, StgUtils.DETAIL_FILE_PREFIX + StgUtils.XML_FILE_EXTENSION);
-            stgFile.deleteOnExit();
             PcompTask pcompTask = new PcompTask(stgFiles.toArray(new File[0]), stgFile, detailFile,
                     ConversionMode.OUTPUT, false, false, directory);
 
diff --git a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationOutputHandler.java b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationOutputHandler.java
index a4fe40b47..da052c031 100644
--- a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationOutputHandler.java
+++ b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationOutputHandler.java
@@ -1,6 +1,7 @@
 package org.workcraft.plugins.mpsat.tasks;
 
 import java.util.HashMap;
+import java.util.HashSet;
 
 import org.workcraft.Trace;
 import org.workcraft.plugins.mpsat.MpsatParameters;
@@ -11,6 +12,7 @@ import org.workcraft.plugins.petri.Place;
 import org.workcraft.plugins.stg.SignalTransition;
 import org.workcraft.plugins.stg.SignalTransition.Type;
 import org.workcraft.plugins.stg.StgModel;
+import org.workcraft.plugins.stg.StgUtils;
 import org.workcraft.util.LogUtils;
 import org.workcraft.workspace.WorkspaceEntry;
 
@@ -22,32 +24,42 @@ class MpsatConformationOutputHandler extends MpsatReachabilityOutputHandler {
 
     @Override
     public MpsatSolution processSolution(MpsatSolution solution, ComponentData data) {
+        final StgModel compStg = getMpsatOutput().getInputStg();
         StgModel stg = getSrcStg(data);
-        if ((solution == null) || (stg == null)) {
+        if ((solution == null) || (compStg == null) || (stg == null)) {
             return solution;
         }
-        LogUtils.logMessage("Processing reported trace: " + solution.getMainTrace());
-        Trace trace = getProjectedTrace(solution.getMainTrace(), data);
         MpsatSolution result = null;
-        HashMap<Place, Integer> marking = PetriUtils.getMarking(stg);
-        if (!PetriUtils.fireTrace(stg, trace)) {
-            LogUtils.logWarning("Cannot execute projected trace: " + trace);
+        Trace compTrace = solution.getMainTrace();
+        LogUtils.logMessage("Processing reported composition trace: " + compTrace);
+        HashMap<Place, Integer> compMarking = PetriUtils.getMarking(compStg);
+        if (!PetriUtils.fireTrace(compStg, compTrace)) {
+            LogUtils.logError("Cannot execute reported composition trace: " + compTrace);
         } else {
-            for (SignalTransition transition: stg.getSignalTransitions()) {
-                if (stg.isEnabled(transition) && (transition.getSignalType() == Type.OUTPUT)) {
-                    String signalRef = transition.getSignalName();
-                    LogUtils.logMessage("Output '" + signalRef + "' is unexpectedly enabled after projected trace: " + trace);
-                    trace.add(stg.getNodeReference(transition));
-                    String comment = "Unexpected change of output '" + signalRef + "'";
-                    result = new MpsatSolution(trace, null, comment);
-                    break;
+            HashSet<String> compEnabledSignals = StgUtils.getEnabledSignals(compStg);
+            Trace trace = getProjectedTrace(compTrace, data);
+            HashMap<Place, Integer> marking = PetriUtils.getMarking(stg);
+            if (!PetriUtils.fireTrace(stg, trace)) {
+                LogUtils.logError("Cannot execute projected trace: " + trace);
+            } else {
+                for (SignalTransition transition: stg.getSignalTransitions()) {
+                    if (stg.isEnabled(transition) && (transition.getSignalType() == Type.OUTPUT)
+                            && !compEnabledSignals.contains(transition.getSignalName())) {
+                        String signalRef = transition.getSignalName();
+                        LogUtils.logWarning("Output '" + signalRef + "' is unexpectedly enabled after projected trace: " + trace);
+                        trace.add(stg.getNodeReference(transition));
+                        String comment = "Unexpected change of output '" + signalRef + "'";
+                        result = new MpsatSolution(trace, null, comment);
+                        break;
+                    }
+                }
+                if (result == null) {
+                    LogUtils.logMessage("No outputs are enabled after projected trace: " + trace);
                 }
             }
+            PetriUtils.setMarking(stg, marking);
         }
-        PetriUtils.setMarking(stg, marking);
-        if (result == null) {
-            LogUtils.logMessage("No outputs are enabled after projected trace: " + trace);
-        }
+        PetriUtils.setMarking(compStg, compMarking);
         return result;
     }
 
diff --git a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationTask.java b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationTask.java
index 3446f51b4..331e5108e 100644
--- a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationTask.java
+++ b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatConformationTask.java
@@ -109,7 +109,6 @@ public class MpsatConformationTask extends MpsatChainTask {
             // Generating .g for the whole system (model and environment)
             File detailFile = new File(directory, StgUtils.DETAIL_FILE_PREFIX + StgUtils.XML_FILE_EXTENSION);
             File stgFile = new File(directory, StgUtils.SYSTEM_FILE_PREFIX + stgFileExtension);
-            stgFile.deleteOnExit();
             PcompTask pcompTask = new PcompTask(new File[]{devStgFile, envStgFile}, stgFile, detailFile,
                     ConversionMode.OUTPUT, true, false, directory);
 
diff --git a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatCscConflictResolutionOutputHandler.java b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatCscConflictResolutionOutputHandler.java
index 330fca014..9f1e7d944 100644
--- a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatCscConflictResolutionOutputHandler.java
+++ b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatCscConflictResolutionOutputHandler.java
@@ -1,16 +1,13 @@
 package org.workcraft.plugins.mpsat.tasks;
 
-import java.io.ByteArrayInputStream;
 import java.util.Collection;
 
 import org.workcraft.Framework;
-import org.workcraft.exceptions.DeserialisationException;
 import org.workcraft.gui.workspace.Path;
 import org.workcraft.plugins.stg.Mutex;
 import org.workcraft.plugins.stg.MutexUtils;
 import org.workcraft.plugins.stg.StgDescriptor;
 import org.workcraft.plugins.stg.StgModel;
-import org.workcraft.plugins.stg.interop.StgImporter;
 import org.workcraft.util.DialogUtils;
 import org.workcraft.workspace.ModelEntry;
 import org.workcraft.workspace.WorkspaceEntry;
@@ -29,22 +26,10 @@ public class MpsatCscConflictResolutionOutputHandler implements Runnable {
         this.mutexes = mutexes;
     }
 
-    private StgModel getResolvedStg() {
-        final byte[] content = output.getStgOutput();
-        if (content == null) {
-            return null;
-        }
-        try {
-            return new StgImporter().importStg(new ByteArrayInputStream(content));
-        } catch (final DeserialisationException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     @Override
     public void run() {
         final Framework framework = Framework.getInstance();
-        final StgModel model = getResolvedStg();
+        final StgModel model = output.getOutputStg();
         if (model == null) {
             final String errorMessage = output.getErrorsHeadAndTail();
             DialogUtils.showWarning("Conflict resolution failed. MPSat output: \\n" + errorMessage);
diff --git a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutput.java b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutput.java
index c5720beac..93afdebdc 100644
--- a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutput.java
+++ b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutput.java
@@ -1,28 +1,29 @@
 package org.workcraft.plugins.mpsat.tasks;
 
 import org.workcraft.plugins.shared.tasks.ExternalProcessOutput;
+import org.workcraft.plugins.stg.StgModel;
 
 public class MpsatOutput extends ExternalProcessOutput {
 
-    private final byte[] stgInput;
-    private final byte[] stgOutput;
+    private final StgModel inputStg;
+    private final StgModel outputStg;
 
     public MpsatOutput(ExternalProcessOutput output) {
         this(output, null, null);
     }
 
-    public MpsatOutput(ExternalProcessOutput output, byte[] stgInput, byte[] stgOutput) {
+    public MpsatOutput(ExternalProcessOutput output, StgModel inputStg, StgModel outputStg) {
         super(output.getReturnCode(), output.getStdout(), output.getStderr());
-        this.stgInput = stgInput;
-        this.stgOutput = stgOutput;
+        this.inputStg = inputStg;
+        this.outputStg = outputStg;
     }
 
-    public byte[] getStgInput() {
-        return stgInput;
+    public StgModel getInputStg() {
+        return inputStg;
     }
 
-    public byte[] getStgOutput() {
-        return stgOutput;
+    public StgModel getOutputStg() {
+        return outputStg;
     }
 
 }
diff --git a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutputPersistencyOutputHandler.java b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutputPersistencyOutputHandler.java
index 9a72a7836..8be3b5837 100644
--- a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutputPersistencyOutputHandler.java
+++ b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatOutputPersistencyOutputHandler.java
@@ -11,8 +11,8 @@ import org.workcraft.plugins.pcomp.tasks.PcompOutput;
 import org.workcraft.plugins.petri.PetriUtils;
 import org.workcraft.plugins.petri.Place;
 import org.workcraft.plugins.stg.SignalTransition;
-import org.workcraft.plugins.stg.SignalTransition.Type;
 import org.workcraft.plugins.stg.StgModel;
+import org.workcraft.plugins.stg.StgUtils;
 import org.workcraft.util.LogUtils;
 import org.workcraft.workspace.WorkspaceEntry;
 
@@ -35,12 +35,12 @@ class MpsatOutputPersistencyOutputHandler extends MpsatReachabilityOutputHandler
         if (!PetriUtils.fireTrace(stg, trace)) {
             LogUtils.logWarning("Cannot execute projected trace: " + trace);
         } else {
-            HashSet<String> enabledLocalSignals = getEnabledLocalSignals(stg);
-            for (SignalTransition transition: getEnabledSignalTransitions(stg)) {
+            HashSet<String> enabledLocalSignals = StgUtils.getEnabledLocalSignals(stg);
+            for (SignalTransition transition: StgUtils.getEnabledSignalTransitions(stg)) {
                 stg.fire(transition);
                 HashSet<String> nonpersistentLocalSignals = new HashSet<>(enabledLocalSignals);
                 nonpersistentLocalSignals.remove(transition.getSignalName());
-                nonpersistentLocalSignals.removeAll(getEnabledLocalSignals(stg));
+                nonpersistentLocalSignals.removeAll(StgUtils.getEnabledLocalSignals(stg));
                 if (!nonpersistentLocalSignals.isEmpty()) {
                     String comment = null;
                     String signalList = ReferenceHelper.getReferencesAsString(nonpersistentLocalSignals);
@@ -64,24 +64,4 @@ class MpsatOutputPersistencyOutputHandler extends MpsatReachabilityOutputHandler
         return result;
     }
 
-    private HashSet<SignalTransition> getEnabledSignalTransitions(StgModel stg) {
-        HashSet<SignalTransition> result = new HashSet<>();
-        for (SignalTransition transition: stg.getSignalTransitions()) {
-            if (stg.isEnabled(transition)) {
-                result.add(transition);
-            }
-        }
-        return result;
-    }
-
-    private HashSet<String> getEnabledLocalSignals(StgModel stg) {
-        HashSet<String> result = new HashSet<>();
-        for (SignalTransition transition: getEnabledSignalTransitions(stg)) {
-            if ((transition.getSignalType() == Type.OUTPUT) || (transition.getSignalType() == Type.INTERNAL)) {
-                result.add(transition.getSignalName());
-            }
-        }
-        return result;
-    }
-
 }
diff --git a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatTask.java b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatTask.java
index 6b1385db6..5fee4c948 100644
--- a/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatTask.java
+++ b/MpsatVerificationPlugin/src/org/workcraft/plugins/mpsat/tasks/MpsatTask.java
@@ -1,15 +1,19 @@
 package org.workcraft.plugins.mpsat.tasks;
 
 import java.io.File;
-import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.workcraft.exceptions.DeserialisationException;
 import org.workcraft.plugins.mpsat.MpsatSettings;
 import org.workcraft.plugins.punf.tasks.PunfTask;
 import org.workcraft.plugins.shared.tasks.ExternalProcessOutput;
 import org.workcraft.plugins.shared.tasks.ExternalProcessTask;
+import org.workcraft.plugins.stg.StgModel;
+import org.workcraft.plugins.stg.interop.StgImporter;
 import org.workcraft.tasks.ProgressMonitor;
 import org.workcraft.tasks.Result;
 import org.workcraft.tasks.Result.Outcome;
@@ -135,21 +139,9 @@ public class MpsatTask implements Task<MpsatOutput> {
             if (!success) {
                 return Result.failure(new MpsatOutput(output));
             } else {
-                byte[] netInput = null;
-                byte[] stgOutput = null;
-                try {
-                    if ((netFile != null) && netFile.exists()) {
-                        netInput = FileUtils.readAllBytes(netFile);
-                    }
-                    File stgFile = new File(directory, STG_FILE_NAME);
-                    if (stgFile.exists()) {
-                        stgOutput = FileUtils.readAllBytes(stgFile);
-                    }
-                } catch (IOException e) {
-                    return Result.exception(e);
-                }
-
-                return Result.success(new MpsatOutput(output, netInput, stgOutput));
+                StgModel inputStg = readStg(netFile);
+                StgModel outputStg = readStg(new File(directory, STG_FILE_NAME));
+                return Result.success(new MpsatOutput(output, inputStg, outputStg));
             }
         }
 
@@ -160,4 +152,17 @@ public class MpsatTask implements Task<MpsatOutput> {
         return Result.failure();
     }
 
+    private StgModel readStg(File file) {
+        if ((file != null) && file.exists()) {
+            try {
+                StgImporter importer = new StgImporter();
+                FileInputStream is = new FileInputStream(file);
+                return importer.importStg(is);
+            } catch (final DeserialisationException | FileNotFoundException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        return null;
+    }
+
 }
diff --git a/StgPlugin/src/org/workcraft/plugins/stg/StgUtils.java b/StgPlugin/src/org/workcraft/plugins/stg/StgUtils.java
index ad2778573..96001d8b8 100644
--- a/StgPlugin/src/org/workcraft/plugins/stg/StgUtils.java
+++ b/StgPlugin/src/org/workcraft/plugins/stg/StgUtils.java
@@ -4,6 +4,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Set;
 
 import org.workcraft.Framework;
@@ -198,4 +199,32 @@ public class StgUtils {
         return result;
     }
 
+    public static HashSet<SignalTransition> getEnabledSignalTransitions(StgModel stg) {
+        HashSet<SignalTransition> result = new HashSet<>();
+        for (SignalTransition transition: stg.getSignalTransitions()) {
+            if (stg.isEnabled(transition)) {
+                result.add(transition);
+            }
+        }
+        return result;
+    }
+
+    public static HashSet<String> getEnabledLocalSignals(StgModel stg) {
+        HashSet<String> result = new HashSet<>();
+        for (SignalTransition transition: getEnabledSignalTransitions(stg)) {
+            if ((transition.getSignalType() == Type.OUTPUT) || (transition.getSignalType() == Type.INTERNAL)) {
+                result.add(transition.getSignalName());
+            }
+        }
+        return result;
+    }
+
+    public static HashSet<String> getEnabledSignals(StgModel stg) {
+        HashSet<String> result = new HashSet<>();
+        for (SignalTransition transition: getEnabledSignalTransitions(stg)) {
+            result.add(transition.getSignalName());
+        }
+        return result;
+    }
+
 }
diff --git a/WorkcraftCore/src/org/workcraft/gui/trees/TreeWindow.java b/WorkcraftCore/src/org/workcraft/gui/trees/TreeWindow.java
index cd31409eb..148078407 100644
--- a/WorkcraftCore/src/org/workcraft/gui/trees/TreeWindow.java
+++ b/WorkcraftCore/src/org/workcraft/gui/trees/TreeWindow.java
@@ -29,40 +29,43 @@ import info.clearthought.layout.TableLayout;
 
 public class TreeWindow<Node> extends JPanel {
 
-    private final class RefreshKeyAdapter extends KeyAdapter {
+    private final class TreeSourceAdapterImplementation extends TreeSourceAdapter<Node> {
+        private final TreeDecorator<Node> decorator;
         private final TreeSource<Node> source;
 
-        private RefreshKeyAdapter(TreeSource<Node> source) {
+        private TreeSourceAdapterImplementation(TreeSource<Node> source, TreeDecorator<Node> decorator) {
+            super(source);
+            this.decorator = decorator;
             this.source = source;
         }
 
         @Override
-        public void keyPressed(KeyEvent e) {
-            if (e.getKeyCode() == KeyEvent.VK_F5) {
-                sourceWithRestructuredTrapped.getListener().restructured(Path.root(source.getRoot()));
-            }
-        }
-    }
+        public TreeListener<Node> getListener(final TreeListener<Node> chain) {
+            return new TreeListenerAdapter<Node>(chain) {
+                @Override
+                public void restructured(Path<Node> path) {
+                    List<TreePath> expanded = new ArrayList<>();
+                    for (int i = 0; i < tree.getRowCount(); i++) {
+                        final TreePath treePath = tree.getPathForRow(i);
+                        if (tree.isExpanded(i)) {
+                            expanded.add(treePath);
+                        }
+                    }
 
-    private final class ClickMouseAdapter extends MouseAdapter {
-        @SuppressWarnings("unchecked")
-        @Override
-        public void mouseClicked(MouseEvent e) {
-            final int x = e.getX();
-            final int y = e.getY();
-            int row = tree.getClosestRowForLocation(x, y);
-            if (row != -1) {
-                final Rectangle rowBounds = tree.getRowBounds(row);
-                if (rowBounds.contains(x, y)) {
-                    Node node = (Node) tree.getPathForRow(row).getLastPathComponent();
-                    if (checkedNodes.contains(node)) {
-                        checkedNodes.remove(node);
-                    } else {
-                        checkedNodes.add(node);
+                    if (!externalExpanded) {
+                        for (Node n : source.getChildren(getRoot())) {
+                            if (Workspace.EXTERNAL_PATH.equals(decorator.getName(n))) {
+                                expanded.add(new TreePath(Path.getPath(source.getPath(n)).toArray()));
+                                externalExpanded = true;
+                            }
+                        }
+                    }
+                    super.restructured(path);
+                    for (TreePath p : expanded) {
+                        tree.expandPath(p);
                     }
-                    tree.repaint(rowBounds);
                 }
-            }
+            };
         }
     }
 
@@ -99,6 +102,37 @@ public class TreeWindow<Node> extends JPanel {
         }
     }
 
+    private final class ClickMouseAdapter extends MouseAdapter {
+        private final TreeSource<Node> source;
+
+        private ClickMouseAdapter(TreeSource<Node> source) {
+            this.source = source;
+        }
+
+        @Override
+        public void mouseClicked(MouseEvent e) {
+            final int x = e.getX();
+            final int y = e.getY();
+            int row = tree.getClosestRowForLocation(x, y);
+            if (row != -1) {
+                final Rectangle rowBounds = tree.getRowBounds(row);
+                if (rowBounds.contains(x, y)) {
+                    @SuppressWarnings("unchecked")
+                    Node node = (Node) tree.getPathForRow(row).getLastPathComponent();
+                    if ((checkBoxMode == CheckBoxMode.ALL)
+                            || ((checkBoxMode == CheckBoxMode.LEAF) && source.isLeaf(node))) {
+                        if (checkedNodes.contains(node)) {
+                            checkedNodes.remove(node);
+                        } else {
+                            checkedNodes.add(node);
+                        }
+                        tree.repaint(rowBounds);
+                    }
+                }
+            }
+        }
+    }
+
     private final class TreeCellRenderer extends DefaultTreeCellRenderer {
         private final TreeSource<Node> source;
         private final TreeDecorator<Node> decorator;
@@ -119,12 +153,12 @@ public class TreeWindow<Node> extends JPanel {
             layout.setVGap(SizeHelper.getLayoutVGap());
         }
 
-        @SuppressWarnings("unchecked")
         @Override
         public Component getTreeCellRendererComponent(JTree tree,
                 Object value, boolean sel, boolean expanded, boolean leaf,
                 int row, boolean hasFocus) {
 
+            @SuppressWarnings("unchecked")
             Node node = (Node) value;
 
             String name = decorator.getName(node);
@@ -144,67 +178,29 @@ public class TreeWindow<Node> extends JPanel {
                 setIcon(icon);
             }
             cellRenderer.removeAll();
-
-            switch (checkBoxMode) {
-            case NONE:
+            if ((checkBoxMode == CheckBoxMode.NONE) || ((checkBoxMode == CheckBoxMode.LEAF) && !source.isLeaf(node))) {
                 return res;
-            case LEAF:
-                if (source.isLeaf(node)) {
-                    cellRenderer.add(checkBox, "0 0");
-                    cellRenderer.add(res, "1 0");
-                } else {
-                    return res;
-                }
-
-                break;
-            case ALL:
-                cellRenderer.add(checkBox, "0 0");
-                cellRenderer.add(res, "1 0");
-                break;
             }
-
+            cellRenderer.add(checkBox, "0 0");
+            cellRenderer.add(res, "1 0");
             checkBox.setSelected(checkedNodes.contains(node));
             return cellRenderer;
         }
     }
 
-    private final class TreeSourceAdapterImplementation extends TreeSourceAdapter<Node> {
-        private final TreeDecorator<Node> decorator;
+    private final class RefreshKeyAdapter extends KeyAdapter {
         private final TreeSource<Node> source;
 
-        private TreeSourceAdapterImplementation(TreeSource<Node> source, TreeDecorator<Node> decorator) {
-            super(source);
-            this.decorator = decorator;
+        private RefreshKeyAdapter(TreeSource<Node> source) {
             this.source = source;
         }
 
         @Override
-        public TreeListener<Node> getListener(final TreeListener<Node> chain) {
-            return new TreeListenerAdapter<Node>(chain) {
-                @Override
-                public void restructured(Path<Node> path) {
-                    List<TreePath> expanded = new ArrayList<>();
-                    for (int i = 0; i < tree.getRowCount(); i++) {
-                        final TreePath treePath = tree.getPathForRow(i);
-                        if (tree.isExpanded(i)) {
-                            expanded.add(treePath);
-                        }
-                    }
-
-                    if (!externalExpanded) {
-                        for (Node n : source.getChildren(getRoot())) {
-                            if (Workspace.EXTERNAL_PATH.equals(decorator.getName(n))) {
-                                expanded.add(new TreePath(Path.getPath(source.getPath(n)).toArray()));
-                                externalExpanded = true;
-                            }
-                        }
-                    }
-                    super.restructured(path);
-                    for (TreePath p : expanded) {
-                        tree.expandPath(p);
-                    }
-                }
-            };
+        public void keyPressed(KeyEvent e) {
+            if (e.getKeyCode() == KeyEvent.VK_F5) {
+                Path<Node> root = Path.root(source.getRoot());
+                sourceWithRestructuredTrapped.getListener().restructured(root);
+            }
         }
     }
 
@@ -218,7 +214,6 @@ public class TreeWindow<Node> extends JPanel {
     private final TreePopupProvider<Node> popupProvider;
     private final Set<Node> checkedNodes = new HashSet<>();
     private CheckBoxMode checkBoxMode = CheckBoxMode.NONE;
-
     private JCheckBox checkBox;
 
     public TreeWindow(TreeSource<Node> source, TreeDecorator<Node> decorator, TreePopupProvider<Node> popupProvider) {
@@ -242,7 +237,8 @@ public class TreeWindow<Node> extends JPanel {
     public void setCheckBoxMode(CheckBoxMode mode) {
         this.checkBoxMode = mode;
         checkedNodes.clear();
-        sourceWithRestructuredTrapped.getListener().restructured(Path.root(sourceWithRestructuredTrapped.getRoot()));
+        Path<Node> root = Path.root(sourceWithRestructuredTrapped.getRoot());
+        sourceWithRestructuredTrapped.getListener().restructured(root);
     }
 
     public void clearCheckBoxes() {
@@ -271,7 +267,7 @@ public class TreeWindow<Node> extends JPanel {
         if (popupProvider != null) {
             tree.addMouseListener(new PopupMouseAdapter(source));
         }
-        tree.addMouseListener(new ClickMouseAdapter());
+        tree.addMouseListener(new ClickMouseAdapter(source));
         tree.setCellRenderer(new TreeCellRenderer(source, decorator));
         tree.addKeyListener(new RefreshKeyAdapter(source));
         setLayout(new BorderLayout());