Object[] getOneRow() throws KettleException {
    if ( !openNextFile() ) {
      return null;
    }

    // Build an empty row based on the meta-data
    Object[] outputRowData = buildEmptyRow();

    try {
      // Create new row or clone
      if ( meta.getIsInFields() ) {
        outputRowData = copyOrCloneArrayFromLoadFile( outputRowData, data.readrow );
      }

      // Read fields...
      for ( int i = 0; i < data.nrInputFields; i++ ) {
        // Get field
        LoadFileInputField loadFileInputField = meta.getInputFields()[i];

        Object o = null;
        int indexField = data.totalpreviousfields + i;
        ValueMetaInterface targetValueMeta = data.outputRowMeta.getValueMeta( indexField );
        ValueMetaInterface sourceValueMeta = data.convertRowMeta.getValueMeta( indexField );

        switch ( loadFileInputField.getElementType() ) {
          case LoadFileInputField.ELEMENT_TYPE_FILECONTENT:

            // DO Trimming!
            switch ( loadFileInputField.getTrimType() ) {
              case LoadFileInputField.TYPE_TRIM_LEFT:
                if ( meta.getEncoding() != null ) {
                  data.filecontent = Const.ltrim( new String( data.filecontent, meta.getEncoding() ) ).getBytes();
                } else {
                  data.filecontent = Const.ltrim( new String( data.filecontent ) ).getBytes();
                }
                break;
              case LoadFileInputField.TYPE_TRIM_RIGHT:
                if ( meta.getEncoding() != null ) {
                  data.filecontent = Const.rtrim( new String( data.filecontent, meta.getEncoding() ) ).getBytes();
                } else {
                  data.filecontent = Const.rtrim( new String( data.filecontent ) ).getBytes();
                }
                break;
              case LoadFileInputField.TYPE_TRIM_BOTH:
                if ( meta.getEncoding() != null ) {
                  data.filecontent = Const.trim( new String( data.filecontent, meta.getEncoding() ) ).getBytes();
                } else {
                  data.filecontent = Const.trim( new String( data.filecontent ) ).getBytes();
                }
                break;
              default:
                break;
            }
            if ( targetValueMeta.getType() != ValueMetaInterface.TYPE_BINARY ) {
              // handle as a String
              if (  meta.getEncoding() != null ) {
                o = new String( data.filecontent, meta.getEncoding() );
              } else {
                o = new String( data.filecontent );
              }
            } else {
              // save as byte[] without any conversion
              o = data.filecontent;
            }
            break;
          case LoadFileInputField.ELEMENT_TYPE_FILESIZE:
            o = String.valueOf( data.fileSize );
            break;
          default:
            break;
        }

        if ( targetValueMeta.getType() == ValueMetaInterface.TYPE_BINARY ) {
          // save as byte[] without any conversion
          outputRowData[indexField] = o;
        } else {
          // convert string (processing type) to the target type
          outputRowData[indexField] = targetValueMeta.convertData( sourceValueMeta, o );
        }

        // Do we need to repeat this field if it is null?
        if ( loadFileInputField.isRepeated() ) {
          if ( data.previousRow != null && o == null ) {
            outputRowData[indexField] = data.previousRow[indexField];
          }
        }
      } // End of loop over fields...
      int rowIndex = data.totalpreviousfields + data.nrInputFields;

      // See if we need to add the filename to the row...
      if ( meta.includeFilename() && meta.getFilenameField() != null && meta.getFilenameField().length() > 0 ) {
        outputRowData[rowIndex++] = data.filename;
      }

      // See if we need to add the row number to the row...
      if ( meta.includeRowNumber() && meta.getRowNumberField() != null && meta.getRowNumberField().length() > 0 ) {
        outputRowData[rowIndex++] = new Long( data.rownr );
      }
      // Possibly add short filename...
      if ( meta.getShortFileNameField() != null && meta.getShortFileNameField().length() > 0 ) {
        outputRowData[rowIndex++] = data.shortFilename;
      }
      // Add Extension
      if ( meta.getExtensionField() != null && meta.getExtensionField().length() > 0 ) {
        outputRowData[rowIndex++] = data.extension;
      }
      // add path
      if ( meta.getPathField() != null && meta.getPathField().length() > 0 ) {
        outputRowData[rowIndex++] = data.path;
      }

      // add Hidden
      if ( meta.isHiddenField() != null && meta.isHiddenField().length() > 0 ) {
        outputRowData[rowIndex++] = new Boolean( data.hidden );
      }
      // Add modification date
      if ( meta.getLastModificationDateField() != null && meta.getLastModificationDateField().length() > 0 ) {
        outputRowData[rowIndex++] = data.lastModificationDateTime;
      }
      // Add Uri
      if ( meta.getUriField() != null && meta.getUriField().length() > 0 ) {
        outputRowData[rowIndex++] = data.uriName;
      }
      // Add RootUri
      if ( meta.getRootUriField() != null && meta.getRootUriField().length() > 0 ) {
        outputRowData[rowIndex++] = data.rootUriName;
      }
      RowMetaInterface irow = getInputRowMeta();

      data.previousRow = irow == null ? outputRowData : irow.cloneRow( outputRowData ); // copy it to make
      // surely the next step doesn't change it in between...

      incrementLinesInput();
      data.rownr++;

    } catch ( Exception e ) {
      throw new KettleException( "Error during processing a row", e );
    }

    return outputRowData;
  }
@Test
  public void testUTF8Encoding() throws KettleException, FileSystemException {
    stepMetaInterface.setIncludeFilename( true );
    stepMetaInterface.setFilenameField( "filename" );
    stepMetaInterface.setIncludeRowNumber( true );
    stepMetaInterface.setRowNumberField( "rownumber" );
    stepMetaInterface.setShortFileNameField( "shortname" );
    stepMetaInterface.setExtensionField( "extension" );
    stepMetaInterface.setPathField( "path" );
    stepMetaInterface.setIsHiddenField( "hidden" );
    stepMetaInterface.setLastModificationDateField( "lastmodified" );
    stepMetaInterface.setUriField( "uri" );
    stepMetaInterface.setRootUriField( "root uri" );

    // string with UTF-8 encoding
    ( (LoadFileInputMeta) runtimeSMI ).setEncoding( "UTF-8" );
    stepInputFiles.addFile( getFile( "UTF-8.txt" ) );
    Object[] result = stepLoadFileInput.getOneRow();
    assertEquals( " UTF-8 string ÕÕÕ€ ", result[0] );
    assertEquals( 1L, result[2] );
    assertEquals( "UTF-8.txt", result[3] );
    assertEquals( "txt", result[4] );
    assertEquals( false, result[6] );
    assertEquals( getFile( "UTF-8.txt" ).getURL().toString(), result[8] );
    assertEquals( getFile( "UTF-8.txt" ).getName().getRootURI(), result[9] );
  }