docs: Result executeMergeStatement(Session session) {
  
          Result          resultOut          = null;
          RowSetNavigator generatedNavigator = null;
          PersistentStore store = session.sessionData.getRowStore(baseTable);
  
          if (generatedIndexes != null) {
              resultOut = Result.newUpdateCountResult(generatedResultMetaData,
                      0);
              generatedNavigator = resultOut.getChainedResult().getNavigator();
          }
  
          int count = 0;
  
          // data generated for non-matching rows
          RowSetNavigatorClient newData = new RowSetNavigatorClient(8);
  
          // rowset for update operation
          HashMappedList  updateRowSet       = new HashMappedList();
          RangeVariable[] joinRangeIterators = targetRangeVariables;
  
          // populate insert and update lists
          RangeIterator[] rangeIterators =
              new RangeIterator[joinRangeIterators.length];
  
          for (int i = 0; i < joinRangeIterators.length; i++) {
              rangeIterators[i] = joinRangeIterators[i].getIterator(session);
          }
  
          for (int currentIndex = 0; 0 <= currentIndex; ) {
              RangeIterator it          = rangeIterators[currentIndex];
              boolean       beforeFirst = it.isBeforeFirst();
  
              if (it.next()) {
                  if (currentIndex < joinRangeIterators.length - 1) {
                      currentIndex++;
  
                      continue;
                  }
              } else {
                  if (currentIndex == 1 && beforeFirst) {
                      Object[] data = getMergeInsertData(session);
  
                      if (data != null) {
                          newData.add(data);
                      }
                  }
  
                  it.reset();
  
                  currentIndex--;
  
                  continue;
              }
  
              // row matches!
              if (updateExpressions != null) {
                  Row row = it.getCurrentRow();    // this is always the second iterator
                  Object[] data = getUpdatedData(session, baseTable,
                                                 updateColumnMap,
                                                 updateExpressions,
                                                 baseTable.getColumnTypes(),
                                                 row.getData());
  
                  updateRowSet.add(row, data);
              }
          }
  
          // run the transaction as a whole, updating and inserting where needed
          // update any matched rows
          if (updateRowSet.size() > 0) {
              count = update(session, baseTable, updateRowSet);
          }
  
          // insert any non-matched rows
          newData.beforeFirst();
  
          while (newData.hasNext()) {
              Object[] data = newData.getNext();
  
              baseTable.insertRow(session, store, data);
  
              if (generatedNavigator != null) {
                  Object[] generatedValues = getGeneratedColumns(data);
  
                  generatedNavigator.add(generatedValues);
              }
          }
  
          baseTable.fireAfterTriggers(session, Trigger.INSERT_AFTER, newData);
  
          count += newData.getSize();
  
          if (resultOut == null) {
              return Result.getUpdateCountResult(count);
          } else {
              resultOut.setUpdateCount(count);
  
              return resultOut;
          }
      }