diff --git a/src/main/java/plugins/adufour/blocks/util/BlocksML.java b/src/main/java/plugins/adufour/blocks/util/BlocksML.java
index 346b0ae493f7bd2123b6baa650c2f65d7efb8bc7..58a5e504bb49e435b209cfacf109bfd2d7247b31 100644
--- a/src/main/java/plugins/adufour/blocks/util/BlocksML.java
+++ b/src/main/java/plugins/adufour/blocks/util/BlocksML.java
@@ -354,7 +354,7 @@ public class BlocksML {
         // scan the protocol for missing plugins
         final Set<String> missingPlugins = getMissingPlugins(xmlRoot, fileVersion);
 
-        if (missingPlugins.size() > 0) {
+        if (!missingPlugins.isEmpty()) {
             // Are we connected to the internet?
             if (!NetworkUtil.hasInternetAccess())
                 throw new IcyHandledException("Some plugins required by this protocol are missing, but no internet connection is available");
@@ -379,7 +379,7 @@ public class BlocksML {
                 if (pDesc == null) {
                     // sadly, I believe the plugin loader could be reloaded at anytime...
                     // double check that for every plugin, just to be safe
-                    if (PluginLoader.getPlugins(Block.class, true, false, false).size() == 0)
+                    if (PluginLoader.getPlugins(Block.class, true, false, false).isEmpty())
                         throw new BlocksReloadedException();
 
                     throw new BlocksException("Couldn't find plugin " + ClassUtil.getSimpleClassName(className) + " online", true);
@@ -402,7 +402,7 @@ public class BlocksML {
         }
 
         switch (fileVersion) {
-            /*case 1:
+            case 1:
                 loadWorkFlow_V1(xmlRoot, targetWorkFlow);
                 break;
             case 2:
@@ -410,7 +410,7 @@ public class BlocksML {
                 break;
             case 3:
                 loadWorkFlow_V3(xmlRoot, targetWorkFlow);
-                break;*/
+                break;
             case 4:
                 loadWorkFlow_V4(xmlRoot, targetWorkFlow);
                 break;
@@ -465,6 +465,374 @@ public class BlocksML {
         return missingPlugins;
     }
 
+    /**
+     * @param workFlowRoot XML element of the workflow root to be loaded.
+     * @param workFlow     Target workflow to add elements from document.
+     */
+    private synchronized void loadWorkFlow_V1(final Element workFlowRoot, final WorkFlow workFlow) {
+        final Element blocksRoot = XMLUtil.getElement(workFlowRoot, "blocks");
+
+        final ArrayList<Element> blocksNode = XMLUtil.getElements(blocksRoot);
+
+        for (final Element blockNode : blocksNode) {
+            final String className = XMLUtil.getAttributeValue(blockNode, "type", null);
+
+            final int xPos = XMLUtil.getAttributeIntValue(blockNode, "xLocation", 0);
+            final int yPos = XMLUtil.getAttributeIntValue(blockNode, "yLocation", 0);
+
+            try {
+                @SuppressWarnings("unchecked") final Class<? extends Block> blockClass = (Class<? extends Block>) ClassUtil.findClass(className);
+
+                final Block block = blockClass.getConstructor().newInstance();
+
+                if (block == null)
+                    throw new BlocksException("Couldn't create block from class " + blockClass.getName(), true);
+
+                if (block instanceof WorkFlow) {
+                    // load the inner work flow
+                    loadWorkFlow_V1(blockNode, (WorkFlow) block);
+
+                    final BlockDescriptor blockDescriptor = ((WorkFlow) block).getBlockDescriptor();
+                    blockDescriptor.setContainer((WorkFlow) block);
+                    blockDescriptor.setLocation(xPos, yPos);
+
+                    workFlow.addBlock(blockDescriptor);
+
+                    // adjust visibility triggers
+                    {
+                        final Element varRoot = XMLUtil.getElement(blockNode, "variables");
+
+                        final Element inVarRoot = XMLUtil.getElement(varRoot, "input");
+
+                        for (final Element varNode : XMLUtil.getElements(inVarRoot)) {
+                            final int id = XMLUtil.getAttributeIntValue(varNode, "ID", -1);
+                            final Var<?> var = blockDescriptor.inputVars.get(id);
+                            final boolean visible = XMLUtil.getAttributeBooleanValue(varNode, "visible", false);
+                            blockDescriptor.inputVars.setVisible(var, visible);
+                        }
+                        final Element outVarRoot = XMLUtil.getElement(varRoot, "output");
+
+                        for (final Element varNode : XMLUtil.getElements(outVarRoot)) {
+                            final int id = XMLUtil.getAttributeIntValue(varNode, "ID", -1);
+                            final Var<?> var = blockDescriptor.outputVars.get(id);
+                            final boolean visible = XMLUtil.getAttributeBooleanValue(varNode, "visible", false);
+                            blockDescriptor.outputVars.setVisible(var, visible);
+                        }
+                    }
+                }
+                else {
+                    final BlockDescriptor blockDescriptor = new BlockDescriptor(-1, block);
+                    blockDescriptor.setContainer(workFlow);
+                    blockDescriptor.setLocation(xPos, yPos);
+
+                    workFlow.addBlock(blockDescriptor);
+
+                    final Element varRoot = XMLUtil.getElement(blockNode, "variables");
+                    final Element inVarRoot = XMLUtil.getElement(varRoot, "input");
+                    for (final Element varNode : XMLUtil.getElements(inVarRoot)) {
+                        final int id = XMLUtil.getAttributeIntValue(varNode, Var.XML_KEY_ID, -1);
+                        final Var<?> var = blockDescriptor.inputVars.get(id);
+                        var.loadFromXML(varNode);
+                        blockDescriptor.inputVars.setVisible(var, XMLUtil.getAttributeBooleanValue(varNode, "visible", false));
+                    }
+                    final Element outVarRoot = XMLUtil.getElement(varRoot, "output");
+                    for (final Element varNode : XMLUtil.getElements(outVarRoot)) {
+                        final int id = XMLUtil.getAttributeIntValue(varNode, Var.XML_KEY_ID, -1);
+                        final Var<?> var = blockDescriptor.outputVars.get(id);
+                        var.loadFromXML(varNode);
+                        blockDescriptor.outputVars.setVisible(var, XMLUtil.getAttributeBooleanValue(varNode, "visible", false));
+                    }
+                }
+            }
+            catch (final Exception e1) {
+                throw new BlocksException("Cannot create block (" + e1.getMessage() + ")", true);
+            }
+        }
+
+        final Element linkRoot = XMLUtil.getElement(workFlowRoot, "links");
+
+        for (final Element linkNode : XMLUtil.getElements(linkRoot)) {
+            final int srcBlockID = XMLUtil.getAttributeIntValue(linkNode, "srcBlockID", -1);
+            final int srcVarID = XMLUtil.getAttributeIntValue(linkNode, "srcVarID", -1);
+            final int dstBlockID = XMLUtil.getAttributeIntValue(linkNode, "dstBlockID", -1);
+            final int dstVarID = XMLUtil.getAttributeIntValue(linkNode, "dstVarID", -1);
+
+            final BlockDescriptor srcBlock = workFlow.getBlock(srcBlockID);
+            // this is assumed correct
+            final Var<Object> srcVar = srcBlock.outputVars.get(srcVarID);
+
+            final BlockDescriptor dstBlock = workFlow.getBlock(dstBlockID);
+            // this is assumed correct
+            final Var<Object> dstVar = dstBlock.inputVars.get(dstVarID);
+
+            workFlow.addLink(srcBlock, srcVar, dstBlock, dstVar);
+        }
+    }
+
+    /**
+     * @param workFlowRoot XML element of the workflow root to be loaded.
+     * @param workFlow     Target workflow to add elements from document.
+     */
+    private synchronized void loadWorkFlow_V2(final Element workFlowRoot, final WorkFlow workFlow) {
+        final Element blocksRoot = XMLUtil.getElement(workFlowRoot, "blocks");
+
+        final ArrayList<Element> blocksNode = XMLUtil.getElements(blocksRoot);
+
+        for (final Element blockNode : blocksNode) {
+            final String className = XMLUtil.getAttributeValue(blockNode, "type", null);
+
+            final int xPos = XMLUtil.getAttributeIntValue(blockNode, "xLocation", -1);
+            final int yPos = XMLUtil.getAttributeIntValue(blockNode, "yLocation", -1);
+
+            try {
+                @SuppressWarnings("unchecked") final Class<? extends Block> blockClass = (Class<? extends Block>) ClassUtil.findClass(className);
+
+                final Block block = blockClass.getDeclaredConstructor().newInstance();
+
+                if (block == null)
+                    throw new BlocksException("Couldn't create block from class " + blockClass.getName(), true);
+
+                if (block instanceof WorkFlow) {
+                    final BlockDescriptor blockDescriptor = ((WorkFlow) block).getBlockDescriptor();
+                    blockDescriptor.setContainer((WorkFlow) block);
+                    blockDescriptor.setLocation(xPos, yPos);
+
+                    workFlow.addBlock(blockDescriptor);
+
+                    // load the inner work flow
+                    loadWorkFlow_V2(blockNode, (WorkFlow) block);
+
+                    // adjust visibility triggers
+                    {
+                        final Element varRoot = XMLUtil.getElement(blockNode, "variables");
+
+                        final Element inVarRoot = XMLUtil.getElement(varRoot, "input");
+
+                        for (final Element varNode : XMLUtil.getElements(inVarRoot)) {
+                            final String uid = XMLUtil.getAttributeValue(varNode, "ID", null);
+                            final Var<?> var = blockDescriptor.inputVars.get(uid);
+                            final boolean visible = XMLUtil.getAttributeBooleanValue(varNode, "visible", false);
+                            blockDescriptor.inputVars.setVisible(var, visible);
+                        }
+                        final Element outVarRoot = XMLUtil.getElement(varRoot, "output");
+
+                        for (final Element varNode : XMLUtil.getElements(outVarRoot)) {
+                            final String uid = XMLUtil.getAttributeValue(varNode, "ID", null);
+                            final Var<?> var = blockDescriptor.outputVars.get(uid);
+                            final boolean visible = XMLUtil.getAttributeBooleanValue(varNode, "visible", false);
+                            blockDescriptor.outputVars.setVisible(var, visible);
+                        }
+                    }
+                }
+                else {
+                    final BlockDescriptor blockDescriptor = new BlockDescriptor(-1, block);
+                    blockDescriptor.setContainer(workFlow);
+                    blockDescriptor.setLocation(xPos, yPos);
+
+                    workFlow.addBlock(blockDescriptor);
+
+                    final Element varRoot = XMLUtil.getElement(blockNode, "variables");
+                    final Element inVarRoot = XMLUtil.getElement(varRoot, "input");
+                    for (final Element varNode : XMLUtil.getElements(inVarRoot)) {
+                        final String uid = XMLUtil.getAttributeValue(varNode, "ID", null);
+                        final Var<?> var = blockDescriptor.inputVars.get(uid);
+                        var.loadFromXML(varNode);
+                        blockDescriptor.inputVars.setVisible(var, XMLUtil.getAttributeBooleanValue(varNode, "visible", false));
+
+                        if (var instanceof MutableType) {
+                            final String type = XMLUtil.getAttributeValue(varNode, "type", null);
+                            if (type != null) {
+                                if (var instanceof VarMutable) {
+                                    ((MutableType) var).setType(Class.forName(type));
+                                }
+                                else if (var instanceof VarMutableArray) {
+                                    ((MutableType) var).setType(Class.forName("[L" + type + ";"));
+                                }
+                            }
+                        }
+                    }
+                    final Element outVarRoot = XMLUtil.getElement(varRoot, "output");
+                    for (final Element varNode : XMLUtil.getElements(outVarRoot)) {
+                        final String uid = XMLUtil.getAttributeValue(varNode, "ID", null);
+                        final Var<?> var = blockDescriptor.outputVars.get(uid);
+                        var.loadFromXML(varNode);
+                        blockDescriptor.outputVars.setVisible(var, XMLUtil.getAttributeBooleanValue(varNode, "visible", false));
+
+                        if (var instanceof MutableType) {
+                            final String type = XMLUtil.getAttributeValue(varNode, "type", null);
+                            if (type != null) {
+                                if (var instanceof VarMutable) {
+                                    ((MutableType) var).setType(Class.forName(type));
+                                }
+                                else if (var instanceof VarMutableArray) {
+                                    ((MutableType) var).setType(Class.forName("[L" + type + ";"));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (final Exception e1) {
+                throw new BlocksException("Cannot create block (" + e1.getMessage() + ")", true);
+            }
+        }
+
+        final Element linkRoot = XMLUtil.getElement(workFlowRoot, "links");
+
+        for (final Element linkNode : XMLUtil.getElements(linkRoot)) {
+            final int srcBlockID = XMLUtil.getAttributeIntValue(linkNode, "srcBlockID", -1);
+            final String srcVarID = XMLUtil.getAttributeValue(linkNode, "srcVarID", null);
+            final int dstBlockID = XMLUtil.getAttributeIntValue(linkNode, "dstBlockID", -1);
+            final String dstVarID = XMLUtil.getAttributeValue(linkNode, "dstVarID", null);
+
+            final BlockDescriptor srcBlock = workFlow.getBlock(srcBlockID);
+            Var<Object> srcVar = srcBlock.outputVars.get(srcVarID);
+            if (srcVar == null)
+                srcVar = srcBlock.inputVars.get(srcVarID);
+
+            final BlockDescriptor dstBlock = workFlow.getBlock(dstBlockID);
+            final Var<Object> dstVar = dstBlock.inputVars.get(dstVarID);
+
+            workFlow.addLink(srcBlock, srcVar, dstBlock, dstVar);
+        }
+    }
+
+    /**
+     * Legacy method for protocols V3.
+     *
+     * @param workFlowRoot XML element of the workflow root to be loaded.
+     * @param workFlow     Target workflow to add elements from document.
+     */
+    private synchronized void loadWorkFlow_V3(final Element workFlowRoot, final WorkFlow workFlow) {
+        final Element blocksRoot = XMLUtil.getElement(workFlowRoot, "blocks");
+
+        final ArrayList<Element> blocksNode = XMLUtil.getElements(blocksRoot);
+
+        for (final Element blockNode : blocksNode) {
+            final String blockType = XMLUtil.getAttributeValue(blockNode, "blockType", null);
+
+            final int xPos = XMLUtil.getAttributeIntValue(blockNode, "xLocation", -1);
+            final int yPos = XMLUtil.getAttributeIntValue(blockNode, "yLocation", -1);
+
+            try {
+                @SuppressWarnings("unchecked") final Class<? extends Block> blockClass = (Class<? extends Block>) ClassUtil.findClass(blockType);
+
+                final Block block = blockClass.getDeclaredConstructor().newInstance();
+
+                if (block == null)
+                    throw new BlocksException("Couldn't create block from class " + blockClass.getName(), true);
+
+                if (block instanceof WorkFlow) {
+                    final int width = XMLUtil.getAttributeIntValue(blockNode, "width", 500);
+                    final int height = XMLUtil.getAttributeIntValue(blockNode, "height", 500);
+
+                    final BlockDescriptor blockDescriptor = ((WorkFlow) block).getBlockDescriptor();
+                    blockDescriptor.setDimension(width, height);
+                    blockDescriptor.setContainer((WorkFlow) block);
+                    blockDescriptor.setLocation(xPos, yPos);
+
+                    workFlow.addBlock(blockDescriptor);
+
+                    // load the inner work flow
+                    loadWorkFlow_V3(blockNode, (WorkFlow) block);
+
+                    // adjust visibility triggers
+                    {
+                        final Element varRoot = XMLUtil.getElement(blockNode, "variables");
+
+                        final Element inVarRoot = XMLUtil.getElement(varRoot, "input");
+
+                        for (final Element varNode : XMLUtil.getElements(inVarRoot)) {
+                            final String uid = XMLUtil.getAttributeValue(varNode, "ID", null);
+                            final Var<?> var = blockDescriptor.inputVars.get(uid);
+                            final boolean visible = XMLUtil.getAttributeBooleanValue(varNode, "visible", false);
+                            blockDescriptor.inputVars.setVisible(var, visible);
+                        }
+                        final Element outVarRoot = XMLUtil.getElement(varRoot, "output");
+
+                        for (final Element varNode : XMLUtil.getElements(outVarRoot)) {
+                            final String uid = XMLUtil.getAttributeValue(varNode, "ID", null);
+                            final Var<?> var = blockDescriptor.outputVars.get(uid);
+                            final boolean visible = XMLUtil.getAttributeBooleanValue(varNode, "visible", false);
+                            blockDescriptor.outputVars.setVisible(var, visible);
+                        }
+                    }
+                }
+                else {
+                    final BlockDescriptor blockDescriptor = new BlockDescriptor(-1, block);
+                    blockDescriptor.setContainer(workFlow);
+                    blockDescriptor.setLocation(xPos, yPos);
+
+                    workFlow.addBlock(blockDescriptor);
+
+                    final Element varRoot = XMLUtil.getElement(blockNode, "variables");
+                    final Element inVarRoot = XMLUtil.getElement(varRoot, "input");
+                    for (final Element varNode : XMLUtil.getElements(inVarRoot)) {
+                        final String uid = XMLUtil.getAttributeValue(varNode, "ID", null);
+                        final Var<?> var = blockDescriptor.inputVars.get(uid);
+                        var.loadFromXML(varNode);
+                        blockDescriptor.inputVars.setVisible(var, XMLUtil.getAttributeBooleanValue(varNode, "visible", false));
+
+                        if (var instanceof MutableType) {
+                            final String type = XMLUtil.getAttributeValue(varNode, "type", null);
+                            if (type != null) {
+                                if (var instanceof VarMutable) {
+                                    ((MutableType) var).setType(Class.forName(type));
+                                }
+                                else if (var instanceof VarMutableArray) {
+                                    ((MutableType) var).setType(Class.forName("[L" + type + ";"));
+                                }
+                            }
+                        }
+                    }
+
+                    final Element outVarRoot = XMLUtil.getElement(varRoot, "output");
+                    for (final Element varNode : XMLUtil.getElements(outVarRoot)) {
+                        final String uid = XMLUtil.getAttributeValue(varNode, "ID", null);
+                        final Var<?> var = blockDescriptor.outputVars.get(uid);
+                        var.loadFromXML(varNode);
+                        blockDescriptor.outputVars.setVisible(var, XMLUtil.getAttributeBooleanValue(varNode, "visible", false));
+
+                        if (var instanceof MutableType) {
+                            final String type = XMLUtil.getAttributeValue(varNode, "type", null);
+                            if (type != null) {
+                                if (var instanceof VarMutable) {
+                                    ((MutableType) var).setType(Class.forName(type));
+                                }
+                                else if (var instanceof VarMutableArray) {
+                                    ((MutableType) var).setType(Class.forName("[L" + type + ";"));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            catch (final Exception e1) {
+                throw new BlocksException("Cannot create block (" + e1.getMessage() + ")", true);
+            }
+        }
+
+        final Element linkRoot = XMLUtil.getElement(workFlowRoot, "links");
+
+        for (final Element linkNode : XMLUtil.getElements(linkRoot)) {
+            final int srcBlockID = XMLUtil.getAttributeIntValue(linkNode, "srcBlockID", -1);
+            final String srcVarID = XMLUtil.getAttributeValue(linkNode, "srcVarID", null);
+            final int dstBlockID = XMLUtil.getAttributeIntValue(linkNode, "dstBlockID", -1);
+            final String dstVarID = XMLUtil.getAttributeValue(linkNode, "dstVarID", null);
+
+            final BlockDescriptor srcBlock = workFlow.getBlock(srcBlockID);
+            Var<Object> srcVar = srcBlock.outputVars.get(srcVarID);
+            if (srcVar == null)
+                srcVar = srcBlock.inputVars.get(srcVarID);
+
+            final BlockDescriptor dstBlock = workFlow.getBlock(dstBlockID);
+            final Var<Object> dstVar = dstBlock.inputVars.get(dstVarID);
+
+            workFlow.addLink(srcBlock, srcVar, dstBlock, dstVar);
+        }
+    }
+
+
     /**
      * @param workFlowRoot XML element of the workflow root to be loaded.
      * @param workFlow     Target workflow to add elements from the document.
diff --git a/src/main/java/plugins/adufour/blocks/util/VarList.java b/src/main/java/plugins/adufour/blocks/util/VarList.java
index 8c4525bcce66a5495fea5dc8c65fe3493264bdcf..8907e7ae8bff54c0942d2b9e67b7ce803c9ba0fb 100644
--- a/src/main/java/plugins/adufour/blocks/util/VarList.java
+++ b/src/main/java/plugins/adufour/blocks/util/VarList.java
@@ -155,6 +155,26 @@ public class VarList implements Iterable<Var<?>> {
         return var == null ? null : (Var<T>) var;
     }
 
+    /**
+     * Legacy method (used to load old XML work flows).
+     *
+     * @param <T>   Type of the variable value.
+     * @param varID Variable identifier.
+     * @return The stored variable.
+     * @throws NoSuchVariableException If no variable is not found with the given identifier
+     */
+    @SuppressWarnings("unchecked")
+    <T> Var<T> get(final int varID) throws NoSuchVariableException {
+        int id = 0;
+        for (final Var<?> var : this) {
+            if (id == varID)
+                return (Var<T>) var;
+            id++;
+        }
+        throw new NoSuchVariableException("No variable with ID " + varID);
+    }
+
+
     /**
      * Returns the unique ID of the specified variable. Although the underlying structure
      *