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,
      LogLevel logLevel ) 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();
    }

    // Set defaults so the run configuration can set it up correctly
    executionConfiguration.setExecutingLocally( true );
    executionConfiguration.setExecutingRemotely( false );
    executionConfiguration.setExecutingClustered( false );

    // Set repository and safe mode information in both the exec config and the metadata
    transMeta.setRepository( spoon.rep );
    transMeta.setMetaStore( spoon.getMetaStore() );

    executionConfiguration.setRepository( spoon.rep );

    executionConfiguration.setSafeModeEnabled( safe );

    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...
      //
      List<StepMeta> selectedSteps = transMeta.getSelectedSteps();
      if ( selectedSteps != null && selectedSteps.size() > 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...
      //
      List<StepMeta> selectedSteps = transMeta.getSelectedSteps();
      if ( selectedSteps != null && selectedSteps.size() > 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 );
        }
      }
    }

    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;
      }
    }

    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 ( Utils.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( logLevel );

    boolean execConfigAnswer = true;

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

    if ( execConfigAnswer ) {
      TransGraph activeTransGraph = spoon.getActiveTransGraph();
      activeTransGraph.transLogDelegate.addTransLog();

      // Set the named parameters
      Map<String, String> paramMap = executionConfiguration.getParams();
      for ( String key : paramMap.keySet() ) {
        transMeta.setParameterValue( key, Const.NVL( paramMap.get( key ), "" ) );
      }
      transMeta.activateParameters();

      // Set the log level
      //
      if ( executionConfiguration.getLogLevel() != null ) {
        transMeta.setLogLevel( executionConfiguration.getLogLevel() );
      }

      // Set the run options
      transMeta.setClearingLog( executionConfiguration.isClearingLog() );
      transMeta.setSafeModeEnabled( executionConfiguration.isSafeModeEnabled() );
      transMeta.setGatheringMetrics( executionConfiguration.isGatheringMetrics() );

      ExtensionPointHandler.callExtensionPoint( log, KettleExtensionPoint.SpoonTransMetaExecutionStart.id, transMeta );
      ExtensionPointHandler.callExtensionPoint( log, KettleExtensionPoint.SpoonTransExecutionConfiguration.id,
          executionConfiguration );

      try {
        ExtensionPointHandler.callExtensionPoint( log, KettleExtensionPoint.SpoonTransBeforeStart.id, new Object[] {
          executionConfiguration, transMeta, transMeta, spoon.getRepository()
        } );
      } catch ( KettleException e ) {
        log.logError( e.getMessage(), transMeta.getFilename() );
        return;
      }

      if ( !executionConfiguration.isExecutingLocally() && !executionConfiguration.isExecutingRemotely() ) {
        if ( transMeta.hasChanged() ) {
          activeTransGraph.showSaveFileMessage();
        }
      }

      // 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( BaseMessages.getString( PKG, "Spoon.Dialog.Warning.NoPreviewOrDebugSteps.Title" ) );
          box.setMessage( BaseMessages.getString( PKG, "Spoon.Dialog.Warning.NoPreviewOrDebugSteps.Message" ) );
          int answer = box.open();
          if ( answer != SWT.YES ) {
            return;
          }
        }
      }

      // 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() ) {
        activeTransGraph.handleTransMetaChanges( transMeta );
        if ( transMeta.hasChanged() ) {
          showSaveTransformationBeforeRunningDialog( spoon.getShell() );
        } else if ( executionConfiguration.getRemoteServer() != null ) {
          String carteObjectId =
              Trans.sendToSlaveServer( transMeta, executionConfiguration, spoon.rep, spoon.getMetaStore() );
          monitorRemoteTrans( transMeta, carteObjectId, executionConfiguration.getRemoteServer() );
          spoon.delegates.slaves.addSpoonSlave( executionConfiguration.getRemoteServer() );

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

        // Are we executing clustered?
        //
      } else if ( executionConfiguration.isExecutingClustered() ) {
        activeTransGraph.handleTransMetaChanges( transMeta );
        if ( transMeta.hasChanged() ) {
          showSaveTransformationBeforeRunningDialog( spoon.getShell() );
        } else {
          splitTrans( transMeta, executionConfiguration );
        }
      }
    }
  }
@Test
  @SuppressWarnings( "ResultOfMethodCallIgnored" )
  public void testSetParamsIntoMetaInExecuteTransformation() throws KettleException {
    doCallRealMethod().when( delegate ).executeTransformation( transMeta, true, false, false,
            false, false, null, false, LogLevel.BASIC );

    RowMetaInterface rowMeta = mock( RowMetaInterface.class );
    TransExecutionConfiguration transExecutionConfiguration = mock( TransExecutionConfiguration.class );
    TransGraph activeTransGraph = mock( TransGraph.class );
    activeTransGraph.transLogDelegate = mock( TransLogDelegate.class );

    doReturn( rowMeta ).when( spoon.variables ).getRowMeta();
    doReturn( EMPTY_STRING_ARRAY ).when( rowMeta ).getFieldNames();
    doReturn( transExecutionConfiguration ).when( spoon ).getTransExecutionConfiguration();
    doReturn( MAP_WITH_TEST_PARAM ).when( transExecutionConfiguration ).getParams();
    doReturn( activeTransGraph ).when( spoon ).getActiveTransGraph();
    doReturn( TEST_LOG_LEVEL ).when( transExecutionConfiguration ).getLogLevel();
    doReturn( TEST_BOOLEAN_PARAM ).when( transExecutionConfiguration ).isClearingLog();
    doReturn( TEST_BOOLEAN_PARAM ).when( transExecutionConfiguration ).isSafeModeEnabled();
    doReturn( TEST_BOOLEAN_PARAM ).when( transExecutionConfiguration ).isGatheringMetrics();

    delegate.executeTransformation( transMeta, true, false, false, false, false,
            null, false, LogLevel.BASIC );

    verify( transMeta ).setParameterValue( TEST_PARAM_KEY, TEST_PARAM_VALUE );
    verify( transMeta ).activateParameters();
    verify( transMeta ).setLogLevel( TEST_LOG_LEVEL );
    verify( transMeta ).setClearingLog( TEST_BOOLEAN_PARAM );
    verify( transMeta ).setSafeModeEnabled( TEST_BOOLEAN_PARAM );
    verify( transMeta ).setGatheringMetrics( TEST_BOOLEAN_PARAM );
  }