/**
   * Add a transformation to the
   *
   * @param transMeta the transformation to add to the map
   * @return the key used to store the transformation in the map
   */
  public String addTransformation(TransMeta transMeta) {
    String key = spoon.delegates.tabs.makeTransGraphTabName(transMeta);

    TransMeta xform = (TransMeta) transformationMap.get(key);
    if (xform == null) {
      transformationMap.put(key, transMeta);
    } else {
      // found a transformation tab that has the same name, is it the same
      // as the one we want to load, if not warn the user of the duplicate
      // name
      // this check may produce false negatives, i.e., references that are
      // deemed
      // different when they in fact refer to the same entry. For example,
      // one of
      // the transforms may use a variable reference or an alternative but
      // equivalent5
      boolean same = false;
      if (transMeta.isRepReference() && xform.isRepReference()) {
        // a repository value, check directory
        same = transMeta.getDirectory().getPath().equals(xform.getDirectory().getPath());
      } else if (transMeta.isFileReference() && xform.isFileReference()) {
        // a file system entry, check file path
        same = transMeta.getFilename().equals(xform.getFilename());
      }

      if (!same) {
        ShowMessageDialog dialog =
            new ShowMessageDialog(
                spoon.getShell(),
                SWT.OK | SWT.ICON_INFORMATION,
                Messages.getString("Spoon.Dialog.TransAlreadyLoaded.Title"),
                "'"
                    + key
                    + "'"
                    + Const.CR
                    + Const.CR
                    + Messages.getString("Spoon.Dialog.TransAlreadyLoaded.Message"));
        dialog.setTimeOut(6);
        dialog.open();
        /*
         * MessageBox mb = new MessageBox(shell, SWT.OK |
         * SWT.ICON_INFORMATION);
         * mb.setMessage("'"+key+"'"+Const.CR+Const.CR+Messages.getString("Spoon.Dialog.TransAlreadyLoaded.Message")); //
         * Transformation is already loaded
         * mb.setText(Messages.getString("Spoon.Dialog.TransAlreadyLoaded.Title")); //
         * Sorry! mb.open();
         */
      }
    }

    return key;
  }
  public void addTransGraph(TransMeta transMeta) {
    String key = addTransformation(transMeta);
    if (key != null) {
      // See if there already is a tab for this graph
      // If no, add it
      // If yes, select that tab
      //
      String tabName = spoon.delegates.tabs.makeTransGraphTabName(transMeta);
      TabItem tabItem =
          spoon.delegates.tabs.findTabItem(tabName, TabMapEntry.OBJECT_TYPE_TRANSFORMATION_GRAPH);
      if (tabItem == null) {
        TransGraph transGraph = new TransGraph(spoon.tabfolder.getSwtTabset(), spoon, transMeta);
        tabItem = new TabItem(spoon.tabfolder, tabName, tabName);
        String toolTipText =
            Messages.getString(
                "Spoon.TabTrans.Tooltip", spoon.delegates.tabs.makeTransGraphTabName(transMeta));
        if (!Const.isEmpty(transMeta.getFilename()))
          toolTipText += Const.CR + Const.CR + transMeta.getFilename();
        tabItem.setToolTipText(toolTipText);
        tabItem.setImage(GUIResource.getInstance().getImageTransGraph());
        tabItem.setControl(transGraph);

        // OK, also see if we need to open a new history window.
        if (transMeta.getLogConnection() != null
            && !Const.isEmpty(transMeta.getLogTable())
            && !transMeta.isSlaveTransformation()) {
          transGraph.addAllTabs();
          transGraph.extraViewTabFolder.setSelection(
              transGraph.transHistoryDelegate.getTransHistoryTab());
        }

        spoon.delegates.tabs.addTab(
            new TabMapEntry(
                tabItem, tabName, transGraph, TabMapEntry.OBJECT_TYPE_TRANSFORMATION_GRAPH));
      }
      int idx = spoon.tabfolder.indexOf(tabItem);

      // keep the focus on the graph
      spoon.tabfolder.setSelected(idx);

      spoon.setUndoMenu(transMeta);
      spoon.enableMenus();
    }
  }
  public void executeTransformation(
      final TransMeta transMeta,
      final boolean local,
      final boolean remote,
      final boolean cluster,
      final boolean preview,
      final boolean debug,
      final Date replayDate,
      final boolean safe)
      throws KettleException {

    if (transMeta == null) {
      return;
    }

    // See if we need to ask for debugging information...
    //
    TransDebugMeta transDebugMeta = null;
    TransExecutionConfiguration executionConfiguration = null;

    if (preview) {
      executionConfiguration = spoon.getTransPreviewExecutionConfiguration();
    } else if (debug) {
      executionConfiguration = spoon.getTransDebugExecutionConfiguration();
    } else {
      executionConfiguration = spoon.getTransExecutionConfiguration();
    }

    if (debug) {
      // See if we have debugging information stored somewhere?
      //
      transDebugMeta = transDebugMetaMap.get(transMeta);
      if (transDebugMeta == null) {
        transDebugMeta = new TransDebugMeta(transMeta);
        transDebugMetaMap.put(transMeta, transDebugMeta);
      }

      // Set the default number of rows to retrieve on all selected steps...
      //
      StepMeta[] selectedSteps = transMeta.getSelectedSteps();
      if (selectedSteps != null && selectedSteps.length > 0) {
        transDebugMeta.getStepDebugMetaMap().clear();
        for (StepMeta stepMeta : transMeta.getSelectedSteps()) {
          StepDebugMeta stepDebugMeta = new StepDebugMeta(stepMeta);
          stepDebugMeta.setRowCount(PropsUI.getInstance().getDefaultPreviewSize());
          stepDebugMeta.setPausingOnBreakPoint(true);
          stepDebugMeta.setReadingFirstRows(false);
          transDebugMeta.getStepDebugMetaMap().put(stepMeta, stepDebugMeta);
        }
      }

    } else if (preview) {
      // See if we have preview information stored somewhere?
      //
      transDebugMeta = transPreviewMetaMap.get(transMeta);
      if (transDebugMeta == null) {
        transDebugMeta = new TransDebugMeta(transMeta);

        transPreviewMetaMap.put(transMeta, transDebugMeta);
      }

      // Set the default number of preview rows on all selected steps...
      //
      StepMeta[] selectedSteps = transMeta.getSelectedSteps();
      if (selectedSteps != null && selectedSteps.length > 0) {
        transDebugMeta.getStepDebugMetaMap().clear();
        for (StepMeta stepMeta : transMeta.getSelectedSteps()) {
          StepDebugMeta stepDebugMeta = new StepDebugMeta(stepMeta);
          stepDebugMeta.setRowCount(PropsUI.getInstance().getDefaultPreviewSize());
          stepDebugMeta.setPausingOnBreakPoint(false);
          stepDebugMeta.setReadingFirstRows(true);
          transDebugMeta.getStepDebugMetaMap().put(stepMeta, stepDebugMeta);
        }
      }
    }

    executionConfiguration.setRepository(spoon.rep);
    executionConfiguration.setSafeModeEnabled(safe);

    int debugAnswer = TransDebugDialog.DEBUG_CONFIG;

    if (debug || preview) {
      transDebugMeta.getTransMeta().setRepository(spoon.rep); // pass repository for mappings
      TransDebugDialog transDebugDialog = new TransDebugDialog(spoon.getShell(), transDebugMeta);
      debugAnswer = transDebugDialog.open();
      if (debugAnswer != TransDebugDialog.DEBUG_CANCEL) {
        executionConfiguration.setExecutingLocally(true);
        executionConfiguration.setExecutingRemotely(false);
        executionConfiguration.setExecutingClustered(false);
      } else {
        // If we cancel the debug dialog, we don't go further with the execution either.
        //
        return;
      }
    } else {
      if (transMeta.findFirstUsedClusterSchema() != null) {
        executionConfiguration.setExecutingLocally(false);
        executionConfiguration.setExecutingRemotely(false);
        executionConfiguration.setExecutingClustered(true);
      } else {
        executionConfiguration.setExecutingLocally(true);
        executionConfiguration.setExecutingRemotely(false);
        executionConfiguration.setExecutingClustered(false);
      }
    }

    Object data[] = spoon.variables.getData();
    String fields[] = spoon.variables.getRowMeta().getFieldNames();
    Map<String, String> variableMap = new HashMap<String, String>();
    variableMap.putAll(executionConfiguration.getVariables()); // the default
    for (int idx = 0; idx < fields.length; idx++) {
      String value = executionConfiguration.getVariables().get(fields[idx]);
      if (Const.isEmpty(value)) value = data[idx].toString();
      variableMap.put(fields[idx], value);
    }

    executionConfiguration.setVariables(variableMap);
    executionConfiguration.getUsedVariables(transMeta);
    executionConfiguration.getUsedArguments(transMeta, spoon.getArguments());
    executionConfiguration.setReplayDate(replayDate);

    executionConfiguration.setLogLevel(spoon.getLog().getLogLevel());

    boolean execConfigAnswer = true;

    if (debugAnswer == TransDebugDialog.DEBUG_CONFIG && replayDate == null) {
      TransExecutionConfigurationDialog dialog =
          new TransExecutionConfigurationDialog(
              spoon.getShell(), executionConfiguration, transMeta);
      execConfigAnswer = dialog.open();
    }

    if (execConfigAnswer) {

      // Verify if there is at least one step specified to debug or preview...
      //
      if (debug || preview) {
        if (transDebugMeta.getNrOfUsedSteps() == 0) {
          MessageBox box = new MessageBox(spoon.getShell(), SWT.ICON_WARNING | SWT.YES | SWT.NO);
          box.setText(Messages.getString("Spoon.Dialog.Warning.NoPreviewOrDebugSteps.Title"));
          box.setMessage(Messages.getString("Spoon.Dialog.Warning.NoPreviewOrDebugSteps.Message"));
          int answer = box.open();
          if (answer != SWT.YES) {
            return;
          }
        }
      }

      // addTransLog(transMeta, executionConfiguration.isExecutingLocally());
      // TransLog transLog = spoon.getActiveTransLog();
      TransGraph activeTransGraph = spoon.getActiveTransGraph();

      // Is this a local execution?
      //
      if (executionConfiguration.isExecutingLocally()) {
        if (debug || preview) {
          activeTransGraph.debug(executionConfiguration, transDebugMeta);
        } else {
          activeTransGraph.start(executionConfiguration);
        }

        // Are we executing remotely?
        //
      } else if (executionConfiguration.isExecutingRemotely()) {
        if (executionConfiguration.getRemoteServer() != null) {
          Trans.sendToSlaveServer(transMeta, executionConfiguration, spoon.rep);
          monitorRemoteTrans(transMeta, executionConfiguration.getRemoteServer());
          spoon.delegates.slaves.addSpoonSlave(executionConfiguration.getRemoteServer());

        } else {
          MessageBox mb = new MessageBox(spoon.getShell(), SWT.OK | SWT.ICON_INFORMATION);
          mb.setMessage(Messages.getString("Spoon.Dialog.NoRemoteServerSpecified.Message"));
          mb.setText(Messages.getString("Spoon.Dialog.NoRemoteServerSpecified.Title"));
          mb.open();
        }

        // Are we executing clustered?
        //
      } else if (executionConfiguration.isExecutingClustered()) {
        splitTrans(transMeta, executionConfiguration);
      }
    }
  }