Program: 157222
Project: 157222
Buggy source:
private KeyboardMetadata addKeyboardRow(@NonNull AddOn.AddOnResourceMapping resourceMapping,Context context,int rowResId,final KeyboardDimens keyboardDimens,@KeyboardRowModeId int rowMode){
  XmlResourceParser parser=context.getResources().getXml(rowResId);
  List<Key> keys=getKeys();
  boolean inKey=false;
  boolean inRow=false;
  final float keyHorizontalGap=keyboardDimens.getKeyHorizontalGap();
  final float rowVerticalGap=keyboardDimens.getRowVerticalGap();
  float x=0;
  float y=rowVerticalGap;
  Key key=null;
  Row currentRow=null;
  float rowHeight=0;
  Resources res=context.getResources();
  KeyboardMetadata m=new KeyboardMetadata();
  try {
    int event;
    while ((event=parser.next()) != XmlResourceParser.END_DOCUMENT) {
      if (event == XmlResourceParser.START_TAG) {
        String tag=parser.getName();
        if (TAG_ROW.equals(tag)) {
          inRow=true;
          x=0;
          currentRow=createRowFromXml(resourceMapping,res,parser,rowMode);
          if (currentRow == null) {
            skipToEndOfRow(parser);
            inRow=false;
          }
 else {
            m.rowsCount++;
            m.isTopRow=currentRow.rowEdgeFlags == Keyboard.EDGE_TOP;
            if (!m.isTopRow) {
              y=getHeight() + getVerticalGap();
            }
            rowHeight=0;
          }
        }
 else         if (TAG_KEY.equals(tag)) {
          inKey=true;
          x+=(keyHorizontalGap / 2);
          key=createKeyFromXml(resourceMapping,mLocalContext,context,currentRow,keyboardDimens,(int)x,(int)y,parser);
          key.width=(int)(key.width - keyHorizontalGap);
          if (m.isTopRow)           keys.add(m.keysCount,key);
 else           keys.add(key);
          m.keysCount++;
          rowHeight=Math.max(key.height,rowHeight);
        }
      }
 else       if (event == XmlResourceParser.END_TAG) {
        if (inKey) {
          inKey=false;
          x+=(key.gap + key.width);
          x+=(keyHorizontalGap / 2);
          if (x > m.rowWidth) {
            m.rowWidth=(int)x;
            mMaxGenericRowsWidth=Math.max(mMaxGenericRowsWidth,m.rowWidth);
          }
        }
 else         if (inRow) {
          inRow=false;
          y+=currentRow.verticalGap;
          y+=rowHeight;
          y+=rowVerticalGap;
          m.totalHeight=(int)(m.totalHeight + (rowHeight + currentRow.verticalGap));
        }
      }
    }
  }
 catch (  Exception e) {
    Logger.e(TAG,"String_Node_Str" + e);
    e.printStackTrace();
  }
  return m;
}

Fixed version (ground truth):
private KeyboardMetadata addKeyboardRow(@NonNull AddOn.AddOnResourceMapping resourceMapping,Context context,int rowResId,final KeyboardDimens keyboardDimens,@KeyboardRowModeId int rowMode){
  XmlResourceParser parser=context.getResources().getXml(rowResId);
  List<Key> keys=getKeys();
  boolean inKey=false;
  boolean inRow=false;
  final float keyHorizontalGap=keyboardDimens.getKeyHorizontalGap();
  final float rowVerticalGap=keyboardDimens.getRowVerticalGap();
  float x=0;
  float y=rowVerticalGap;
  Key key=null;
  Row currentRow=null;
  float rowHeight=0;
  Resources res=context.getResources();
  KeyboardMetadata m=new KeyboardMetadata();
  try {
    int event;
    while ((event=parser.next()) != XmlResourceParser.END_DOCUMENT) {
      if (event == XmlResourceParser.START_TAG) {
        String tag=parser.getName();
        if (TAG_ROW.equals(tag)) {
          inRow=true;
          x=0;
          currentRow=createRowFromXml(resourceMapping,res,parser,rowMode);
          if (currentRow == null) {
            skipToEndOfRow(parser);
            inRow=false;
          }
 else {
            m.rowsCount++;
            m.isTopRow=currentRow.rowEdgeFlags == Keyboard.EDGE_TOP;
            if (!m.isTopRow) {
              y=getHeight() + getVerticalGap();
            }
            rowHeight=0;
          }
        }
 else         if (TAG_KEY.equals(tag)) {
          inKey=true;
          x+=(keyHorizontalGap / 2);
          key=createKeyFromXml(resourceMapping,mLocalContext,context,currentRow,keyboardDimens,(int)x,(int)y,parser);
          key.width=(int)(key.width - keyHorizontalGap);
          if (m.isTopRow)           keys.add(m.keysCount,key);
 else           keys.add(key);
          m.keysCount++;
          rowHeight=Math.max(key.height,rowHeight);
        }
      }
 else       if (event == XmlResourceParser.END_TAG) {
        if (inKey) {
          inKey=false;
          x+=(key.gap + key.width);
          x+=(keyHorizontalGap / 2);
          if (x > m.rowWidth) {
            m.rowWidth=(int)x;
            mMaxGenericRowsWidth=Math.max(mMaxGenericRowsWidth,m.rowWidth);
          }
        }
 else         if (inRow) {
          inRow=false;
          y+=currentRow.verticalGap;
          y+=rowHeight;
          y+=rowVerticalGap;
          m.totalHeight=(int)(m.totalHeight + (rowHeight + currentRow.verticalGap));
        }
      }
    }
  }
 catch (  XmlPullParserException e) {
    Logger.e(TAG,e,"String_Node_Str" + e.getMessage());
  }
catch (  IOException e) {
    Logger.e(TAG,e,"String_Node_Str" + e.getMessage());
  }
  return m;
}