From 91e3a4ef2ab14defa2ff43528c0fc13ebf1361f2 Mon Sep 17 00:00:00 2001
From: Amandine Tournay <amandine.tournay@pasteur.fr>
Date: Tue, 25 Aug 2020 18:05:47 +0200
Subject: [PATCH] Mavenized plugin

---
 .classpath                                    |  44 +++++-
 .gitignore                                    |  11 +-
 pom.xml                                       |  82 ++++++++++
 .../sequenceblocks/SequenceBlocks.java        |  16 ++
 .../sequenceblocks/add/AddOverlays.java       |  79 ++++++++++
 .../tprovoost/sequenceblocks/add/AddRois.java |  63 ++++++++
 .../sequenceblocks/convert/ConvertColor.java  | 131 ++++++++++++++++
 .../sequenceblocks/convert/ConvertStack.java  |  63 ++++++++
 .../sequenceblocks/convert/ConvertType.java   |  57 +++++++
 .../sequenceblocks/convert/Resize.java        |  92 +++++++++++
 .../creation/CombineChannels.java             |  89 +++++++++++
 .../creation/CreateSequence.java              |  45 ++++++
 .../creation/DuplicateSequence.java           |  48 ++++++
 .../sequenceblocks/extract/CropCZT.java       |  84 ++++++++++
 .../sequenceblocks/extract/CropSequence.java  |  84 ++++++++++
 .../extract/ExtractChannel.java               |  59 +++++++
 .../extract/ExtractMultiChannels.java         |  53 +++++++
 .../sequenceblocks/extract/ExtractSlice.java  |  52 +++++++
 .../sequenceblocks/extract/ExtractTime.java   |  52 +++++++
 .../sequenceblocks/files/IsFileValid.java     |  67 ++++++++
 .../sequenceblocks/files/LoadMetadata.java    |  85 ++++++++++
 .../sequenceblocks/files/LoadSequence.java    |  74 +++++++++
 .../sequenceblocks/files/LoadSubSequence.java | 137 ++++++++++++++++
 .../sequenceblocks/files/SaveMetadata.java    |  51 ++++++
 .../sequenceblocks/files/SaveSequence.java    |  98 ++++++++++++
 .../sequenceblocks/images/AddImage.java       |  52 +++++++
 .../sequenceblocks/images/AsImageArray.java   |  51 ++++++
 .../sequenceblocks/images/GetImage.java       |  56 +++++++
 .../sequenceblocks/images/RemoveImage.java    |  54 +++++++
 .../sequenceblocks/images/SetImage.java       |  57 +++++++
 .../PositionedSequenceFileImporter.java       |  91 +++++++++++
 .../importer/SequenceFileImporterClose.java   |  63 ++++++++
 .../SequenceFileImporterGetImage.java         | 119 ++++++++++++++
 .../SequenceFileImporterGetMetadata.java      |  84 ++++++++++
 .../SequenceFileImporterGetThumbnail.java     |  78 ++++++++++
 .../SequenceFileImporterGetTileSize.java      |  81 ++++++++++
 .../SequenceFileImporterLoadSequence.java     | 140 +++++++++++++++++
 .../importer/SequenceFileImporterOpen.java    | 147 ++++++++++++++++++
 .../infos/CreateLinearColormap.java           |  48 ++++++
 .../sequenceblocks/infos/Dimensions.java      |  61 ++++++++
 .../sequenceblocks/infos/EzVarColormap.java   |  19 +++
 .../sequenceblocks/infos/GetChannelName.java  |  55 +++++++
 .../sequenceblocks/infos/GetChannelsName.java |  61 ++++++++
 .../sequenceblocks/infos/GetColormap.java     |  60 +++++++
 .../sequenceblocks/infos/GetColormaps.java    |  62 ++++++++
 .../sequenceblocks/infos/GetDataType.java     |  53 +++++++
 .../sequenceblocks/infos/GetFileName.java     |  69 ++++++++
 .../sequenceblocks/infos/GetMetaData.java     | 106 +++++++++++++
 .../sequenceblocks/infos/GetName.java         |  49 ++++++
 .../infos/GetOutputFilename.java              |  64 ++++++++
 .../sequenceblocks/infos/GetResolution.java   |  65 ++++++++
 .../sequenceblocks/infos/GetRoisAsRegion.java | 100 ++++++++++++
 .../sequenceblocks/infos/ReadMetadata.java    | 107 +++++++++++++
 .../sequenceblocks/infos/SetChannelName.java  |  65 ++++++++
 .../sequenceblocks/infos/SetChannelsName.java |  58 +++++++
 .../sequenceblocks/infos/SetColormap.java     |  57 +++++++
 .../sequenceblocks/infos/SetColormaps.java    |  53 +++++++
 .../sequenceblocks/infos/SetName.java         |  53 +++++++
 .../sequenceblocks/infos/SetResolution.java   |  70 +++++++++
 .../sequenceblocks/infos/VarColormap.java     |  90 +++++++++++
 .../loop/SequenceChannelBatch.java            |  77 +++++++++
 .../loop/SequenceFileImporterBatch.java       |  70 +++++++++
 .../SequenceFileImporterChannelBatch.java     |  54 +++++++
 .../loop/SequenceFileImporterFrameBatch.java  |  54 +++++++
 .../loop/SequenceFileImporterRegionBatch.java | 137 ++++++++++++++++
 .../loop/SequenceFileImporterSeriesBatch.java |  48 ++++++
 .../loop/SequenceFileImporterSliceBatch.java  |  54 +++++++
 .../loop/SequenceFileImporterTileBatch.java   | 109 +++++++++++++
 .../loop/SequenceFrameBatch.java              |  76 +++++++++
 .../loop/SequenceRegionBatch.java             | 104 +++++++++++++
 .../loop/SequenceSliceBatch.java              |  77 +++++++++
 .../op/AdditiveFillSequence.java              |  95 +++++++++++
 .../sequenceblocks/op/FillInnerSequence.java  |  69 ++++++++
 .../sequenceblocks/op/FillOuterSequence.java  |  83 ++++++++++
 .../sequenceblocks/remove/RemoveAllRois.java  |  50 ++++++
 .../sequenceblocks/remove/RemoveChannel.java  |  59 +++++++
 .../sequenceblocks/remove/RemoveFrame.java    |  53 +++++++
 .../sequenceblocks/remove/RemoveOverlays.java |  69 ++++++++
 .../sequenceblocks/remove/RemoveRois.java     |  58 +++++++
 .../sequenceblocks/remove/RemoveSlice.java    |  53 +++++++
 src/main/resources/SequenceBlocks.xml         |  22 +++
 src/main/resources/SequenceBlocks_icon.png    | Bin 0 -> 7025 bytes
 82 files changed, 5679 insertions(+), 6 deletions(-)
 create mode 100644 pom.xml
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/SequenceBlocks.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/add/AddOverlays.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/add/AddRois.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertColor.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertStack.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertType.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/convert/Resize.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/creation/CombineChannels.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/creation/CreateSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/creation/DuplicateSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/extract/CropCZT.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/extract/CropSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractChannel.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractMultiChannels.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractSlice.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractTime.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/files/IsFileValid.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/files/LoadMetadata.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/files/LoadSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/files/LoadSubSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/files/SaveMetadata.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/files/SaveSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/images/AddImage.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/images/AsImageArray.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/images/GetImage.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/images/RemoveImage.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/images/SetImage.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/importer/PositionedSequenceFileImporter.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterClose.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetImage.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetMetadata.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetThumbnail.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetTileSize.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterLoadSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterOpen.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/CreateLinearColormap.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/Dimensions.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/EzVarColormap.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetChannelName.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetChannelsName.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetColormap.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetColormaps.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetDataType.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetFileName.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetMetaData.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetName.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetOutputFilename.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetResolution.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/GetRoisAsRegion.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/ReadMetadata.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/SetChannelName.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/SetChannelsName.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/SetColormap.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/SetColormaps.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/SetName.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/SetResolution.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/infos/VarColormap.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceChannelBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterChannelBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterFrameBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterRegionBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterSeriesBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterSliceBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterTileBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFrameBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceRegionBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceSliceBatch.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/op/AdditiveFillSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/op/FillInnerSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/op/FillOuterSequence.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveAllRois.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveChannel.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveFrame.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveOverlays.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveRois.java
 create mode 100644 src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveSlice.java
 create mode 100644 src/main/resources/SequenceBlocks.xml
 create mode 100644 src/main/resources/SequenceBlocks_icon.png

diff --git a/.classpath b/.classpath
index 373b83c..4622235 100644
--- a/.classpath
+++ b/.classpath
@@ -1,10 +1,48 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="src" path="src/main/resources"/>
+	<classpathentry kind="src" path="src/test/java"/>
 	<classpathentry kind="lib" path="/Icy-App/plugins/adufour/ezplug/EzPlug.jar"/>
 	<classpathentry kind="lib" path="/Icy-App/plugins/adufour/blocks/Blocks.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
 	<classpathentry kind="var" path="ICY_JAR"/>
-	<classpathentry kind="output" path="bin"/>
-	<referencedentry kind="lib" path="D:/Stephane/Documents/dev/GIT/Icy-App/lib/scifio.jar" sourcepath="D:/Stephane/Documents/dev/GIT/bioformats"/>
+	<classpathentry kind="lib" path="F:/SDKs/Java/jdk1.8.0_241/lib/tools.jar"/>
+	<classpathentry kind="var" path="USER_HOME/SDKs/Java/jdk1.8.0_251/lib/tools.jar"/>
+	<classpathentry kind="var" path="USER_HOME/SDKs/Java/jdk1.8.0_251/lib/tools.jar"/>
+	<classpathentry kind="var" path="USER_HOME/SDKs/Java/jdk1.8.0_251/lib/tools.jar"/>
+	<classpathentry kind="var" path="USER_HOME/SDKs/Java/jdk1.8.0_251/lib/tools.jar"/>
+	<classpathentry kind="var" path="USER_HOME/SDKs/Java/jdk1.8.0_251/lib/tools.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.bioimageanalysis.icy:icy-kernel:2.1.0"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: net.sf.ehcache:ehcache:2.10.6"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.slf4j:slf4j-api:1.7.25"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.bioimageanalysis.icy:icy-bioformats:6.3.1"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.bioimageanalysis.icy:icy-insubstantial:7.3.7"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.bioimageanalysis.icy:icy-vtk:6.3.0.1"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: net.imagej:ij:1.52q"/>
+	<classpathentry kind="var" path="USER_HOME/SDKs/Java/jdk1.8.0_251/lib/tools.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: javax.media:jai-core:1.1.3"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: javax.media:jai-codec:1.1.3"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.jogl:jogl-all:2.1.5-01"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.jogl:jogl-all-natives-linux-amd64:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.jogl:jogl-all-natives-linux-i586:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.jogl:jogl-all-natives-macosx-universal:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.jogl:jogl-all-natives-windows-amd64:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.jogl:jogl-all-natives-windows-i586:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.gluegen:gluegen-rt:2.1.5-01"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.gluegen:gluegen-rt-natives-linux-amd64:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.gluegen:gluegen-rt-natives-linux-i586:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.gluegen:gluegen-rt-natives-macosx-universal:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.gluegen:gluegen-rt-natives-windows-amd64:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.jogamp.gluegen:gluegen-rt-natives-windows-i586:2.1.5"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.javassist:javassist:3.22.0-GA"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: net.sourceforge.jexcelapi:jxl:2.6.12"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: log4j:log4j:1.2.14"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.swinglabs.swingx:swingx-all:1.6.5-1"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.bioimageanalysis.icy:icy-blocks:1.0.1"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.bioimageanalysis.icy:icy-protocols:3.0.9"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.bioimageanalysis.icy:icy-javadocparser:1.0.0"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: com.nativelibs4java:ochafik-util:0.12"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Maven: org.bioimageanalysis.icy:icy-ezplug:3.15.13"/>
+	<classpathentry kind="output" path="target/classes"/>
 </classpath>
diff --git a/.gitignore b/.gitignore
index 88e283f..4d6d26e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,8 @@
-bin
-*.jar
-
+.idea/
+.settings/
+build/
+target/
+*.iml
+*.eml
+.classpath
+.project
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ff17425
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.bioimageanalysis.icy</groupId>
+    <artifactId>icy-sequence-blocks</artifactId>
+    <version>2.0.14</version>
+
+    <packaging>jar</packaging>
+
+    <name>SequenceBlocks</name>
+    <description>
+        This plugin allows one to use various basic sequence operations within Blocks.
+    </description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <jdk.version>1.8</jdk.version>
+
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+
+        <outputJar>${project.build.outputDirectory}/../plugin</outputJar>
+    </properties>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.1.2</version>
+                <configuration>
+                    <outputDirectory>${outputJar}</outputDirectory>
+                    <archive>
+                        <manifest>
+                            <addClasspath>true</addClasspath>
+                            <mainClass>plugins.tprovoost.sequenceblocks.SequenceBlocks</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.bioimageanalysis.icy</groupId>
+            <artifactId>icy-kernel</artifactId>
+            <version>2.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.bioimageanalysis.icy</groupId>
+            <artifactId>icy-blocks</artifactId>
+            <version>1.0.1</version>
+        </dependency>
+    </dependencies>
+
+    <repositories>
+        <repository>
+            <id>icy</id>
+            <url>https://icy-nexus.pasteur.fr/repository/Icy/</url>
+        </repository>
+    </repositories>
+
+    <distributionManagement>
+        <snapshotRepository>
+            <id>icy-dev</id>
+            <name>icy-dev</name>
+            <url>https://icy-nexus-dev.pasteur.cloud/repository/icy-core/</url>
+        </snapshotRepository>
+        <repository>
+            <id>icy-prod</id>
+            <name>icy-prod</name>
+            <url>https://icy-nexus.pasteur.fr/repository/icy-core/</url>
+        </repository>
+    </distributionManagement>
+    
+</project>
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/SequenceBlocks.java b/src/main/java/plugins/tprovoost/sequenceblocks/SequenceBlocks.java
new file mode 100644
index 0000000..2a194ff
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/SequenceBlocks.java
@@ -0,0 +1,16 @@
+package plugins.tprovoost.sequenceblocks;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginLibrary;
+
+/**
+ * This class is used as a main class for all the blocks contained in this
+ * package. Each Block has a specified dedicated purpose. More documentation on
+ * the concerned files.
+ * 
+ * @author thomasprovoost
+ */
+public class SequenceBlocks extends Plugin implements PluginLibrary
+{
+    //
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/add/AddOverlays.java b/src/main/java/plugins/tprovoost/sequenceblocks/add/AddOverlays.java
new file mode 100644
index 0000000..4251b97
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/add/AddOverlays.java
@@ -0,0 +1,79 @@
+package plugins.tprovoost.sequenceblocks.add;
+
+import icy.painter.Overlay;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to add one or several {@link Overlay} to a Sequence
+ * 
+ * @author Stephane
+ */
+public class AddOverlays extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarArray<Overlay> overlays = new VarArray<Overlay>("Overlay(s)", Overlay[].class, new Overlay[0])
+    {
+        @Override
+        public String getValueAsString()
+        {
+            final Overlay[] value = getValue();
+
+            if (value == null || value.length == 0)
+                return "No overlay";
+
+            return value.length + " overlay";
+        }
+    };
+
+    @Override
+    public void run()
+    {
+        final Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        final Overlay[] o = overlays.getValue();
+        if (o != null)
+        {
+            s.beginUpdate();
+            try
+            {
+                for (Overlay overlay : o)
+                    s.addOverlay(overlay);
+            }
+            finally
+            {
+                s.endUpdate();
+            }
+        }
+
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("overlay(s)", overlays);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/add/AddRois.java b/src/main/java/plugins/tprovoost/sequenceblocks/add/AddRois.java
new file mode 100644
index 0000000..cbf26c8
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/add/AddRois.java
@@ -0,0 +1,63 @@
+package plugins.tprovoost.sequenceblocks.add;
+
+import java.util.Arrays;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to add one or several {@link ROI} to a Sequence
+ * 
+ * @author Stephane
+ */
+public class AddRois extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarROIArray rois = new VarROIArray("Roi(s)");
+    final protected VarBoolean removePrevious = new VarBoolean("Remove previous", Boolean.FALSE);
+
+    @Override
+    public void run()
+    {
+        final Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        if (removePrevious.getValue().booleanValue())
+            s.removeAllROI();
+
+        final ROI[] r = rois.getValue();
+        if (r != null)
+            s.addROIs(Arrays.asList(r), false);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("rois(s)", rois);
+        inputMap.add("remove", removePrevious);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertColor.java b/src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertColor.java
new file mode 100644
index 0000000..3347c03
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertColor.java
@@ -0,0 +1,131 @@
+package plugins.tprovoost.sequenceblocks.convert;
+
+import java.awt.image.BufferedImage;
+
+import icy.image.IcyBufferedImageUtil;
+import icy.image.lut.LUT;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import icy.util.OMEUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarEnum;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to render a given Sequence using a specific LUT.<br>
+ * The result can be provided ARGB, RGB or GRAY sequence.
+ * 
+ * @author Stephane
+ */
+public class ConvertColor extends Plugin implements SequenceBlock, PluginBundled
+{
+    public static enum ColorConversion
+    {
+        GRAY, RGB, ARGB;
+    };
+
+    final protected VarSequence EZseq = new VarSequence("Sequence", null);
+    final protected VarEnum<ColorConversion> EZtype = new VarEnum<ColorConversion>("Conversion", ColorConversion.ARGB);
+    final protected Var<LUT> EZlut = new Var<LUT>("Lut", LUT.class);
+    final protected VarSequence varOut = new VarSequence("Out", null);
+
+    @Override
+    public void run()
+    {
+        Sequence s;
+
+        // EZ PLUG
+        s = EZseq.getValue();
+        if (s == null)
+            throw new VarException(EZseq, "Input sequence is null.");
+
+        varOut.setValue(convertColor(s, getImageType(EZtype.getValue()), EZlut.getValue()));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("Sequence", EZseq);
+        inputMap.add("Conversion", EZtype);
+        inputMap.add("Lut", EZlut);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("Out", varOut);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+
+    public static int getImageType(ColorConversion value)
+    {
+        switch (value)
+        {
+            default:
+            case ARGB:
+                return BufferedImage.TYPE_INT_ARGB;
+
+            case RGB:
+                return BufferedImage.TYPE_INT_RGB;
+
+            case GRAY:
+                return BufferedImage.TYPE_BYTE_GRAY;
+        }
+    }
+
+    public static Sequence convertColor(Sequence source, int imageType, LUT lut)
+    {
+        final Sequence result = new Sequence(OMEUtil.createOMEXMLMetadata(source.getOMEXMLMetadata()));
+        // image receiver
+        final BufferedImage imgOut = new BufferedImage(source.getSizeX(), source.getSizeY(), imageType);
+
+        result.beginUpdate();
+        try
+        {
+            for (int t = 0; t < source.getSizeT(); t++)
+                for (int z = 0; z < source.getSizeZ(); z++)
+                    result.setImage(t, z, IcyBufferedImageUtil.toBufferedImage(source.getImage(t, z), imgOut, lut));
+
+            // rename channels and set final name
+            switch (imageType)
+            {
+                default:
+                case BufferedImage.TYPE_INT_ARGB:
+                    result.setChannelName(0, "red");
+                    result.setChannelName(1, "green");
+                    result.setChannelName(2, "blue");
+                    result.setChannelName(3, "alpha");
+                    result.setName(source.getName() + " (ARGB rendering)");
+                    break;
+
+                case BufferedImage.TYPE_INT_RGB:
+                    result.setChannelName(0, "red");
+                    result.setChannelName(1, "green");
+                    result.setChannelName(2, "blue");
+                    result.setName(source.getName() + " (RGB rendering)");
+                    break;
+
+                case BufferedImage.TYPE_BYTE_GRAY:
+                    result.setChannelName(0, "gray");
+                    result.setName(source.getName() + " (gray rendering)");
+                    break;
+            }
+        }
+        finally
+        {
+            result.endUpdate();
+        }
+
+        return result;
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertStack.java b/src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertStack.java
new file mode 100644
index 0000000..e7dbfdc
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertStack.java
@@ -0,0 +1,63 @@
+package plugins.tprovoost.sequenceblocks.convert;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarEnum;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class ConvertStack extends Plugin implements SequenceBlock, PluginBundled
+{
+    public static enum TypeConversion
+    {
+        STACK, TIME
+    };
+
+    final protected VarEnum<TypeConversion> type = new VarEnum<TypeConversion>("Type Wanted", TypeConversion.STACK);
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarSequence outputSequence = new VarSequence("Out", null);
+
+    @Override
+    public void run()
+    {
+        Sequence in = inputSequence.getValue();
+        if (in == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        // create a copy as we don't want to modify input
+        Sequence out = SequenceUtil.getCopy(in);
+        if (type.getValue() == TypeConversion.TIME)
+            SequenceUtil.convertToTime(out);
+        else
+            SequenceUtil.convertToStack(out);
+        outputSequence.setValue(out);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("Type Wanted", type);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("out", outputSequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertType.java b/src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertType.java
new file mode 100644
index 0000000..0ec910c
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/convert/ConvertType.java
@@ -0,0 +1,57 @@
+package plugins.tprovoost.sequenceblocks.convert;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import icy.type.DataType;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarEnum;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class ConvertType extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarEnum<DataType> type = new VarEnum<DataType>("Type Wanted", DataType.UBYTE);
+    final protected VarSequence inputSequence = new VarSequence("sequence", null);
+    final protected VarSequence outputSequence = new VarSequence("converted", null);
+    final protected VarBoolean rescale = new VarBoolean("Rescale", Boolean.TRUE);
+
+    @Override
+    public void run()
+    {
+        Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        outputSequence.setValue(SequenceUtil.convertToType(s, type.getValue(), rescale.getValue().booleanValue()));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("Type Wanted", type);
+        inputMap.add("Rescale", rescale);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("converted", outputSequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/convert/Resize.java b/src/main/java/plugins/tprovoost/sequenceblocks/convert/Resize.java
new file mode 100644
index 0000000..b222d0f
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/convert/Resize.java
@@ -0,0 +1,92 @@
+package plugins.tprovoost.sequenceblocks.convert;
+
+import icy.image.IcyBufferedImageUtil.FilterType;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+
+import javax.swing.SwingConstants;
+
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarEnum;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+public class Resize extends Plugin implements SequenceBlock, PluginBundled
+{
+    protected enum Proportional
+    {
+        NO, TO_WIDTH, TO_HEIGHT
+    };
+
+    final protected  VarSequence EZseq = new VarSequence("Sequence", null);
+    final protected  VarInteger EZsizew = new VarInteger("Width", 320);
+    final protected  VarInteger EZsizeh = new VarInteger("Height", 200);
+    final protected  VarEnum<Proportional> EZproportional = new VarEnum<Proportional>("Proportional", Proportional.NO);
+    final protected  VarBoolean EZscale = new VarBoolean("Scale content", Boolean.TRUE);
+    final protected  VarEnum<FilterType> EZtype = new VarEnum<FilterType>("Filter", FilterType.BICUBIC);
+    final protected  VarSequence varOut = new VarSequence("Out", null);
+
+    @Override
+    public void run()
+    {
+        Sequence s;
+        int w, h;
+        FilterType type;
+
+        // EZ PLUG
+        s = EZseq.getValue();
+        w = EZsizew.getValue().intValue();
+        h = EZsizeh.getValue().intValue();
+        type = EZtype.getValue();
+
+        if (s == null || w <= 0 || h <= 0)
+            throw new VarException(null, "No sequence chosen for resize, or wrong size.");
+
+        double scale = 1d * s.getWidth() / s.getHeight();
+        switch (EZproportional.getValue())
+        {
+            case NO:
+                break;
+            case TO_WIDTH:
+                h = (int) (w / scale);
+                break;
+            case TO_HEIGHT:
+                w = (int) (scale * h);
+                break;
+        }
+
+        if (EZscale.getValue().booleanValue())
+            varOut.setValue(SequenceUtil.scale(s, w, h, type));
+        else
+            varOut.setValue(SequenceUtil.scale(s, w, h, false, SwingConstants.CENTER, SwingConstants.CENTER, type));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("Sequence", EZseq);
+        inputMap.add("Width", EZsizew);
+        inputMap.add("Height", EZsizeh);
+        inputMap.add("Proportional", EZproportional);
+        inputMap.add("Filter", EZtype);
+        inputMap.add("Scale content", EZscale);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("Out", varOut);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/creation/CombineChannels.java b/src/main/java/plugins/tprovoost/sequenceblocks/creation/CombineChannels.java
new file mode 100644
index 0000000..b1fc9e1
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/creation/CombineChannels.java
@@ -0,0 +1,89 @@
+package plugins.tprovoost.sequenceblocks.creation;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarIntegerArrayNative;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class CombineChannels extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence 1", null);
+    final protected VarSequence inputSequence2 = new VarSequence("Sequence 2", null);
+    final protected VarSequence outputSequence = new VarSequence("Merged", null);
+    final protected VarIntegerArrayNative channelIdx = new VarIntegerArrayNative("Channel(s) 1", new int[] {0});
+    final protected VarIntegerArrayNative channelIdx2 = new VarIntegerArrayNative("Channel(s) 2", new int[] {0});
+    final protected VarBoolean fillStackHole = new VarBoolean("Fill stack hole", Boolean.TRUE);
+    final protected VarBoolean fitToMaxSize = new VarBoolean("Fit to max size", Boolean.TRUE);
+
+    @Override
+    public void run()
+    {
+        Sequence s = inputSequence.getValue();
+        Sequence s2 = inputSequence2.getValue();
+
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence 1 is null.");
+        if (s2 == null)
+            throw new VarException(inputSequence2, "Input sequence 2 is null.");
+
+        int[] channels1 = channelIdx.getValue();
+        int[] channels2 = channelIdx2.getValue();
+        int sizeC1 = channels1.length;
+        int sizeC2 = channels2.length;
+
+        // Because of concatC, it is necessary to create a sequence[] and int[] of the same size,
+        // and duplicate the sequence as many times in the first as necessary.
+        Sequence[] sequences = new Sequence[sizeC1 + sizeC2];
+        int channels[] = new int[sizeC1 + sizeC2];
+
+        for (int i = 0; i < sizeC1; ++i)
+        {
+            sequences[i] = s;
+            channels[i] = channels1[i];
+        }
+        for (int i = 0; i < sizeC2; ++i)
+        {
+            sequences[sizeC1 + i] = s2;
+            channels[sizeC1 + i] = channels2[i];
+        }
+
+        final Sequence res = SequenceUtil.concatC(sequences, channels, fillStackHole.getValue().booleanValue(),
+                fitToMaxSize.getValue().booleanValue(), null);
+
+        outputSequence.setValue(res);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence 1", inputSequence);
+        inputMap.add("Channel 1", channelIdx);
+        inputMap.add("sequence 2", inputSequence2);
+        inputMap.add("Channel 2", channelIdx2);
+        inputMap.add("fit to max size", fitToMaxSize);
+        inputMap.add("fill stack hole", fillStackHole);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("out", outputSequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/creation/CreateSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/creation/CreateSequence.java
new file mode 100644
index 0000000..a133b94
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/creation/CreateSequence.java
@@ -0,0 +1,45 @@
+package plugins.tprovoost.sequenceblocks.creation;
+
+import icy.image.IcyBufferedImage;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class CreateSequence extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<IcyBufferedImage> in = new Var<IcyBufferedImage>("image (optional)", IcyBufferedImage.class);
+    final protected VarSequence out = new VarSequence("sequence", null);
+
+    @Override
+    public void run()
+    {
+        out.setValue(new Sequence(in.getValue()));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("image (optional)", in);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("sequence", out);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/creation/DuplicateSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/creation/DuplicateSequence.java
new file mode 100644
index 0000000..3379d9d
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/creation/DuplicateSequence.java
@@ -0,0 +1,48 @@
+package plugins.tprovoost.sequenceblocks.creation;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class DuplicateSequence extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence in = new VarSequence("sequence", null);
+    final protected VarSequence out = new VarSequence("duplicated", null);
+
+    @Override
+    public void run()
+    {
+        Sequence s = in.getValue();
+        if (s == null)
+            throw new VarException(in, "Input Sequence is null.");
+        out.setValue(SequenceUtil.getCopy(s));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", in);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("duplicated", out);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/extract/CropCZT.java b/src/main/java/plugins/tprovoost/sequenceblocks/extract/CropCZT.java
new file mode 100644
index 0000000..4ffa86c
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/extract/CropCZT.java
@@ -0,0 +1,84 @@
+package plugins.tprovoost.sequenceblocks.extract;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import icy.type.rectangle.Rectangle5D;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+public class CropCZT extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSeq = new VarSequence("Sequence", null);
+    final protected VarInteger varStartC = new VarInteger("Start index C", 0);
+    final protected VarInteger varSizeC = new VarInteger("Size C", 1);
+    final protected VarInteger varStartZ = new VarInteger("Start index Z", 0);
+    final protected VarInteger varSizeZ = new VarInteger("Size Z", 1);
+    final protected VarInteger varStartT = new VarInteger("Start index T", 0);
+    final protected VarInteger varSizeT = new VarInteger("Size T", 1);
+    final protected VarSequence varOut = new VarSequence("Out", null);
+
+    @Override
+    public void run()
+    {
+        final Sequence seq;
+        final int startX, sizeX;
+        final int startY, sizeY;
+        final int startC, sizeC;
+        final int startZ, sizeZ;
+        final int startT, sizeT;
+
+        // EZ PLUG
+        seq = varSeq.getValue();
+
+        if (seq == null)
+            throw new VarException(varSeq, "No sequence chosen !");
+
+        startC = Math.min(varStartC.getValue().intValue(), seq.getSizeC() - 1);
+        sizeC = Math.min(varSizeC.getValue().intValue(), seq.getSizeC() - startC);
+        startZ = Math.min(varStartZ.getValue().intValue(), seq.getSizeZ() - 1);
+        sizeZ = Math.min(varSizeZ.getValue().intValue(), seq.getSizeZ() - startZ);
+        startT = Math.min(varStartT.getValue().intValue(), seq.getSizeT() - 1);
+        sizeT = Math.min(varSizeT.getValue().intValue(), seq.getSizeT() - startT);
+
+        startX = 0;
+        sizeX = seq.getSizeX();
+        startY = 0;
+        sizeY = seq.getSizeY();
+
+        if ((sizeC <= 0) || (sizeZ <= 0) || (sizeT <= 0))
+            throw new VarException(null, "Size C/Z/T cannot be <= 0 !");
+
+        varOut.setValue(SequenceUtil.getSubSequence(seq,
+                new Rectangle5D.Integer(startX, startY, startZ, startT, startC, sizeX, sizeY, sizeZ, sizeT, sizeC)));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("Sequence", varSeq);
+        inputMap.add("Start index C", varStartC);
+        inputMap.add("Size C", varSizeC);
+        inputMap.add("Start index Z", varStartZ);
+        inputMap.add("Size Z", varSizeZ);
+        inputMap.add("Start index T", varStartT);
+        inputMap.add("Size T", varSizeT);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("Out", varOut);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/extract/CropSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/extract/CropSequence.java
new file mode 100644
index 0000000..8379e58
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/extract/CropSequence.java
@@ -0,0 +1,84 @@
+package plugins.tprovoost.sequenceblocks.extract;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import icy.roi.ROIUtil;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import icy.type.collection.CollectionUtil;
+import icy.util.ShapeUtil.BooleanOperator;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarMutable;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class CropSequence extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    VarMutable inputROIs = new VarMutable("ROI(s)", null)
+    {
+        @Override
+        public boolean isAssignableFrom(@SuppressWarnings("rawtypes") Var source)
+        {
+            return (ROI.class == source.getType()) || (ROI[].class == source.getType());
+        }
+    };
+    final protected VarSequence outputSequence = new VarSequence("Cropped", null);
+
+    @Override
+    public void run()
+    {
+        outputSequence.setValue(null);
+
+        final Sequence s = inputSequence.getValue();
+        if (s == null)
+            return;
+
+        final Object obj = inputROIs.getValue();
+        if (obj == null)
+            return;
+
+        final List<ROI> rois;
+
+        if (obj instanceof ROI)
+        {
+            rois = new ArrayList<ROI>();
+            rois.add((ROI) obj);
+        }
+        else
+            rois = CollectionUtil.asList((ROI[]) obj);
+
+        final ROI roi = ROIUtil.merge(rois, BooleanOperator.OR);
+
+        outputSequence.setValue(SequenceUtil.getSubSequence(s, roi));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("roi", inputROIs);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("cropped", outputSequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractChannel.java b/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractChannel.java
new file mode 100644
index 0000000..4ed5c38
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractChannel.java
@@ -0,0 +1,59 @@
+package plugins.tprovoost.sequenceblocks.extract;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class ExtractChannel extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarSequence outputSequence = new VarSequence("Extracted", null);
+    final protected VarInteger channelIdx = new VarInteger("Channel", 0);
+
+    @Override
+    public void run()
+    {
+        final Sequence s = inputSequence.getValue();
+        final int channel = channelIdx.getValue().intValue();
+
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+        if (channel < 0 || channel >= s.getSizeC())
+            throw new VarException(channelIdx, "Channel index must be between 0 and " + (s.getSizeC() - 1));
+
+        final Sequence res = SequenceUtil.extractChannel(s, channelIdx.getValue().intValue());
+        res.setName(s.getName() + " - channel: " + channelIdx.getValue());
+
+        outputSequence.setValue(res);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("channel", channelIdx);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("extracted", outputSequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractMultiChannels.java b/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractMultiChannels.java
new file mode 100644
index 0000000..56f892e
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractMultiChannels.java
@@ -0,0 +1,53 @@
+package plugins.tprovoost.sequenceblocks.extract;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarIntegerArrayNative;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class ExtractMultiChannels extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarSequence outputSequence = new VarSequence("Extracted", null);
+    final protected VarIntegerArrayNative channelIdx = new VarIntegerArrayNative("Channel(s)", new int[] {0});
+
+    @Override
+    public void run()
+    {
+        Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+        Sequence res = SequenceUtil.extractChannels(s, channelIdx.getValue());
+        res.setName(s.getName() + " - channel: " + channelIdx.getValue());
+        outputSequence.setValue(res);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("Channel", channelIdx);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("extracted", outputSequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractSlice.java b/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractSlice.java
new file mode 100644
index 0000000..d579387
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractSlice.java
@@ -0,0 +1,52 @@
+package plugins.tprovoost.sequenceblocks.extract;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class ExtractSlice extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarSequence outputSequence = new VarSequence("Extracted", null);
+    final protected VarInteger chosenZ = new VarInteger("Z", 0);
+
+    @Override
+    public void run()
+    {
+        Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+        Sequence extracted = SequenceUtil.extractSlice(s, chosenZ.getValue().intValue());
+        outputSequence.setValue(extracted);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("Z pos", chosenZ);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("extracted", outputSequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractTime.java b/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractTime.java
new file mode 100644
index 0000000..6700458
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/extract/ExtractTime.java
@@ -0,0 +1,52 @@
+package plugins.tprovoost.sequenceblocks.extract;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class ExtractTime extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarSequence outputSequence = new VarSequence("Extracted", null);
+    final protected VarInteger chosenT = new VarInteger("T", 0);
+
+    @Override
+    public void run()
+    {
+        Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+        Sequence extracted = SequenceUtil.extractFrame(s, chosenT.getValue().intValue());
+        outputSequence.setValue(extracted);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("T pos", chosenT);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("extracted", outputSequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/files/IsFileValid.java b/src/main/java/plugins/tprovoost/sequenceblocks/files/IsFileValid.java
new file mode 100644
index 0000000..7b250ea
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/files/IsFileValid.java
@@ -0,0 +1,67 @@
+package plugins.tprovoost.sequenceblocks.files;
+
+import java.io.File;
+
+import icy.file.Loader;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarMutable;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to know if a file represents an image file
+ * 
+ * @author Stephane
+ */
+public class IsFileValid extends Plugin implements PluginLibrary, SequenceBlock, PluginBundled
+{
+    final protected VarMutable f_in = new VarMutable("File", null)
+    {
+        @Override
+        public boolean isAssignableFrom(@SuppressWarnings("rawtypes") Var source)
+        {
+            return String.class == source.getType() || File.class == source.getType();
+        }
+    };
+    final protected VarBoolean result = new VarBoolean("Valid", Boolean.FALSE);
+
+    @Override
+    public void run()
+    {
+        final Object obj = f_in.getValue();
+        if (obj != null)
+        {
+            final File f;
+
+            if (obj instanceof String)
+                f = new File((String) obj);
+            else
+                f = (File) obj;
+
+            result.setValue(Boolean.valueOf(Loader.isSupportedImageFile(f.getAbsolutePath())));
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("file", f_in);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("valid", result);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/files/LoadMetadata.java b/src/main/java/plugins/tprovoost/sequenceblocks/files/LoadMetadata.java
new file mode 100644
index 0000000..18d6f4f
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/files/LoadMetadata.java
@@ -0,0 +1,85 @@
+package plugins.tprovoost.sequenceblocks.files;
+
+import java.io.File;
+
+import icy.file.Loader;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.MetaDataUtil;
+import ome.xml.meta.OMEXMLMetadata;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarMutable;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to load Sequence metadata from a file
+ * 
+ * @author Stephane
+ */
+public class LoadMetadata extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarMutable f_in = new VarMutable("File", null)
+    {
+        @Override
+        public boolean isAssignableFrom(@SuppressWarnings("rawtypes") Var source)
+        {
+            return (String.class == source.getType()) || (File.class == source.getType());
+        }
+    };
+    final protected Var<OMEXMLMetadata> output = new Var<OMEXMLMetadata>("Metadata", OMEXMLMetadata.class);
+    final protected VarInteger numSerie = new VarInteger("Series number", 1);
+
+    @Override
+    public void run()
+    {
+        final Object obj = f_in.getValue();
+        if (obj != null)
+        {
+            final File f;
+
+            if (obj instanceof String)
+                f = new File((String) obj);
+            else
+                f = (File) obj;
+
+            try
+            {
+                final OMEXMLMetadata meta = Loader.getOMEXMLMetaData(f.getAbsolutePath());
+
+                if (meta != null)
+                {
+                    output.setValue(meta);
+                    numSerie.setValue(Integer.valueOf(MetaDataUtil.getNumSeries(meta)));
+                }
+            }
+            catch (Exception e)
+            {
+                throw new VarException(null, e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("file", f_in);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("Metadata", output);
+        outputMap.add("Serie number", numSerie);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/files/LoadSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/files/LoadSequence.java
new file mode 100644
index 0000000..a0135c2
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/files/LoadSequence.java
@@ -0,0 +1,74 @@
+package plugins.tprovoost.sequenceblocks.files;
+
+import java.io.File;
+
+import icy.file.Loader;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarMutable;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to load a Sequence from a file
+ * 
+ * @author Stephane
+ */
+public class LoadSequence extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarMutable f_in = new VarMutable("File", null)
+    {
+        @Override
+        public boolean isAssignableFrom(@SuppressWarnings("rawtypes") Var source)
+        {
+            return (String.class == source.getType()) || (File.class == source.getType());
+        }
+    };
+    final protected VarInteger serie_in = new VarInteger("Series", 0);
+    final protected VarSequence outputSequence = new VarSequence("Sequence", null);
+
+    @Override
+    public void run()
+    {
+        final Object obj = f_in.getValue();
+        if (obj != null)
+        {
+            final File f;
+
+            if (obj instanceof String)
+                f = new File((String) obj);
+            else
+                f = (File) obj;
+
+            // if (f.isDirectory())
+            // throw new VarException("file should not be a directory.");
+
+            outputSequence.setValue(Loader.loadSequence(f.getAbsolutePath(), serie_in.getValue().intValue(), false));
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("file", f_in);
+        inputMap.add("serie", serie_in);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("sequence", outputSequence);
+
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/files/LoadSubSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/files/LoadSubSequence.java
new file mode 100644
index 0000000..27861d6
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/files/LoadSubSequence.java
@@ -0,0 +1,137 @@
+package plugins.tprovoost.sequenceblocks.files;
+
+import java.io.File;
+
+import icy.file.Loader;
+import icy.file.SequenceFileImporter;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import plugins.adufour.blocks.tools.io.IOBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarMutable;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to returns a Sequence with the given parameters from the specified closed) SequenceFileImporter.
+ * 
+ * @author Stephane
+ */
+public class LoadSubSequence extends Plugin implements IOBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<SequenceFileImporter> importer;
+    final protected VarMutable file;
+    final protected VarInteger series;
+    final protected VarInteger resolution;
+    final protected VarROIArray region;
+    final protected VarInteger minZIndex;
+    final protected VarInteger maxZIndex;
+    final protected VarInteger minTIndex;
+    final protected VarInteger maxTIndex;
+    final protected VarInteger cIndex;
+    final protected VarBoolean showProgress;
+
+    final protected VarSequence sequence;
+
+    public LoadSubSequence()
+    {
+        super();
+
+        importer = new Var<SequenceFileImporter>("Importer", SequenceFileImporter.class);
+        file = new VarMutable("File", null)
+        {
+            @Override
+            public boolean isAssignableFrom(@SuppressWarnings("rawtypes") Var source)
+            {
+                return (String.class == source.getType()) || (File.class == source.getType());
+            }
+        };
+        series = new VarInteger("Series", 0);
+        resolution = new VarInteger("Resolution (0=full, 1=1/2, ..)", 0);
+        region = new VarROIArray("XY region (ROI)", null);
+        minZIndex = new VarInteger("Z min (slice)", -1);
+        maxZIndex = new VarInteger("Z max (slice)", -1);
+        minTIndex = new VarInteger("T min (frame)", -1);
+        maxTIndex = new VarInteger("T max (frame)", -1);
+        cIndex = new VarInteger("C (channel) index", -1);
+        showProgress = new VarBoolean("Show progress", Boolean.FALSE);
+
+        sequence = new VarSequence("Sequence", null);
+    }
+
+    @Override
+    public void run()
+    {
+        final String path;
+        final Object obj = file.getValue();
+
+        if (obj != null)
+        {
+            if (obj instanceof String)
+                path = (String) obj;
+            else
+                path = ((File) obj).getAbsolutePath();
+        }
+        else
+            throw new VarException(file, "File is null !");
+
+        // here importer can be null so we don't test for it
+        final SequenceFileImporter imp = importer.getValue();
+        final int s = series.getValue().intValue();
+        final int r = resolution.getValue().intValue();
+        final ROI[] rois = region.getValue();
+        final ROI roi = ((rois != null) && (rois.length > 0)) ? rois[0] : null;
+        final int minZ = minZIndex.getValue().intValue();
+        final int maxZ = maxZIndex.getValue().intValue();
+        final int minT = minTIndex.getValue().intValue();
+        final int maxT = maxTIndex.getValue().intValue();
+        final int c = cIndex.getValue().intValue();
+        final boolean progress = showProgress.getValue().booleanValue();
+
+        try
+        {
+            sequence.setValue(Loader.loadSequence(imp, path, s, r,
+                    (roi != null) ? roi.getBounds5D().toRectangle2D().getBounds() : null, minZ, maxZ, minT, maxT, c,
+                    false, progress));
+        }
+        catch (Exception e)
+        {
+            throw new VarException(importer, e.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("file", file);
+        inputMap.add("importer", importer);
+        inputMap.add("series", series);
+        inputMap.add("resolution", resolution);
+        inputMap.add("region", region);
+        inputMap.add("minZ", minZIndex);
+        inputMap.add("maxZ", maxZIndex);
+        inputMap.add("minT", minTIndex);
+        inputMap.add("maxT", maxTIndex);
+        inputMap.add("cIndex", cIndex);
+        inputMap.add("showProgress", showProgress);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("sequence", sequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/files/SaveMetadata.java b/src/main/java/plugins/tprovoost/sequenceblocks/files/SaveMetadata.java
new file mode 100644
index 0000000..da34944
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/files/SaveMetadata.java
@@ -0,0 +1,51 @@
+package plugins.tprovoost.sequenceblocks.files;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to save Sequence metadata
+ * 
+ * @author Stephane
+ */
+public class SaveMetadata extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence sequence = new VarSequence("Sequence", null);
+    final protected VarBoolean success = new VarBoolean("Success", Boolean.FALSE);
+
+    @Override
+    public void run()
+    {
+        Sequence s = sequence.getValue();
+        if (s == null)
+            throw new VarException(sequence, "Sequence is null");
+
+        success.setValue(Boolean.valueOf(s.saveXMLData()));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", sequence);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("success", success);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/files/SaveSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/files/SaveSequence.java
new file mode 100644
index 0000000..98e0a21
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/files/SaveSequence.java
@@ -0,0 +1,98 @@
+package plugins.tprovoost.sequenceblocks.files;
+
+import java.io.File;
+
+import icy.file.FileUtil;
+import icy.file.ImageFileFormat;
+import icy.file.Saver;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarEnum;
+import plugins.adufour.vars.lang.VarMutable;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to save a Sequence into a file
+ * 
+ * @author Stephane
+ */
+public class SaveSequence extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarMutable f_in = new VarMutable("File", null)
+    {
+        @Override
+        public boolean isAssignableFrom(@SuppressWarnings("rawtypes") Var source)
+        {
+            return String.class == source.getType() || File.class == source.getType();
+        }
+    };
+    final protected VarBoolean overwriteForce = new VarBoolean("Overwrite", Boolean.TRUE);
+    final protected VarBoolean multipleFile = new VarBoolean("Multiple file", Boolean.FALSE);
+    final protected VarSequence sequence = new VarSequence("Sequence", null);
+    final protected VarEnum<ImageFileFormat> format = new VarEnum<ImageFileFormat>("Format", ImageFileFormat.TIFF);
+
+    @Override
+    public void run()
+    {
+        final Sequence seq = sequence.getValue();
+
+        if (seq != null)
+        {
+            final Object obj = f_in.getValue();
+
+            if (obj != null)
+            {
+                String path;
+
+                if (obj instanceof String)
+                    path = (String) obj;
+                else
+                    path = ((File) obj).getAbsolutePath();
+
+                if (FileUtil.isDirectory(path))
+                    path += FileUtil.separator + FileUtil.getFileName(seq.getOutputFilename(false));
+
+                // force extension depending file format
+                path = FileUtil.setExtension(path, "." + format.getValue().getExtensions()[0]);
+
+                // cannot overwrite ??
+                if (FileUtil.exists(path) && !overwriteForce.getValue().booleanValue())
+                    throw new VarException(f_in,
+                            "File already exists. If you want to overwrite, please check the \"overwrite\" field.");
+
+                // save sequence
+                Saver.save(seq, new File(path), multipleFile.getValue().booleanValue(), false);
+            }
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("file", f_in);
+        inputMap.add("sequence", sequence);
+        inputMap.add("format", format);
+        inputMap.add("overwrite", overwriteForce);
+        inputMap.add("multiple file", multipleFile);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/images/AddImage.java b/src/main/java/plugins/tprovoost/sequenceblocks/images/AddImage.java
new file mode 100644
index 0000000..35c88c4
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/images/AddImage.java
@@ -0,0 +1,52 @@
+package plugins.tprovoost.sequenceblocks.images;
+
+import icy.image.IcyBufferedImage;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Add an image to the Sequence.
+ * 
+ * @author thomasprovoost
+ */
+public class AddImage extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<IcyBufferedImage> in = new Var<IcyBufferedImage>("Image", IcyBufferedImage.class);
+    final protected VarSequence varSeq = new VarSequence("Sequence", null);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSeq.getValue();
+        if (s == null)
+            throw new VarException(varSeq, "Input sequence is null.");
+        s.addImage(in.getValue());
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSeq);
+        inputMap.add("image", in);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/images/AsImageArray.java b/src/main/java/plugins/tprovoost/sequenceblocks/images/AsImageArray.java
new file mode 100644
index 0000000..6179b1a
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/images/AsImageArray.java
@@ -0,0 +1,51 @@
+package plugins.tprovoost.sequenceblocks.images;
+
+import icy.image.IcyBufferedImage;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Returns all images from the Sequence as an image array.
+ * 
+ * @author thomasprovoost
+ */
+public class AsImageArray extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarArray<IcyBufferedImage> out = new VarArray<IcyBufferedImage>("Image array", IcyBufferedImage[].class, null);
+    final protected VarSequence varSeq = new VarSequence("Sequence", null);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSeq.getValue();
+        if (s == null)
+            throw new VarException(varSeq, "Input sequence is null.");
+        out.setValue(s.getAllImage().toArray(new IcyBufferedImage[0]));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSeq);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("image array", out);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/images/GetImage.java b/src/main/java/plugins/tprovoost/sequenceblocks/images/GetImage.java
new file mode 100644
index 0000000..748afec
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/images/GetImage.java
@@ -0,0 +1,56 @@
+package plugins.tprovoost.sequenceblocks.images;
+
+import icy.image.IcyBufferedImage;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Get the image at the given [T,Z] position from the Sequence.
+ * 
+ * @author thomasprovoost
+ */
+public class GetImage extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence varSeq = new VarSequence("Sequence", null);
+    final protected VarInteger imgIdxT = new VarInteger("T", -1);
+    final protected VarInteger imgIdxZ = new VarInteger("Z", -1);
+    final protected Var<IcyBufferedImage> out = new Var<IcyBufferedImage>("out", IcyBufferedImage.class);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSeq.getValue();
+        if (s == null)
+            throw new VarException(varSeq, "Input sequence is null.");
+        out.setValue(s.getImage(imgIdxT.getValue().intValue(), imgIdxZ.getValue().intValue()));
+    }
+
+    @Override
+    public void declareInput(final VarList inputMap)
+    {
+        inputMap.add("sequence", varSeq);
+        inputMap.add("Idx T", imgIdxT);
+        inputMap.add("Idx Z", imgIdxZ);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("out", out);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/images/RemoveImage.java b/src/main/java/plugins/tprovoost/sequenceblocks/images/RemoveImage.java
new file mode 100644
index 0000000..1380a86
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/images/RemoveImage.java
@@ -0,0 +1,54 @@
+package plugins.tprovoost.sequenceblocks.images;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Remove an image from the Sequence.
+ * 
+ * @author thomasprovoost
+ */
+public class RemoveImage extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    VarSequence varSeq = new VarSequence("Sequence", null);
+    VarInteger imgIdxT = new VarInteger("T", 0);
+    VarInteger imgIdxZ = new VarInteger("Z", 0);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSeq.getValue();
+        if (s == null)
+            throw new VarException(varSeq, "Input sequence is null !");
+
+        s.removeImage(imgIdxT.getValue().intValue(), imgIdxZ.getValue().intValue());
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSeq);
+        inputMap.add("Idx T", imgIdxT);
+        inputMap.add("Idx Z", imgIdxZ);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/images/SetImage.java b/src/main/java/plugins/tprovoost/sequenceblocks/images/SetImage.java
new file mode 100644
index 0000000..b185d7d
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/images/SetImage.java
@@ -0,0 +1,57 @@
+package plugins.tprovoost.sequenceblocks.images;
+
+import icy.image.IcyBufferedImage;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Set an image at the given [T,Z] position from the Sequence.
+ * 
+ * @author thomasprovoost
+ */
+public class SetImage extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    Var<IcyBufferedImage> in = new Var<IcyBufferedImage>("Image", IcyBufferedImage.class);
+    VarSequence varSeq = new VarSequence("Sequence", null);
+    VarInteger imgIdxT = new VarInteger("T", 0);
+    VarInteger imgIdxZ = new VarInteger("Z", 0);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSeq.getValue();
+        if (s == null)
+            throw new VarException(varSeq, "Input sequence is null.");
+        s.setImage(imgIdxT.getValue().intValue(), imgIdxZ.getValue().intValue(), in.getValue());
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSeq);
+        inputMap.add("image", in);
+        inputMap.add("Idx T", imgIdxT);
+        inputMap.add("Idx Z", imgIdxZ);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/importer/PositionedSequenceFileImporter.java b/src/main/java/plugins/tprovoost/sequenceblocks/importer/PositionedSequenceFileImporter.java
new file mode 100644
index 0000000..75a25a7
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/importer/PositionedSequenceFileImporter.java
@@ -0,0 +1,91 @@
+/**
+ * 
+ */
+package plugins.tprovoost.sequenceblocks.importer;
+
+import java.awt.Rectangle;
+import java.io.IOException;
+
+import icy.common.exception.UnsupportedFormatException;
+import icy.file.SequenceFileImporter;
+import icy.sequence.MetaDataUtil;
+import ome.xml.meta.OMEXMLMetadata;
+
+/**
+ * This class allow to use a {@link SequenceFileImporter} while storing a current position information to make its usage
+ * more convenient with Protocols.
+ * 
+ * @author Stephane
+ */
+public class PositionedSequenceFileImporter
+{
+    public SequenceFileImporter importer;
+    protected OMEXMLMetadata metadata;
+    public int s;
+    public int t;
+    public int z;
+    public int c;
+    public Rectangle xyRegion;
+
+    public PositionedSequenceFileImporter(SequenceFileImporter importer, OMEXMLMetadata metadata, int s, int t, int z,
+            int c, Rectangle xyRegion)
+    {
+        super();
+
+        this.importer = importer;
+        this.xyRegion = xyRegion;
+        this.metadata = metadata;
+        this.s = s;
+        this.t = t;
+        this.z = z;
+        this.c = c;
+    }
+
+    public PositionedSequenceFileImporter(SequenceFileImporter importer)
+    {
+        this(importer, null, -1, -1, -1, -1, null);
+    }
+
+    public PositionedSequenceFileImporter(PositionedSequenceFileImporter positionedImporter)
+    {
+        this(positionedImporter.importer, positionedImporter.metadata, positionedImporter.s, positionedImporter.t,
+                positionedImporter.z, positionedImporter.c, positionedImporter.xyRegion);
+    }
+
+    public OMEXMLMetadata getMetadata() throws UnsupportedFormatException, IOException
+    {
+        // not yet defined --> take it from importer if possible
+        if ((metadata == null) && (importer.getOpened() != null))
+        {
+            metadata = importer.getOMEXMLMetaData();
+            // clean the metadata
+            MetaDataUtil.clean(metadata);
+        }
+
+        return metadata;
+    }
+
+    @Override
+    public String toString()
+    {
+        String result;
+
+        if (importer != null)
+            result = importer.getClass().getSimpleName();
+        else
+            result = "No importer";
+
+        if (s != -1)
+            result += " S=" + s;
+        if (t != -1)
+            result += " T=" + t;
+        if (z != -1)
+            result += " Z=" + z;
+        if (c != -1)
+            result += " C=" + c;
+        if (xyRegion != null)
+            result += " XY=" + xyRegion;
+
+        return result;
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterClose.java b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterClose.java
new file mode 100644
index 0000000..ccaa55b
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterClose.java
@@ -0,0 +1,63 @@
+package plugins.tprovoost.sequenceblocks.importer;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import plugins.adufour.blocks.tools.io.IOBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to close currently opened SequenceFileImporter.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterClose extends Plugin implements IOBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<PositionedSequenceFileImporter> importer;
+
+    public SequenceFileImporterClose()
+    {
+        super();
+
+        importer = new Var<PositionedSequenceFileImporter>("Importer", PositionedSequenceFileImporter.class);
+    }
+
+    @Override
+    public void run()
+    {
+        final PositionedSequenceFileImporter pi = importer.getValue();
+
+        if (pi == null)
+            throw new VarException(importer, "Importer is null !");
+
+        try
+        {
+            pi.importer.close();
+        }
+        catch (Exception e)
+        {
+            throw new VarException(importer, e.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("importer", importer);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetImage.java b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetImage.java
new file mode 100644
index 0000000..3720a15
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetImage.java
@@ -0,0 +1,119 @@
+package plugins.tprovoost.sequenceblocks.importer;
+
+import java.awt.Rectangle;
+
+import icy.file.SequenceFileImporter;
+import icy.image.IcyBufferedImage;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import plugins.adufour.blocks.tools.io.IOBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to returns an image from the given parameters and opened SequenceFileImporter.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterGetImage extends Plugin implements IOBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<PositionedSequenceFileImporter> importer;
+    final protected VarInteger series;
+    final protected VarInteger resolution;
+    final protected VarROIArray region;
+    final protected VarInteger zIndex;
+    final protected VarInteger tIndex;
+    final protected VarInteger cIndex;
+
+    final protected Var<IcyBufferedImage> image;
+
+    public SequenceFileImporterGetImage()
+    {
+        super();
+
+        importer = new Var<PositionedSequenceFileImporter>("Importer", PositionedSequenceFileImporter.class);
+        series = new VarInteger("Series", 0);
+        resolution = new VarInteger("Resolution (0=full, 1=1/2, ..)", 0);
+        region = new VarROIArray("XY region (ROI)", null);
+        zIndex = new VarInteger("Z (slice) index", 0);
+        tIndex = new VarInteger("T (frame) index", 0);
+        cIndex = new VarInteger("C (channel) index", -1);
+
+        image = new Var<IcyBufferedImage>("Image", IcyBufferedImage.class);
+    }
+
+    @Override
+    public void run()
+    {
+        final PositionedSequenceFileImporter pi = importer.getValue();
+
+        if (pi == null)
+            throw new VarException(importer, "Importer is null !");
+
+        final SequenceFileImporter imp = pi.importer;
+
+        if (imp.getOpened() == null)
+            throw new VarException(importer, "Importer is not opened !");
+
+        final int res = resolution.getValue().intValue();
+        final ROI[] rois = region.getValue();
+
+        int s = series.getValue().intValue();
+        int z = zIndex.getValue().intValue();
+        int t = tIndex.getValue().intValue();
+        int c = cIndex.getValue().intValue();
+        Rectangle rect = ((rois != null) && (rois.length > 0)) ? rois[0].getBounds5D().toRectangle2D().getBounds()
+                : null;
+
+        // default values ? use internal position if any defined
+        if ((s == 0) && (pi.s != -1))
+            s = pi.s;
+        if ((z == 0) && (pi.z != -1))
+            z = pi.z;
+        if ((t == 0) && (pi.t != -1))
+            t = pi.t;
+        if ((c == 0) && (pi.c != -1))
+            c = pi.c;
+        if ((rect == null) && (pi.xyRegion != null))
+            rect = pi.xyRegion;
+
+        try
+        {
+            image.setValue(imp.getImage(s, res, rect, z, t, c));
+        }
+        catch (Exception e)
+        {
+            throw new VarException(importer, e.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("importer", importer);
+        inputMap.add("series", series);
+        inputMap.add("resolution", resolution);
+        inputMap.add("region", region);
+        inputMap.add("zIndex", zIndex);
+        inputMap.add("tIndex", tIndex);
+        inputMap.add("cIndex", cIndex);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("image", image);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetMetadata.java b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetMetadata.java
new file mode 100644
index 0000000..cb20523
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetMetadata.java
@@ -0,0 +1,84 @@
+package plugins.tprovoost.sequenceblocks.importer;
+
+import icy.file.SequenceFileImporter;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.MetaDataUtil;
+import ome.xml.meta.OMEXMLMetadata;
+import plugins.adufour.blocks.tools.io.IOBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+import plugins.tprovoost.sequenceblocks.infos.ReadMetadata;
+
+/**
+ * Block to returns the metadata from the specified opened SequenceFileImporter.
+ * 
+ * @see ReadMetadata
+ * @author Stephane
+ */
+public class SequenceFileImporterGetMetadata extends Plugin implements IOBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<PositionedSequenceFileImporter> importer;
+    final protected Var<OMEXMLMetadata> metadata;
+    final protected VarInteger numSeries;
+
+    public SequenceFileImporterGetMetadata()
+    {
+        super();
+        
+        importer = new Var<PositionedSequenceFileImporter>("Importer", PositionedSequenceFileImporter.class);
+        metadata = new Var<OMEXMLMetadata>("Metadata", OMEXMLMetadata.class);
+        numSeries = new VarInteger("Series number", 1);
+    }
+
+    @Override
+    public void run()
+    {
+        final PositionedSequenceFileImporter pi = importer.getValue();
+
+        if (pi == null)
+            throw new VarException(importer, "Importer is null !");
+
+        final SequenceFileImporter imp = pi.importer;
+
+        if (imp.getOpened() == null)
+            throw new VarException(importer, "Importer is not opened !");
+
+        try
+        {
+            final OMEXMLMetadata meta = imp.getOMEXMLMetaData();
+
+            metadata.setValue(meta);
+
+            if (meta != null)
+                numSeries.setValue(Integer.valueOf(MetaDataUtil.getNumSeries(meta)));
+        }
+        catch (Exception e)
+        {
+            throw new VarException(importer, e.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("importer", importer);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("metadata", metadata);
+        outputMap.add("numSerie", numSeries);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetThumbnail.java b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetThumbnail.java
new file mode 100644
index 0000000..7303276
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetThumbnail.java
@@ -0,0 +1,78 @@
+package plugins.tprovoost.sequenceblocks.importer;
+
+import icy.file.SequenceFileImporter;
+import icy.image.IcyBufferedImage;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import plugins.adufour.blocks.tools.io.IOBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to returns a thumbnail from the specified opened SequenceFileImporter.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterGetThumbnail extends Plugin implements IOBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<PositionedSequenceFileImporter> importer;
+    final protected VarInteger series;
+    final protected Var<IcyBufferedImage> thumbnail;
+
+    public SequenceFileImporterGetThumbnail()
+    {
+        super();
+
+        importer = new Var<PositionedSequenceFileImporter>("Importer", PositionedSequenceFileImporter.class);
+        series = new VarInteger("Series", 0);
+        thumbnail = new Var<IcyBufferedImage>("Thumbnail", IcyBufferedImage.class);
+    }
+
+    @Override
+    public void run()
+    {
+        final PositionedSequenceFileImporter pi = importer.getValue();
+
+        if (pi == null)
+            throw new VarException(importer, "Importer is null !");
+
+        final SequenceFileImporter imp = pi.importer;
+
+        if (imp.getOpened() == null)
+            throw new VarException(importer, "Importer is not opened !");
+
+        final int s = series.getValue().intValue();
+
+        try
+        {
+            thumbnail.setValue(imp.getThumbnail(s));
+        }
+        catch (Exception e)
+        {
+            throw new VarException(importer, e.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("importer", importer);
+        inputMap.add("series", series);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("thumbnail", thumbnail);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetTileSize.java b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetTileSize.java
new file mode 100644
index 0000000..7fa5e34
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterGetTileSize.java
@@ -0,0 +1,81 @@
+package plugins.tprovoost.sequenceblocks.importer;
+
+import icy.file.SequenceFileImporter;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import plugins.adufour.blocks.tools.io.IOBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to returns the optimal tile size for region reading from the specified opened SequenceFileImporter. 
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterGetTileSize extends Plugin implements IOBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<PositionedSequenceFileImporter> importer;
+    final protected VarInteger series;
+    final protected VarInteger tileW;
+    final protected VarInteger tileH;
+
+    public SequenceFileImporterGetTileSize()
+    {
+        super();
+
+        importer = new Var<PositionedSequenceFileImporter>("Importer", PositionedSequenceFileImporter.class);
+        series = new VarInteger("Series", 0);
+        tileW = new VarInteger("Tile width", 0);
+        tileH = new VarInteger("Tile height", 0);
+    }
+
+    @Override
+    public void run()
+    {
+        final PositionedSequenceFileImporter pi = importer.getValue();
+
+        if (pi == null)
+            throw new VarException(importer, "Importer is null !");
+
+        final SequenceFileImporter imp = pi.importer;
+
+        if (imp.getOpened() == null)
+            throw new VarException(importer, "Importer is not opened !");
+        
+        final int s = series.getValue().intValue();
+
+        try
+        {
+            tileW.setValue(Integer.valueOf(imp.getTileWidth(s)));
+            tileH.setValue(Integer.valueOf(imp.getTileHeight(s)));
+        }
+        catch (Exception e)
+        {
+            throw new VarException(importer, e.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("importer", importer);
+        inputMap.add("series", series);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("tileW", tileW);
+        outputMap.add("tileH", tileH);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterLoadSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterLoadSequence.java
new file mode 100644
index 0000000..34c8ba2
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterLoadSequence.java
@@ -0,0 +1,140 @@
+package plugins.tprovoost.sequenceblocks.importer;
+
+import java.awt.Rectangle;
+
+import icy.file.Loader;
+import icy.file.SequenceFileImporter;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import ome.xml.meta.OMEXMLMetadata;
+import plugins.adufour.blocks.tools.io.IOBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to returns a Sequence from the given parameters and opened SequenceFileImporter.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterLoadSequence extends Plugin implements IOBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<PositionedSequenceFileImporter> importer;
+    final protected VarInteger series;
+    final protected VarInteger resolution;
+    final protected VarROIArray region;
+    final protected VarInteger minZIndex;
+    final protected VarInteger maxZIndex;
+    final protected VarInteger minTIndex;
+    final protected VarInteger maxTIndex;
+    final protected VarInteger cIndex;
+
+    final protected VarSequence sequence;
+
+    public SequenceFileImporterLoadSequence()
+    {
+        super();
+
+        importer = new Var<PositionedSequenceFileImporter>("Importer", PositionedSequenceFileImporter.class);
+
+        series = new VarInteger("Series", 0);
+        resolution = new VarInteger("Resolution (0=full, 1=1/2, ..)", 0);
+        region = new VarROIArray("XY region (ROI)", null);
+        minZIndex = new VarInteger("Z min (slice)", -1);
+        maxZIndex = new VarInteger("Z max (slice)", -1);
+        minTIndex = new VarInteger("T min (frame)", -1);
+        maxTIndex = new VarInteger("T max (frame)", -1);
+        cIndex = new VarInteger("C (channel) index", -1);
+
+        sequence = new VarSequence("Sequence", null);
+    }
+
+    @Override
+    public void run()
+    {
+        final PositionedSequenceFileImporter pi = importer.getValue();
+
+        if (pi == null)
+            throw new VarException(importer, "Importer is null !");
+
+        final SequenceFileImporter imp = pi.importer;
+
+        if (imp.getOpened() == null)
+            throw new VarException(importer, "Importer is not opened !");
+
+        final int res = resolution.getValue().intValue();
+        final ROI[] rois = region.getValue();
+
+        int s = series.getValue().intValue();
+        int minZ = minZIndex.getValue().intValue();
+        int maxZ = maxZIndex.getValue().intValue();
+        int minT = minTIndex.getValue().intValue();
+        int maxT = maxTIndex.getValue().intValue();
+        int c = cIndex.getValue().intValue();
+        Rectangle rect = ((rois != null) && (rois.length > 0)) ? rois[0].getBounds5D().toRectangle2D().getBounds()
+                : null;
+
+        // default values ? use internal position if any defined
+        if ((s == 0) && (pi.s != -1))
+            s = pi.s;
+        if ((minZ == -1) && (maxZ == -1) && (pi.z != -1))
+        {
+            minZ = pi.z;
+            maxZ = pi.z;
+        }
+        if ((minT == -1) && (maxT == -1) && (pi.t != -1))
+        {
+            minT = pi.t;
+            maxT = pi.t;
+        }
+        if ((c == 0) && (pi.c != -1))
+            c = pi.c;
+        if ((rect == null) && (pi.xyRegion != null))
+            rect = pi.xyRegion;
+
+        try
+        {
+            
+            // get metadata
+            final OMEXMLMetadata meta = pi.getMetadata();
+
+            sequence.setValue(Loader.internalLoadSingle(imp, meta, s, res, rect, minZ, maxZ, minT, maxT, c, false, null));
+        }
+        catch (Exception e)
+        {
+            throw new VarException(importer, e.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("importer", importer);
+        inputMap.add("series", series);
+        inputMap.add("resolution", resolution);
+        inputMap.add("region", region);
+        inputMap.add("minZ", minZIndex);
+        inputMap.add("maxZ", maxZIndex);
+        inputMap.add("minT", minTIndex);
+        inputMap.add("maxT", maxTIndex);
+        inputMap.add("cIndex", cIndex);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("sequence", sequence);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterOpen.java b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterOpen.java
new file mode 100644
index 0000000..720b9c6
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/importer/SequenceFileImporterOpen.java
@@ -0,0 +1,147 @@
+package plugins.tprovoost.sequenceblocks.importer;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import icy.file.Loader;
+import icy.file.SequenceFileImporter;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.util.ClassUtil;
+import plugins.adufour.blocks.tools.io.IOBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.gui.model.ValueSelectionModel;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarMutable;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to open a file with a given SequenceFileImporter.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterOpen extends Plugin implements IOBlock, PluginLibrary, PluginBundled
+{
+    final static String ID_AUTO = "Automatic";
+
+    final protected VarString importerName;
+    final protected Var<PositionedSequenceFileImporter> importer;
+    final protected VarMutable file;
+    final protected VarInteger flag;
+
+    // internal
+    final protected Map<String, SequenceFileImporter> importersMap;
+
+    public SequenceFileImporterOpen()
+    {
+        super();
+
+        final List<String> importersName = new ArrayList<String>();
+        final List<SequenceFileImporter> importers = Loader.getSequenceFileImporters();
+
+        importerName = new VarString("Select importer", "", 1 + importers.size());
+        // build importer map
+        importersMap = new HashMap<String, SequenceFileImporter>();
+
+        // automatic selection
+        importersName.add(ID_AUTO);
+        importersMap.put(ID_AUTO, null);
+        for (SequenceFileImporter importer : importers)
+        {
+            String className = ClassUtil.getBaseClassName(importer.getClass().getName());
+            final int ind = className.lastIndexOf('.');
+
+            // just get final class name without package name
+            if (ind > -1)
+                className = className.substring(ind + 1, className.length());
+
+            importersName.add(className);
+            importersMap.put(className, importer);
+        }
+
+        // initialize importer selector field
+        importerName.setDefaultEditorModel(new ValueSelectionModel<String>(
+                importersName.toArray(new String[importersName.size()]), importersName.get(0), false));
+
+        importer = new Var<PositionedSequenceFileImporter>("Importer", PositionedSequenceFileImporter.class);
+        file = new VarMutable("File", null)
+        {
+            @SuppressWarnings("rawtypes")
+            @Override
+            public boolean isAssignableFrom(Var source)
+            {
+                return (String.class == source.getType()) || (File.class == source.getType());
+            }
+        };
+        flag = new VarInteger("Flag", 0);
+    }
+
+    @SuppressWarnings("resource")
+    @Override
+    public void run()
+    {
+        final String path;
+        final Object obj = file.getValue();
+
+        if (obj != null)
+        {
+            if (obj instanceof String)
+                path = (String) obj;
+            else
+                path = ((File) obj).getAbsolutePath();
+        }
+        else
+            throw new VarException(file, "File is null !");
+
+        // get selected importer
+        SequenceFileImporter imp = importersMap.get(importerName.getValue());
+
+        // automatic selection from input file ?
+        if (imp == null)
+            imp = Loader.getSequenceFileImporter(path, true);
+
+        // cannot get importer ?
+        if (imp == null)
+            throw new VarException(importer, "Cannot find an importer for file: '" + path + "' !");
+
+        // set importer
+        importer.setValue(new PositionedSequenceFileImporter(imp));
+
+        try
+        {
+            // try to open the importer
+            imp.open(path, flag.getValue().intValue());
+        }
+        catch (Exception e)
+        {
+            throw new VarException(importer, e.getMessage());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("name", importerName);
+        inputMap.add("file", file);
+        inputMap.add("flag", flag);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("importer", importer);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/CreateLinearColormap.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/CreateLinearColormap.java
new file mode 100644
index 0000000..7616d67
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/CreateLinearColormap.java
@@ -0,0 +1,48 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.image.colormap.LinearColorMap;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+
+import java.awt.Color;
+
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarColor;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to create a linear colormap from a color value
+ * 
+ * @author Stephane
+ * @see SetColormap
+ */
+public class CreateLinearColormap extends Plugin implements SequenceBlock, PluginBundled
+{
+    private VarColor color = new VarColor("Color", Color.white);
+    private VarColormap colormap = new VarColormap("Color map", LinearColorMap.gray_);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("input", color);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("output", colormap);
+    }
+
+    @Override
+    public void run()
+    {
+        colormap.setValue(new LinearColorMap("color", color.getValue()));
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/Dimensions.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/Dimensions.java
new file mode 100644
index 0000000..3dbc2df
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/Dimensions.java
@@ -0,0 +1,61 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class Dimensions extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    VarSequence varSeq = new VarSequence("Sequence", null);
+    VarInteger sizeZ = new VarInteger("Size Z", 1);
+    VarInteger sizeT = new VarInteger("Size T", 1);
+    VarInteger sizeC = new VarInteger("Size C", 1);
+    VarInteger width = new VarInteger("Width", 1);
+    VarInteger height = new VarInteger("Height", 1);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSeq.getValue();
+        if (s == null)
+            throw new VarException(varSeq, "Input sequence is null.");
+        
+        width.setValue(Integer.valueOf(s.getWidth()));
+        height.setValue(Integer.valueOf(s.getHeight()));
+        sizeC.setValue(Integer.valueOf(s.getSizeC()));
+        sizeZ.setValue(Integer.valueOf(s.getSizeZ()));
+        sizeT.setValue(Integer.valueOf(s.getSizeT()));
+    }
+
+    @Override
+    public void declareInput(final VarList inputMap)
+    {
+        inputMap.add("sequence", varSeq);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("width", width);
+        outputMap.add("height", height);
+        outputMap.add("size C", sizeC);
+        outputMap.add("size Z", sizeZ);
+        outputMap.add("size T", sizeT);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/EzVarColormap.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/EzVarColormap.java
new file mode 100644
index 0000000..d3fd86c
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/EzVarColormap.java
@@ -0,0 +1,19 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.image.colormap.IcyColorMap;
+import plugins.adufour.ezplug.EzVar;
+import plugins.tprovoost.sequenceblocks.infos.VarColormap.ColormapSelectionModel;
+
+public class EzVarColormap extends EzVar<IcyColorMap>
+{
+    /**
+     * Constructs a new variable that handles colormap data.
+     * 
+     * @param varName
+     *        the parameter name
+     */
+    public EzVarColormap(String varName, IcyColorMap defaultValue)
+    {
+        super(new VarColormap(varName, defaultValue), new ColormapSelectionModel());
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetChannelName.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetChannelName.java
new file mode 100644
index 0000000..ba5f734
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetChannelName.java
@@ -0,0 +1,55 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class GetChannelName extends Plugin implements SequenceBlock, PluginBundled
+{
+    private VarSequence varSequence = new VarSequence("Sequence", null);
+    private VarInteger varIdx = new VarInteger("Channel", 0);
+    private VarString varName = new VarString("Name", "");
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSequence.getValue();
+        if (s == null)
+            throw new VarException(varSequence, "Sequence is null");
+
+        int index = varIdx.getValue().intValue();
+        if (index < 0 || index >= s.getSizeC())
+            throw new VarException(varIdx, "Wrong channel index.");
+
+        varName.setValue(s.getChannelName(index));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+        inputMap.add("index", varIdx);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("name", varName);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetChannelsName.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetChannelsName.java
new file mode 100644
index 0000000..5506b01
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetChannelsName.java
@@ -0,0 +1,61 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to retrieve all channels name from a given sequence
+ * 
+ * @author Stephane
+ * @see GetChannelName
+ * @see SetChannelsName
+ */
+public class GetChannelsName extends Plugin implements SequenceBlock, PluginBundled
+{
+    private VarSequence varSequence = new VarSequence("Sequence", null);
+    private VarArray<String> varNames = new VarArray<String>("Names", String[].class, new String[0]);
+
+    @Override
+    public void run()
+    {
+        final Sequence s = varSequence.getValue();
+        if (s == null)
+            throw new VarException(varSequence, "Sequence is null");
+
+        final List<String> names = new ArrayList<String>();
+
+        for (int c = 0; c < s.getSizeC(); c++)
+            names.add(s.getChannelName(c));
+
+        varNames.setValue(names.toArray(new String[names.size()]));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("names", varNames);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetColormap.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetColormap.java
new file mode 100644
index 0000000..98a564d
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetColormap.java
@@ -0,0 +1,60 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.image.colormap.LinearColorMap;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.BlocksException;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to retrieve a channel colormap from a given sequence
+ * 
+ * @author Stephane
+ * @see SetColormap
+ */
+public class GetColormap extends Plugin implements SequenceBlock, PluginBundled
+{
+    private VarSequence sequenceIn = new VarSequence("Sequence", null);
+    private VarInteger numChannel = new VarInteger("Channel", 0);
+    private VarColormap colormap = new VarColormap("Color map", LinearColorMap.gray_);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("input", sequenceIn);
+        inputMap.add("numChannel", numChannel);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("output", colormap);
+    }
+
+    @Override
+    public void run()
+    {
+        final Sequence seq = sequenceIn.getValue();
+
+        if (seq != null)
+        {
+            final int ch = numChannel.getValue().intValue();
+
+            if (ch < seq.getSizeC())
+                colormap.setValue(seq.getColorMap(ch));
+            else
+                throw new BlocksException("Block 'Get Colormap': illegal channel number for this sequence !", true);
+        }
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetColormaps.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetColormaps.java
new file mode 100644
index 0000000..dcc86d7
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetColormaps.java
@@ -0,0 +1,62 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.image.colormap.IcyColorMap;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to retrieve all channels colormap from a given sequence
+ * 
+ * @author Stephane
+ * @see SetColormaps
+ */
+public class GetColormaps extends Plugin implements SequenceBlock, PluginBundled
+{
+    private VarSequence sequenceIn = new VarSequence("Sequence", null);
+    private VarArray<IcyColorMap> colormaps = new VarArray<IcyColorMap>("Color maps", IcyColorMap[].class,
+            new IcyColorMap[0]);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("input", sequenceIn);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("Colormaps", colormaps);
+    }
+
+    @Override
+    public void run()
+    {
+        final Sequence seq = sequenceIn.getValue();
+        if (seq == null)
+            throw new VarException(sequenceIn, "Sequence is null");
+
+        final List<IcyColorMap> cms = new ArrayList<IcyColorMap>();
+
+        for (int c = 0; c < seq.getSizeC(); c++)
+            cms.add(seq.getColorMap(c));
+
+        colormaps.setValue(cms.toArray(new IcyColorMap[cms.size()]));
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetDataType.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetDataType.java
new file mode 100644
index 0000000..d47fe2d
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetDataType.java
@@ -0,0 +1,53 @@
+/**
+ * 
+ */
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import icy.type.DataType;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarEnum;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Returns the DataType of the Sequence object
+ * 
+ * @author Stephane
+ */
+public class GetDataType extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected VarEnum<DataType> type = new VarEnum<DataType>("Data type", DataType.UBYTE);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSequence.getValue();
+        if (s == null)
+            throw new VarException(varSequence, "Sequence is null");
+        type.setValue(s.getDataType_());
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("type", type);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetFileName.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetFileName.java
new file mode 100644
index 0000000..477a915
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetFileName.java
@@ -0,0 +1,69 @@
+/**
+ * 
+ */
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.file.FileUtil;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Returns the origin filename (from where the sequence has been loaded / saved)
+ * 
+ * @author Stephane
+ */
+public class GetFileName extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected VarString filename = new VarString("Filename", "");
+    final protected VarBoolean withFolder = new VarBoolean("Folder", Boolean.TRUE);
+    final protected VarBoolean withExtension = new VarBoolean("Extension", Boolean.TRUE);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSequence.getValue();
+
+        if (s == null)
+            throw new VarException(varSequence, "Sequence is null");
+
+        String result = s.getFilename();
+
+        // remove folder information ?
+        if (!withFolder.getValue().booleanValue())
+            result = FileUtil.getFileName(result);
+        // remove extension ?
+        if (!withExtension.getValue().booleanValue())
+            FileUtil.setExtension(result, "");
+
+        filename.setValue(result);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+        inputMap.add("folder", withFolder);
+        inputMap.add("extension", withExtension);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("name", filename);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetMetaData.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetMetaData.java
new file mode 100644
index 0000000..0145c1f
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetMetaData.java
@@ -0,0 +1,106 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import java.awt.Rectangle;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import ome.xml.meta.OMEXMLMetadata;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to return metadata information from a Sequence object.
+ *
+ * @see ReadMetadata
+ * @author Stephane
+ */
+public class GetMetaData extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected Var<OMEXMLMetadata> metaData = new Var<OMEXMLMetadata>("Metadata", OMEXMLMetadata.class);
+    final protected VarString name = new VarString("Name", "");
+    final protected VarInteger seriesIndex = new VarInteger("Series index", 0);
+    final protected VarDouble pxSizeX = new VarDouble("Pixel Size X (µm)", 1d);
+    final protected VarDouble pxSizeY = new VarDouble("Pixel Size Y (µm)", 1d);
+    final protected VarDouble pxSizeZ = new VarDouble("Pixel Size Z (µm)", 1d);
+    final protected VarDouble timeIntT = new VarDouble("Time interval T (s)", 100d);
+    final protected VarDouble positionX = new VarDouble("Position X (µm)", 0d);
+    final protected VarDouble positionY = new VarDouble("Position Y (µm)", 0d);
+    final protected VarDouble positionZ = new VarDouble("Position Z (µm)", 0d);
+    final protected VarInteger originResolution = new VarInteger("Resolution", 0);
+    final protected Var<Rectangle> originRegion = new Var<Rectangle>("Region", new Rectangle());
+    final protected VarInteger originZMin = new VarInteger("Z min", -1);
+    final protected VarInteger originZMax = new VarInteger("Z max", -1);
+    final protected VarInteger originTMin = new VarInteger("T min", -1);
+    final protected VarInteger originTMax = new VarInteger("T max", -1);
+    final protected VarInteger originChannel = new VarInteger("Channel", -1);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSequence.getValue();
+
+        if (s == null)
+            throw new VarException(varSequence, "Sequence is null");
+
+        metaData.setValue(s.getOMEXMLMetadata());
+        name.setValue(s.getName());
+        seriesIndex.setValue(Integer.valueOf(s.getSeries()));
+        pxSizeX.setValue(Double.valueOf(s.getPixelSizeX()));
+        pxSizeY.setValue(Double.valueOf(s.getPixelSizeY()));
+        pxSizeZ.setValue(Double.valueOf(s.getPixelSizeZ()));
+        timeIntT.setValue(Double.valueOf(s.getTimeInterval()));
+        positionX.setValue(Double.valueOf(s.getPositionX()));
+        positionY.setValue(Double.valueOf(s.getPositionY()));
+        positionZ.setValue(Double.valueOf(s.getPositionZ()));
+        originResolution.setValue(Integer.valueOf(s.getOriginResolution()));
+        originRegion.setValue(s.getOriginXYRegion());
+        originZMin.setValue(Integer.valueOf(s.getOriginZMin()));
+        originZMax.setValue(Integer.valueOf(s.getOriginZMax()));
+        originTMin.setValue(Integer.valueOf(s.getOriginTMin()));
+        originTMax.setValue(Integer.valueOf(s.getOriginTMax()));
+        originChannel.setValue(Integer.valueOf(s.getOriginChannel()));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("metadata", metaData);
+        outputMap.add("name", name);
+        outputMap.add("seriesIndex", seriesIndex);
+        outputMap.add("Pixel Size X (mm)", pxSizeX);
+        outputMap.add("Pixel Size Y (mm)", pxSizeY);
+        outputMap.add("Pixel Size Z (mm)", pxSizeZ);
+        outputMap.add("Time interval T (ms)", timeIntT);
+        outputMap.add("positionx", positionX);
+        outputMap.add("positiony", positionY);
+        outputMap.add("positionz", positionZ);
+        outputMap.add("originResolution", originResolution);
+        outputMap.add("originRegion", originRegion);
+        outputMap.add("originZMin", originZMin);
+        outputMap.add("originZMax", originZMax);
+        outputMap.add("originTMin", originTMin);
+        outputMap.add("originTMax", originTMax);
+        outputMap.add("originChannel", originChannel);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetName.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetName.java
new file mode 100644
index 0000000..c102a40
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetName.java
@@ -0,0 +1,49 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Returns the name of the Sequence object
+ * 
+ * @author Stephane
+ */
+public class GetName extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected VarString name = new VarString("Name", "");
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSequence.getValue();
+        if (s == null)
+            throw new VarException(varSequence, "Sequence is null");
+        name.setValue(s.getName());
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("name", name);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetOutputFilename.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetOutputFilename.java
new file mode 100644
index 0000000..3e9deec
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetOutputFilename.java
@@ -0,0 +1,64 @@
+/**
+ * 
+ */
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.file.FileUtil;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Returns the output filename generated from origin filename and internal partitioning information
+ * 
+ * @author Stephane
+ */
+public class GetOutputFilename extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected VarString outFilename = new VarString("Output filename", "");
+    final protected VarBoolean withFolder = new VarBoolean("Folder", Boolean.TRUE);
+    final protected VarBoolean withExtension = new VarBoolean("Extension", Boolean.TRUE);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSequence.getValue();
+        if (s == null)
+            throw new VarException(varSequence, "Sequence is null");
+
+        String result = s.getOutputFilename(withExtension.getValue().booleanValue());
+
+        if (!withFolder.getValue().booleanValue())
+            result = FileUtil.getFileName(result);
+
+        outFilename.setValue(result);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+        inputMap.add("folder", withFolder);
+        inputMap.add("extension", withExtension);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("outFilename", outFilename);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetResolution.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetResolution.java
new file mode 100644
index 0000000..aa738a9
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetResolution.java
@@ -0,0 +1,65 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to return pixel size and time interval information from a Sequence object.
+ *
+ * @see ReadMetadata
+ * @see GetMetaData
+ * @author Stephane
+ */
+public class GetResolution extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected VarDouble pxSizeX = new VarDouble("Pixel Size X (µm)", 1d);
+    final protected VarDouble pxSizeY = new VarDouble("Pixel Size Y (µm)", 1d);
+    final protected VarDouble pxSizeZ = new VarDouble("Pixel Size Z (µm)", 1d);
+    final protected VarDouble timeIntT = new VarDouble("Time interval T (s)", 0.1d);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSequence.getValue();
+        if (s != null)
+        {
+            pxSizeX.setValue(Double.valueOf(s.getPixelSizeX()));
+            pxSizeY.setValue(Double.valueOf(s.getPixelSizeY()));
+            pxSizeZ.setValue(Double.valueOf(s.getPixelSizeZ()));
+            timeIntT.setValue(Double.valueOf(s.getTimeInterval()));
+        }
+        else
+        {
+            throw new VarException(varSequence, "Sequence is null");
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("Pixel Size X (µm)", pxSizeX);
+        outputMap.add("Pixel Size Y (µm)", pxSizeY);
+        outputMap.add("Pixel Size Z (µm)", pxSizeZ);
+        outputMap.add("Time interval T (s)", timeIntT);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetRoisAsRegion.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetRoisAsRegion.java
new file mode 100644
index 0000000..2ddd6e7
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/GetRoisAsRegion.java
@@ -0,0 +1,100 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarEnum;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.kernel.roi.roi2d.ROI2DRectangle;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to retrieve ROI(s) from a Sequence as 2D Rectangular regions.<br>
+ * The <i>origin resolution</i> parameter indicate if we want to rescale ROI to the original image resolution in case we
+ * have a Sequence which represents a sub resolution of the original image.
+ * 
+ * @author Stephane
+ */
+public class GetRoisAsRegion extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    public static enum TypeSelection
+    {
+        ALL, SELECTED
+    };
+
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarEnum<TypeSelection> type = new VarEnum<TypeSelection>("ROI(s) to get", TypeSelection.ALL);
+    final protected VarBoolean originResolution = new VarBoolean("Origin resolution", Boolean.TRUE);
+    final protected VarROIArray regionsRois = new VarROIArray("Region ROI(s)", null);
+
+    @Override
+    public void run()
+    {
+        final Sequence sequence = inputSequence.getValue();
+        if (sequence == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        final List<ROI> rois;
+        final List<ROI2DRectangle> result = new ArrayList<ROI2DRectangle>();
+
+        switch (type.getValue())
+        {
+            default:
+                rois = sequence.getROIs();
+                break;
+            case SELECTED:
+                rois = sequence.getSelectedROIs();
+                break;
+        }
+
+        final boolean scale = originResolution.getValue().booleanValue();
+
+        // build rectangular ROI(s)
+        for (ROI roi : rois)
+        {
+            // get ROI 2D bounds
+            Rectangle rect = roi.getBounds5D().toRectangle2D().getBounds();
+
+            // scale if needed
+            if (scale)
+                rect = SequenceUtil.getOriginRectangle(rect, sequence);
+
+            // add to result
+            result.add(new ROI2DRectangle(rect));
+        }
+
+        regionsRois.setValue(result.toArray(new ROI[result.size()]));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("type", type);
+        inputMap.add("originResolution", originResolution);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("regionsRois", regionsRois);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/ReadMetadata.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/ReadMetadata.java
new file mode 100644
index 0000000..e492453
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/ReadMetadata.java
@@ -0,0 +1,107 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.MetaDataUtil;
+import ome.xml.meta.OMEXMLMetadata;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+import plugins.tprovoost.sequenceblocks.files.LoadMetadata;
+
+/**
+ * Block to return main informations from a metadata object.
+ * 
+ * @see LoadMetadata
+ * @author Stephane
+ */
+public class ReadMetadata extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected Var<OMEXMLMetadata> metadata = new Var<OMEXMLMetadata>("Metadata", OMEXMLMetadata.class);
+    final protected VarInteger serie = new VarInteger("Series", 0);
+
+    final protected VarInteger numSerie = new VarInteger("Num serie", 1);
+    final protected VarString name = new VarString("Name", "");
+    final protected VarInteger sizeX = new VarInteger("Size X", 1);
+    final protected VarInteger sizeY = new VarInteger("Size Y", 1);
+    final protected VarInteger sizeC = new VarInteger("Size C", 1);
+    final protected VarInteger sizeZ = new VarInteger("Size Z", 1);
+    final protected VarInteger sizeT = new VarInteger("Size T", 1);
+    final protected VarDouble pxSizeX = new VarDouble("Pixel Size X (µm)", 1d);
+    final protected VarDouble pxSizeY = new VarDouble("Pixel Size Y (µm)", 1d);
+    final protected VarDouble pxSizeZ = new VarDouble("Pixel Size Z (µm)", 1d);
+    final protected VarDouble timeIntT = new VarDouble("Time interval T (s)", 100d);
+    final protected VarDouble positionX = new VarDouble("Position X (µm)", 0d);
+    final protected VarDouble positionY = new VarDouble("Position Y (µm)", 0d);
+    final protected VarDouble positionZ = new VarDouble("Position Z (µm)", 0d);
+
+    @Override
+    public void run()
+    {
+        final OMEXMLMetadata meta = metadata.getValue();
+        if (meta == null)
+            throw new VarException(metadata, "Metadata is null !");
+
+        final int s = serie.getValue().intValue();
+        final int numS = MetaDataUtil.getNumSeries(meta);
+
+        numSerie.setValue(Integer.valueOf(numS));
+
+        if (s >= numS)
+            throw new VarException(serie, "Serie index must be between 0 and " + (numS - 1));
+
+        name.setValue(MetaDataUtil.getName(meta, s));
+        sizeX.setValue(Integer.valueOf(MetaDataUtil.getSizeX(meta, s)));
+        sizeY.setValue(Integer.valueOf(MetaDataUtil.getSizeY(meta, s)));
+        sizeZ.setValue(Integer.valueOf(MetaDataUtil.getSizeZ(meta, s)));
+        sizeT.setValue(Integer.valueOf(MetaDataUtil.getSizeT(meta, s)));
+        sizeC.setValue(Integer.valueOf(MetaDataUtil.getSizeC(meta, s)));
+        pxSizeX.setValue(Double.valueOf(MetaDataUtil.getPixelSizeX(meta, s, pxSizeX.getDefaultValue().doubleValue())));
+        pxSizeY.setValue(Double.valueOf(MetaDataUtil.getPixelSizeY(meta, s, pxSizeY.getDefaultValue().doubleValue())));
+        pxSizeZ.setValue(Double.valueOf(MetaDataUtil.getPixelSizeZ(meta, s, pxSizeZ.getDefaultValue().doubleValue())));
+        timeIntT.setValue(
+                Double.valueOf(MetaDataUtil.getTimeInterval(meta, s, timeIntT.getDefaultValue().doubleValue())));
+        // get position of first plane only for now
+        positionX.setValue(Double.valueOf(MetaDataUtil.getPositionX(meta, s, 0, 0, 0, 0d)));
+        positionY.setValue(Double.valueOf(MetaDataUtil.getPositionY(meta, s, 0, 0, 0, 0d)));
+        positionZ.setValue(Double.valueOf(MetaDataUtil.getPositionZ(meta, s, 0, 0, 0, 0d)));
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("Metadata", metadata);
+        inputMap.add("Serie", serie);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        outputMap.add("numSerie", numSerie);
+        outputMap.add("Name", name);
+        outputMap.add("Size X", sizeX);
+        outputMap.add("Size Y", sizeY);
+        outputMap.add("Size C", sizeC);
+        outputMap.add("Size Z", sizeZ);
+        outputMap.add("Size T", sizeT);
+        outputMap.add("Pixel Size X (mm)", pxSizeX);
+        outputMap.add("Pixel Size Y (mm)", pxSizeY);
+        outputMap.add("Pixel Size Z (mm)", pxSizeZ);
+        outputMap.add("Time interval T (ms)", timeIntT);
+        outputMap.add("positionx", positionX);
+        outputMap.add("positiony", positionY);
+        outputMap.add("positionz", positionZ);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetChannelName.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetChannelName.java
new file mode 100644
index 0000000..2b94357
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetChannelName.java
@@ -0,0 +1,65 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import icy.util.StringUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to set channel name of the specified sequence
+ * 
+ * @author Stephane
+ * @see GetChannelsName
+ * @see SetChannelName
+ */
+public class SetChannelName extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected VarString varName = new VarString("Name", "");
+    final protected VarInteger idx = new VarInteger("Channel", 0);
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSequence.getValue();
+        if (s == null)
+            throw new VarException(varSequence, "Sequence is null");
+
+        int index = idx.getValue().intValue();
+        if (index < 0 || index >= s.getSizeC())
+            throw new VarException(idx, "Wrong channel index.");
+
+        String name = varName.getName();
+        if (StringUtil.isEmpty(name))
+            throw new VarException(varName, "Name cannot be empty");
+
+        s.setChannelName(index, varName.getValue());
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+        inputMap.add("index", idx);
+        inputMap.add("name", varName);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetChannelsName.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetChannelsName.java
new file mode 100644
index 0000000..ce421ee
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetChannelsName.java
@@ -0,0 +1,58 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to set all channels name of the specified sequence
+ * 
+ * @author Stephane
+ * @see GetChannelsName
+ * @see SetChannelName
+ */
+public class SetChannelsName extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected VarArray<String> varNames = new VarArray<String>("Names", String[].class, new String[0]);
+
+    @Override
+    public void run()
+    {
+        final Sequence s = varSequence.getValue();
+        if (s == null)
+            throw new VarException(varSequence, "Sequence is null");
+
+        final String[] names = varNames.getValue();
+        if (names == null)
+            throw new VarException(varNames, "Names is null");
+
+        for (int c = 0; c < Math.min(s.getSizeC(), names.length); c++)
+            s.setChannelName(c, names[c]);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+        inputMap.add("names", varNames);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetColormap.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetColormap.java
new file mode 100644
index 0000000..3a7e57c
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetColormap.java
@@ -0,0 +1,57 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.image.colormap.IcyColorMap;
+import icy.image.colormap.LinearColorMap;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.BlocksException;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+public class SetColormap extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence sequenceIn = new VarSequence("Sequence", null);
+    final protected VarInteger numChannel = new VarInteger("Channel", 0);
+    final protected VarColormap colormap = new VarColormap("Color map", LinearColorMap.gray_);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("input", sequenceIn);
+        inputMap.add("numChannel", numChannel);
+        inputMap.add("colormap", colormap);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        // no output here
+    }
+
+    @Override
+    public void run()
+    {
+        final Sequence seq = sequenceIn.getValue();
+
+        if (seq != null)
+        {
+            final int ch = numChannel.getValue().intValue();
+            final IcyColorMap map = colormap.getValue();
+
+            if ((ch < seq.getSizeC()) && (map != null))
+                seq.setColormap(ch, map, map.isAlpha());
+            else
+                throw new BlocksException("Block 'Set Colormap': illegal channel number for this sequence !", true);
+        }
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetColormaps.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetColormaps.java
new file mode 100644
index 0000000..9e0d9e5
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetColormaps.java
@@ -0,0 +1,53 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.image.colormap.IcyColorMap;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+public class SetColormaps extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence sequenceIn = new VarSequence("Input", null);
+    final protected VarArray<IcyColorMap> colormaps = new VarArray<IcyColorMap>("Color maps", IcyColorMap[].class,
+            new IcyColorMap[0]);
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("input", sequenceIn);
+        inputMap.add("colormaps", colormaps);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        // no output here
+    }
+
+    @Override
+    public void run()
+    {
+        final Sequence seq = sequenceIn.getValue();
+        if (seq == null)
+            throw new VarException(sequenceIn, "Sequence is null");
+
+        final IcyColorMap[] cms = colormaps.getValue();
+        if (cms == null)
+            throw new VarException(colormaps, "Color maps is null");
+
+        for (int c = 0; c < Math.min(seq.getSizeC(), cms.length); c++)
+            seq.setColormap(c, cms[c], cms[c].isAlpha());
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetName.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetName.java
new file mode 100644
index 0000000..2cf4be8
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetName.java
@@ -0,0 +1,53 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.lang.VarString;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class SetName extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected VarString name = new VarString("Name", "");
+
+    @Override
+    public void run()
+    {
+        Sequence s = varSequence.getValue();
+        if (s != null)
+        {
+            s.setName(name.getValue());
+        }
+        else
+        {
+            throw new VarException(varSequence, "Sequence is null");
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", varSequence);
+        inputMap.add("name", name);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetResolution.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetResolution.java
new file mode 100644
index 0000000..e821818
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/SetResolution.java
@@ -0,0 +1,70 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * @author thomasprovoost
+ */
+public class SetResolution extends Plugin implements SequenceBlock, PluginBundled
+{
+    final protected  VarSequence varSequence = new VarSequence("Sequence", null);
+    final protected  VarDouble pxSizeX = new VarDouble("Pixel Size X (µm)", 1d);
+    final protected  VarDouble pxSizeY = new VarDouble("Pixel Size Y (µm)", 1d);
+    final protected  VarDouble pxSizeZ = new VarDouble("Pixel Size Z (µm)", 1d);
+    final protected  VarDouble timeIntT = new VarDouble("Time interval T (s)", 100d);
+
+	@Override
+	public void run()
+	{
+		Sequence s = varSequence.getValue();
+
+		if (s != null)
+		{
+			double x = pxSizeX.getValue().doubleValue();
+			double y = pxSizeY.getValue().doubleValue();
+			double z = pxSizeZ.getValue().doubleValue();
+			double ti = timeIntT.getValue().doubleValue();
+			if (x != -1)
+				s.setPixelSizeX(x);
+			if (y != -1)
+				s.setPixelSizeY(y);
+			if (z != -1)
+				s.setPixelSizeZ(z);
+			if (ti != -1)
+				s.setTimeInterval(ti);
+		} else
+		{
+			throw new VarException(varSequence, "Sequence is null");
+		}
+	}
+
+	@Override
+	public void declareInput(VarList inputMap)
+	{
+		inputMap.add("sequence", varSequence);
+		inputMap.add("PxSize X (µm)", pxSizeX);
+		inputMap.add("PxSize Y (µm)", pxSizeY);
+		inputMap.add("PxSize Z (µm)", pxSizeZ);
+		inputMap.add("Time interval T (s)", timeIntT);
+	}
+
+	@Override
+	public void declareOutput(VarList outputMap)
+	{
+	    //
+	}
+
+	@Override
+	public String getMainPluginClassName()
+	{
+		return SequenceBlocks.class.getName();
+	}
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/infos/VarColormap.java b/src/main/java/plugins/tprovoost/sequenceblocks/infos/VarColormap.java
new file mode 100644
index 0000000..017f8b9
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/infos/VarColormap.java
@@ -0,0 +1,90 @@
+package plugins.tprovoost.sequenceblocks.infos;
+
+import javax.swing.JComboBox;
+
+import org.w3c.dom.Node;
+
+import icy.gui.component.renderer.ColormapComboBoxRenderer;
+import icy.image.colormap.IcyColorMap;
+import icy.image.colormap.LinearColorMap;
+import icy.util.XMLUtil;
+import plugins.adufour.vars.gui.VarEditor;
+import plugins.adufour.vars.gui.model.ValueSelectionModel;
+import plugins.adufour.vars.gui.swing.ComboBox;
+import plugins.adufour.vars.lang.Var;
+
+/**
+ * Define a specific Var type for ColorMap object
+ * 
+ * @author emilie
+ */
+public class VarColormap extends Var<IcyColorMap>
+{
+    public static class ColormapSelectionModel extends ValueSelectionModel<IcyColorMap>
+    {
+        public ColormapSelectionModel()
+        {
+            super(IcyColorMap.getAllColorMaps(true, true).toArray(new IcyColorMap[0]), LinearColorMap.gray_, false);
+        }
+
+        @Override
+        public boolean isValid(IcyColorMap value)
+        {
+            return true;
+        }
+    }
+
+    public final String ID_NODE = "colormap";
+
+    /**
+     * Create a new VarColormap with given name and default value
+     */
+    public VarColormap(String name, IcyColorMap defaultValue)
+    {
+        super(name, new ColormapSelectionModel());
+    }
+
+    @Override
+    public VarEditor<IcyColorMap> createVarEditor()
+    {
+        // create the var editor (combo box type here)
+        final ComboBox<IcyColorMap> result = new ComboBox<IcyColorMap>(this);
+        // get the editor component
+        final JComboBox combo = result.getEditorComponent();
+        // and set a specific renderer
+        combo.setRenderer(new ColormapComboBoxRenderer(combo));
+
+        return result;
+    }
+
+    @Override
+    public boolean loadFromXML(Node node)
+    {
+        try
+        {
+            final IcyColorMap map = new IcyColorMap();
+            map.loadFromXML(XMLUtil.setElement(node, ID_NODE));
+            setValue(map);
+
+            return true;
+        }
+        catch (Exception e)
+        {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean saveToXML(Node node) throws UnsupportedOperationException
+    {
+        try
+        {
+            getValue().saveToXML(XMLUtil.setElement(node, ID_NODE));
+            return true;
+        }
+        catch (Exception e)
+        {
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceChannelBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceChannelBatch.java
new file mode 100644
index 0000000..f227dcd
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceChannelBatch.java
@@ -0,0 +1,77 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.lang.Batch;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Simple batch loop to iterate over all C channel from an input Sequence.
+ * 
+ * @author Stephane
+ */
+public class SequenceChannelBatch extends Batch implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    // important to not initialize and create them in getBatchSource() and getBatchElement()
+    protected VarSequence inputSequence;
+    protected VarSequence element;
+
+    public SequenceChannelBatch()
+    {
+        super();
+    }
+
+    @Override
+    public VarSequence getBatchSource()
+    {
+        // initialize variable if needed
+        if (inputSequence == null)
+            inputSequence = new VarSequence("Sequence", null);
+
+        return inputSequence;
+    }
+
+    @Override
+    public VarSequence getBatchElement()
+    {
+        // initialize element if needed
+        if (element == null)
+            element = new VarSequence("Channel Sequence", null);
+
+        return element;
+    }
+
+    @Override
+    public void initializeLoop()
+    {
+        final Sequence value = inputSequence.getValue();
+
+        if (value == null)
+            throw new VarException(inputSequence, "No input sequence indicated");
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set result in element
+        element.setValue(
+                SequenceUtil.extractChannel(inputSequence.getValue(), getIterationCounter().getValue().intValue()));
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= inputSequence.getValue().getSizeC();
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterBatch.java
new file mode 100644
index 0000000..782c76c
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterBatch.java
@@ -0,0 +1,70 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import icy.file.SequenceFileImporter;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import plugins.adufour.blocks.lang.Batch;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+import plugins.tprovoost.sequenceblocks.importer.PositionedSequenceFileImporter;
+
+/**
+ * Base abstract class for {@link SequenceFileImporter} batch loop.
+ * 
+ * @author Stephane
+ */
+public abstract class SequenceFileImporterBatch extends Batch implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    // important to not initialize and create them in getBatchSource() and getBatchElement()
+    protected Var<PositionedSequenceFileImporter> positionedImporter;
+    protected Var<PositionedSequenceFileImporter> element;
+
+    // internal
+    protected int limit;
+
+    @Override
+    public Var<PositionedSequenceFileImporter> getBatchSource()
+    {
+        // initialize variable if needed
+        if (positionedImporter == null)
+            positionedImporter = new Var<PositionedSequenceFileImporter>("Importer",
+                    PositionedSequenceFileImporter.class);
+
+        return positionedImporter;
+    }
+
+    @Override
+    public Var<PositionedSequenceFileImporter> getBatchElement()
+    {
+        // initialize element if needed
+        if (element == null)
+            element = new Var<PositionedSequenceFileImporter>("Loop importer", PositionedSequenceFileImporter.class);
+
+        return element;
+    }
+
+    @Override
+    public void initializeLoop()
+    {
+        final PositionedSequenceFileImporter value = positionedImporter.getValue();
+
+        if (value == null)
+            throw new VarException(positionedImporter, "Input importer is null !");
+
+        final SequenceFileImporter imp = value.importer;
+
+        if (imp.getOpened() == null)
+            throw new VarException(positionedImporter, "Importer is not opened !");
+
+        // init element with a copy of current positioned importer
+        element.setValue(new PositionedSequenceFileImporter(value));
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterChannelBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterChannelBatch.java
new file mode 100644
index 0000000..46640c5
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterChannelBatch.java
@@ -0,0 +1,54 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import icy.file.SequenceFileImporter;
+import icy.sequence.MetaDataUtil;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.importer.PositionedSequenceFileImporter;
+
+/**
+ * Simple batch loop to iterate over all C channel from specified opened {@link SequenceFileImporter} object.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterChannelBatch extends SequenceFileImporterBatch
+{
+    @Override
+    public void initializeLoop()
+    {
+        super.initializeLoop();
+
+        final PositionedSequenceFileImporter pi = positionedImporter.getValue();
+
+        try
+        {
+            // can iterate over C dimension ?
+            if (pi.c == -1)
+                limit = MetaDataUtil.getSizeC(pi.getMetadata(), (pi.s == -1) ? 0 : pi.s);
+            else
+                limit = 1;
+        }
+        catch (Exception e)
+        {
+            throw new VarException(element,
+                    "Error while initializing SequenceFileImporter channel batch: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set current position C
+        if (positionedImporter.getValue().c == -1)
+        {
+            element.getValue().c = getIterationCounter().getValue().intValue();
+            // force element changed event so loop get correctly executed
+            element.valueChanged(element, element.getValue(), element.getValue());
+        }
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= limit;
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterFrameBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterFrameBatch.java
new file mode 100644
index 0000000..e91d5f4
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterFrameBatch.java
@@ -0,0 +1,54 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import icy.file.SequenceFileImporter;
+import icy.sequence.MetaDataUtil;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.importer.PositionedSequenceFileImporter;
+
+/**
+ * Simple batch loop to iterate over all T frame from the specified opened {@link SequenceFileImporter} object.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterFrameBatch extends SequenceFileImporterBatch
+{
+    @Override
+    public void initializeLoop()
+    {
+        super.initializeLoop();
+
+        final PositionedSequenceFileImporter pi = positionedImporter.getValue();
+
+        try
+        {
+            // can iterate over T dimension ?
+            if (pi.t == -1)
+                limit = MetaDataUtil.getSizeT(pi.getMetadata(), (pi.s == -1) ? 0 : pi.s);
+            else
+                limit = 1;
+        }
+        catch (Exception e)
+        {
+            throw new VarException(element,
+                    "Error while initializing SequenceFileImporter frame batch: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set current position T
+        if (positionedImporter.getValue().t == -1)
+        {
+            element.getValue().t = getIterationCounter().getValue().intValue();
+            // force element changed event so loop get correctly executed
+            element.valueChanged(element, element.getValue(), element.getValue());
+        }
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= limit;
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterRegionBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterRegionBatch.java
new file mode 100644
index 0000000..0bbd8bb
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterRegionBatch.java
@@ -0,0 +1,137 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+import icy.file.SequenceFileImporter;
+import icy.roi.ROI;
+import icy.sequence.MetaDataUtil;
+import icy.type.rectangle.Rectangle2DUtil;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.importer.PositionedSequenceFileImporter;
+
+/**
+ * Simple batch loop to iterate over a set of XY region defined by ROIs from the specified opened
+ * {@link SequenceFileImporter} object.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterRegionBatch extends SequenceFileImporterBatch
+{
+    protected VarROIArray rois;
+    protected VarInteger inputRoisResolution;
+    protected VarInteger inputRoisMargin;
+    protected List<Rectangle> regions;
+
+    @Override
+    public void initializeLoop()
+    {
+        super.initializeLoop();
+
+        final PositionedSequenceFileImporter pi = positionedImporter.getValue();
+
+        // can iterate over XY dimension ?
+        if ((pi.xyRegion == null) && (rois.getValue() != null))
+        {
+            final int s = (pi.s == -1) ? 0 : pi.s;
+            final Rectangle regionMask;
+
+            try
+            {
+                // mask for region
+                regionMask = new Rectangle(0, 0, MetaDataUtil.getSizeX(pi.getMetadata(), s),
+                        MetaDataUtil.getSizeY(pi.getMetadata(), s));
+            }
+            catch (Exception e)
+            {
+                throw new VarException(element,
+                        "Error while initializing SequenceFileImporter region batch: " + e.getMessage());
+            }
+
+            final double scaleFactor = Math.pow(2, inputRoisResolution.getValue().doubleValue());
+            final double margeFactor = 1d + (inputRoisMargin.getValue().doubleValue() / 100d);
+
+            // build 2D regions from ROI
+            regions = new ArrayList<Rectangle>();
+            for (ROI roi : rois.getValue())
+            {
+                Rectangle2D region = roi.getBounds5D().toRectangle2D();
+
+                // convert to full resolution if needed
+                if (scaleFactor != 1d)
+                    region = Rectangle2DUtil.getScaledRectangle(region, scaleFactor, false, true);
+                // apply marge factor if needed
+                if (margeFactor != 1d)
+                    region = Rectangle2DUtil.getScaledRectangle(region, margeFactor, true, false);
+
+                // use regionMask to limit to image region
+                regions.add(region.getBounds().intersection(regionMask));
+            }
+
+            // set limit
+            limit = regions.size();
+        }
+        else
+            limit = 1;
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set current position XY region
+        if (positionedImporter.getValue().xyRegion == null)
+        {
+            element.getValue().xyRegion = regions.get(getIterationCounter().getValue().intValue());
+            // force element changed event so loop get correctly executed
+            element.valueChanged(element, element.getValue(), element.getValue());
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        super.declareInput(inputMap);
+
+        // lazy creation
+        if (rois == null)
+            rois = new VarROIArray("XY regions (ROIs)");
+        if (inputRoisResolution == null)
+            inputRoisResolution = new VarInteger("ROIs resolution", 0);
+        if (inputRoisMargin == null)
+            inputRoisMargin = new VarInteger("ROIs margin", 20);
+
+        inputMap.add("regions", rois);
+        inputMap.add("inputResolution", inputRoisResolution);
+        inputMap.add("inputRoisMarge", inputRoisMargin);
+    }
+
+    @Override
+    public void declareLoopVariables(List<Var<?>> loopVariables)
+    {
+        // lazy creation
+        if (rois == null)
+            rois = new VarROIArray("XY regions (ROIs)");
+        if (inputRoisResolution == null)
+            inputRoisResolution = new VarInteger("ROIs resolution", 0);
+        if (inputRoisMargin == null)
+            inputRoisMargin = new VarInteger("ROIs margin", 20);
+
+        loopVariables.add(rois);
+        loopVariables.add(inputRoisResolution);
+        loopVariables.add(inputRoisMargin);
+
+        super.declareLoopVariables(loopVariables);
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= limit;
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterSeriesBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterSeriesBatch.java
new file mode 100644
index 0000000..255c14c
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterSeriesBatch.java
@@ -0,0 +1,48 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import icy.file.SequenceFileImporter;
+import icy.sequence.MetaDataUtil;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.importer.PositionedSequenceFileImporter;
+
+/**
+ * Simple batch loop to iterate over all series from the specified opened {@link SequenceFileImporter} object.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterSeriesBatch extends SequenceFileImporterBatch
+{
+    @Override
+    public void initializeLoop()
+    {
+        super.initializeLoop();
+
+        final PositionedSequenceFileImporter pi = positionedImporter.getValue();
+
+        try
+        {
+            // force series iteration as by default series is set to 0
+            limit = MetaDataUtil.getNumSeries(pi.getMetadata());
+        }
+        catch (Exception e)
+        {
+            throw new VarException(element,
+                    "Error while initializing SequenceFileImporter series batch: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set current position S
+        element.getValue().s = getIterationCounter().getValue().intValue();
+        // force element changed event so loop get correctly executed
+        element.valueChanged(element, element.getValue(), element.getValue());
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= limit;
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterSliceBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterSliceBatch.java
new file mode 100644
index 0000000..061b76d
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterSliceBatch.java
@@ -0,0 +1,54 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import icy.file.SequenceFileImporter;
+import icy.sequence.MetaDataUtil;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.importer.PositionedSequenceFileImporter;
+
+/**
+ * Simple batch loop to iterate over all Z slice from specified opened {@link SequenceFileImporter} object.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterSliceBatch extends SequenceFileImporterBatch
+{
+    @Override
+    public void initializeLoop()
+    {
+        super.initializeLoop();
+
+        final PositionedSequenceFileImporter pi = positionedImporter.getValue();
+
+        try
+        {
+            // can iterate over Z dimension ?
+            if (pi.z == -1)
+                limit = MetaDataUtil.getSizeZ(pi.getMetadata(), (pi.s == -1) ? 0 : pi.s);
+            else
+                limit = 1;
+        }
+        catch (Exception e)
+        {
+            throw new VarException(element,
+                    "Error while initializing SequenceFileImporter slice batch: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set current position Z
+        if (positionedImporter.getValue().z == -1)
+        {
+            element.getValue().z = getIterationCounter().getValue().intValue();
+            // force element changed event so loop get correctly executed
+            element.valueChanged(element, element.getValue(), element.getValue());
+        }
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= limit;
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterTileBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterTileBatch.java
new file mode 100644
index 0000000..5386fb6
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFileImporterTileBatch.java
@@ -0,0 +1,109 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import java.awt.Rectangle;
+import java.util.List;
+
+import icy.file.SequenceFileImporter;
+import icy.image.ImageUtil;
+import icy.sequence.MetaDataUtil;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.importer.PositionedSequenceFileImporter;
+
+/**
+ * Simple batch loop to iterate over all XY tile from the specified opened {@link SequenceFileImporter} object.
+ * 
+ * @author Stephane
+ */
+public class SequenceFileImporterTileBatch extends SequenceFileImporterBatch
+{
+    protected final VarInteger tileW;
+    protected final VarInteger tileH;
+
+    protected List<Rectangle> tiles;
+
+    public SequenceFileImporterTileBatch()
+    {
+        super();
+
+        tileW = new VarInteger("Tile width (-1 = auto)", 0);
+        tileH = new VarInteger("Tile height (-1 = auto)", 0);
+    }
+
+    @Override
+    public void initializeLoop()
+    {
+        super.initializeLoop();
+
+        final PositionedSequenceFileImporter pi = positionedImporter.getValue();
+
+        // can iterate over XY dimension ?
+        if (pi.xyRegion == null)
+        {
+            final SequenceFileImporter imp = pi.importer;
+            final int s = (pi.s == -1) ? 0 : pi.s;
+            final int sizeX;
+            final int sizeY;
+            int tw;
+            int th;
+
+            try
+            {
+                sizeX = MetaDataUtil.getSizeX(pi.getMetadata(), s);
+                sizeY = MetaDataUtil.getSizeY(pi.getMetadata(), s);
+
+                tw = tileW.getValue().intValue();
+                th = tileH.getValue().intValue();
+                // auto ? --> get it from importer
+                if (tw == -1)
+                    tw = imp.getTileWidth(s);
+                // auto ? --> get it from importer
+                if (th == -1)
+                    th = imp.getTileHeight(s);
+            }
+            catch (Exception e)
+            {
+                throw new VarException(positionedImporter,
+                        "Error while initializing SequenceFileImporter tile batch: " + e.getMessage());
+            }
+
+            // any size supported ? --> use 1024 by default
+            if (tw == -1)
+                tw = 1024;
+            // tile loading not supported ? --> use full width
+            else if (tw == 0)
+                tw = sizeX;
+            // any size supported ? --> use 1024 by default
+            if (th == -1)
+                th = 1024;
+            // tile loading not supported ? --> use full height
+            else if (th == 0)
+                th = sizeY;
+
+            // get tiles
+            tiles = ImageUtil.getTileList(sizeX, sizeY, tw, th);
+            // set limit
+            limit = tiles.size();
+        }
+        else
+            limit = 1;
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set current position XY region
+        if (positionedImporter.getValue().xyRegion == null)
+        {
+            element.getValue().xyRegion = tiles.get(getIterationCounter().getValue().intValue());
+            // force element changed event so loop get correctly executed
+            element.valueChanged(element, element.getValue(), element.getValue());
+        }
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= limit;
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFrameBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFrameBatch.java
new file mode 100644
index 0000000..d06b0a6
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceFrameBatch.java
@@ -0,0 +1,76 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.lang.Batch;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Simple batch loop to iterate over all T frame from an input Sequence.
+ * 
+ * @author Stephane
+ */
+public class SequenceFrameBatch extends Batch implements PluginLibrary, PluginBundled
+{
+    // important to not initialize and create them in getBatchSource() and getBatchElement()
+    protected VarSequence inputSequence;
+    protected VarSequence element;
+
+    public SequenceFrameBatch()
+    {
+        super();
+    }
+
+    @Override
+    public VarSequence getBatchSource()
+    {
+        // initialize variable if needed
+        if (inputSequence == null)
+            inputSequence = new VarSequence("Sequence", null);
+
+        return inputSequence;
+    }
+
+    @Override
+    public VarSequence getBatchElement()
+    {
+        // initialize element if needed
+        if (element == null)
+            element = new VarSequence("Channel Sequence", null);
+
+        return element;
+    }
+
+    @Override
+    public void initializeLoop()
+    {
+        final Sequence value = inputSequence.getValue();
+
+        if (value == null)
+            throw new VarException(inputSequence, "No input sequence indicated");
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set result in element
+        element.setValue(
+                SequenceUtil.extractFrame(inputSequence.getValue(), getIterationCounter().getValue().intValue()));
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= inputSequence.getValue().getSizeT();
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceRegionBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceRegionBatch.java
new file mode 100644
index 0000000..548ba91
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceRegionBatch.java
@@ -0,0 +1,104 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import java.util.List;
+
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.lang.Batch;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.Var;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Simple batch loop to iterate over a set of Region (ROIs) from an input Sequence.
+ * 
+ * @author Stephane
+ */
+public class SequenceRegionBatch extends Batch implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    // important to not initialize and create them in getBatchSource() and getBatchElement()
+    protected VarSequence inputSequence;
+    protected VarSequence element;
+    protected final VarROIArray rois;
+
+    public SequenceRegionBatch()
+    {
+        super();
+
+        rois = new VarROIArray("ROI(s)");
+    }
+
+    @Override
+    public VarSequence getBatchSource()
+    {
+        // initialize variable if needed
+        if (inputSequence == null)
+            inputSequence = new VarSequence("Sequence", null);
+
+        return inputSequence;
+    }
+
+    @Override
+    public VarSequence getBatchElement()
+    {
+        // initialize element if needed
+        if (element == null)
+            element = new VarSequence("Channel Sequence", null);
+
+        return element;
+    }
+
+    @Override
+    public void initializeLoop()
+    {
+        final Sequence value = inputSequence.getValue();
+
+        if (value == null)
+            throw new VarException(inputSequence, "No input sequence indicated");
+
+        if (rois.getValue() == null)
+            throw new VarException(rois, "No roi(s) indicated --> no region to iterate over");
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set result in element
+        element.setValue(SequenceUtil.getSubSequence(inputSequence.getValue(),
+                rois.getValue()[getIterationCounter().getValue().intValue()]));
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= rois.getValue().length;
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        super.declareInput(inputMap);
+
+        inputMap.add("ROIs", rois);
+    }
+
+    @Override
+    public void declareLoopVariables(List<Var<?>> loopVariables)
+    {
+        super.declareLoopVariables(loopVariables);
+
+        loopVariables.add(rois);
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceSliceBatch.java b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceSliceBatch.java
new file mode 100644
index 0000000..4a0440a
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/loop/SequenceSliceBatch.java
@@ -0,0 +1,77 @@
+package plugins.tprovoost.sequenceblocks.loop;
+
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.lang.Batch;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Simple batch loop to iterate over all Z slice from an input Sequence.
+ * 
+ * @author Stephane
+ */
+public class SequenceSliceBatch extends Batch implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    // important to not initialize and create them in getBatchSource() and getBatchElement()
+    protected VarSequence inputSequence;
+    protected VarSequence element;
+
+    public SequenceSliceBatch()
+    {
+        super();
+    }
+
+    @Override
+    public VarSequence getBatchSource()
+    {
+        // initialize variable if needed
+        if (inputSequence == null)
+            inputSequence = new VarSequence("Sequence", null);
+
+        return inputSequence;
+    }
+
+    @Override
+    public VarSequence getBatchElement()
+    {
+        // initialize element if needed
+        if (element == null)
+            element = new VarSequence("Channel Sequence", null);
+
+        return element;
+    }
+
+    @Override
+    public void initializeLoop()
+    {
+        final Sequence value = inputSequence.getValue();
+
+        if (value == null)
+            throw new VarException(inputSequence, "No input sequence indicated");
+    }
+
+    @Override
+    public void beforeIteration()
+    {
+        // set result in element
+        element.setValue(
+                SequenceUtil.extractSlice(inputSequence.getValue(), getIterationCounter().getValue().intValue()));
+    }
+
+    @Override
+    public boolean isStopConditionReached()
+    {
+        return getIterationCounter().getValue().intValue() >= inputSequence.getValue().getSizeZ();
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/op/AdditiveFillSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/op/AdditiveFillSequence.java
new file mode 100644
index 0000000..ec957c7
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/op/AdditiveFillSequence.java
@@ -0,0 +1,95 @@
+/**
+ * 
+ */
+package plugins.tprovoost.sequenceblocks.op;
+
+import icy.image.ImageDataIterator;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceDataIterator;
+import icy.type.DataIterator;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to do additive fill of area inside the ROI regions with the specified value.<br>
+ * The result of this operation is similar to heatmap production from ROIs.
+ * 
+ * @author Stephane
+ */
+public class AdditiveFillSequence extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarROIArray rois = new VarROIArray("Roi(s)");
+
+    @Override
+    public void run()
+    {
+        final Sequence sequence = inputSequence.getValue();
+        if (sequence == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        if (rois.getValue() != null)
+        {
+            for (ROI roi : rois.getValue())
+                doAdditiveFill(sequence, roi, 1d);
+
+            sequence.dataChanged();
+        }
+    }
+
+    public static void doAdditiveFill(Sequence sequence, ROI roi, double value)
+    {
+        doAdditiveFill(new SequenceDataIterator(sequence, roi), value);
+    }
+
+    public static void doAdditiveFill(DataIterator it, double value)
+    {
+        it.reset();
+
+        while (!it.done())
+        {
+            it.set(it.get() + value);
+            it.next();
+        }
+
+        try
+        {
+            // not really nice to do that here, but it's to preserve backward compatibility
+            if (it instanceof SequenceDataIterator)
+                ((SequenceDataIterator) it).flush();
+            else if (it instanceof ImageDataIterator)
+                ((ImageDataIterator) it).flush();
+        }
+        catch (Throwable t)
+        {
+            // ignore
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("rois", rois);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/op/FillInnerSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/op/FillInnerSequence.java
new file mode 100644
index 0000000..39c7c63
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/op/FillInnerSequence.java
@@ -0,0 +1,69 @@
+/**
+ * 
+ */
+package plugins.tprovoost.sequenceblocks.op;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceDataIterator;
+import icy.type.DataIteratorUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to fill area inside the ROI regions with the specified value
+ * 
+ * @author Stephane
+ */
+public class FillInnerSequence extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarROIArray rois = new VarROIArray("Roi(s)");
+    final protected VarDouble fillValue = new VarDouble("Value", 0d);
+
+    @Override
+    public void run()
+    {
+        final Sequence sequence = inputSequence.getValue();
+        if (sequence == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        if (rois.getValue() != null)
+        {
+            final double value = fillValue.getValue().doubleValue();
+
+            for (ROI roi : rois.getValue())
+                DataIteratorUtil.set(new SequenceDataIterator(sequence, roi), value);
+
+            sequence.dataChanged();
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("rois", rois);
+        inputMap.add("value", fillValue);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/op/FillOuterSequence.java b/src/main/java/plugins/tprovoost/sequenceblocks/op/FillOuterSequence.java
new file mode 100644
index 0000000..7e3faea
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/op/FillOuterSequence.java
@@ -0,0 +1,83 @@
+/**
+ * 
+ */
+package plugins.tprovoost.sequenceblocks.op;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import icy.roi.ROIUtil;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceDataIterator;
+import icy.type.DataIteratorUtil;
+import icy.type.collection.CollectionUtil;
+import icy.util.ShapeUtil.BooleanOperator;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarDouble;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.kernel.roi.roi5d.ROI5DStackRectangle;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to fill area outside the ROI regions with the specified value
+ * 
+ * @author Stephane
+ */
+public class FillOuterSequence extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarROIArray rois = new VarROIArray("Roi(s)");
+    final protected VarDouble fillValue = new VarDouble("Value", 0d);
+
+    @Override
+    public void run()
+    {
+        final Sequence sequence = inputSequence.getValue();
+        if (sequence == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        if (rois.getValue() != null)
+        {
+            try
+            {
+                final ROI roiUnion = ROIUtil.merge(CollectionUtil.asList(rois.getValue()), BooleanOperator.OR);
+                final ROI roiSeq = new ROI5DStackRectangle(sequence.getBounds5D());
+                final ROI roi = roiSeq.getSubtraction(roiUnion);
+
+                final double value = fillValue.getValue().doubleValue();
+
+                DataIteratorUtil.set(new SequenceDataIterator(sequence, roi), value);
+
+                sequence.dataChanged();
+            }
+            catch (UnsupportedOperationException e)
+            {
+                throw new VarException(rois, e.getMessage());
+            }
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("rois", rois);
+        inputMap.add("value", fillValue);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveAllRois.java b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveAllRois.java
new file mode 100644
index 0000000..6ce1c1a
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveAllRois.java
@@ -0,0 +1,50 @@
+package plugins.tprovoost.sequenceblocks.remove;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to remove all the {@link ROI} from a Sequence
+ * 
+ * @author Stephane
+ */
+public class RemoveAllRois extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+
+    @Override
+    public void run()
+    {
+        final Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        s.removeAllROI(false);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveChannel.java b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveChannel.java
new file mode 100644
index 0000000..946b5cb
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveChannel.java
@@ -0,0 +1,59 @@
+package plugins.tprovoost.sequenceblocks.remove;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to remove a channel from a Sequence
+ * 
+ * @author Stephane
+ */
+public class RemoveChannel extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarInteger channelIdx = new VarInteger("Channel", 0);
+
+    @Override
+    public void run()
+    {
+        Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+        if (s.getSizeC() == 1)
+            throw new VarException(inputSequence, "Cannot remove channel on single channel image");
+
+        int channel = channelIdx.getValue().intValue();
+        if (channel < 0 || channel >= s.getSizeC())
+            throw new VarException(channelIdx, "Channel index must be between 0 and " + (s.getSizeC() - 1));
+
+        SequenceUtil.removeChannel(s, channel);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("channel", channelIdx);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveFrame.java b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveFrame.java
new file mode 100644
index 0000000..4583bfd
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveFrame.java
@@ -0,0 +1,53 @@
+package plugins.tprovoost.sequenceblocks.remove;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to remove a frame from a Sequence
+ * 
+ * @author Stephane
+ */
+public class RemoveFrame extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarInteger frameInd = new VarInteger("Frame", 0);
+
+    @Override
+    public void run()
+    {
+        Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        SequenceUtil.removeTAndShift(s, frameInd.getValue().intValue());
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("frame", frameInd);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveOverlays.java b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveOverlays.java
new file mode 100644
index 0000000..78d90d2
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveOverlays.java
@@ -0,0 +1,69 @@
+/**
+ * 
+ */
+package plugins.tprovoost.sequenceblocks.remove;
+
+import icy.painter.Overlay;
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to remove one or several {@link Overlay} from a {@link Sequence}
+ * 
+ * @author Stephane
+ */
+public class RemoveOverlays extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarArray<Overlay> overlays = new VarArray<Overlay>("Overlay(s)", Overlay[].class, new Overlay[0]);
+
+    @Override
+    public void run()
+    {
+        final Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        final Overlay[] o = overlays.getValue();
+        if (o != null)
+        {
+            s.beginUpdate();
+            try
+            {
+                for (Overlay overlay : o)
+                    s.removeOverlay(overlay);
+            }
+            finally
+            {
+                s.endUpdate();
+            }
+        }
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("overlay(s)", overlays);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveRois.java b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveRois.java
new file mode 100644
index 0000000..2866f0d
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveRois.java
@@ -0,0 +1,58 @@
+package plugins.tprovoost.sequenceblocks.remove;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.roi.ROI;
+import icy.sequence.Sequence;
+
+import java.util.Arrays;
+
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarROIArray;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to remove one or several {@link ROI} from a Sequence
+ * 
+ * @author Stephane
+ */
+public class RemoveRois extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarROIArray rois = new VarROIArray("Roi(s)");
+
+    @Override
+    public void run()
+    {
+        final Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        final ROI[] r = rois.getValue();
+        if (r != null)
+            s.removeROIs(Arrays.asList(r), false);
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("rois(s)", rois);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
diff --git a/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveSlice.java b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveSlice.java
new file mode 100644
index 0000000..56fecec
--- /dev/null
+++ b/src/main/java/plugins/tprovoost/sequenceblocks/remove/RemoveSlice.java
@@ -0,0 +1,53 @@
+package plugins.tprovoost.sequenceblocks.remove;
+
+import icy.plugin.abstract_.Plugin;
+import icy.plugin.interface_.PluginBundled;
+import icy.plugin.interface_.PluginLibrary;
+import icy.sequence.Sequence;
+import icy.sequence.SequenceUtil;
+import plugins.adufour.blocks.tools.sequence.SequenceBlock;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarInteger;
+import plugins.adufour.vars.lang.VarSequence;
+import plugins.adufour.vars.util.VarException;
+import plugins.tprovoost.sequenceblocks.SequenceBlocks;
+
+/**
+ * Block to remove a Z slice from a Sequence
+ * 
+ * @author Stephane
+ */
+public class RemoveSlice extends Plugin implements SequenceBlock, PluginLibrary, PluginBundled
+{
+    final protected VarSequence inputSequence = new VarSequence("Sequence", null);
+    final protected VarInteger sliceInd = new VarInteger("Slice", 0);
+
+    @Override
+    public void run()
+    {
+        Sequence s = inputSequence.getValue();
+        if (s == null)
+            throw new VarException(inputSequence, "Input sequence is null.");
+
+        SequenceUtil.removeZAndShift(s, sliceInd.getValue().intValue());
+    }
+
+    @Override
+    public void declareInput(VarList inputMap)
+    {
+        inputMap.add("sequence", inputSequence);
+        inputMap.add("slice", sliceInd);
+    }
+
+    @Override
+    public void declareOutput(VarList outputMap)
+    {
+        //
+    }
+
+    @Override
+    public String getMainPluginClassName()
+    {
+        return SequenceBlocks.class.getName();
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/SequenceBlocks.xml b/src/main/resources/SequenceBlocks.xml
new file mode 100644
index 0000000..352d4eb
--- /dev/null
+++ b/src/main/resources/SequenceBlocks.xml
@@ -0,0 +1,22 @@
+<?xml version='1.0' encoding='ISO-8859-1' standalone='no'?>
+<root>
+<url><![CDATA[http://www.bioimageanalysis.org/icy/repository/getXMLPluginFile.php?pluginId=182&beta=0]]></url><name>Sequence Blocks</name><version>1.0.0.1</version><required_kernel_version>1.2.5.0</required_kernel_version><kernel_ver>1.2.5.0</kernel_ver><jar_url><![CDATA[http://www.bioimageanalysis.org/icy/repository/getJarFile.php?pluginId=182&beta=0]]></jar_url><icon_url><![CDATA[http://bioimageanalysis.org/icy/image.php?idAttach=1256]]></icon_url><image_url></image_url><description><![CDATA[This plugin allows one to use various basic sequence operations within Blocks.]]></description><classname><![CDATA[plugins.tprovoost.sequenceblocks.SequenceBlocks]]></classname><author><![CDATA[tprovoost - Thomas Provoost]]></author><changelog><![CDATA[-
+Version 1.0.0.1
+Date 2012-06-22 15:17:27
+
+Added Description to the Blocks.
+Corrected Save Sequence block name.
+
+-
+Version 1.0.0.0
+Date 2012-06-21 15:37:19
+
+First real version.
+
+-
+Version 0.0.1.0
+Date 2012-06-21 15:00:05
+
+
+
+]]></changelog><dependencies><dependency><classname>plugins.adufour.blocks.Blocks</classname><version>0.0.0.1</version></dependency></dependencies></root>
\ No newline at end of file
diff --git a/src/main/resources/SequenceBlocks_icon.png b/src/main/resources/SequenceBlocks_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a70e1f10004bbd8666695af79be78770dadbd1b
GIT binary patch
literal 7025
zcmV-%8;<0OP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF000U@X+uL$Nkc;*
zaB^>EX>4Tx0C?J+Q+HUC_ZB|i_hk=OLfG)Jmu!ImA|tE_$Pihg5Rw34gb)%y#f69p
zRumNxoJdu~g4GI0orvO~D7a@qiilc^Ra`jkAKa(4eR}Wh?fcjJyyu+f{LXpL4}cL8
zCXwc%Y5+M>g*-agACFH+#L2yY0u@N$1RxOR%fe>`#Q*^C19^CUbg)1C0k3ZW0swH;
zE+i7i;s1lWP$pLZAdvvzA`<5d0gzGv$SzdK6adH=0I*ZDWC{S3003-xd_p1ssto|_
z^hrJi0NAOM+!p}Yq8zCR0F40vnJ7mj0zkU}U{!%qECRs70HCZuA}$2Lt^t5qwlYTo
zfV~9(c8*w(4?ti5fSE!p%m5%b0suoE6U_r4Oaq`W(!b!TUvP!ENC5!A%azTSOVTqG
zxRuZvck=My;vwR~Y_URN7by^C3FIQ2mzyIKNaq7g&I|wm8u`(|{y0C7=jP<$=4R(?
z@ASo@{%i1WB0eGU-~POe0t5gMPS5Y!U*+Z218~Oyuywy{sapWrRsd+<`CT*H37}dE
z(0cicc{uz)9-g64$UGe!3JVMEC1RnyFyo6p|1;rl;ER6t{6HT5+j{T-ahgDxt-zy$
z{c&M#cCJ#6=gR~_F>d$gBmT#QfBlXr(c(0*Tr3re@mPttP$EsodAU-NL?OwQ;u7h9
zGVvdl{RxwI4FIf$Pry#L2er#=z<%xl0*ek<(slqqe)BDi8VivC5N9+pdG`PSlfU_o
zKq~<N&6lL(006w`7+k277fi+o002awfhw>;2Moa!tiTSO!5zH77Xo1hL_iEAz&sE_
z2IPPo3ZWR5K^auQI@koYumc*P5t`u;w81er4d>tzT!HIw7Y1M$p28Tsh6w~g$Osc*
zAv%Z=Vvg7%&IlKojszlMNHmgwq#)^t6j36@$a16tsX}UzT}UJHEpik&ja)$bklV;0
zGK&0)yhkyVfwEBp)B<%txu_o+ipHRG(R4HqU4WLNYtb6C9zB4zqNmYI=yh}eeTt4_
zfYC7yW{lZkT#ScBV2M~7CdU?I<ybXVk2PZ*ST}YR8^E4n?+7FUi+~gC2wsE`!fb+&
zkVjZdSVO2K>?5=ix(HVZgM=}{CnA%mPqZa^68Xe<Vmh&qSVpWS?jar_o+Vx<4ijIK
zNF)x)lH^VbAtjJ9NefA9NZUv)q*J6m(hzB!OeX7)ZOPu`2(o~zAeWK1kPnbglKaWS
z<hK+$#faie38ExYq?8g$HDy2L1f`!cLYbhdQO&8I)Cj7GI-goeZJ>5gFH?u96Et<2
zCC!@_L(8Nsqt(!wX=iEoXfNq>x(VHb9z~bXm(pwK2kGbOgY<U{4TcSa$4Fu*8EYAP
z8K)Sx884YkrUlcNnaETy*D@QKXP6I|Z&g?-_9}c8k;)R4I+a$HewF8{R8@0TKh=4v
z3skFB5362QeWpfLvryxy3Dg#=)u|m-yQwy=&Qf<$k5JE1U!%TX{et>q4YG!XMxcgB
zqf}$J#u<$v7REAV@mNCEa#jQDENhreVq3EL>`ZnA`x|yIdrVV9bE;;nW|3x{=5fsd
z4#u(I@HyF>O3oq94bFQl11&!-vDRv>X03j$H`;pIzS?5#a_tuF>)P*iaGgM%ES>c_
zZ94aL3A#4AQM!e?+jY<CKGS3CdFcuD%JmNE-O)$&ZS<q{7wYfU@6jJOFf<4@kQr<-
zIAie4kYng;m}$7t@Py&05zA=0k;G`D(Mh8xxF+t0XX7<^7d~dJZyaK*G~Q+0Ydm3M
zX)@cS#H7XKzA4R=Yno=d(X`Wa%*@Cv+^pEF$?T3f)tqadVZPbC+x(4%rA3^@N{cp&
z$Clcbe9HxvO_ukpm{vYkc~<pS*Q`m_T<a|BZPr(8P#ag944XQe%eJVko2|rln{D3|
z;uMc5(kb;*ZrU;I{Ok(sn(PMcIrd@pCH8Ih&mGJh5*^k%bUS=<bal*jY;e5mq~SEf
zsl=(n=~rhPXQ6YQ^EDTyOOVSFmv)yIQ*Eb;r*5Bm%a!FC?z+;o)Agg9yPMpt*=^L_
z%ss_@tNTqZn;Xep!#(do^zips;&II5ou`|p!t;>lFJ5+DSzi0S9#6BJCZ5(XZOGfi
zTj0IRdtf>~J!SgN=>tB-J_4V5pNGDtz9Qc}z9W9tewls;{GR(e`pf-~_`l(K@)q$<
z1z-We0p$U`ff|9c18V~x1epY-2Q>wa1-k|>3_cY?3<(WcA99m#z!&lx`C~KOXDpi0
z70L*m6<QnmFw7=Q9@Y_#hR+D!5Pol_`Aq4|wg`yeM{J0=A88qx7x{e@DJn9mF6vRV
zQ*?23_bk?|<XQV?y^isZsf@Wh+iJFQc4w?=Y*K7v?3=iNxT?5;c!&5!@s|>G6C?@k
ziR8rC#65}Qa{}jVnlqf_npBo_W3J`gqPZ95>CVfZcRX1&S&)1<g_shTvOnd6AVN?t
z7*FM=ZcQB%@`Rg(Pes0>jiOPpx423?lIEROmG(H@JAFg?XogQlb;dIZPf{y+kr|S?
zBlAsGMAqJ{&)IR=Ejg5&l$@hd4QZCNE7vf$D7Q~$D=U)?<ay?8${Ul1%J<|W`E&Ez
z6>Nn}(WA6du22pZOfRS_cv~1-c(_QtNLti0-)8>m`6CO07JR*suu!<Lv)H(JS@GZ^
zzeT$iBa2fPcP=qqQo3Y#Y4Fm0%V^88mi<uTSW;E;YI)r9j#7itrKLkFf>$(^sg%jf
zZm#rNxnmV!m1I@#YM0epR(~oNm0zrItf;Q|utvD%;#W>z)qM4NZQ9!2O1H}G>qzUQ
z>u#*~S--DJy=p<#(1!30tsC);<r`mZO5Sv#dTRBK&9u$R%>y-IHSJr>wyfLop*ExT
zdYyk=%U1oZtGB+{Cfe4&-FJKQ4uc&PJKpb<?7X!rcvow^MSb;d((Z!Yj~Zedy1(Xr
z-MB}0PsN^(d!>5^_C@dOYIJXG+^@gCvI%WcHjN%gI&kHifN$EH?V5MBa9S!3!a?Q1
zC*P)gd*e{(q0YnH!_D8Bf4B7r>qvPk(mKC&tSzH$pgp0z@92!9ogH2sN4~fJe(y2k
zV|B+hk5`_cohUu=`Q(C=<ELb&o}ErVJ=B@pdG}2GnQL89UA<>R&z?UQbnZ;IU-!xL
z-sg{9@Vs#JBKKn3CAUkhJ+3`ResKNaNUvLO>t*-L?N>ambo5Q@JJIjcfBI^`)pOVQ
z*DhV3dA;w(>>IakCfyvkCA#(acJ}QTcM9%I++BK)c(44v+WqPW`VZ=VwEnSWz-{38
zV8CF{!&wjS4he^z{*?dIhvCvk%tzHDMk9@nogW_?4H~`jWX_Y}r?RIL&&qyQ|9R_k
ztLNYS;`>X_Sp3-V3;B!Bzpi<y^K$R2sjoW6BgY@S&UroYru?nW+kNl2@4DZ|y&st<
z{6PLt^U?Za$EVOw_de%*{`@cZg!B7=IVBMQ000JJOGiWi&;ZZ?(0lA7!T<mO32;bR
za{vGf6951U69E94oEQKA00(qQO+^RX1{DkuH>1&8f&c&zuSrBfRCwC$nrn<*S9QmK
z>%8u{?>q1DjP0=<65_mr1FhNufucrDO9GWzRcb3cfwmMO656Wj2UKH$s!E_XZu_CA
zf;ug#P@~egN(lngmWDzQ1mnaI$Byl>J)W66bLYO#J<q*&Kio;|5Ie=hAx`l6c+a_e
z@AE(F?B8AwxMElAie0fQcEzsP6}w_r?5EP~S8L)O+o-ym_`t{vetVgduhu%`Cq3c2
z-bK|ba6c~h4Z4i@0%4v5am?Pwzr=&DTLHFiWo~AQ`}}Fym5mf@-n1>vs)eH?tkuj+
z#2JHCGr!VguiIwd6Hm~2eF#uvr@+p#aC@-?g$;r~?vtt;XslG|FMk`$@3Q$OVQRvV
ztij+o?V!%Xam3y;Z4SQn1gJ3w+z0GJ7_kk;25bS_fsG?DJz>#u3sSO$TsbjrA)_~@
zg*9Ua8LWkfISc_D2%GGUG!N6d^j>jE1=umc&Q8Y8w&C`kfHp`f>$4clbN9J6+%ko{
zAqOiZ2rO{cFpB{!b|KP;V?n`(ks37nm?WcJR_xp4v-iM>OSfshYyq~`nCrlOHtYgw
zU4cxXW<k*f%M(0HC?aeE(3)1>5O}cIhGqbXzQEwtaD}-XY<~lkT?mfDe4mG#iU(O^
z|EngzyKm%fQ{+CA<MxF*B6&<Vh58Z_yzq@nwd|Q~Td&8Nnv|<IK1He5H1U~;`7X3p
zpx%Uf_WW850+zsp4|CfrrneVqsZheUWs+9P$>WAjfQaUVfd|RhNBhU~ii;CqgsSVY
zYugz2U0Y_$Y!}8-NXB4!61)kZEcCjD<s*=sf@dO#T$mmcYI827vLUyeQEeCrV^|5{
zU<9$jl!2KXsBx&?Xi<Jko`F5Z;?r*>Xl`P}{ZA%>Cy16~)FRCHq0jTO?ZfaO4Ze2C
z1=u*w+qdM{X*ukQEQmAMV4ySuoeET%;4gzH#2y3ZR|FD_eXB()f`zYZPJY+WY9c!}
zLcRxa2fnM|`f13O;Ls^3DY)ZqG2J=A>sg$78crP3%uc#u<u%PTqjtuaLIkG*SkT}I
z6s+NcbTteN-$U5T@{e|=cxeI3>=cWgp74%w8&h#$d>pC9V2z6@58#Q!5KKbuD)65~
z%BNwgffd2H*3c{BcUa>7g3X2nL;Z0@za%6}8oL3NKD0uZH1Nk&;eavxWeXY^^c2Pj
zXpoWhCAGo00^=4;14RoS&ybsQaK^_p0!S6&2`3WROT@mHqQ?aVxMhajp<#C-AOfoq
zs0?m(z^*`Wl}&BVM^0okmtvF))&y`P<TqHX)r}-a4PFDRKDe$>z0ro79I{ahNx)sv
z<d!w6sTuSYX<)Dh5CvfR&=IKFFp^?cV>qUv;(`Wlc3@i>f;<e$7LAHSoY|zk3>9QZ
z+psc#y5?ab?zxZ%7mNj#dwgxO%)a8RRV$CktuC+{!kR{|O_8W;NbM5Mx$EU^&5BI8
zLNyHO2S{?#NWN?_vE4)7o=4tPLT@P&M;2;Dh)$J}zF>_Cv1gNd7C9F*nluGFg{fIk
z5zJXo^N>Lv*&s-!pk!d8h*+awU2D-E&q;92l$_yr(bf)b@}H4ON%k#t%sstD{+fvR
z#|nlTeLBmFX8+AM<@V(}y5=f#i_V6Bnp2><5yozDY+6g(i)E0dGMyNrE+q4Yxs#gO
zl0jJxNwr9`dn2cg-c7f47yZ`H6SWhRy@na2IQ0y(s!4iafPMlc8v=o@0i8l<pqxj_
z7SeSwp%2lLLFa_p4HkuKj$zg6`&x_Uy<h!u^B;RX>X#%MJbE<i%s0&bs>=h5nz$j{
zGGgIpHsa+|5s7%?Ld;al5Juow5a*zhgPJm=Mq_mh#&1wA)WKS1FqlJ}<G9mxBufeU
z2~p3G#4w0qDuvk|IDJTi;pex>24lgvK-Wc94N{C@wxhc<_4qG3Tg`jF@!=Eyvix+r
z^NM0{ZiM?cYvy_hvRVYsK&b(zGr)(j8qAD>Z^NPkUKyOoBHdt<A8|->HbKe57APf(
zbU7eg%?J~ijKQtLAOKH6W`^VY1z0n%9D&iWA%#OJU}I7P`qjW-ej1iyXe}a51wL@C
z4Q?LhUGNi_ut6M%tl`dWMxpOOHY%7D)QUlQ;8j6V==MQ}P|~0+7y!8x>;argVIcz-
zsDkOrWrD%pD1-`{&mbZ&>Ol@D2~1kUoqWXx$)GR^?KU_-ZVdbk>^?{UZV^`0@F<-L
zR1NqVq705CP|v_vLkv#XmmvnT3M@rP^B9~BeTK7G4Bu4Qhmt>x4Bc$#-i`~d17m=r
zpsztRL<u~ZKvP3aU|>Pj!(6Tyl+iR4XAEkSpz|<jpOx4EiGh9!{Sfjoj9M@s!kGc|
z2k=AyPY>W&2<;f2Q84Yp&($DbfejX93Mm=na>1aiW01BNGsse=6GJwDVg|QOK;jAQ
z-Z_IBPzY@!ETk~dkQxZi@fcg6RD<g#p`3?MUVuT$7Ia+*edOh0@S-R%nrBnT=hGhC
z@fI6P=fK(sQN`wsi-z35&~yw@9vV5=oQGOYI9_%*wq$eq*%+0W3(oAiFj|J316yp^
z5JHeaCxh6A>D=(aM+}_KLCb^L1g0!#=H$S)L+hj6r_>i;aS9Al7*o*qk+s5)j=^x;
zqPYMIKgdwY+3|Bln3#k7*hOM61JB01Y81!^hNrra1V|@44+i6P47w26>lhq?7I0z!
z{T|HtP_7LzXsu&V4Ti_v3t><hs0n79eVI^Tbs=Usf_nEQFld3ObqsdaF*y2S4AvE>
z3t(_LgMy36*>J0S8ByT&c15<9MK+ZNG+k))pr>F>!Kn<6q_C7gJA+;XIFJgYeMlon
zEKvF3+Z+KL17!^=h65oSPQdrz8XsIi%3L}M{78Giop<_k;qhemVn^?4hp<_On^ZH8
z^sX)t)yfpY2(Qy;0>ykE<{Pj!cs?Qef|)#o84IR;!?6ekX6P+-bN2i&F3=X3D8hyU
z*cu`QITyTi7;EH5AeUhDoJ;<l6*`qF!E$Y%e51AJz!y%OyyUUK#Zq9*hG$pdNaLK@
zo)<%Y=(KcpH5Ra`2ye0>Rj&gI7#EtSg~hr-r5B#r@nP%CFcM6{*C7R}z!42cTacZT
z3eUN)Z8OZ)eo82?)`Ug`u?1VoFs@$%6v#U+v0G&|Q*w2r&PM^(DIotJ1uPfx-mrLL
ztBaz5aRtg;x|G-jJ>d8L-4x!p?N}`mZ|3yr!#{KK`v>oNHYo0BHtJ@g{uKG;lN{}=
z(3*+}i`MxlAeWE=<|Qb=C8xmq_AgJ}yDhl)k@oC01xLm`o01sgVKS$^a%MxXxwK((
zvgCBTYdFaX9{u(gxaP=7vrYkt@|blB$jhcchUqAXZDcx!S*L)ULjkkNp*=Ed?LGYN
z>H}Z>{nkYlP@VJrxU{PMFZuorn@i0}%W}L!;fPzdGG`)ZS!rd{O2ge;uk@ap?8NrW
zKv_<6#pTedevSfW%!Qc>f(?Z&aP!sBJS}FiZbYTeiC|v5m>g`K!Azw{62hv2%tbs0
zQ!8N3oJ)ZoEM%NmwRv!%zyrq*=njvxF1j@4T<C&Q%Kk>9=-4^m{n^ou7ir7;K~S}S
zsj{TYRzCZWwe8EXjGxKY4vy(nYx;CT*$1wT!R^9)i1A~XTBpE>Wq4B!bHu>W7IGd6
zn3;77gej)v4=Io`j1j^CG}7Tls0=3-HG5d&!5HYijN<5d1yE^6jPfm&rncia_E%O)
z&RUjp-!s|r{(f;*_u@F#X-}KXWU4ZEJbLS&ynpqfd*6x0#}+h<rjSc9C4mA^W0=he
z6*4^uuEMNSK(>@I;~HcMal6B65bNK6)xg-00<unl7Q$W>4_vBVf%6IwMW8b!qP5)$
zlH6J*d7ZO8g*d6!hBSjDHYSObjw8z--_)ne9%}3}hTUs1yPg~C$O}_qro22%iB*c=
zW*8!9yWmzZW56cXQ(|hE68p|DC1x<}L$l|{tpZ<^0Iq1)U?%%<Hq}bBs~p6(9Z^P$
zQc5I^eOsrVgDPeiTW7YnUbs66+)Ir;7<MDv^IUU;9zK}#LyQ-~j0H6xITm5oDIi}r
zXUpp2f;0>*gnelCUg`&bkpTZSH|M``)26alDouRz*?+z5zbn67>$E*L$=9$PFj|pj
z87fJP(hw^lPPD{v;%8ZGy<pUHh0yGV=RLw;AQ6~XFdv-7K(O8yuzpv&Vc3iC0L@pn
zS;{$d-E}2*_wGA#pa1-IX|*~R+xFC0+N{mFLA5;V*pDss&~c9p3tg}X8w0d$8!W`l
zW8HnVxQEqaZ@%mMcSYSoX9?!p4{kY`Am|?wV%K`#P;DKB^1@6ZV3-H?Ag@e6(0NaS
zzf&m8*lGGfYy0*a@&^t~+EG-_+i^~kL0*m=lpRxssaz&co@&Xp6Sh2gqAp%^O5U?&
zjoUUXnA7Hethue7nW9^GOTjI^Iac`_er@qrCmZki*2((k7=}I(9b&#lfxkl&Biw?J
zKW82Dz(;6vFA)b{>g0CGJ)j#!;-;zNJp8Z|-+8C!Ywd4*<RQ<$`5NmM-NpX159$-%
zv|M%nPH{HgXz9rX<CkOebn;zY$ns2=r{$=9pw!RSydCYgZM;rjbzL)By|I(>*wC}j
zvEf_Y13W;5`w?zNv6ueEm9s9X01=Ra6@i_5^ijtRLwEVZf0&#4)NX6A5||ZTkeG<o
zNB+UY*Wb<b<TmqY_(jHZl|rs)+m9Fb_f~=v#oMyC75Z5x`f~T7!A5me%d}oH((KS>
z50`;C{!joBAdF+N7Z+{!>;LQMfzXYh<r&j4T6Z<#WR|sm;h`)ow(aHgkjhlTHnZKo
zCcVR(SBF<l1xJ%su;$EimCb<HgjtSldzmqnILk(Q%gfbXuji*C(p6#_f@xt)S7jzh
zQms>Cl0jfr`e#g>gvL&6Ybl)fZRJ?*z;)Mpbtmb?mX3@B?Vo%f@{i>K<v6Z12ZK_)
zxaiiJP0GU^S=(7kNhPLhj81K(`YBS%EGKODb;Q7OU5w?3wrxAJEr||y4&)eE;zW+6
zQPo`X>UE-DlmK?SU5UT)6*D>*FgDCynb;VTG{M$NZ&sO_NW-k3AkBX0tt_9+QU)p$
zA=R-~vC=w^P6A`hK#2~Fo1zNwfZ}W76PQz~x9LM4I-p(m__9d%G-NFiQ@0&`67&(s
zo`FvFuHUHt^TAICaV}6gGA3QtS$I54f@d?OnqtzrA?+G;h-|Ois?&_pYr+FEX!xJ~
z>^Cc)_{34^_s8Ooe|$O{AD@b=)uR8~ztt}L`33(|pE`4J|7W7|?e10Y-S(l`Fbiit
z|DDf_YAv4ail{s$Jx%<ZJKo>Oxw$hHf8<b9INQT`SqrcLYq94YE`9Qo<#Ml=&+Xk?
zC@SSv?!VvmKk|_v7?$bcu4_rPR5-T(%s=^EJ(&E!FaGIfld|~>PkpXhsf;$$QI=+=
zwk-VllOJv9j7F0FWKMD~*W?g*&rD6#s@<-e4?|}oIQjKlVF=kN$d*7o_6Fp8cURpr
zRqgb>o}bwilttl_xBYFw7CZf;Z~Z}Jgg^}#WQri_vdUi(UiJbQkdJ{o3UU)j4rJr{
z#RVV+6M}gZ__trjTG$B0*p#vHaf=={9wt~rks}2%nkfE;<i$C!%g_D~86{5NSc_;b
P00000NkvXXu0mjfirI-=

literal 0
HcmV?d00001

-- 
GitLab