@Override
  public void performDragOver(DropTargetEvent event) {
    if (!ArtifactTransfer.getInstance().isSupportedType(event.currentDataType)) {
      event.detail = DND.DROP_NONE;
      return;
    }
    final ArtifactData artData = ArtifactTransfer.getInstance().nativeToJava(event.currentDataType);
    if (artData == null) {
      event.detail = DND.DROP_NONE;
      return;
    }
    for (Artifact art : artData.getArtifacts()) {
      if (art.isOfType(CoreArtifactTypes.UniversalGroup)) {
        event.detail = DND.DROP_NONE;
        return;
      }
    }
    Tree tree = treeViewer.getTree();
    TreeItem dragOverTreeItem = tree.getItem(treeViewer.getTree().toControl(event.x, event.y));

    event.feedback = DND.FEEDBACK_EXPAND;
    event.detail = DND.DROP_NONE;

    // Set as COPY if drag item over group (copy versus move will be determined on drop
    if (dragOverTreeItem != null
        && ((GroupExplorerItem) dragOverTreeItem.getData()).isUniversalGroup()) {
      event.detail = DND.DROP_COPY;
      tree.setInsertMark(null, false);
    }
    // Handle re-ordering within same group
    else if (dragOverTreeItem != null
        && !((GroupExplorerItem) dragOverTreeItem.getData()).isUniversalGroup()) {
      GroupExplorerItem dragOverGroupItem = (GroupExplorerItem) dragOverTreeItem.getData();
      IStructuredSelection selectedItem = (IStructuredSelection) treeViewer.getSelection();
      Object obj = selectedItem.getFirstElement();
      if (obj instanceof GroupExplorerItem) {
        GroupExplorerItem droppingGroupItem = (GroupExplorerItem) obj;

        // the group to move must belong to the same group as the member to insert before/after
        if (dragOverGroupItem.getParentItem().equals(droppingGroupItem.getParentItem())) {
          if (isFeedbackAfter) {
            event.feedback = DND.FEEDBACK_INSERT_AFTER;
          } else {
            event.feedback = DND.FEEDBACK_INSERT_BEFORE;
          }
          event.detail = DND.DROP_MOVE;
        }
      } else {
        if (isFeedbackAfter) {
          event.feedback = DND.FEEDBACK_INSERT_AFTER;
        } else {
          event.feedback = DND.FEEDBACK_INSERT_BEFORE;
        }
        event.detail = DND.DROP_COPY;
      }
    } else {
      tree.setInsertMark(null, false);
    }
  }