Program: 176739
Project: 176739
Buggy source:
/** 
 * Adds the nodes to flush stack.
 * @param node the node
 * @param eventType the event type
 */
private void addNodesToFlushStack(Node node,EventType eventType){
  Map<NodeLink,Node> children=node.getChildren();
  if (children != null) {
    Map<NodeLink,Node> oneToOneChildren=new HashMap<NodeLink,Node>();
    Map<NodeLink,Node> oneToManyChildren=new HashMap<NodeLink,Node>();
    Map<NodeLink,Node> manyToOneChildren=new HashMap<NodeLink,Node>();
    Map<NodeLink,Node> manyToManyChildren=new HashMap<NodeLink,Node>();
    for (    NodeLink nodeLink : children.keySet()) {
      Relation.ForeignKey multiplicity=nodeLink.getMultiplicity();
switch (multiplicity) {
case ONE_TO_ONE:
        oneToOneChildren.put(nodeLink,children.get(nodeLink));
      break;
case ONE_TO_MANY:
    oneToManyChildren.put(nodeLink,children.get(nodeLink));
  break;
case MANY_TO_ONE:
manyToOneChildren.put(nodeLink,children.get(nodeLink));
break;
case MANY_TO_MANY:
manyToManyChildren.put(nodeLink,children.get(nodeLink));
break;
}
}
for (NodeLink nodeLink : oneToManyChildren.keySet()) {
Node childNode=children.get(nodeLink);
if (!childNode.isTraversed()) {
addNodesToFlushStack(childNode,eventType);
}
}
for (NodeLink nodeLink : manyToManyChildren.keySet()) {
Node childNode=children.get(nodeLink);
if (childNode != null) {
if (node.isDirty() && !node.isTraversed()) {
JoinTableMetadata jtmd=(JoinTableMetadata)nodeLink.getLinkProperty(LinkProperty.JOIN_TABLE_METADATA);
if (jtmd != null) {
String joinColumnName=(String)jtmd.getJoinColumns().toArray()[0];
String inverseJoinColumnName=(String)jtmd.getInverseJoinColumns().toArray()[0];
Object entityId=node.getEntityId();
Object childId=childNode.getEntityId();
Set<Object> childValues=new HashSet<Object>();
childValues.add(childId);
OPERATION operation=null;
if (node.getCurrentNodeState().getClass().equals(ManagedState.class)) {
operation=OPERATION.INSERT;
}
 else if (node.getCurrentNodeState().getClass().equals(RemovedState.class)) {
operation=OPERATION.DELETE;
}
addJoinTableDataIntoMap(operation,jtmd.getJoinTableSchema(),jtmd.getJoinTableName(),joinColumnName,inverseJoinColumnName,node.getDataClass(),entityId,childValues);
}
}
if (!childNode.isTraversed()) {
addNodesToFlushStack(childNode,eventType);
}
}
}
for (NodeLink nodeLink : oneToOneChildren.keySet()) {
if (!node.isTraversed()) {
node.setTraversed(true);
flushStack.push(node);
logEvent(node,eventType);
Node childNode=children.get(nodeLink);
addNodesToFlushStack(childNode,eventType);
}
}
for (NodeLink nodeLink : manyToOneChildren.keySet()) {
if (!node.isTraversed()) {
node.setTraversed(true);
flushStack.push(node);
logEvent(node,eventType);
}
Node childNode=children.get(nodeLink);
Map<NodeLink,Node> parents=childNode.getParents();
for (NodeLink parentLink : parents.keySet()) {
Relation.ForeignKey multiplicity=parentLink.getMultiplicity();
if (multiplicity.equals(Relation.ForeignKey.MANY_TO_ONE)) {
Node parentNode=parents.get(parentLink);
if (!parentNode.isTraversed() && parentNode.isDirty()) {
addNodesToFlushStack(parentNode,eventType);
}
}
}
if (!childNode.isTraversed() && childNode.isDirty()) {
addNodesToFlushStack(childNode,eventType);
}
 else if (!childNode.isDirty()) {
childNode.setTraversed(true);
flushStack.push(childNode);
logEvent(childNode,eventType);
}
}
}
if (!node.isTraversed() && node.isDirty()) {
node.setTraversed(true);
flushStack.push(node);
logEvent(node,eventType);
}
}

Fixed version (ground truth):
/** 
 * Adds the nodes to flush stack.
 * @param node the node
 * @param eventType the event type
 */
private void addNodesToFlushStack(Node node,EventType eventType){
  Map<NodeLink,Node> children=node.getChildren();
  if (children != null) {
    Map<NodeLink,Node> oneToOneChildren=new HashMap<NodeLink,Node>();
    Map<NodeLink,Node> oneToManyChildren=new HashMap<NodeLink,Node>();
    Map<NodeLink,Node> manyToOneChildren=new HashMap<NodeLink,Node>();
    Map<NodeLink,Node> manyToManyChildren=new HashMap<NodeLink,Node>();
    for (    NodeLink nodeLink : children.keySet()) {
      Relation.ForeignKey multiplicity=nodeLink.getMultiplicity();
switch (multiplicity) {
case ONE_TO_ONE:
        oneToOneChildren.put(nodeLink,children.get(nodeLink));
      break;
case ONE_TO_MANY:
    oneToManyChildren.put(nodeLink,children.get(nodeLink));
  break;
case MANY_TO_ONE:
manyToOneChildren.put(nodeLink,children.get(nodeLink));
break;
case MANY_TO_MANY:
manyToManyChildren.put(nodeLink,children.get(nodeLink));
break;
}
}
for (NodeLink nodeLink : oneToManyChildren.keySet()) {
Node childNode=children.get(nodeLink);
if (!childNode.isTraversed()) {
addNodesToFlushStack(childNode,eventType);
}
}
for (NodeLink nodeLink : manyToManyChildren.keySet()) {
Node childNode=children.get(nodeLink);
if (childNode != null) {
if (node.isDirty() && !node.isTraversed()) {
JoinTableMetadata jtmd=(JoinTableMetadata)nodeLink.getLinkProperty(LinkProperty.JOIN_TABLE_METADATA);
if (jtmd != null) {
String joinColumnName=(String)jtmd.getJoinColumns().toArray()[0];
String inverseJoinColumnName=(String)jtmd.getInverseJoinColumns().toArray()[0];
Object entityId=node.getEntityId();
Object childId=childNode.getEntityId();
Set<Object> childValues=new HashSet<Object>();
childValues.add(childId);
OPERATION operation=null;
if (node.getCurrentNodeState().getClass().equals(ManagedState.class)) {
operation=OPERATION.INSERT;
}
 else if (node.getCurrentNodeState().getClass().equals(RemovedState.class)) {
operation=OPERATION.DELETE;
}
addJoinTableData(operation,jtmd.getJoinTableSchema(),jtmd.getJoinTableName(),joinColumnName,inverseJoinColumnName,node.getDataClass(),entityId,childValues);
}
}
if (!childNode.isTraversed()) {
addNodesToFlushStack(childNode,eventType);
}
}
}
for (NodeLink nodeLink : oneToOneChildren.keySet()) {
if (!node.isTraversed()) {
node.setTraversed(true);
flushStack.push(node);
logEvent(node,eventType);
Node childNode=children.get(nodeLink);
addNodesToFlushStack(childNode,eventType);
}
}
for (NodeLink nodeLink : manyToOneChildren.keySet()) {
if (!node.isTraversed()) {
node.setTraversed(true);
flushStack.push(node);
logEvent(node,eventType);
}
Node childNode=children.get(nodeLink);
Map<NodeLink,Node> parents=childNode.getParents();
for (NodeLink parentLink : parents.keySet()) {
Relation.ForeignKey multiplicity=parentLink.getMultiplicity();
if (multiplicity.equals(Relation.ForeignKey.MANY_TO_ONE)) {
Node parentNode=parents.get(parentLink);
if (!parentNode.isTraversed() && parentNode.isDirty()) {
addNodesToFlushStack(parentNode,eventType);
}
}
}
if (!childNode.isTraversed() && childNode.isDirty()) {
addNodesToFlushStack(childNode,eventType);
}
 else if (!childNode.isDirty()) {
childNode.setTraversed(true);
flushStack.push(childNode);
logEvent(childNode,eventType);
}
}
}
if (!node.isTraversed() && node.isDirty()) {
node.setTraversed(true);
flushStack.push(node);
logEvent(node,eventType);
}
}