question: private void mergeStates ( int rowNum , short [ ] newValues , Vector < Integer > rowsBeingUpdated ) { short [ ] oldValues = tempStateTable . elementAt ( rowNum ) ; boolean isLoopingState = loopingStates . contains ( new Integer ( rowNum ) ) ; for ( int i = 0 ; i < oldValues . length ; i ++ ) { if ( oldValues [ i ] == newValues [ i ] ) { continue ; } else if ( isLoopingState && loopingStates . contains ( new Integer ( oldValues [ i ] ) ) ) { if ( newValues [ i ] != 0 ) { if ( oldValues [ i ] == 0 ) { clearLoopingStates = true ; } oldValues [ i ] = newValues [ i ] ; } } else if ( oldValues [ i ] == 0 ) { oldValues [ i ] = newValues [ i ] ; } else if ( i == numCategories ) { oldValues [ i ] = ( short ) ( ( newValues [ i ] & ALL_FLAGS ) | oldValues [ i ] ) ; } else if ( oldValues [ i ] != 0 && newValues [ i ] != 0 ) { int combinedRowNum = searchMergeList ( oldValues [ i ] , newValues [ i ] ) ; if ( combinedRowNum != 0 ) { oldValues [ i ] = ( short ) combinedRowNum ; } else { int oldRowNum = oldValues [ i ] ; int newRowNum = newValues [ i ] ; combinedRowNum = tempStateTable . size ( ) ; if ( mergeList == null ) { mergeList = new Vector < > ( ) ; } mergeList . addElement ( new int [ ] { oldRowNum , newRowNum , combinedRowNum } ) ; short [ ] newRow = new short [ numCategories + 1 ] ; short [ ] oldRow = tempStateTable . elementAt ( oldRowNum ) ; System . arraycopy ( oldRow , 0 , newRow , 0 , numCategories + 1 ) ; tempStateTable . addElement ( newRow ) ; oldValues [ i ] = ( short ) combinedRowNum ; if ( ( decisionPointList . contains ( new Integer ( oldRowNum ) ) || decisionPointList . contains ( new Integer ( newRowNum ) ) ) && ! decisionPointList . contains ( new Integer ( combinedRowNum ) ) ) { decisionPointList . addElement ( new Integer ( combinedRowNum ) ) ; } if ( ( rowsBeingUpdated . contains ( new Integer ( oldRowNum ) ) || rowsBeingUpdated . contains ( new Integer ( newRowNum ) ) ) && ! rowsBeingUpdated . contains ( new Integer ( combinedRowNum ) ) ) { decisionPointList . addElement ( new Integer ( combinedRowNum ) ) ; } for ( int k = 0 ; k < decisionPointStack . size ( ) ; k ++ ) { Vector < Integer > dpl = decisionPointStack . elementAt ( k ) ; if ( ( dpl . contains ( new Integer ( oldRowNum ) ) || dpl . contains ( new Integer ( newRowNum ) ) ) && ! dpl . contains ( new Integer ( combinedRowNum ) ) ) { dpl . addElement ( new Integer ( combinedRowNum ) ) ; } } mergeStates ( combinedRowNum , tempStateTable . elementAt ( newValues [ i ] ) , rowsBeingUpdated ) ; } } } return ; }
target:  The real work of making the state table deterministic happens here.  This function merges a state in the state table (specified by rowNum) with a state that is passed in (newValues).  The basic process is to copy the nonzero cells in newStates into the state in the state table (we'll call that oldValues).  If there's a collision (i.e., if the same cell has a nonzero value in both states, and it's not the SAME value), then we have to reconcile the collision.  We do this by creating a new state, adding it to the end of the state table, and using this function recursively to merge the original two states into a single, combined state.  This process may happen recursively (i.e., each successive level may involve collisions).  To prevent infinite recursion, we keep a log of merge operations.  Any time we're merging two states we've merged before, we can just supply the row number for the result of that merge operation rather than creating a new state just like it.