diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..3d47f986c41db29ec6dc0d5036bf760b3a1cf366
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.idea/
+target/
+.settings/
+*.iml
+.project
+.classpath
\ No newline at end of file
diff --git a/SpotDetectorBlock.jar b/SpotDetectorBlock.jar
new file mode 100644
index 0000000000000000000000000000000000000000..539289c9d1d969b9060a79531a676bad1798603b
Binary files /dev/null and b/SpotDetectorBlock.jar differ
diff --git a/bin/META-INF/MANIFEST.MF b/bin/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..59499bce4a2bd51cba227b7c00fcf745b19c95a4
--- /dev/null
+++ b/bin/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/bin/SpotDetectorBlock.jar b/bin/SpotDetectorBlock.jar
new file mode 100644
index 0000000000000000000000000000000000000000..539289c9d1d969b9060a79531a676bad1798603b
Binary files /dev/null and b/bin/SpotDetectorBlock.jar differ
diff --git a/bin/export.jardesc b/bin/export.jardesc
new file mode 100644
index 0000000000000000000000000000000000000000..d0489862901c9bcf97a0e330c7eed8eb283a98f1
--- /dev/null
+++ b/bin/export.jardesc
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
+<jardesc>
+    <jar path="Spot Detector Block/SpotDetectorBlock.jar"/>
+    <options buildIfNeeded="true" compress="true" descriptionLocation="/Spot Detector Block/export.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="true" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+    <selectedProjects/>
+    <manifest generateManifest="true" manifestLocation="/Icy-Kernel/META-INF/MANIFEST.MF" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
+        <javaElement handleIdentifier="=Spot Detector Block/src"/>
+    </selectedElements>
+</jardesc>
diff --git a/bin/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$1.class b/bin/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..78f5baa5a3e3033f8603fd5038459ef0c1aaa04d
Binary files /dev/null and b/bin/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$1.class differ
diff --git a/bin/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$detectionMethodEnum.class b/bin/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$detectionMethodEnum.class
new file mode 100644
index 0000000000000000000000000000000000000000..4cb76999790403d420aae245c0c06b27112b62bf
Binary files /dev/null and b/bin/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$detectionMethodEnum.class differ
diff --git a/bin/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.class b/bin/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.class
new file mode 100644
index 0000000000000000000000000000000000000000..1842a96c51e8a96641fade50dfb5b30a3ada2fde
Binary files /dev/null and b/bin/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.class differ
diff --git a/export.jardesc b/export.jardesc
new file mode 100644
index 0000000000000000000000000000000000000000..d0489862901c9bcf97a0e330c7eed8eb283a98f1
--- /dev/null
+++ b/export.jardesc
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
+<jardesc>
+    <jar path="Spot Detector Block/SpotDetectorBlock.jar"/>
+    <options buildIfNeeded="true" compress="true" descriptionLocation="/Spot Detector Block/export.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="true" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+    <selectedProjects/>
+    <manifest generateManifest="true" manifestLocation="/Icy-Kernel/META-INF/MANIFEST.MF" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
+        <javaElement handleIdentifier="=Spot Detector Block/src"/>
+    </selectedElements>
+</jardesc>
diff --git a/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$1.class b/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..21a2c8cbbc3885ff46fd45e056396a28fa6c1b92
Binary files /dev/null and b/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$1.class differ
diff --git a/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$detectionMethodEnum.class b/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$detectionMethodEnum.class
new file mode 100644
index 0000000000000000000000000000000000000000..a63c2634e8a0dc8254b23802036e937f1fb6455c
Binary files /dev/null and b/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock$detectionMethodEnum.class differ
diff --git a/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.class b/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.class
new file mode 100644
index 0000000000000000000000000000000000000000..18acbd22587e5a190180a28bf30d220a46457cba
Binary files /dev/null and b/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.class differ
diff --git a/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.java b/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf32d9a11718ca62862bdc5acc2ac7a5d36c3d74
--- /dev/null
+++ b/src/plugins/fab/waveletspotdetectorblock/WaveletSpotDetectorBlock.java
@@ -0,0 +1,272 @@
+package plugins.fab.waveletspotdetectorblock;
+
+import icy.plugin.abstract_.Plugin;
+import icy.roi.ROI;
+import icy.roi.ROI2D;
+import icy.sequence.Sequence;
+import icy.system.thread.ThreadUtil;
+
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+
+import javax.xml.bind.JAXBContext;
+
+import plugins.adufour.blocks.lang.Block;
+import plugins.adufour.blocks.util.VarList;
+import plugins.adufour.vars.lang.VarBoolean;
+import plugins.adufour.vars.lang.VarEnum;
+import plugins.adufour.vars.lang.VarGenericArray;
+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.fab.spotDetector.DetectionSpot;
+import plugins.fab.spotDetector.detector.DetectionToROI;
+import plugins.fab.spotDetector.detector.UDWTScale;
+import plugins.fab.spotDetector.detector.UDWTWaveletCore;
+
+public class WaveletSpotDetectorBlock extends Plugin implements Block {
+
+	enum detectionMethodEnum
+	{
+		BRIGHT_SPOT,
+		DARK_SPOT
+	}
+
+	VarSequence inputSequenceVar = new VarSequence("input Sequence", null);
+	VarEnum<detectionMethodEnum> detectionMethod = new VarEnum<detectionMethodEnum>( "Spot to detect" , detectionMethodEnum.BRIGHT_SPOT );
+	VarBoolean computeWATConsideringROIBoolean = new VarBoolean( "Compute WAT considering ROI", false );
+	VarSequence inputSequenceROIVar = new VarSequence("ROIs from sequence for WAT", null);
+	VarBoolean force2DWaveletVar = new VarBoolean( "Force 2D Wavelets", false );
+	VarROIArray inputROIForMask = new VarROIArray("ROIs for detection mask", null);
+
+	VarBoolean[] useScaleBoolean = {
+			new VarBoolean( "Scale 1" , false ),
+			new VarBoolean( "Scale 2" , true  ),
+			new VarBoolean( "Scale 3" , false ),
+			new VarBoolean( "Scale 4" , false ),
+			new VarBoolean( "Scale 5" , false )
+	};
+
+	VarInteger[] scaleParameter = {
+		new VarInteger( "Th. scale 1:" , 100 ),
+		new VarInteger( "Th. scale 2:" , 100 ),
+		new VarInteger( "Th. scale 3:" , 100 ),
+		new VarInteger( "Th. scale 4:" , 100 ),
+		new VarInteger( "Th. scale 5:" , 100 )
+	};
+
+	VarSequence outSequence = new VarSequence("output Sequence", null);
+	VarSequence denoisedSequence = new VarSequence("denoised Sequence", null);
+	VarSequence binarySpotSequence = new VarSequence("binary Spot Sequence", null);
+	VarROIArray detectionAsROIOut = new VarROIArray("detection as ROIs", null);
+
+	@Override
+	public void run() {
+
+		// test if input sequence has only 1 channel.
+
+		Sequence inputSequence = inputSequenceVar.getValue();
+
+		if ( inputSequence == null )
+		{
+			throw new VarException("The input sequence must be set");
+		}
+
+		if ( inputSequence.getSizeC() != 1 )
+		{
+			throw new VarException("The input sequence must contain only 1 channel. Please use 'Extract Channel' prior to the WaveletBlock");
+		}
+
+//		inputChannelVar
+
+		// init detection.
+
+		UDWTWaveletCore waveletCore = new UDWTWaveletCore();
+
+		boolean detectNegative ;
+
+		if ( detectionMethod.getValue() == detectionMethodEnum.BRIGHT_SPOT )
+		{
+			detectNegative = false;
+		}else
+		{
+			detectNegative = true;
+		}
+
+		boolean computeWATwithROI = computeWATConsideringROIBoolean.getValue();
+
+		// copy ROI from input sequence to the computation sequence
+
+		Sequence inputComputationSequence = inputSequence.getCopy();
+
+		if ( inputSequenceROIVar.getValue() !=null )
+		{
+			for ( ROI2D roi : inputSequenceROIVar.getValue().getROI2Ds() )
+			{
+				ROI2D roiCopy = (ROI2D) roi.getCopy();
+
+				if( roiCopy != null )
+				{
+					inputComputationSequence.addROI( roiCopy );
+				}
+			}
+		}
+
+		//Icy.addSequence( inputComputationSequence );
+
+		// create UDWTScale Parameter list.
+
+		final ArrayList<UDWTScale> UDWTScaleArrayList = new ArrayList<UDWTScale>();
+
+//		System.out.println("Block debug.");
+
+		ThreadUtil.invokeNow( new Runnable() {
+
+			@Override
+			public void run() {
+
+				for ( int i = 0 ; i< 5 ; i++ )
+				{
+					//System.out.println( "Scale enabled #" +i +" : " + useScaleBoolean[i].getValue() );
+					UDWTScale scale = new UDWTScale( i+1 , useScaleBoolean[i].getValue() , scaleParameter[i].getValue() );
+					UDWTScaleArrayList.add( scale );
+				}
+			}
+
+		});
+
+
+		// Perform detection.
+
+		ArrayList<DetectionSpot> detectionResult;
+		detectionResult = waveletCore.computeDetection(
+				true,
+				UDWTScaleArrayList ,
+				inputComputationSequence ,
+				detectNegative ,
+				computeWATwithROI , force2DWaveletVar.getValue() );
+
+//		System.out.println( "ROI Mask : " + inputROIForMask.getValue() );
+
+		// Filter spot with ROIs.
+
+		if ( inputROIForMask.getValue().length != 0 )
+		{
+			ArrayList<DetectionSpot> detectionResultCopy = new ArrayList<DetectionSpot>( detectionResult );
+
+			detectionList:
+				for ( DetectionSpot spot : detectionResultCopy )
+				{
+//					Point2D spotCoordinates = new Point2D.Double( spot.getMassCenter().x , spot.getMassCenter().y );
+//					spot.getMassCenter()
+
+					ROI detectionAsROI = null;
+
+					try
+					{
+						ArrayList<DetectionSpot> detectionList = new ArrayList<DetectionSpot>( );
+						detectionList.add( spot );
+						detectionAsROI = DetectionToROI.convertDetectionToROI( detectionList ).get( 0 );
+					} catch ( NullPointerException e )
+					{
+						System.err.println("Error in spot to ROI conversion");
+					}
+
+					if ( detectionAsROI == null )
+					{
+						System.err.println("Can't convert spot to ROI. spot=" + spot );
+						continue;
+					}
+
+//					System.out.println( "spot as ROI to test: " + detectionAsROI.getBounds5D() );
+
+					for ( ROI roi : inputROIForMask.getValue() )
+					{
+//						System.out.println( "roi contenant: " + roi.getBounds5D() );
+
+						if ( roi.contains( detectionAsROI ) )
+						{
+//							System.out.println("contains");
+							continue detectionList;
+						}
+					}
+//					System.out.println("don't contains");
+
+					detectionResult.remove( spot );
+
+				}
+		}
+
+
+		// set outputs.
+
+		// binary output: propagate ROIs.
+		{
+			Sequence binarySequence = waveletCore.getBinarySequence();
+
+			if ( inputSequenceROIVar.getValue() !=null )
+			{
+				for ( ROI2D roi : inputSequenceROIVar.getValue().getROI2Ds() )
+				{
+					//System.out.println("roi:"+roi);
+					String name = roi.getName();
+
+					ROI2D roiCopy = (ROI2D) roi.getCopy();
+					roi.setName( name ); // because of the bug when coppying roi.
+					roiCopy.setName( name ); // else the name has " copy" in the end of it.
+
+					binarySequence.addROI( roiCopy );
+				}
+			}
+
+			binarySpotSequence.setValue( binarySequence );
+		}
+
+		// output detection as ROI
+		{
+			ArrayList<ROI> roiList = DetectionToROI.convertDetectionToROI( detectionResult );
+			ROI roi[] = new ROI[ roiList.size() ];
+			int i = 0;
+			for ( ROI roiCandidate : roiList )
+			{
+				roi[i] = roiCandidate;
+				i++;
+			}
+			detectionAsROIOut.setValue( roi );
+		}
+
+
+	}
+
+	@Override
+	public void declareInput(VarList inputMap) {
+
+		inputMap.add( inputSequenceVar );
+		inputMap.add( detectionMethod );
+		inputMap.add( "input Sequence ROIs" , inputSequenceROIVar );
+		inputMap.add( computeWATConsideringROIBoolean );
+		inputMap.add( inputROIForMask );
+
+		for (int i = 0 ; i<5 ; i++)
+		{
+			inputMap.add( useScaleBoolean[i] );
+		}
+		for (int i = 0 ; i<5 ; i++)
+		{
+			inputMap.add( scaleParameter[i] );
+		}
+		inputMap.add( force2DWaveletVar );
+	}
+
+	@Override
+	public void declareOutput(VarList outputMap) {
+
+//		outputMap.add( outSequence );
+//		outputMap.add( denoisedSequence );
+		outputMap.add( binarySpotSequence );
+		outputMap.add( detectionAsROIOut );
+
+	}
+
+}