private static BPMNDiagram removeConnectedGateways(BPMNDiagram diagram) {
    List<Gateway> XOR = getXORGateways(diagram);
    Iterator<Flow> iterator = diagram.getFlows().iterator();

    while (iterator.hasNext()) {
      Flow flow = iterator.next();
      if (XOR.contains(flow.getSource())
          && XOR.contains(flow.getTarget())
          && isSplit(diagram, flow.getSource())
          && isSplit(diagram, flow.getTarget())) {
        if (!flow.getSource().equals(flow.getTarget())) {
          List<Flow> flows = getOutgoingFlows(diagram, flow.getTarget());
          for (Flow flow1 : flows) {
            diagram.addFlow(flow.getSource(), flow1.getTarget(), "");
          }
          diagram.removeGateway((Gateway) flow.getTarget());
          XOR = getXORGateways(diagram);
        } else {
          diagram.removeEdge(flow);
        }
        iterator = diagram.getFlows().iterator();
      }
    }

    return diagram;
  }
  public static BPMNDiagram mergeDiagram(BPMNDiagram diagram) {
    diagram = separateSplitFromJoin(diagram);
    diagram = removeXORtoAND(diagram);
    diagram = removeConnectedGateways(diagram);

    int curr = diagram.getNodes().size() + diagram.getFlows().size();
    int size = 0;
    while (size != curr) {
      mergeActivitiesAfterXOR(diagram);
      mergeActivitiesBeforeXOR(diagram);
      size = curr;
      curr = diagram.getNodes().size() + diagram.getFlows().size();
    }

    return diagram;
  }
 private static List<Flow> getOutgoingFlows(BPMNDiagram diagram, BPMNNode bpmnNode) {
   List<Flow> flows = new ArrayList<Flow>();
   for (Flow flow : diagram.getFlows()) {
     if (flow.getSource().equals(bpmnNode)) {
       flows.add(flow);
     }
   }
   return flows;
 }
 private static List<Activity> getOutgoingActivities(BPMNDiagram diagram, BPMNNode bpmnNode) {
   List<Activity> flows = new ArrayList<Activity>();
   for (Flow flow : diagram.getFlows()) {
     if (flow.getSource().equals(bpmnNode) && flow.getTarget() instanceof Activity) {
       flows.add((Activity) flow.getTarget());
     }
   }
   return flows;
 }
 private static List<BPMNNode> getIncomingNodes(BPMNDiagram diagram, BPMNNode bpmnNode) {
   List<BPMNNode> flows = new ArrayList<BPMNNode>();
   for (Flow flow : diagram.getFlows()) {
     if (flow.getTarget().equals(bpmnNode)) {
       flows.add(flow.getSource());
     }
   }
   return flows;
 }
  private static BPMNDiagram removeXORtoAND(BPMNDiagram diagram) {
    List<Gateway> XOR = getXORGateways(diagram);
    List<Gateway> AND = getANDGateways(diagram);
    for (Gateway gateway1 : XOR) {
      for (Gateway gateway2 : AND) {
        List<Flow> flows = new ArrayList<Flow>();
        for (Flow flow : diagram.getFlows()) {
          if (flow.getSource().equals(gateway1) && flow.getTarget().equals(gateway2)) {
            flows.add(flow);
          }
        }
        if (flows.size() > 1) {
          for (int i = 1; i < flows.size(); i++) {
            diagram.removeEdge(flows.get(i));
          }
        }
      }
    }

    return diagram;
  }