@Override
 protected PortObject[] execute(final PortObject[] inObjects, final ExecutionContext exec)
     throws Exception {
   // Initialising
   exec.setMessage("initialising");
   final ClusterTreeModel model = (ClusterTreeModel) inObjects[0];
   final BufferedDataTable data = (BufferedDataTable) inObjects[1];
   final int distanceColumnIdx =
       data.getDataTableSpec().findColumnIndex(distanceColumnModel.getColumnName());
   final Map<RowKey, DistanceVectorDataValue> distanceMatrix =
       new HashMap<RowKey, DistanceVectorDataValue>();
   for (final DataRow dataRow : data) {
     final DistanceVectorDataValue distanceVector =
         (DistanceVectorDataValue) dataRow.getCell(distanceColumnIdx);
     distanceMatrix.put(dataRow.getKey(), distanceVector);
   }
   exec.setMessage("computing");
   final DendrogramNode origRoot = model.getRoot();
   final Map<Triple<DendrogramNode, RowKey, RowKey>, Number> m =
       visit(
           origRoot,
           new HashMap<Triple<DendrogramNode, RowKey, RowKey>, Number>(),
           distanceMatrix,
           model.getClusterDistances().length + 1,
           exec.createSilentSubExecutionContext(.9));
   final Map<RowKey, Pair<DataRow, Integer>> rows = new HashMap<RowKey, Pair<DataRow, Integer>>();
   int idx = 0;
   for (final DataRow dataRow : data) {
     rows.put(dataRow.getKey(), Pair.create(dataRow, Integer.valueOf(idx++)));
   }
   exec.setMessage("creating final tree");
   final ClusterViewNode tree = buildNewTree(convertM(m), origRoot, rows, exec).getO1();
   final ArrayList<DistanceVectorDataValue>
       origList = new ArrayList<DistanceVectorDataValue>(model.getClusterDistances().length + 1),
       newList = new ArrayList<DistanceVectorDataValue>(model.getClusterDistances().length + 1);
   flatten(origRoot, origList, distanceMatrix);
   exec.checkCanceled();
   flatten(tree, newList, distanceMatrix);
   logger.info("Before:      " + sumDistance(origList));
   logger.info("After:       " + sumDistance(newList));
   final ClusterTreeModel clusterTreeModel =
       new ClusterTreeModel(
           (DataTableSpec) model.getSpec(),
           tree,
           model.getClusterDistances(),
           model.getClusterDistances().length + 1) {
         @Override
         public String getSummary() {
           return "Before: " + sumDistance(origList) + "\nAfter:  " + sumDistance(newList);
         }
       };
   return new PortObject[] {clusterTreeModel};
 }
 /** {@inheritDoc} */
 @Override
 protected void loadValidatedSettingsFrom(final NodeSettingsRO settings)
     throws InvalidSettingsException {
   distanceColumnModel.loadSettingsFrom(settings);
 }
 /** {@inheritDoc} */
 @Override
 protected void validateSettings(final NodeSettingsRO settings) throws InvalidSettingsException {
   distanceColumnModel.validateSettings(settings);
 }
 /** {@inheritDoc} */
 @Override
 protected void saveSettingsTo(final NodeSettingsWO settings) {
   distanceColumnModel.saveSettingsTo(settings);
 }