class SelectValues extends BaseTransform<SelectValuesMeta, SelectValuesData> implements ITransform<SelectValuesMeta, SelectValuesData> {

  public boolean processRow() throws HopException {
    Object[] rowData = getRow(); // get row from rowset, wait for our turn, indicate busy!
    if ( rowData == null ) { // no more input to be expected...

      setOutputDone();
      return false;
    }

    Object[] rowCopy = null;
    if ( getTransformMeta().isDoingErrorHandling() ) {
      rowCopy = getInputRowMeta().cloneRow( rowData );
    }

    if ( log.isRowLevel() ) {
      logRowlevel( BaseMessages.getString( PKG, "SelectValues.Log.GotRowFromPreviousTransform" )
        + getInputRowMeta().getString( rowData ) );
    }

    if ( first ) {
      first = false;

      data.selectRowMeta = getInputRowMeta().clone();
      meta.getSelectFields( data.selectRowMeta, getTransformName() );
      data.deselectRowMeta = data.selectRowMeta.clone();
      meta.getDeleteFields( data.deselectRowMeta );
      data.metadataRowMeta = data.deselectRowMeta.clone();
      meta.getMetadataFields( data.metadataRowMeta, getTransformName(), this );
    }

    try {
      Object[] outputData = rowData;

      if ( data.select ) {
        outputData = selectValues( getInputRowMeta(), outputData );
      }
      if ( data.deselect ) {
        outputData = removeValues( data.selectRowMeta, outputData );
      }
      if ( data.metadata ) {
        outputData = metadataValues( data.deselectRowMeta, outputData );
      }

      if ( outputData == null ) {
        setOutputDone(); // signal end to receiver(s)
        return false;
      }

      // Send the row on its way
      //
      putRow( data.metadataRowMeta, outputData );
      if ( log.isRowLevel() ) {
        logRowlevel( BaseMessages.getString( PKG, "SelectValues.Log.WroteRowToNextTransform" )
          + data.metadataRowMeta.getString( outputData ) );
      }

    } catch ( HopException e ) {
      if ( getTransformMeta().isDoingErrorHandling() ) {
        String field;
        if ( e instanceof HopConversionException ) {
          List<IValueMeta> fields = ( (HopConversionException) e ).getFields();
          field = fields.isEmpty() ? null : fields.get( 0 ).getName();
        } else {
          field = null;
        }
        putError( getInputRowMeta(), rowCopy, 1, e.getMessage(), field, "SELECT001" );
      } else {
        throw e;
      }
    }

    if ( checkFeedback( getLinesRead() ) ) {
      logBasic( BaseMessages.getString( PKG, "SelectValues.Log.LineNumber" ) + getLinesRead() );
    }

    return true;
  }

  public  SelectValues( TransformMeta transformMeta, SelectValuesMeta meta, SelectValuesData data, int copyNr, PipelineMeta pipelineMeta,
                       Pipeline pipeline );

}