public void prepareFieldNamesParameters( String[] parameters, String[] parameterFieldNames, String[] parameterValues,
                                                    NamedParams namedParam, JobEntryTrans jobEntryTrans )
    throws UnknownParamException {
    for ( int idx = 0; idx < parameters.length; idx++ ) {
      // Grab the parameter value set in the Trans job entry
      // Set fieldNameParameter only if exists and if it is not declared any staticValue( parameterValues array )
      //
      String thisValue = namedParam.getParameterValue( parameters[ idx ] );
      // multiple executions on the same jobEntryTrans variableSpace need to be updated even for nulls or blank values.
      // so we have to ask if that same variable had a value before and if it had - and the new value is empty -
      // we should set it as a blank value instead of ignoring it.
      // NOTE: we should only replace it if we have a parameterFieldNames defined -> parameterFieldNames[ idx ] ) != null
      if ( !Utils.isEmpty( jobEntryTrans.getVariable( parameters[ idx ] ) ) && Utils.isEmpty( thisValue )
        && idx < parameterFieldNames.length && !Utils.isEmpty( Const.trim( parameterFieldNames[ idx ] ) ) ) {
        jobEntryTrans.setVariable( parameters[ idx ], "" );
      }
      // Set value only if is not empty at namedParam and exists in parameterFieldNames
      if ( !Utils.isEmpty( thisValue ) && idx < parameterFieldNames.length ) {
        // If exists then ask if is not empty
        if ( !Utils.isEmpty( Const.trim( parameterFieldNames[ idx ] ) ) ) {
          // If is not empty then we have to ask if it exists too in parameterValues array, since the values in
          // parameterValues prevail over parameterFieldNames
          if ( idx < parameterValues.length ) {
            // If is empty at parameterValues array, then we can finally add that variable with that value
            if ( Utils.isEmpty( Const.trim( parameterValues[ idx ] ) ) ) {
              jobEntryTrans.setVariable( parameters[ idx ], thisValue );
            }
          } else {
            // Or if not in parameterValues then we can add that variable with that value too
            jobEntryTrans.setVariable( parameters[ idx ], thisValue );
          }
        }
      }
    }
  }
@Test
  public void testPrepareFieldNamesParametersWithNulls() throws UnknownParamException {
    //NOTE: this only tests the prepareFieldNamesParameters function not all variable substitution logic
    // array of params
    String[] parameterNames = new String[7];
    parameterNames[0] = "param1";
    parameterNames[1] = "param2";
    parameterNames[2] = "param3";
    parameterNames[3] = "param4";
    parameterNames[4] = "param5";
    parameterNames[5] = "param6";
    parameterNames[6] = "param7";

    // array of fieldNames params
    String[] parameterFieldNames = new String[7];
    parameterFieldNames[0] = null;
    parameterFieldNames[2] = "ValueParam3";
    parameterFieldNames[3] = "FieldValueParam4";
    parameterFieldNames[4] = "FieldValueParam5";
    parameterFieldNames[6] = "FieldValueParam7";

    // array of parameterValues params
    String[] parameterValues = new String[7];
    parameterValues[1] = "ValueParam2";
    parameterValues[3] = "";
    parameterValues[4] = "StaticValueParam5";
    parameterValues[5] = "StaticValueParam6";


    JobEntryTrans jet = new JobEntryTrans();
    VariableSpace variableSpace = new Variables();
    jet.copyVariablesFrom( variableSpace );

    jet.setVariable( "param6", "someDummyPreviousValue6" );
    jet.setVariable( "param7", "someDummyPreviousValue7" );

    //at this point StreamColumnNameParams are already inserted in namedParams
    NamedParams namedParam = Mockito.mock( NamedParamsDefault.class );
    Mockito.doReturn( "value1" ).when( namedParam ).getParameterValue(  "param1" );
    Mockito.doReturn( "value2" ).when( namedParam ).getParameterValue(  "param2" );
    Mockito.doReturn( "value3" ).when( namedParam ).getParameterValue(  "param3" );
    Mockito.doReturn( "value4" ).when( namedParam ).getParameterValue(  "param4" );
    Mockito.doReturn( "value5" ).when( namedParam ).getParameterValue(  "param5" );
    Mockito.doReturn( "" ).when( namedParam ).getParameterValue(  "param6" );
    Mockito.doReturn( "" ).when( namedParam ).getParameterValue(  "param7" );

    jet.prepareFieldNamesParameters( parameterNames, parameterFieldNames, parameterValues, namedParam, jet );
    // "param1" has parameterFieldName value = null and no parameterValues defined so it should be null
    Assert.assertEquals( null, jet.getVariable( "param1" ) );
    // "param2" has only parameterValues defined and no parameterFieldName value so it should be null
    Assert.assertEquals( null, jet.getVariable( "param2" ) );
    // "param3" has only the parameterFieldName defined so it should return the mocked value
    Assert.assertEquals( "value3", jet.getVariable( "param3" ) );
    // "param4" has parameterFieldName and also an empty parameterValues defined so it should return the mocked value
    Assert.assertEquals( "value4", jet.getVariable( "param4" ) );
    // "param5" has parameterFieldName and also parameterValues defined with a not empty value so it should return null
    Assert.assertEquals( null, jet.getVariable( "param5" ) );
    // "param6" only has a parameterValues defined with a not empty value and has a previous value on it ( someDummyPreviousValue6 )
    // so it should keep "someDummyPreviousValue6" since there is no parameterFieldNames definition
    Assert.assertEquals( "someDummyPreviousValue6", jet.getVariable( "param6" ) );
    // "param7" only has a parameterFieldNames defined and has a previous value on it ( someDummyPreviousValue7 )
    // so it should update to the new value mocked = "" even it is a blank value - PDI-18227
    Assert.assertEquals( "", jet.getVariable( "param7" ) );
  }