public JobEntryDialogInterface getJobEntryDialog( JobEntryInterface jobEntryInterface, JobMeta jobMeta ) {
    Class<?>[] paramClasses = new Class<?>[] { Shell.class, JobEntryInterface.class, Repository.class, JobMeta.class };
    Object[] paramArgs = new Object[] { spoon.getShell(), jobEntryInterface, spoon.getRepository(), jobMeta };

    PluginRegistry registry = PluginRegistry.getInstance();
    PluginInterface plugin = registry.getPlugin( JobEntryPluginType.class, jobEntryInterface );
    String dialogClassName = plugin.getClassMap().get( JobEntryDialogInterface.class );
    if ( dialogClassName == null ) {
      // try the deprecated way
      log.logDebug( "Use of JobEntryInterface#getDialogClassName is deprecated, use PluginDialog annotation instead." );
      dialogClassName = jobEntryInterface.getDialogClassName();
    }

    try {
      Class<JobEntryDialogInterface> dialogClass = registry.getClass( plugin, dialogClassName );
      Constructor<JobEntryDialogInterface> dialogConstructor = dialogClass.getConstructor( paramClasses );
      JobEntryDialogInterface entryDialogInterface = dialogConstructor.newInstance( paramArgs );
      entryDialogInterface.setMetaStore( spoon.getMetaStore() );
      return entryDialogInterface;
    } catch ( Throwable t ) {
      t.printStackTrace();
      String errorTitle = BaseMessages.getString( PKG, "Spoon.Dialog.ErrorCreatingJobDialog.Title" );
      String errorMsg = BaseMessages.getString( PKG, "Spoon.Dialog.ErrorCreatingJobEntryDialog.Message", dialogClassName );
      spoon.getLog().logError( spoon.toString(), errorMsg );
      new ErrorDialog( spoon.getShell(), errorTitle, errorMsg, t );
      return null;
    }
  }
@Test
  public void testGetJobEntryDialogClass() throws KettlePluginException {
    PluginRegistry registry = PluginRegistry.getInstance();
    PluginMockInterface plugin = mock( PluginMockInterface.class );
    when( plugin.getIds() ).thenReturn( new String[] { "mockJobPlugin" } );
    when( plugin.matches( "mockJobPlugin" ) ).thenReturn( true );
    when( plugin.getName() ).thenReturn( "mockJobPlugin" );

    JobEntryInterface jobEntryInterface = mock( JobEntryInterface.class );
    when( jobEntryInterface.getDialogClassName() ).thenReturn( String.class.getName() );
    when( plugin.getClassMap() ).thenReturn( new HashMap<Class<?>, String>() {{
        put( JobEntryInterface.class, jobEntryInterface.getClass().getName() );
        put( JobEntryDialogInterface.class, JobEntryDialogInterface.class.getName() );
      }} );

    registry.registerPlugin( JobEntryPluginType.class, plugin );

    SpoonJobDelegate delegate = mock( SpoonJobDelegate.class );
    Spoon spoon = mock( Spoon.class );
    delegate.spoon = spoon;
    delegate.log = mock( LogChannelInterface.class );
    when( spoon.getShell() ).thenReturn( mock( Shell.class ) );
    doCallRealMethod().when( delegate ).getJobEntryDialog( any( JobEntryInterface.class ), any( JobMeta.class ) );

    JobMeta meta = mock( JobMeta.class );

    // verify that dialog class is requested from plugin
    try {
      delegate.getJobEntryDialog( jobEntryInterface, meta ); // exception is expected here
    } catch ( Throwable ignore ) {
      verify( jobEntryInterface, never() ).getDialogClassName();
    }

    // verify that the deprecated way is still valid
    when( plugin.getClassMap() ).thenReturn( new HashMap<Class<?>, String>() {{
        put( JobEntryInterface.class, jobEntryInterface.getClass().getName() );
      }} );
    try {
      delegate.getJobEntryDialog( jobEntryInterface, meta ); // exception is expected here
    } catch ( Throwable ignore ) {
      verify( jobEntryInterface, times( 1 ) ).getDialogClassName();
    }

    // cleanup
    registry.removePlugin( JobEntryPluginType.class, plugin );
  }