/** Split objects into normal and disease components */
  private void splitObjects() {
    normalIds = new HashSet<Long>();
    diseaseIds = new HashSet<Long>();
    RenderablePathway diagram = (RenderablePathway) getRenderable();
    if (pathway == null || diagram.getReactomeDiagramId() == null) return;
    try {
      GKInstance pdInst = adaptor.fetchInstance(diagram.getReactomeDiagramId());
      // Get the disease pathway instance
      List<GKInstance> pathways =
          pdInst.getAttributeValuesList(ReactomeJavaConstants.representedPathway);

      GKInstance diseasePathway = null;
      GKInstance normalPathway = null;
      GKInstance disease = (GKInstance) pathway.getAttributeValue(ReactomeJavaConstants.disease);
      if (disease == null && contains(pathway, pathways)) {
        normalPathway = pathway;
      } else {
        diseasePathway = pathway;
        // There should be a normal pathway contained by a disease pathway
        List<?> subPathways = diseasePathway.getAttributeValuesList(ReactomeJavaConstants.hasEvent);
        for (Object obj : subPathways) {
          GKInstance subPathway = (GKInstance) obj;
          disease = (GKInstance) subPathway.getAttributeValue(ReactomeJavaConstants.disease);
          if (disease == null && contains(subPathway, pathways)) {
            normalPathway = subPathway;
            break;
          }
        }
      }
      if (normalPathway != null) {
        // Get all disease related objects
        Set<GKInstance> normalEvents = InstanceUtilities.grepPathwayEventComponents(normalPathway);
        for (GKInstance inst : normalEvents) normalIds.add(inst.getDBID());
        Set<GKInstance> normalEntities = InstanceUtilities.grepPathwayParticipants(normalPathway);
        for (GKInstance inst : normalEntities) normalIds.add(inst.getDBID());
        if (diseasePathway != null) {
          Set<GKInstance> allEvents = InstanceUtilities.grepPathwayEventComponents(diseasePathway);
          allEvents.removeAll(normalEvents);
          for (GKInstance inst : allEvents) {
            diseaseIds.add(inst.getDBID());
            // Want to make sure disease pathways are connected to objects
            if (inst.getSchemClass().isa(ReactomeJavaConstants.ReactionlikeEvent)) {
              Set<GKInstance> rxtEntities = InstanceUtilities.getReactionParticipants(inst);
              for (GKInstance rxtEntity : rxtEntities) {
                diseaseIds.add(rxtEntity.getDBID());
              }
            }
          }
          //                    Set<GKInstance> allEntities =
          // InstanceUtilities.grepPathwayParticipants(diseasePathway);
          //                    allEntities.removeAll(normalEntities);
          //                    for (GKInstance inst : allEntities)
          //                        diseaseIds.add(inst.getDBID());
        }
      }
      splitComponents();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  @Override
  public void paint(Graphics g) {
    // Clear the editor
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    // In case g is provided by other graphics context (e.g during exporting)
    g2.setFont(getFont());
    g2.setBackground(background);
    Dimension size = getPreferredSize();
    g2.clearRect(0, 0, size.width, size.height);
    // TODO: Delete the follow two statements. For test only
    //        g2.setPaint(Color.yellow);
    //        g2.fillRect(0, 0, size.width, size.height);
    // Enable zooming
    g2.scale(scaleX, scaleY);

    List comps = displayedObject.getComponents();
    // Draw nodes first
    if (comps == null || comps.size() == 0) return;
    java.util.List edges = new ArrayList();
    Rectangle clip = g.getClipBounds();
    // Draw Compartments first
    List<RenderableCompartment> compartments = drawCompartments(g, comps, null, clip);
    drawComponents(g, normalComps, clip);
    if (isForNormal) {
      // Replace the original components with new set of Renderable objects for further processing
      RenderablePathway pathway = (RenderablePathway) displayedObject;
      List<Renderable> components = pathway.getComponents();
      components.clear();
      components.addAll(normalComps);
      components.addAll(compartments); // Don't forget them
      return;
    }
    // Draw a transparent background: light grey
    Color color = new Color(204, 204, 204, 175);
    g2.setPaint(color);
    //        Dimension size = getPreferredSize();
    // Preferred size has been scaled. Need to scale it back
    g2.fillRect(0, 0, (int) (size.width / scaleX + 1.0d), (int) (size.height / scaleY + 1.0d));
    // Draw disease related objects
    for (Renderable r : diseaseComps) {
      if (lofNodes.contains(r)) ((Node) r).setNeedDashedBorder(true);
    }
    drawComponents(g, diseaseComps, clip);
    if (overlaidObjects.size() > 0)
      drawComponents(
          g,
          overlaidObjects,
          clip,
          true); // Want to draw edge first so that no validation is needed.
    if (crossedObjects.size() > 0) drawCrosses(g, crossedObjects, clip);
    RenderablePathway pathway = (RenderablePathway) displayedObject;
    pathway.setBgComponents(new ArrayList<Renderable>(normalComps));
    List<Renderable> fgComps = new ArrayList<Renderable>();
    fgComps.addAll(diseaseComps);
    fgComps.addAll(overlaidObjects);
    // Don't want to place compartments and pathway
    for (Iterator<Renderable> it = fgComps.iterator(); it.hasNext(); ) {
      Renderable r = it.next();
      if (r instanceof RenderableCompartment || r instanceof RenderablePathway) it.remove();
    }
    pathway.setFgComponents(fgComps);
  }