public AvgerageZStack(List<Plate> curPlateSelection) {
    this.curPlateSelection = curPlateSelection;
    Plate avgZStack = new Plate();
    avgZStack.setBarcode("avgz-stack");

    for (Well well : curPlateSelection.get(0).getWells()) {
      Well zStackWell = new Well();
      zStackWell.setPlateColumn(well.getPlateColumn());
      zStackWell.setPlateRow(well.getPlateRow());

      populateWell(well.getPlateColumn(), well.getPlateRow(), zStackWell);
      avgZStack.getWells().add(zStackWell);
    }

    PlatePanel.createPanelDialog(avgZStack, null, null);
  }
  @Override
  protected BufferedDataTable[] execute(BufferedDataTable[] inData, ExecutionContext exec)
      throws Exception {

    List<File> inputFiles =
        FileSelectPanel.getInputFiles(propInputDir.getStringValue(), getAllowedFileExtensions());

    if (inputFiles.isEmpty()) {
      throw new RuntimeException("No files selected");
    }

    // first group files into plate-groups
    Map<String, List<File>> plateFiles = splitFilesIntoPlates(inputFiles);

    if (inputFiles.isEmpty()) {
      throw new RuntimeException("No valid envision-files in selection " + inputFiles);
    }

    // split files
    List<String> allAttributes = mergeAttributes(plateFiles);
    List<Attribute> colAttributes = compileColumnModel(allAttributes);

    DataTableSpec outputSpec = AttributeUtils.compileTableSpecs(colAttributes);
    BufferedDataContainer container = exec.createDataContainer(outputSpec);

    // populate the table
    int fileCounter = 0, rowCounter = 0;
    for (String barcode : plateFiles.keySet()) {

      logger.info("Processing plate " + barcode);

      Plate plate = new Plate();

      // invalidate plate-dims as these become fixed in the loop
      plate.setNumColumns(-1);
      plate.setNumRows(-1);

      for (File file : plateFiles.get(barcode)) {
        String attributeName = getAttributeNameOfEnvisionFile(file);
        parseFile(plate, attributeName, file);

        BufTableUtils.updateProgress(exec, fileCounter++, inputFiles.size());
      }

      // now create the data-rows for this table
      for (Well well : plate.getWells()) {
        if (well.getReadOutNames().isEmpty()) {
          continue;
        }

        DataCell[] knimeRow = new DataCell[colAttributes.size()];

        // first add the barcode-column
        knimeRow[0] = new StringCell(barcode);

        knimeRow[1] = colAttributes.get(1).createCell(well.getPlateRow());
        knimeRow[2] = colAttributes.get(2).createCell(well.getPlateColumn());

        for (String attributeName : allAttributes) {
          int rowIndex = allAttributes.indexOf(attributeName);
          Double value = well.getReadout(attributeName);

          if (value != null) {
            knimeRow[3 + rowIndex] = new DoubleCell(value);
          } else {
            knimeRow[3 + rowIndex] = DataType.getMissingCell();
          }
        }

        DataRow tableRow = new DefaultRow(new RowKey("" + rowCounter++), knimeRow);
        container.addRowToTable(tableRow);
      }
    }

    container.close();

    return new BufferedDataTable[] {container.getTable()};
  }