@Override
 public void contentAdded(ContentManagerEvent event) {
   if (devMotivePanel == null && event.getContent().getComponent() instanceof DevMotivePanel) {
     DevMotivePanel panel = (DevMotivePanel) event.getContent().getComponent();
     if (annotation.getFile().equals(panel.getFile())) {
       devMotivePanel = panel;
       devMotivePanel.addChangeListener(this);
     }
   }
 }
 @Override
 public void contentRemoved(ContentManagerEvent event) {
   if (devMotivePanel != null && devMotivePanel.equals(event.getContent().getComponent())) {
     releasePanel();
     updateAnnotations();
   }
 }
 @Nullable
 @Override
 public String getToolTip(int line, Editor editor) {
   VcsRevisionNumber revisionNumber = annotation.getLineRevisionNumber(line);
   if (revisionNumber == null) {
     return null;
   }
   if (devMotivePanel == null) {
     return "Dev Motive closed";
   }
   Collection<WorkItem> workItems =
       devMotivePanel.getWorkItemsByRevisionNumber(revisionNumber, true);
   if (workItems == null) {
     if (loadRevisionNumber(revisionNumber)) {
       return "Loading association information...";
     } else {
       return "Revision not found";
     }
   } else if (!workItems.isEmpty()) {
     StringBuffer buf = new StringBuffer();
     for (WorkItem workItem : workItems) {
       if (buf.length() > 0) {
         buf.append("\n\n");
       }
       buf.append(getWorkItemToolTip(workItem));
     }
     return buf.toString();
   } else {
     return null;
   }
 }
  @Nullable
  @Override
  public String getLineText(int line, Editor editor) {
    VcsRevisionNumber revisionNumber = annotation.getLineRevisionNumber(line);
    if (revisionNumber == null) {
      return null;
    }
    if (devMotivePanel == null) {
      return "---";
    }
    Collection<WorkItem> workItems =
        devMotivePanel.getWorkItemsByRevisionNumber(revisionNumber, false);
    if (workItems == null) {
      return unknownLine;
    }
    StringBuffer buf = new StringBuffer();
    for (WorkItem workItem : workItems) {
      if (buf.length() > 0) {
        buf.append(", ");
      }
      switch (workItem.getType()) {
        case DEFECT:
          buf.append("D: ");
          break;

        case USER_STORY:
          buf.append("U: ");
          break;
      }
      buf.append(workItem.getId());
    }
    return buf.toString();
  }
 @Override
 public void doAction(int line) {
   if (devMotivePanel == null) {
     return;
   }
   VcsRevisionNumber revisionNumber = annotation.getLineRevisionNumber(line);
   if (revisionNumber != null) {
     devMotivePanel.selectRevision(revisionNumber);
   }
 }
 private boolean loadRevisionNumber(VcsRevisionNumber revisionNumber) {
   List<VcsFileRevision> revisions = annotation.getRevisions();
   if (revisions != null) {
     for (VcsFileRevision revision : revisions) {
       if (revisionNumber.equals(revision.getRevisionNumber())) {
         devMotivePanel.load(Arrays.asList(revision));
         return true;
       }
     }
   }
   return false;
 }
 @Override
 public Cursor getCursor(int line) {
   if (devMotivePanel == null) {
     return Cursor.getDefaultCursor();
   }
   VcsRevisionNumber revisionNumber = annotation.getLineRevisionNumber(line);
   if (revisionNumber != null) {
     Collection<WorkItem> workItems =
         devMotivePanel.getWorkItemsByRevisionNumber(revisionNumber, true);
     if (workItems != null && !workItems.isEmpty()) {
       return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
     }
   }
   return Cursor.getDefaultCursor();
 }
  public DevMotiveAnnotationGutter(
      Project project,
      FileAnnotation annotation,
      List<VcsFileRevision> revisions,
      EditorGutter editorGutter) {
    this.annotation = annotation;

    devMotivePanel =
        AliContentFactory.addDevMotiveContent(
            project, annotation.getFile(), revisions, annotation.getVcsKey().getName(), this, true);
    devMotivePanel.addChangeListener(this);

    if (editorGutter instanceof EditorGutterComponentEx) {
      editorGutterComponentEx = (EditorGutterComponentEx) editorGutter;
      unknownLine = "???";
    } else {
      // unable to resize, make sure to reserve enough room
      unknownLine = "??????????";
    }
  }
 private void releasePanel() {
   if (devMotivePanel != null) {
     devMotivePanel.removeChangeListener(this);
     devMotivePanel = null;
   }
 }