diff --git a/Coloc_2.java b/Coloc_2.java
index c8a334c..1651a0b 100644
--- a/Coloc_2.java
+++ b/Coloc_2.java
@@ -1,684 +1,688 @@
 import gadgets.DataContainer;
 import ij.IJ;
 import ij.ImagePlus;
 import ij.Prefs;
 import ij.WindowManager;
 import ij.gui.GenericDialog;
 import ij.gui.Roi;
 import ij.gui.ShapeRoi;
 import ij.plugin.PlugIn;
 import ij.plugin.frame.RoiManager;
 import ij.process.Blitter;
 import ij.process.ImageProcessor;
 
 import java.awt.Checkbox;
 import java.awt.Frame;
 import java.awt.Rectangle;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.awt.event.WindowListener;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
 import mpicbg.imglib.container.array.ArrayContainerFactory;
 import mpicbg.imglib.cursor.LocalizableByDimCursor;
 import mpicbg.imglib.cursor.LocalizableCursor;
 import mpicbg.imglib.cursor.special.TwinCursor;
 import mpicbg.imglib.image.Image;
 import mpicbg.imglib.image.ImageFactory;
 import mpicbg.imglib.image.ImagePlusAdapter;
 import mpicbg.imglib.type.logic.BitType;
 import mpicbg.imglib.type.numeric.RealType;
 import results.PDFWriter;
 import results.ResultHandler;
 import results.SingleWindowDisplay;
 import results.Warning;
 import algorithms.Algorithm;
 import algorithms.AutoThresholdRegression;
 import algorithms.CostesSignificanceTest;
 import algorithms.Histogram2D;
 import algorithms.InputCheck;
 import algorithms.LiHistogram2D;
 import algorithms.LiICQ;
 import algorithms.MandersColocalization;
 import algorithms.MissingPreconditionException;
 import algorithms.PearsonsCorrelation;
 
 /**
    Copyright 2010, 2011 Daniel J. White, Tom Kazimiers, Johannes Schindelin
    and the Fiji project. Fiji is just imageJ - batteries included.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see http://www.gnu.org/licenses/ .
  */
 
 /**
  * A plugin which does analysis colocalisation on a pair of images.
  *
  * @param <T>
  */
 public class Coloc_2<T extends RealType<T>> implements PlugIn {
 
 	// a small bounding box container
 	protected class BoundingBox {
 		public int[] offset;
 		public int[] size;
 		public BoundingBox(int [] offset, int[] size) {
 			this.offset = offset.clone();
 			this.size = size.clone();
 		}
 	}
 
 	// a storage class for ROI information
 	protected class MaskInfo {
 		BoundingBox roi;
 		public Image<T> mask;
 
 		// constructors
 		public MaskInfo(BoundingBox roi, Image<T> mask) {
 			this.roi = roi;
 			this.mask = mask;
 		}
 
 		public MaskInfo() { }
 	}
 
 	// the storage key for Fiji preferences
 	protected final static String PREF_KEY = "Coloc_2.";
 
 	// Allowed types of ROI configuration
 	protected enum RoiConfiguration {
 		None,
 		Img1,
 		Img2,
 		Mask,
 		RoiManager
 	};
 
 	// the ROI configuration to use
 	protected RoiConfiguration roiConfig = RoiConfiguration.Img1;
 
 	// A list of all ROIs/masks found
 	protected ArrayList<MaskInfo> masks = new ArrayList<MaskInfo>();
 
 	// default indices of image, mask and ROI choices
 	protected static int index1 = 0;
 	protected static int index2 = 1;
 	protected static int indexMask = 0;
 	protected static int indexRoi = 0;
 
 	// the images to work on
 	protected Image<T> img1, img2;
 
 	// the channels of the images to use
 	protected int img1Channel = 1, img2Channel = 1;
 
 	/* The different algorithms this plug-in provides.
 	 * If a reference is null it will not get run.
 	 */
 	protected PearsonsCorrelation<T> pearsonsCorrelation;
 	protected LiHistogram2D<T> liHistogramCh1;
 	protected LiHistogram2D<T> liHistogramCh2;
 	protected LiICQ<T> liICQ;
 	protected MandersColocalization<T> mandersCorrelation;
 	protected Histogram2D<T> histogram2D;
 	protected CostesSignificanceTest<T> costesSignificance;
 	// indicates if images should be printed in result
 	protected boolean displayImages;
 
 	// indicates if a PDF should be saved automatically
 	protected boolean autoSavePdf;
 
 	public void run(String arg0) {
 		if (showDialog()) {
 			try {
 				for (MaskInfo mi : masks) {
 					colocalise(img1, img2, mi.roi, mi.mask);
 				}
 			} catch (MissingPreconditionException e) {
 				IJ.handleException(e);
 				IJ.showMessage("An error occured, could not colocalize!");
 				return;
 			}
 		}
 	}
 
 	public boolean showDialog() {
 		// get IDs of open windows
 		int[] windowList = WindowManager.getIDList();
 		// if there are less than 2 windows open, cancel
 		if (windowList == null || windowList.length < 2) {
 			IJ.showMessage("At least 2 images must be open!");
 			return false;
 		}
 
 		/* create a new generic dialog for the
 		 * display of various options.
 		 */
 		final GenericDialog gd
 			= new GenericDialog("Coloc 2");
 
 		String[] titles = new String[windowList.length];
 		/* the masks and ROIs array needs three more entries than
 		 * windows to contain "none", "ROI ch 1" and "ROI ch 2"
 		 */
 		String[] roisAndMasks= new String[windowList.length + 4];
 		roisAndMasks[0]="<None>";
 		roisAndMasks[1]="ROI(s) in channel 1";
 		roisAndMasks[2]="ROI(s) in channel 2";
 		roisAndMasks[3]="ROI Manager";
 
 		// go through all open images and add them to GUI
 		for (int i=0; i < windowList.length; i++) {
 			ImagePlus imp = WindowManager.getImage(windowList[i]);
 			if (imp != null) {
 				titles[i] = imp.getTitle();
 				roisAndMasks[i + 4] =imp.getTitle();
 			} else {
 				titles[i] = "";
 			}
 		}
 
 		// set up the users preferences
 		displayImages = Prefs.get(PREF_KEY+"displayImages", false);
 		autoSavePdf = Prefs.get(PREF_KEY+"autoSavePdf", true);
 		boolean displayShuffledCostes = Prefs.get(PREF_KEY+"displayShuffledCostes", false);
 		boolean useLiCh1 = Prefs.get(PREF_KEY+"useLiCh1", true);
 		boolean useLiCh2 = Prefs.get(PREF_KEY+"useLiCh2", true);
 		boolean useLiICQ = Prefs.get(PREF_KEY+"useLiICQ", true);
 		boolean useManders = Prefs.get(PREF_KEY+"useManders", true);
 		boolean useScatterplot = Prefs.get(PREF_KEY+"useScatterplot", true);
 		boolean useCostes = Prefs.get(PREF_KEY+"useCostes", true);
 		int psf = (int) Prefs.get(PREF_KEY+"psf", 3);
 		int nrCostesRandomisations = (int) Prefs.get(PREF_KEY+"nrCostesRandomisations", 10);
 
 		/* make sure the default indices are no bigger
 		 * than the amount of images we have
 		 */
 		index1 = clip( index1, 0, titles.length );
 		index2 = clip( index2, 0, titles.length );
 		indexMask = clip( indexMask, 0, roisAndMasks.length - 1);
 
 		gd.addChoice("Channel_1", titles, titles[index1]);
 		gd.addChoice("Channel_2", titles, titles[index2]);
 		gd.addChoice("ROI_or_mask", roisAndMasks, roisAndMasks[indexMask]);
 		//gd.addChoice("Use ROI", roiLabels, roiLabels[indexRoi]);
 
 		gd.addCheckbox("Show_\"Save_PDF\"_Dialog", autoSavePdf);
 		gd.addCheckbox("Display_Images_in_Result", displayImages);
 		gd.addCheckbox("Display_Shuffled_Images", displayShuffledCostes);
 		final Checkbox shuffleCb = (Checkbox) gd.getCheckboxes().lastElement();
 		// Add algorithm options
 		gd.addMessage("Algorithms:");
 		gd.addCheckbox("Li_Histogram_Channel_1", useLiCh1);
 		gd.addCheckbox("Li_Histogram_Channel_2", useLiCh2);
 		gd.addCheckbox("Li_ICQ", useLiICQ);
 		gd.addCheckbox("Manders'_Correlation", useManders);
 		gd.addCheckbox("2D_Instensity_Histogram", useScatterplot);
 		gd.addCheckbox("Costes'_Significance_Test", useCostes);
 		final Checkbox costesCb = (Checkbox) gd.getCheckboxes().lastElement();
 		gd.addNumericField("PSF", psf, 1);
 		gd.addNumericField("Costes_randomisations", nrCostesRandomisations, 0);
 
 		// disable shuffle checkbox if costes checkbox is set to "off"
 		shuffleCb.setEnabled(useCostes);
 		costesCb.addItemListener(new ItemListener() {
 			@Override
 			public void itemStateChanged(ItemEvent e) {
 				shuffleCb.setEnabled(costesCb.getState());
 			}
 		});
 
 		// show the dialog, finally
 		gd.showDialog();
 		// do nothing if dialog has been canceled
 		if (gd.wasCanceled())
 			return false;
 
 		ImagePlus imp1 = WindowManager.getImage(gd.getNextChoiceIndex() + 1);
 		ImagePlus imp2 = WindowManager.getImage(gd.getNextChoiceIndex() + 1);
 		// get information about the mask/ROI to use
 		indexMask = gd.getNextChoiceIndex();
 		if (indexMask == 0)
 			roiConfig = RoiConfiguration.None;
 		else if (indexMask == 1)
 			roiConfig = RoiConfiguration.Img1;
 		else if (indexMask == 2)
 			roiConfig = RoiConfiguration.Img2;
 		else if (indexMask == 3)
 			roiConfig = RoiConfiguration.RoiManager;
 		else {
 			roiConfig = RoiConfiguration.Mask;
 			/* Make indexMask the reference to the mask image to use.
 			 * To do this we reduce it by three for the first three
 			 * entries in the combo box.
 			 */
 			indexMask = indexMask - 4;
 		}
 
 		// save the ImgLib wrapped images as members
 		img1 = ImagePlusAdapter.wrap(imp1);
 		img2 = ImagePlusAdapter.wrap(imp2);
 
 		/* check if we have a valid ROI for the selected configuration
 		 * and if so, get the ROI's bounds. Alternatively, a mask can
 		 * be selected (that is basically all, but a rectangle).
 		 */
 		if (roiConfig == RoiConfiguration.Img1 && hasValidRoi(imp1)) {
 			createMasksFromImage(imp1);
 		} else if (roiConfig == RoiConfiguration.Img2 && hasValidRoi(imp2)) {
 			createMasksFromImage(imp2);
 		} else if (roiConfig == RoiConfiguration.RoiManager) {
-			createMasksFromRoiManager(imp1.getWidth(), imp1.getHeight());
+			if (!createMasksFromRoiManager(imp1.getWidth(), imp1.getHeight()))
+				return false;
 		} else if (roiConfig == RoiConfiguration.Mask) {
 			// get the image to be used as mask
 			ImagePlus maskImp = WindowManager.getImage(windowList[indexMask]);
 			Image<T> maskImg = ImagePlusAdapter.<T>wrap( maskImp );
 			// get a valid mask info for the image
 			MaskInfo mi = getBoundingBoxOfMask(maskImg);
 			masks.add( mi ) ;
 		} else {
 			/* if no ROI/mask is selected, just add an empty MaskInfo
 			 * to colocalise both images without constraints.
 			 */
 			masks.add(new MaskInfo(null, null));
 		}
 
 		// read out GUI data
 		autoSavePdf = gd.getNextBoolean();
 		displayImages = gd.getNextBoolean();
 		displayShuffledCostes = gd.getNextBoolean();
 		useLiCh1 = gd.getNextBoolean();
 		useLiCh2 = gd.getNextBoolean();
 		useLiICQ = gd.getNextBoolean();
 		useManders = gd.getNextBoolean();
 		useScatterplot = gd.getNextBoolean();
 		useCostes = gd.getNextBoolean();
 		psf = (int) gd.getNextNumber();
 		nrCostesRandomisations = (int) gd.getNextNumber();
 
 		// save user preferences
 		Prefs.set(PREF_KEY+"autoSavePdf", autoSavePdf);
 		Prefs.set(PREF_KEY+"displayImages", displayImages);
 		Prefs.set(PREF_KEY+"displayShuffledCostes", displayShuffledCostes);
 		Prefs.set(PREF_KEY+"useLiCh1", useLiCh1);
 		Prefs.set(PREF_KEY+"useLiCh2", useLiCh2);
 		Prefs.set(PREF_KEY+"useLiICQ", useLiICQ);
 		Prefs.set(PREF_KEY+"useManders", useManders);
 		Prefs.set(PREF_KEY+"useScatterplot", useScatterplot);
 		Prefs.set(PREF_KEY+"useCostes", useCostes);
 		Prefs.set(PREF_KEY+"psf", psf);
 		Prefs.set(PREF_KEY+"nrCostesRandomisations", nrCostesRandomisations);
 
 		// Parse algorithm options
 		pearsonsCorrelation = new PearsonsCorrelation<T>(PearsonsCorrelation.Implementation.Fast);
 
 		if (useLiCh1)
 			liHistogramCh1 = new LiHistogram2D<T>("Li - Ch1", true);
 		if (useLiCh2)
 			liHistogramCh2 = new LiHistogram2D<T>("Li - Ch2", false);
 		if (useLiICQ)
 			liICQ = new LiICQ<T>();
 		if (useManders)
 			mandersCorrelation = new MandersColocalization<T>();
 		if (useScatterplot)
 			histogram2D = new Histogram2D<T>("2D intensity histogram");
 		if (useCostes) {
 			costesSignificance = new CostesSignificanceTest<T>(pearsonsCorrelation,
 					psf, nrCostesRandomisations, displayShuffledCostes);
 		}
 
 		return true;
 	}
 
 	/**
 	 * Call this method to run a whole colocalisation configuration,
 	 * all selected algorithms get run on the supplied images. You
 	 * can specify the data further by supplying appropriate
 	 * information in the mask structure.
 	 *
 	 * @param img1
 	 * @param img2
 	 * @param roi
 	 * @param mask
 	 * @param maskBB
 	 * @throws MissingPreconditionException
 	 */
 	public void colocalise(Image<T> img1, Image<T> img2, BoundingBox roi,
 			Image<T> mask) throws MissingPreconditionException {
 		// create a new container for the selected images and channels
 		DataContainer<T> container;
 		if (mask != null) {
 			container = new DataContainer<T>(img1, img2,
 					img1Channel, img2Channel, mask, roi.offset, roi.size);
 		} else if (roi != null) {
 				// we have no mask, but a regular ROI in use
 				container = new DataContainer<T>(img1, img2,
 						img1Channel, img2Channel, roi.offset, roi.size);
 		} else {
 			// no mask and no ROI is present
 			container = new DataContainer<T>(img1, img2,
 					img1Channel, img2Channel);
 		}
 
 		// create a results handler
 		final List<ResultHandler<T>> listOfResultHandlers = new ArrayList<ResultHandler<T>>();
 		final PDFWriter<T> pdfWriter = new PDFWriter<T>(container);
 		final SingleWindowDisplay<T> swDisplay = new SingleWindowDisplay<T>(container, pdfWriter);
 		listOfResultHandlers.add(swDisplay);
 		listOfResultHandlers.add(pdfWriter);
 		//ResultHandler<T> resultHandler = new EasyDisplay<T>(container);
 
 		// this list contains the algorithms that will be run when the user clicks ok
 		List<Algorithm<T>> userSelectedJobs = new ArrayList<Algorithm<T>>();
 
 		// add some pre-processing jobs:
 		userSelectedJobs.add( container.setInputCheck(
 			new InputCheck<T>()) );
 		userSelectedJobs.add( container.setAutoThreshold(
 			new AutoThresholdRegression<T>(pearsonsCorrelation)) );
 
 		// add user selected algorithms
 		addIfValid(pearsonsCorrelation, userSelectedJobs);
 		addIfValid(liHistogramCh1, userSelectedJobs);
 		addIfValid(liHistogramCh2, userSelectedJobs);
 		addIfValid(liICQ, userSelectedJobs);
 		addIfValid(mandersCorrelation, userSelectedJobs);
 		addIfValid(histogram2D, userSelectedJobs);
 		addIfValid(costesSignificance, userSelectedJobs);
 
 		// execute all algorithms
 		int count = 0;
 		int jobs = userSelectedJobs.size();
 		for (Algorithm<T> a : userSelectedJobs){
 			try {
 				count++;
 				IJ.showStatus(count + "/" + jobs + ": Running " + a.getName());
 				a.execute(container);
 			}
 			catch (MissingPreconditionException e){
 				for (ResultHandler<T> r : listOfResultHandlers){
 					r.handleWarning(
 							new Warning( "Probem with input data", a.getName() + ": " + e.getMessage() ) );
 				}
 			}
 		}
 		// clear status
 		IJ.showStatus("");
 
 		// let the algorithms feed their results to the handler
 		for (Algorithm<T> a : userSelectedJobs){
 			for (ResultHandler<T> r : listOfResultHandlers)
 				a.processResults(r);
 		}
 		// if we have ROIs/masks, add them to results
 		if (displayImages) {
 			Image<T> channel1, channel2;
 			if (mask != null || roi != null) {
 				int[] offset = container.getMaskBBOffset();
 				int[] size = container.getMaskBBSize();
 				channel1 = createMaskImage( container.getSourceImage1(),
 						container.getMask(), offset, size, "Channel 1" );
 				channel2 = createMaskImage( container.getSourceImage2(),
 						container.getMask(), offset, size, "Channel 2" );
 			} else {
 				channel1 = container.getSourceImage1();
 				channel2 = container.getSourceImage2();
 				channel1.setName("Channel 1");
 				channel2.setName("Channel 2");
 			}
 			for (ResultHandler<T> r : listOfResultHandlers) {
 				r.handleImage (channel1);
 				r.handleImage (channel2);
 			}
 		}
 		// do the actual results processing
 		swDisplay.process();
 		// add window to the IJ window manager
 		swDisplay.addWindowListener(new WindowAdapter() {
 			@Override
 			public void windowClosed(WindowEvent e) {
 				WindowManager.removeWindow((Frame) swDisplay);
 			}
 		});
 		WindowManager.addWindow(swDisplay);
 		// show PDF saving dialog if requested
 		if (autoSavePdf)
 			pdfWriter.process();
     }
 
 	/**
 	 * A method to get the bounding box from the data in the given
 	 * image that is above zero. Those values are interpreted as a
 	 * mask. It will return null if no mask information was found.
 	 *
 	 * @param mask The image to look for "on" values in
 	 * @return a new MaskInfo object or null
 	 */
 	protected MaskInfo getBoundingBoxOfMask(Image<T> mask) {
 		LocalizableCursor<T> cursor = mask.createLocalizableCursor();
 
 		int numMaskDims = mask.getNumDimensions();
 		// the "off type" of the mask
 		T offType = mask.createType();
 		offType.setZero();
 		// the corners of the bounding box
 		int[] min = null;
 		int[] max = null;
 		// indicates if mask data has been found
 		boolean maskFound = false;
 		// a container for temporary position information
 		int[] pos = new int[numMaskDims];
 		// walk over the mask
 		while (cursor.hasNext() ) {
 			cursor.fwd();
 			T data = cursor.getType();
 			// test if the current mask data represents on or off
 			if (data.compareTo(offType) > 0) {
 				// get current position
 				cursor.getPosition(pos);
 				if (!maskFound) {
 					// we found mask data, first time
 					maskFound = true;
 					// init min and max with the current position
 					min = Arrays.copyOf(pos, numMaskDims);
 					max = Arrays.copyOf(pos, numMaskDims);
 				} else {
 					/* Is is at least second hit, compare if it
 					 * has new "extreme" positions, i.e. does
 					 * is make the BB bigger?
 					 */
 					for (int d=0; d<numMaskDims; d++) {
 						if (pos[d] < min[d]) {
 							// is it smaller than min
 							min[d] = pos[d];
 						} else if (pos[d] > max[d]) {
 							// is it larger than max
 							max[d] = pos[d];
 						}
 					}
 				}
 			}
 		}
 
 		cursor.close();
 
 		if (!maskFound) {
 			return null;
 		} else {
 			// calculate size
 			int[] size = new int[numMaskDims];
 			for (int d=0; d<numMaskDims; d++)
 				size[d] = max[d] - min[d] + 1;
 			// create and add bounding box
 			BoundingBox bb = new BoundingBox(min, size);
 			return new MaskInfo(bb, mask);
 		}
 	}
 
 	/**
 	* Adds the provided Algorithm to the list if it is not null.
 	*/
 	protected void addIfValid(Algorithm<T> a, List<Algorithm<T>> list) {
 		if (a != null)
 			list.add(a);
 	}
 
 	/**
 	 * Returns true if a custom ROI has been selected, i.e if the current
 	 * ROI does not have the extent of the whole image.
 	 * @return true if custom ROI selected, false otherwise
 	 */
 	protected boolean hasValidRoi(ImagePlus imp) {
 		Roi roi = imp.getRoi();
 		if (roi == null)
 			return false;
 
 		Rectangle theROI = roi.getBounds();
 
 		// if the ROI is the same size as the image (default ROI), return false
 		return (theROI.height != imp.getHeight()
 					|| theROI.width != imp.getWidth());
 	}
 
 	/**
 	* Clips a value to the specified bounds.
 	*/
 	protected static int clip(int val, int min, int max) {
 		return Math.max( Math.min( val, max ), min );
 	}
 
 	/**
 	 * This method checks if the given ImagePlus contains any
 	 * masks or ROIs. If so, the appropriate date structures
 	 * are created and filled.
 	 */
 	protected void createMasksFromImage(ImagePlus imp) {
 		// get ROIs from current image in Fiji
 		Roi[] impRois = split(imp.getRoi());
 		// create the ROIs
 		createMasksAndRois(impRois, imp.getWidth(), imp.getHeight());
 	}
 
 	/**
 	 * A method to fill the masks array with data based on the ROI manager.
 	 */
-	protected void createMasksFromRoiManager(int width, int height) {
+	protected boolean createMasksFromRoiManager(int width, int height) {
 		RoiManager roiManager = RoiManager.getInstance();
-		if (roiManager == null)
+		if (roiManager == null) {
 			IJ.error("Could not get ROI Manager instance.");
+			return false;
+		}
 		Roi[] selectedRois = roiManager.getSelectedRoisAsArray();
 		// create the ROIs
 		createMasksAndRois(selectedRois, width, height);
+		return true;
 	}
 
 	/**
 	 * Creates appropriate data structures from the ROI information
 	 * passed. If an irregular ROI is found, it will be put into a
 	 * frame of its bounding box size and put into an Image<T>.
 	 *
 	 * In the end the members ROIs, masks and maskBBs will be
 	 * filled if ROIs or masks were found. They will be null
 	 * otherwise.
 	 */
 	protected void createMasksAndRois(Roi[] rois, int width, int height) {
 		// create empty list
 		masks.clear();
 
 		for (Roi r : rois ){
 			MaskInfo mi = new MaskInfo();
 			// add it to the list of masks/ROIs
 			masks.add(mi);
 			// get the ROIs/masks bounding box
 			Rectangle rect = r.getBounds();
 			mi.roi = new BoundingBox(
 					new int[] {rect.x, rect.y} ,
 					new int[] {rect.width, rect.height});
 			ImageProcessor ipMask = r.getMask();
 			// check if we got a regular ROI and return if so
 			if (ipMask == null) {
 				continue;
 			}
 
 			// create a mask processor of the same size as a slice
 			ImageProcessor ipSlice = ipMask.createProcessor(width, height);
 			// fill the new slice with black
 			ipSlice.setValue(0.0);
 			ipSlice.fill();
 			// position the mask on the new  mask processor
 			ipSlice.copyBits(ipMask, mi.roi.offset[0], mi.roi.offset[1], Blitter.COPY);
 			// create an Image<T> out of it
 			ImagePlus maskImp = new ImagePlus("Mask", ipSlice);
 			// and remember it and the masks bounding box
 			mi.mask = ImagePlusAdapter.<T>wrap( maskImp );
 		}
 	}
 
 	/**
 	 * This method duplicates the given images, but respects
 	 * ROIs if present. Meaning, a sub-picture will be created when
 	 * source images are ROI/MaskImages.
 	 * @throws MissingPreconditionException
 	 */
 	protected Image<T> createMaskImage(Image<T> image, Image<BitType> mask,
 			int[] offset, int[] size, String name) throws MissingPreconditionException {
 		int[] pos = image.createPositionArray();
 		// sanity check
 		if (pos.length != offset.length || pos.length != size.length) {
 			throw new MissingPreconditionException("Mask offset and size must be of same dimensionality like image.");
 		}
 		// use twin cursor for only one image
 		TwinCursor<T> cursor = new TwinCursor<T>(
 				image.createLocalizableByDimCursor(),
 				image.createLocalizableByDimCursor(),
 				mask.createLocalizableCursor());
 		// prepare output image
 		ImageFactory<T> maskFactory = new ImageFactory<T>(
 				image.createType(), new ArrayContainerFactory());
 		Image<T> maskImage = maskFactory.createImage( size, name );
 		LocalizableByDimCursor<T> maskCursor =
 				maskImage.createLocalizableByDimCursor();
 		// go through the visible data and copy it to the output
 		while (cursor.hasNext()) {
 			cursor.fwd();
 			cursor.getPosition(pos);
 			// shift coordinates by offset
 			for (int i=0; i < pos.length; ++i) {
 				pos[i] = pos[i] - offset[i];
 			}
 			// write out to correct position
 			maskCursor.setPosition( pos );
 			maskCursor.getType().set( cursor.getChannel1() );
 		}
 
 		cursor.close();
 		maskCursor.close();
 
 		return maskImage;
 	}
 
 	/**
 	 * Splits a non overlapping composite ROI into its sub ROIs.
 	 *
 	 * @param roi The ROI to split
 	 * @return A list of one or more ROIs
 	 */
 	public static Roi[] split(Roi roi) {
 		if (roi instanceof ShapeRoi)
 			return ((ShapeRoi)roi).getRois();
 		return new Roi[] { roi };
 	}
 }