diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..188b1d84fb18c6553ac7919d819b07a11682e197
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry excluding="plugins/stef/micromanager/block/lang/VarChannels.java|plugins/stef/micromanager/block/lang/VarChannelsEditor.java|plugins/stef/micromanager/block/capture/MicroscopeSnapChannels.java|plugins/stef/micromanager/block/setting/MicroscopeChannels.java" kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk6"/>
+	<classpathentry kind="var" path="ICY_HOME/icy.jar"/>
+	<classpathentry kind="lib" path="/Icy-App/plugins/adufour/blocks/Blocks.jar"/>
+	<classpathentry kind="lib" path="/Icy-App/plugins/adufour/ezplug/EzPlug.jar"/>
+	<classpathentry kind="var" path="MM_HOME/plugins/Micro-Manager/MMCoreJ.jar"/>
+	<classpathentry kind="var" path="MM_HOME/plugins/Micro-Manager/MMJ_.jar" sourcepath="/GIT/micro-manager"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/Icy-MicroManager"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/Protocols"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/.project b/.project
new file mode 100644
index 0000000000000000000000000000000000000000..69ac57a3b81b7f8c20af41d22bf7a766d5a60087
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Icy-MMBlocks</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..777f2b1b7197528708b584e1a659a2b2b82947ea
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# Icy-MMBlocks
+Blocks (protocols) for Micro-Manager (Icy plugin).
diff --git a/export.jardesc b/export.jardesc
new file mode 100644
index 0000000000000000000000000000000000000000..c4150f940dd353805a94805d447bb31a3e81fb95
--- /dev/null
+++ b/export.jardesc
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
+<jardesc>
+    <jar path="Icy-MMBlocks/MicroscopyBlocks.jar"/>
+    <options buildIfNeeded="true" compress="true" descriptionLocation="/Icy-MMBlocks/export.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="true" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+    <selectedProjects/>
+    <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
+        <javaElement handleIdentifier="=Icy-MMBlocks/src"/>
+    </selectedElements>
+</jardesc>
diff --git a/src/plugins/stef/micromanager/block/AbstractMicroscopeBlock.java b/src/plugins/stef/micromanager/block/AbstractMicroscopeBlock.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ae8f4bed2e0c6c146149ea9a20ad752a5cffbf3
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/AbstractMicroscopeBlock.java
@@ -0,0 +1,62 @@
+/**
+ * 
+ */
+package plugins.stef.micromanager.block;
+
+import icy.gui.dialog.MessageDialog;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import mmcorej.CMMCore;
+
+import org.micromanager.utils.ReportingUtils;
+
+import plugins.adufour.blocks.lang.Block;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+import plugins.tprovoost.Microscopy.MicroManagerForIcy.MicromanagerPlugin;
+
+/**
+ * @author Stephane
+ */
+public abstract class AbstractMicroscopeBlock extends Plugin implements Block, PluginLibrary, PluginBundled
+{
+    public AbstractMicroscopeBlock()
+    {
+        super();
+
+        MicromanagerPlugin.init();
+
+        if (!MicroManager.isInitialized())
+            throw new RuntimeException("Cannot initialize Micro-Manager !");
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return MicroscopyBlocks.class.getName();
+    }
+
+    public static CMMCore getMMCore(boolean throwException)
+    {
+        try
+        {
+            return MicroManager.getCore();
+        }
+        catch (Throwable e)
+        {
+            ReportingUtils.logError(e);
+            if (throwException)
+                throw new RuntimeException("Cannot retrieve Micro-Manager core !", e);
+
+            MessageDialog.showDialog("Cannot find Micro-Manager...",
+                    "You need to start Micro-Manager plugin before using Micro-Manager blocks !",
+                    MessageDialog.WARNING_MESSAGE);
+
+            // throw new VarException(null,
+            // "Cannot retrieve Micro-Manager core...\nBe sure you started Micro-Manager plugin
+            // before using Micro-Manager blocks !");
+        }
+
+        return null;
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/MicroscopyBlocks.java b/src/plugins/stef/micromanager/block/MicroscopyBlocks.java
new file mode 100644
index 0000000000000000000000000000000000000000..72b350059b2d8eca903f2d7eac8602bf073849fc
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/MicroscopyBlocks.java
@@ -0,0 +1,12 @@
+package plugins.stef.micromanager.block;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginLibrary;
+
+public class MicroscopyBlocks extends Plugin implements PluginLibrary
+{
+    public MicroscopyBlocks()
+    {
+        super();
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/capture/MicroscopeGetMetadata.java b/src/plugins/stef/micromanager/block/capture/MicroscopeGetMetadata.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f98172515c6d4825643d87172f5aae4504c9518
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/capture/MicroscopeGetMetadata.java
@@ -0,0 +1,50 @@
+/**
+ * 
+ */
+package plugins.stef.micromanager.block.capture;
+
+import org.json.JSONObject;
+
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * Retrieve global acquisition metadata and last acquired image metadata (Micro-Manager)
+ * 
+ * @author Stephane
+ */
+public class MicroscopeGetMetadata extends AbstractMicroscopeBlock
+{
+    VarInteger channel = new VarInteger("Channel", 0);
+    Var<JSONObject> metadata = new Var<JSONObject>("Image metadata", JSONObject.class);
+    Var<JSONObject> acqMetadata = new Var<JSONObject>("Acquisition metadata", JSONObject.class);
+
+    @Override
+    public void run()
+    {
+        metadata.setValue(MicroManager.getMetadata(channel.getValue().intValue()));
+        acqMetadata.setValue(MicroManager.getAcquisitionMetaData());
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("channel", channel);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("imageMetadata", metadata);
+        outputMap.add("acqMetadata", acqMetadata);
+    }
+
+    @Override
+    public String getName()
+    {
+        return "Get Micro-Manager Metadata";
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/capture/MicroscopeSetTaggedImage.java b/src/plugins/stef/micromanager/block/capture/MicroscopeSetTaggedImage.java
new file mode 100644
index 0000000000000000000000000000000000000000..a118be785210d6b2af4da307058cd137cf0178e7
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/capture/MicroscopeSetTaggedImage.java
@@ -0,0 +1,77 @@
+/**
+ * 
+ */
+package plugins.stef.micromanager.block.capture;
+
+import mmcorej.TaggedImage;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.tools.MMUtils;
+
+/**
+ * Set a TaggedImage into a Sequence (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeSetTaggedImage extends AbstractMicroscopeBlock
+{
+    VarArray<TaggedImage> taggedImages = new VarArray<TaggedImage>("Tagged image(s)", TaggedImage[].class,
+            new TaggedImage[0]);
+    VarSequence seq = new VarSequence("Sequence", null);
+    VarInteger posT = new VarInteger("T", -1);
+    VarInteger posZ = new VarInteger("Z", -1);
+    VarInteger posC = new VarInteger("C", -1);
+    VarInteger sizeT = new VarInteger("Size T", -1);
+    VarInteger sizeZ = new VarInteger("Size Z", -1);
+    VarInteger sizeC = new VarInteger("Size C", -1);
+
+    @Override
+    public void run()
+    {
+        try
+        {
+            for (TaggedImage image : taggedImages.getValue())
+            {
+                // set image position metadata
+                MMUtils.setImageMetadata(image,  posT.getValue().intValue(), posZ.getValue().intValue(), posC
+                        .getValue().intValue(), sizeT.getValue().intValue(), sizeZ.getValue().intValue(), sizeC.getValue().intValue());
+                // store image in sequence
+                MMUtils.setImage(seq.getValue(), image);
+            }
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(taggedImages, t.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("taggedImage", taggedImages);
+        inputMap.add("seq", seq);
+        inputMap.add("t", posT);
+        inputMap.add("z", posZ);
+        inputMap.add("c", posC);
+        inputMap.add("sizeT", sizeT);
+        inputMap.add("sizeZ", sizeZ);
+        inputMap.add("sizeC", sizeC);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+
+    }
+
+    @Override
+    public String getName()
+    {
+        return "Set Tagged Image(s)";
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/capture/MicroscopeSnapChannels.java b/src/plugins/stef/micromanager/block/capture/MicroscopeSnapChannels.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c31aa4b872e50cb868a11529ecd72e7fbaa7753
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/capture/MicroscopeSnapChannels.java
@@ -0,0 +1,143 @@
+package plugins.stef.micromanager.block.capture;
+
+import icy.util.StringUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import mmcorej.TaggedImage;
+
+import org.json.JSONObject;
+import org.micromanager.utils.ChannelSpec;
+import org.micromanager.utils.MDUtils;
+
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.stef.micromanager.block.lang.EzVarMMGroup;
+import plugins.stef.micromanager.block.lang.VarChannels;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+import plugins.tprovoost.Microscopy.MicroManager.tools.StageMover;
+
+/**
+ * Snap multi channel image (Micro-Manager)
+ * 
+ * @author Stephane
+ */
+public class MicroscopeSnapChannels extends AbstractMicroscopeBlock
+{
+    VarObject trigger;
+    EzVarMMGroup group;
+    VarChannels channels;
+    VarArray<TaggedImage> out;
+
+    public MicroscopeSnapChannels()
+    {
+        super();
+
+        trigger = new VarObject("Trigger", null);
+        group = new EzVarMMGroup();
+        channels = new VarChannels(group);
+        out = new VarArray<TaggedImage>("Tagged image(s)", TaggedImage[].class, new TaggedImage[0]);
+    }
+
+    @Override
+    public void run()
+    {
+        // default
+        out.setValue(new TaggedImage[0]);
+
+        final ChannelSpec[] specs = channels.getValue();
+        // no channel to process
+        if (specs.length <= 0)
+            return;
+
+        try
+        {
+            MicroManager.setChannelGroup(group.getValue());
+        }
+        catch (Exception e)
+        {
+            throw new VarException(group.getVariable(), "Group value is not valid.");
+        }
+
+        final List<TaggedImage> result = new ArrayList<TaggedImage>();
+
+        for (int ch = 0; ch < specs.length; ch++)
+        {
+            final ChannelSpec cs = specs[ch];
+
+            // channel not used --> skip
+            if (!cs.useChannel)
+                continue;
+
+            try
+            {
+                final String configName = cs.config;
+
+                // set config
+                if (!StringUtil.isEmpty(configName))
+                    MicroManager.setConfigForGroup(MicroManager.getChannelGroup(), configName, true);
+                // set exposure
+                MicroManager.setExposure(cs.exposure);
+                // doing Z-Stack ? --> apply Z-offset
+                if (cs.doZStack.booleanValue() && (cs.zOffset != 0d))
+                    StageMover.moveZRelative(cs.zOffset, true);
+
+                // do image acquisition
+
+                final List<TaggedImage> images = MicroManager.snapTaggedImage();
+
+                // restore Z position if needed
+                if (cs.doZStack.booleanValue() && (cs.zOffset != 0d))
+                    StageMover.moveZRelative(-cs.zOffset, true);
+
+                // no image ? --> error
+                if (images.isEmpty())
+                    throw new Exception("Cannot snap image from Micro-Manager !");
+
+                // set metadata
+                for (TaggedImage image : images)
+                {
+                    final JSONObject tags = image.tags;
+
+                    MDUtils.setNumChannels(tags, specs.length);
+                    MDUtils.setChannelIndex(tags, ch);
+                    MDUtils.setChannelColor(tags, cs.color.getRGB());
+                }
+
+                // add to result
+                result.addAll(images);
+            }
+            catch (Throwable t)
+            {
+                throw new VarException(out, t.getMessage());
+            }
+        }
+
+        // set result
+        out.setValue(result.toArray(new TaggedImage[result.size()]));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+        inputMap.add("group", group.getVariable());
+        inputMap.add("channels", channels);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("out", out);
+    }
+
+    @Override
+    public String getName()
+    {
+        return "Snap Channel(s)";
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/capture/MicroscopeSnapImage.java b/src/plugins/stef/micromanager/block/capture/MicroscopeSnapImage.java
new file mode 100644
index 0000000000000000000000000000000000000000..baf19d0cda1bc450ab623a170332e930b06b72ff
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/capture/MicroscopeSnapImage.java
@@ -0,0 +1,57 @@
+package plugins.stef.micromanager.block.capture;
+
+import java.util.List;
+
+import mmcorej.TaggedImage;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * Snap single channel image (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeSnapImage extends AbstractMicroscopeBlock
+{
+    VarArray<TaggedImage> out = new VarArray<TaggedImage>("Tagged image(s)", TaggedImage[].class, new TaggedImage[0]);
+    VarObject trigger = new VarObject("Trigger", null);
+
+    @Override
+    public void run()
+    {
+        try
+        {
+            final List<TaggedImage> images = MicroManager.snapTaggedImage();
+            if (images.isEmpty())
+                throw new Exception("Cannot snap image from Micro-Manager !");
+
+            out.setValue(images.toArray(new TaggedImage[images.size()]));
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(out, t.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("out", out);
+    }
+
+    @Override
+    public String getName()
+    {
+        return "Snap Image";
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/lang/VarChannels.java b/src/plugins/stef/micromanager/block/lang/VarChannels.java
new file mode 100644
index 0000000000000000000000000000000000000000..df454e529062b2c3bf0650c1ac0fa2ca25794754
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/lang/VarChannels.java
@@ -0,0 +1,113 @@
+package plugins.stef.micromanager.block.lang;
+
+import icy.type.collection.CollectionUtil;
+
+import org.micromanager.utils.ChannelSpec;
+
+import plugins.adufour.vars.gui.VarEditor;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.util.VarListener;
+
+public class VarChannels extends VarArray<ChannelSpec>
+{
+    VarChannelsEditor editor;
+
+    public VarChannels(String name, EzVarMMGroup groupVar)
+    {
+        super(name, ChannelSpec[].class, null);
+
+        // can be initialized by super constructor
+        if (editor == null)
+            editor = new VarChannelsEditor(this);
+
+        setGroup(groupVar.getValue());
+
+        groupVar.getVariable().addListener(new VarListener<String>()
+        {
+            @Override
+            public void valueChanged(Var<String> source, String oldValue, String newValue)
+            {
+                setGroup(newValue);
+            }
+
+            @Override
+            public void referenceChanged(Var<String> source, Var<? extends String> oldReference,
+                    Var<? extends String> newReference)
+            {
+                //
+            }
+        });
+    }
+
+    public VarChannels(EzVarMMGroup groupVar)
+    {
+        this("Channels", groupVar);
+    }
+
+    @Override
+    public VarEditor<ChannelSpec[]> createVarEditor()
+    {
+        if (editor == null)
+            editor = new VarChannelsEditor(this);
+
+        return editor;
+    }
+
+    @Override
+    public ChannelSpec[] getValue()
+    {
+        return editor.table.getChannels().toArray(new ChannelSpec[0]);
+    }
+
+    @Override
+    public void setValue(ChannelSpec[] value)
+    {
+        editor.table.setChannels(CollectionUtil.asArrayList(value));
+    }
+
+    public void setGroup(String groupName)
+    {
+        editor.setGroup(groupName);
+    }
+
+    // public static List<ChannelSpec> generateChannels(String groupName)
+    // {
+    // final List<ChannelSpec> toReturn = new ArrayList<ChannelSpec>();
+    // if (groupName == null)
+    // return toReturn;
+    //
+    // final List<String> presets = MicroManager.getConfigs(groupName);
+    //
+    // if (presets != null)
+    // {
+    // try
+    // {
+    // final String cam = MicroManager.getCamera();
+    //
+    // for (String s : presets)
+    // {
+    // ChannelSpec cs = new ChannelSpec();
+    //
+    // cs.config = s;
+    // cs.camera = cam;
+    // cs.color = Color.WHITE;
+    // cs.doZStack = true;
+    // cs.skipFactorFrame = 0;
+    // cs.zOffset = 0D;
+    // cs.exposure = 10;
+    // cs.useChannel = true;
+    //
+    // toReturn.add(cs);
+    // }
+    // }
+    // catch (Throwable t)
+    // {
+    // ReportingUtils.logError(t);
+    // }
+    // }
+    //
+    // return toReturn;
+    // }
+
+}
diff --git a/src/plugins/stef/micromanager/block/lang/VarChannelsEditor.java b/src/plugins/stef/micromanager/block/lang/VarChannelsEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef3e7e4c0f75188a94c6d9cd7c3ca93865dd07d5
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/lang/VarChannelsEditor.java
@@ -0,0 +1,190 @@
+package plugins.stef.micromanager.block.lang;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.ScrollPaneConstants;
+
+import org.micromanager.dialogs.ChannelTableModel;
+import org.micromanager.utils.ChannelSpec;
+import org.micromanager.utils.TooltipTextMaker;
+
+import plugins.adufour.vars.gui.VarEditor;
+import plugins.adufour.vars.lang.Var;
+import plugins.tprovoost.Microscopy.MicroManager.gui.ChannelTable;
+
+public class VarChannelsEditor extends VarEditor<ChannelSpec[]>
+{
+    protected JPanel mainPanel;
+    protected ChannelTable table;
+
+    public VarChannelsEditor(Var<ChannelSpec[]> variable)
+    {
+        super(variable);
+
+        // can be done by super constructor
+        if (mainPanel == null)
+            initialize();
+
+        setEditorEnabled(true);
+    }
+
+    @Override
+    protected JPanel createEditorComponent()
+    {
+        // initialize if needed
+        if (mainPanel == null)
+            initialize();
+
+        return mainPanel;
+    }
+
+    private void initialize()
+    {
+        table = new ChannelTable();
+
+        JScrollPane scroll = new JScrollPane(table);
+        scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
+        scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
+        // better to give it a very small size
+        scroll.setMinimumSize(new Dimension(240, 60));
+        scroll.setPreferredSize(new Dimension(240, 100));
+
+        JButton btnAddChannel = new JButton("Add Channel");
+        btnAddChannel.setToolTipText("Create new channel for currently selected channel group");
+        btnAddChannel.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+                final ChannelTableModel model = (ChannelTableModel) table.getModel();
+                model.addNewChannel();
+                model.fireTableDataChanged();
+            }
+        });
+        JButton btnRemoveChannel = new JButton("Remove Channel");
+        btnRemoveChannel.setToolTipText("Remove currently selected channel");
+        btnRemoveChannel.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+                int sel = table.getSelectedRow();
+
+                if (sel > -1)
+                {
+                    final ChannelTableModel model = (ChannelTableModel) table.getModel();
+                    model.removeChannel(sel);
+                    model.fireTableDataChanged();
+                    if (table.getRowCount() > sel)
+                        table.setRowSelectionInterval(sel, sel);
+                }
+            }
+        });
+
+        final JButton upButton = new JButton("Up");
+        upButton.setToolTipText(TooltipTextMaker
+                .addHTMLBreaksForTooltip("Move currently selected channel up (Channels higher on list are acquired first)"));
+        upButton.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+                int sel = table.getSelectedRow();
+
+                if (sel > -1)
+                {
+                    final ChannelTableModel model = (ChannelTableModel) table.getModel();
+                    int newSel = model.rowUp(sel);
+                    model.fireTableDataChanged();
+                    table.setRowSelectionInterval(newSel, newSel);
+                }
+            }
+        });
+
+        final JButton downButton = new JButton("Down");
+        downButton
+                .setToolTipText(TooltipTextMaker
+                        .addHTMLBreaksForTooltip("Move currently selected channel down (Channels lower on list are acquired later)"));
+        downButton.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+                int sel = table.getSelectedRow();
+
+                if (sel > -1)
+                {
+                    final ChannelTableModel model = (ChannelTableModel) table.getModel();
+                    int newSel = model.rowDown(sel);
+                    model.fireTableDataChanged();
+                    table.setRowSelectionInterval(newSel, newSel);
+                }
+            }
+        });
+
+        JPanel panelButtons = new JPanel();
+        panelButtons.setLayout(new BoxLayout(panelButtons, BoxLayout.X_AXIS));
+        panelButtons.add(btnAddChannel);
+        panelButtons.add(btnRemoveChannel);
+        panelButtons.add(upButton);
+        panelButtons.add(downButton);
+
+        mainPanel = new JPanel(new BorderLayout());
+        mainPanel.add(scroll, BorderLayout.CENTER);
+        mainPanel.add(panelButtons, BorderLayout.NORTH);
+        mainPanel.validate();
+    }
+
+    @Override
+    protected void activateListeners()
+    {
+        //
+    }
+
+    @Override
+    protected void deactivateListeners()
+    {
+        //
+    }
+
+    @Override
+    protected void updateInterfaceValue()
+    {
+        //
+    }
+
+    public void setGroup(String group)
+    {
+        table.setGroup(group);
+    }
+
+    @Override
+    public Dimension getPreferredSize()
+    {
+        if (mainPanel != null)
+            return mainPanel.getPreferredSize();
+
+        return new Dimension(400, 140);
+    }
+
+    @Override
+    public void setComponentToolTipText(String s)
+    {
+        if (mainPanel != null)
+            mainPanel.setToolTipText(s);
+    }
+
+    @Override
+    protected void setEditorEnabled(boolean enabled)
+    {
+        if (mainPanel != null)
+            mainPanel.setEnabled(enabled);
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/lang/VarMMGroup.java b/src/plugins/stef/micromanager/block/lang/VarMMGroup.java
new file mode 100644
index 0000000000000000000000000000000000000000..b94129e403ec351babafdf6b88ac15897831378f
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/lang/VarMMGroup.java
@@ -0,0 +1,33 @@
+/**
+ * 
+ */
+package plugins.stef.micromanager.block.lang;
+
+import java.util.List;
+
+import plugins.adufour.vars.gui.model.ValueSelectionModel;
+import plugins.adufour.vars.lang.VarString;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * EzVar representing Micro-Manager config group.
+ * 
+ * @author Stephane
+ */
+public class VarMMGroup extends VarString
+{
+    public VarMMGroup(String name)
+    {
+        super(name, "");
+       
+        final List<String> groups = MicroManager.getConfigGroups();
+        
+        if (groups.size() > 0)
+            setDefaultEditorModel(new ValueSelectionModel<String>(groups.toArray(new String[groups.size()]), groups.get(0), false));
+    }
+
+    public VarMMGroup()
+    {
+        this("Group");
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/lang/VarMMPreset.java b/src/plugins/stef/micromanager/block/lang/VarMMPreset.java
new file mode 100644
index 0000000000000000000000000000000000000000..cffe45d472ad9fd0dbed0f3f55c9b42a6b1010fa
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/lang/VarMMPreset.java
@@ -0,0 +1,59 @@
+/**
+ * 
+ */
+package plugins.stef.micromanager.block.lang;
+
+import java.util.List;
+
+import plugins.adufour.vars.gui.model.ValueSelectionModel;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarListener;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * EzVar representing Micro-Manager config preset.
+ * 
+ * @author Stephane
+ */
+public class VarMMPreset extends VarString
+{
+    public VarMMPreset(String name, VarMMGroup groupVar)
+    {
+        super(name, "");
+
+        // set values
+        refreshPresets(groupVar.getValue());
+
+        // listen group var change
+        groupVar.addListener(new VarListener<String>()
+        {
+            @Override
+            public void valueChanged(Var<String> source, String oldValue, String newValue)
+            {
+                refreshPresets(newValue);
+            }
+
+            @Override
+            public void referenceChanged(Var<String> source, Var<? extends String> oldReference,
+                    Var<? extends String> newReference)
+            {
+                //
+            }
+        });
+    }
+
+    public VarMMPreset(VarMMGroup groupVar)
+    {
+        this("Preset", groupVar);
+    }
+
+    public void refreshPresets(String group)
+    {
+        final List<String> presets = MicroManager.getConfigs(group);
+
+        if (presets.size() > 0)
+            setDefaultEditorModel(new ValueSelectionModel<String>(presets.toArray(new String[presets.size()]),
+                    presets.get(0), false));
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/lang/VarMultiStagePosition.java b/src/plugins/stef/micromanager/block/lang/VarMultiStagePosition.java
new file mode 100644
index 0000000000000000000000000000000000000000..92f0982dd25eb315c252e6433bbf11566aeb7055
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/lang/VarMultiStagePosition.java
@@ -0,0 +1,102 @@
+package plugins.stef.micromanager.block.lang;
+
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+
+import org.micromanager.api.MultiStagePosition;
+
+import plugins.adufour.vars.gui.VarEditor;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+public class VarMultiStagePosition extends VarArray<MultiStagePosition>
+{
+    VarEditorMultiStagePositions pos;
+
+    public VarMultiStagePosition(String name, MultiStagePosition[] defaultValue)
+    {
+        super(name, MultiStagePosition[].class, defaultValue);
+
+        // can be initialized with super constructor
+        if (pos == null)
+            pos = new VarEditorMultiStagePositions(this);
+    }
+
+    @Override
+    public VarEditor<MultiStagePosition[]> createVarEditor()
+    {
+        if (pos == null)
+            pos = new VarEditorMultiStagePositions(this);
+
+        return pos;
+    }
+
+    private class VarEditorMultiStagePositions extends VarEditor<MultiStagePosition[]>
+    {
+        JButton btnOpen;
+
+        public VarEditorMultiStagePositions(Var<MultiStagePosition[]> variable)
+        {
+            super(variable);
+        }
+
+        @Override
+        protected JComponent createEditorComponent()
+        {
+            btnOpen = new JButton("Open");
+            btnOpen.addActionListener(new ActionListener()
+            {
+                @Override
+                public void actionPerformed(ActionEvent e)
+                {
+                    MicroManager.getMMStudio().showXYPositionList();
+                }
+            });
+
+            return btnOpen;
+        }
+
+        @Override
+        protected void activateListeners()
+        {
+        }
+
+        @Override
+        protected void deactivateListeners()
+        {
+        }
+
+        @Override
+        protected void updateInterfaceValue()
+        {
+        }
+
+        @Override
+        public Dimension getPreferredSize()
+        {
+            if (btnOpen != null)
+                return btnOpen.getPreferredSize();
+
+            return new Dimension(100, 24);
+        }
+
+        @Override
+        public void setComponentToolTipText(String s)
+        {
+            if (btnOpen != null)
+                btnOpen.setToolTipText(s);
+        }
+
+        @Override
+        protected void setEditorEnabled(boolean enabled)
+        {
+            if (btnOpen != null)
+                btnOpen.setEnabled(enabled);
+        }
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/setting/MicroscopeChannels.java b/src/plugins/stef/micromanager/block/setting/MicroscopeChannels.java
new file mode 100644
index 0000000000000000000000000000000000000000..042d8fb5140d63301dc2cd6b7703d0595b1f3fa3
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/setting/MicroscopeChannels.java
@@ -0,0 +1,45 @@
+package plugins.stef.micromanager.block.setting;
+
+import plugins.adufour.blocks.tools.input.InputBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.stef.micromanager.block.lang.EzVarMMGroup;
+import plugins.stef.micromanager.block.lang.VarChannels;
+
+/**
+ * Define a list of channel (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeChannels extends AbstractMicroscopeBlock implements InputBlock
+{
+    EzVarMMGroup group;
+    VarChannels channels;
+
+    public MicroscopeChannels()
+    {
+        group = new EzVarMMGroup();
+        channels = new VarChannels(group);
+    }
+
+    @Override
+    public void run()
+    {
+        //
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        if (group != null)
+            inputMap.add("groups", group.getVariable());
+        if (channels != null)
+            inputMap.add("channels", channels);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/setting/MicroscopeGetBinning.java b/src/plugins/stef/micromanager/block/setting/MicroscopeGetBinning.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd9384fe16b11a41ec56528d495a45e882181390
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/setting/MicroscopeGetBinning.java
@@ -0,0 +1,44 @@
+package plugins.stef.micromanager.block.setting;
+
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * Return camera binning value (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeGetBinning extends AbstractMicroscopeBlock
+{
+    VarObject trigger = new VarObject("Trigger", null);
+    VarInteger binning = new VarInteger("Binning", 1);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("binning", binning);
+    }
+
+    @Override
+    public void run()
+    {
+        try
+        {
+            binning.setValue(Integer.valueOf(MicroManager.getBinning()));
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(binning, t.getMessage());
+        }
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/setting/MicroscopeGetExposure.java b/src/plugins/stef/micromanager/block/setting/MicroscopeGetExposure.java
new file mode 100644
index 0000000000000000000000000000000000000000..3701e04014a5e78b000e39bd69c737ec92e00eec
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/setting/MicroscopeGetExposure.java
@@ -0,0 +1,44 @@
+package plugins.stef.micromanager.block.setting;
+
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * Return camera exposure value in ms (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeGetExposure extends AbstractMicroscopeBlock
+{
+    VarObject trigger = new VarObject("Trigger", null);
+    VarDouble exposure = new VarDouble("Exposure (ms)", 50d);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("exposure", exposure);
+    }
+
+    @Override
+    public void run()
+    {
+        try
+        {
+            exposure.setValue(Double.valueOf(MicroManager.getExposure()));
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(exposure, t.getMessage());
+        }
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/setting/MicroscopePositions.java b/src/plugins/stef/micromanager/block/setting/MicroscopePositions.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc87ec8f97df95d198fa5d6858f331be39052980
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/setting/MicroscopePositions.java
@@ -0,0 +1,65 @@
+package plugins.stef.micromanager.block.setting;
+
+import org.micromanager.MMStudio;
+import org.micromanager.api.MultiStagePosition;
+import org.micromanager.api.PositionList;
+
+import plugins.adufour.blocks.tools.input.InputBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.stef.micromanager.block.lang.VarMultiStagePosition;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * Define a list of stage positions (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopePositions extends AbstractMicroscopeBlock implements InputBlock
+{
+    VarArray<MultiStagePosition> varPositions;
+
+    public MicroscopePositions()
+    {
+        super();
+
+        varPositions = new VarMultiStagePosition("Positions", null);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("positions", varPositions);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public void run()
+    {
+        final MMStudio mstudio = MicroManager.getMMStudio();
+        if (mstudio == null)
+            throw new VarException(null,
+                    "Cannot retrieve Micro-Manager core...\nBe sure you started Micro-Manager plugin before using Micro-Manager blocks !");
+
+        try
+        {
+            final PositionList list = mstudio.getPositionList();
+
+            if (list.getPositions() == null)
+                throw new VarException(varPositions, "PositionList is empty. There should be at least one value.");
+
+            varPositions.setValue(list.getPositions());
+        }
+        catch (Exception e)
+        {
+            throw new VarException(varPositions, e.getMessage());
+        }
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/setting/MicroscopeSetBinning.java b/src/plugins/stef/micromanager/block/setting/MicroscopeSetBinning.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7929ee4e5cac81cf25df061413d39f0f9cd3180
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/setting/MicroscopeSetBinning.java
@@ -0,0 +1,53 @@
+/**
+ * 
+ */
+package plugins.stef.micromanager.block.setting;
+
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * Set the camera binning value (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeSetBinning extends AbstractMicroscopeBlock
+{
+    VarObject trigger = new VarObject("Trigger", null);
+    VarInteger binning = new VarInteger("Binning", 1);
+    VarBoolean done = new VarBoolean("Done", false);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+        inputMap.add("binning", binning);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("done", done);
+    }
+
+    @Override
+    public void run()
+    {
+        done.setValue(Boolean.FALSE);
+
+        try
+        {
+            MicroManager.setBinning(binning.getValue().intValue());
+            done.setValue(Boolean.TRUE);
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(binning, t.getMessage());
+        }
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/setting/MicroscopeSetConfig.java b/src/plugins/stef/micromanager/block/setting/MicroscopeSetConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ab9a964f23dac0ed9006a08ac5d4e2a4bcd8859
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/setting/MicroscopeSetConfig.java
@@ -0,0 +1,134 @@
+package plugins.stef.micromanager.block.setting;
+
+import java.util.List;
+
+import plugins.adufour.blocks.lang.BlockDescriptor;
+import plugins.adufour.blocks.lang.WorkFlow;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.protocols.Protocols;
+import plugins.adufour.protocols.gui.MainFrame;
+import plugins.adufour.protocols.gui.ProtocolPanel;
+import plugins.adufour.protocols.gui.block.BlockPanel;
+import plugins.adufour.protocols.gui.block.WorkFlowContainer;
+import plugins.adufour.vars.gui.VarEditor;
+import plugins.adufour.vars.gui.swing.ComboBox;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.adufour.vars.util.VarListener;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.stef.micromanager.block.lang.VarMMGroup;
+import plugins.stef.micromanager.block.lang.VarMMPreset;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * Set a preset for a specified group (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeSetConfig extends AbstractMicroscopeBlock
+{
+    VarObject trigger;
+    VarMMGroup group;
+    VarMMPreset preset;
+    VarBoolean wait;
+    VarBoolean done;
+
+    public MicroscopeSetConfig()
+    {
+        super();
+
+        trigger = new VarObject("Trigger", null);
+        group = new VarMMGroup();
+        preset = new VarMMPreset(group);
+        wait = new VarBoolean("Wait", true);
+        done = new VarBoolean("Done", false);
+
+        // listen group var to refresh the preset GUI which is disconnected from preset var
+        group.addListener(new VarListener<String>()
+        {
+            @Override
+            public void valueChanged(Var<String> source, String oldValue, String newValue)
+            {
+                refreshPresetsGUI(newValue);
+            }
+
+            @Override
+            public void referenceChanged(Var<String> source, Var<? extends String> oldReference,
+                    Var<? extends String> newReference)
+            {
+                //
+            }
+        });
+    }
+
+    @Override
+    public void run()
+    {
+        done.setValue(Boolean.FALSE);
+
+        try
+        {
+            MicroManager.setConfigForGroup(group.getValue(), preset.getValue(), wait.getValue().booleanValue());
+            done.setValue(Boolean.TRUE);
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(group, t.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+        inputMap.add("group", group);
+        inputMap.add("preset", preset);
+        inputMap.add("wait", wait);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        if (done != null)
+            outputMap.add("done", done);
+    }
+
+    @SuppressWarnings("unchecked")
+    public void refreshPresetsGUI(String group)
+    {
+        final MainFrame protocols = Protocols.getInstance();
+        if (protocols != null)
+        {
+            final ProtocolPanel protocolPanel = protocols.getActiveProtocol();
+            if (protocolPanel != null)
+            {
+                final WorkFlowContainer wfc = protocolPanel.getWorkFlowContainer();
+                final WorkFlow wf = protocolPanel.getWorkFlow();
+
+                // get our block descriptor
+                final BlockDescriptor bd = wf.getInputOwner(preset);
+                if (bd != null)
+                {
+                    // get our block panel
+                    final BlockPanel bp = wfc.getBlockPanel(bd);
+                    if (bp != null)
+                    {
+                        // get GUI component for preset var
+                        final VarEditor<?> editor = bp.getVarEditor(preset);
+                        // should be a combo box
+                        if (editor instanceof ComboBox<?>)
+                        {
+                            final ComboBox<String> combo = (ComboBox<String>) editor;
+                            final List<String> presets = MicroManager.getConfigs(group);
+
+                            if (presets.size() > 0)
+                                combo.setDefaultValues(presets.toArray(new String[presets.size()]), 0, false);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/setting/MicroscopeSetExposure.java b/src/plugins/stef/micromanager/block/setting/MicroscopeSetExposure.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f177e7b61a01b7ecbe514d5e0672be2796f0be0
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/setting/MicroscopeSetExposure.java
@@ -0,0 +1,50 @@
+package plugins.stef.micromanager.block.setting;
+
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * Set the camera exposure value (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeSetExposure extends AbstractMicroscopeBlock
+{
+    VarObject trigger = new VarObject("Trigger", null);
+    VarDouble exposure = new VarDouble("Exposure", 10d);
+    VarBoolean done = new VarBoolean("Done", false);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+        inputMap.add("exposure", exposure);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("done", done);
+    }
+
+    @Override
+    public void run()
+    {
+        done.setValue(Boolean.FALSE);
+
+        try
+        {
+            MicroManager.setExposure(exposure.getValue().doubleValue());
+            done.setValue(Boolean.TRUE);
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(exposure, t.getMessage());
+        }
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/setting/MicroscopeSetShutter.java b/src/plugins/stef/micromanager/block/setting/MicroscopeSetShutter.java
new file mode 100644
index 0000000000000000000000000000000000000000..84e1e7e011aed04a79a7d281d54b4a556332c377
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/setting/MicroscopeSetShutter.java
@@ -0,0 +1,49 @@
+package plugins.stef.micromanager.block.setting;
+
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
+
+/**
+ * Set the shutter position: open / close (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeSetShutter extends AbstractMicroscopeBlock
+{
+    VarObject trigger = new VarObject("Trigger", null);
+    VarBoolean open = new VarBoolean("Open", true);
+    VarBoolean done = new VarBoolean("Done", false);
+
+    @Override
+    public void run()
+    {
+        done.setValue(Boolean.FALSE);
+
+        try
+        {
+            MicroManager.setShutterOpen(open.getValue().booleanValue());
+            done.setValue(Boolean.TRUE);
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(open, t.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+        inputMap.add("open", open);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("done", done);
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/stage/MicroscopeGetStageXYZ.java b/src/plugins/stef/micromanager/block/stage/MicroscopeGetStageXYZ.java
new file mode 100644
index 0000000000000000000000000000000000000000..a67874c466651de9e70936cbd0bc8e814980e716
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/stage/MicroscopeGetStageXYZ.java
@@ -0,0 +1,55 @@
+package plugins.stef.micromanager.block.stage;
+
+import icy.type.point.Point3D;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.tools.StageMover;
+
+/**
+ * Return the stage XYZ position (Micro-Manager)
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeGetStageXYZ extends AbstractMicroscopeBlock
+{
+    VarObject trigger = new VarObject("Trigger", null);
+    VarBoolean wait = new VarBoolean("Wait stage", true);
+    VarDouble outX = new VarDouble("X", 0d);
+    VarDouble outY = new VarDouble("Y", 0d);
+    VarDouble outZ = new VarDouble("Z", 0d);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+        inputMap.add("wait", wait);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("x", outX);
+        outputMap.add("y", outY);
+        outputMap.add("z", outZ);
+    }
+
+    @Override
+    public void run()
+    {
+        try
+        {
+            Point3D.Double pos = StageMover.getXYZ();
+            outX.setValue(Double.valueOf(pos.x));
+            outY.setValue(Double.valueOf(pos.y));
+            outZ.setValue(Double.valueOf(pos.z));
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(outX, t.getMessage());
+        }
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/stage/MicroscopeSetStagePosition.java b/src/plugins/stef/micromanager/block/stage/MicroscopeSetStagePosition.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e85038c75734b04a938d823722941a867c8bef9
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/stage/MicroscopeSetStagePosition.java
@@ -0,0 +1,93 @@
+package plugins.stef.micromanager.block.stage;
+
+import org.micromanager.api.MultiStagePosition;
+
+import icy.system.thread.ThreadUtil;
+import mmcorej.CMMCore;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.stef.micromanager.block.setting.MicroscopePositions;
+
+/**
+ * Set the stage to given position (Micro-Manager).<br>
+ * This block should be used in conjunction with {@link MicroscopePositions} block and an indexer
+ * so we can move to each position.
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeSetStagePosition extends AbstractMicroscopeBlock
+{
+    Var<MultiStagePosition> input;
+    VarBoolean waitForStage;
+    VarBoolean done;
+
+    public MicroscopeSetStagePosition()
+    {
+        super();
+
+        input = new Var<MultiStagePosition>("Position", MultiStagePosition.class);
+        waitForStage = new VarBoolean("Wait stage", true);
+        done = new VarBoolean("Done", false);
+    }
+
+    @Override
+    public void run()
+    {
+        done.setValue(Boolean.FALSE);
+
+        final CMMCore core = getMMCore(true);
+
+        if (waitForStage.getValue().booleanValue())
+        {
+            try
+            {
+                MultiStagePosition.goToPosition(input.getValue(), core);
+                done.setValue(Boolean.TRUE);
+            }
+            catch (Throwable t)
+            {
+                throw new VarException(input, t.getMessage());
+            }
+        }
+        else
+        {
+            // do it in background
+            ThreadUtil.bgRun(new Runnable()
+            {
+                @Override
+                public void run()
+                {
+                    try
+                    {
+                        MultiStagePosition.goToPosition(input.getValue(), core);
+                    }
+                    catch (Throwable t)
+                    {
+                        throw new VarException(input, t.getMessage());
+                    }
+                }
+            });
+
+            done.setValue(Boolean.TRUE);
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        if (input != null)
+            inputMap.add("position", input);
+        if (waitForStage != null)
+            inputMap.add("waitStage", waitForStage);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        if (done != null)
+            outputMap.add("done", done);
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/stage/MicroscopeSetStageXY.java b/src/plugins/stef/micromanager/block/stage/MicroscopeSetStageXY.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d180fcb1e57917dca86b05f3ebffdd703122dda
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/stage/MicroscopeSetStageXY.java
@@ -0,0 +1,81 @@
+package plugins.stef.micromanager.block.stage;
+
+import java.awt.geom.Point2D;
+
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.tools.StageMover;
+
+/**
+ * Set the stage to given XY position (Micro-Manager).
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeSetStageXY extends AbstractMicroscopeBlock
+{
+    VarDouble inX;
+    VarDouble inY;
+    VarObject trigger = new VarObject("Trigger", null);
+    VarBoolean wait = new VarBoolean("Wait Stage", true);
+    VarBoolean relative = new VarBoolean("Relative", true);
+    VarBoolean done = new VarBoolean("Done", false);
+
+    public MicroscopeSetStageXY()
+    {
+        super();
+
+        try
+        {
+            Point2D.Double pos = StageMover.getXY();
+            inX = new VarDouble("X", pos.x);
+            inY = new VarDouble("Y", pos.y);
+        }
+        catch (Throwable t)
+        {
+            inX = new VarDouble("X", 0d);
+            inY = new VarDouble("Y", 0d);
+        }
+    }
+
+    @Override
+    public void run()
+    {
+        done.setValue(Boolean.FALSE);
+
+        try
+        {
+            if (relative.getValue().booleanValue())
+                StageMover.moveXYRelative(inX.getValue().doubleValue(), inY.getValue().doubleValue(), wait.getValue()
+                        .booleanValue());
+            else
+                StageMover.moveXYAbsolute(inX.getValue().doubleValue(), inY.getValue().doubleValue(), wait.getValue()
+                        .booleanValue());
+
+            done.setValue(Boolean.TRUE);
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(relative, t.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+        inputMap.add("x", inX);
+        inputMap.add("y", inY);
+        inputMap.add("relative", relative);
+        inputMap.add("wait", wait);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("done", done);
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/stage/MicroscopeSetStageZ.java b/src/plugins/stef/micromanager/block/stage/MicroscopeSetStageZ.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0f8d84609cc1de5fecb515ae25cd1fad8c8868f
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/stage/MicroscopeSetStageZ.java
@@ -0,0 +1,70 @@
+package plugins.stef.micromanager.block.stage;
+
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarObject;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.tools.StageMover;
+
+/**
+ * Set the Z stage to given Z position (Micro-Manager).
+ * 
+ * @author Stephane Dallongeville
+ */
+public class MicroscopeSetStageZ extends AbstractMicroscopeBlock
+{
+    VarDouble inZ;
+    VarObject trigger = new VarObject("Trigger", null);
+    VarBoolean varWait = new VarBoolean("Wait stage", true);
+    VarBoolean varRelative = new VarBoolean("Relative", true);
+    VarBoolean varDone = new VarBoolean("Done", false);
+
+    public MicroscopeSetStageZ()
+    {
+        try
+        {
+            double z = StageMover.getZ();
+            inZ = new VarDouble("Z", z);
+        }
+        catch (Throwable t)
+        {
+            inZ = new VarDouble("Z", 0d);
+        }
+    }
+
+    @Override
+    public void run()
+    {
+        varDone.setValue(Boolean.FALSE);
+        try
+        {
+            if (varRelative.getValue().booleanValue())
+                StageMover.moveZRelative(inZ.getValue().doubleValue(), varWait.getValue().booleanValue());
+            else
+                StageMover.moveZAbsolute(inZ.getValue().doubleValue(), varWait.getValue().booleanValue());
+
+            varDone.setValue(Boolean.TRUE);
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(varRelative, t.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("trigger", trigger);
+        inputMap.add("z", inZ);
+        inputMap.add("relative", varRelative);
+        inputMap.add("wait", varWait);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("done", varDone);
+    }
+}
diff --git a/src/plugins/stef/micromanager/block/tool/TaggedImageToIcyImage.java b/src/plugins/stef/micromanager/block/tool/TaggedImageToIcyImage.java
new file mode 100644
index 0000000000000000000000000000000000000000..8dd0a27d96e197cedceecaf90f9a7e6044fd9604
--- /dev/null
+++ b/src/plugins/stef/micromanager/block/tool/TaggedImageToIcyImage.java
@@ -0,0 +1,56 @@
+/**
+ * 
+ */
+package plugins.stef.micromanager.block.tool;
+
+import icy.image.IcyBufferedImage;
+import icy.type.collection.CollectionUtil;
+import mmcorej.TaggedImage;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.util.VarException;
+import plugins.stef.micromanager.block.AbstractMicroscopeBlock;
+import plugins.tprovoost.Microscopy.MicroManager.tools.MMUtils;
+
+/**
+ * Block to convert a TaggedImage to an IcyBufferedImage (Micro-Manager)
+ * 
+ * @author Stephane
+ */
+public class TaggedImageToIcyImage extends AbstractMicroscopeBlock
+{
+    VarArray<TaggedImage> in = new VarArray<TaggedImage>("Tagged Image", TaggedImage[].class, new TaggedImage[0]);
+    Var<IcyBufferedImage> out = new Var<IcyBufferedImage>("Icy Image", IcyBufferedImage.class);
+
+    @Override
+    public void run()
+    {
+        try
+        {
+            out.setValue(MMUtils.convertToIcyImage(CollectionUtil.asList(in.getValue())));
+        }
+        catch (Throwable t)
+        {
+            throw new VarException(out, t.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("taggedImage", in);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("icyImage", out);
+    }
+
+    @Override
+    public String getName()
+    {
+        return "TaggedImage to IcyBufferedImage";
+    }
+}
\ No newline at end of file