/**
   * Method gotoPreviousAnnotation.
   *
   * @param aType String
   * @return R4EAnnotation
   */
  public R4EAnnotation gotoPreviousAnnotation(String aType) {
    R4EAnnotation originalAnnotation = null;
    R4EAnnotation foundAnnotation = null;

    // We need to only consider the anomalies currently visible in the viewport
    if (null != fCurrentDiffNode.getAnnotationSupport()) {
      ITextEditor editor = fCurrentDiffNode.getAnnotationSupport().getEditor();
      if (null != editor) {
        IReviewAnnotationModel model = fCurrentDiffNode.getAnnotationSupport().getAnnotationModel();
        if (null != model) {
          ICompareNavigator navigator =
              ((R4ECompareEditorInput) editor.getEditorInput()).getNavigator();

          originalAnnotation = (R4EAnnotation) model.getPreviousAnnotation(aType);
          if (null != originalAnnotation) {
            R4EAnnotation annotation = originalAnnotation;
            do {
              final IR4EUIPosition annotationPositon = annotation.getR4EPosition();
              if (UIUtils.selectElementInEditorPane(navigator, annotationPositon, true)) {
                foundAnnotation = annotation;
                break;
              }
              annotation = (R4EAnnotation) model.getPreviousAnnotation(aType);
            } while (!originalAnnotation.getR4EPosition().isSameAs(annotation.getR4EPosition()));
          }
        }
      }
    }
    return foundAnnotation;
  }
  /**
   * Method getParticipant.
   *
   * @param aId - String
   * @return R4EParticipant
   */
  protected R4EParticipant getParticipant(String aId) {
    // First check if the participant already exist in the participant list
    for (R4EParticipant tmpPart : fParticipants) {
      if (aId.equalsIgnoreCase(tmpPart.getId())) {
        return null;
      }
    }
    final R4EParticipant participant = RModelFactory.eINSTANCE.createR4EParticipant();
    if (R4EUIModelController.isUserQueryAvailable()) {
      final IQueryUser query = new QueryUserFactory().getInstance();
      try {
        final List<IUserInfo> users = query.searchByUserId(aId);

        // Fill info with first user returned
        for (IUserInfo user : users) {
          if (user.getUserId().toLowerCase().equals(aId)) {
            participant.setId(user.getUserId().toLowerCase());
            participant.setEmail(user.getEmail());
            fParticipantsDetailsValues.add(UIUtils.buildUserDetailsString(user));
            return participant;
          }
        }
      } catch (NamingException e) {
        R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
        R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
      } catch (IOException e) {
        R4EUIPlugin.getDefault().logWarning("Exception: " + e.toString(), e);
      }
    }
    participant.setId(aId);
    fParticipantsDetailsValues.add("");
    return participant;
  }
  /**
   * Method addUserToParticipantList.
   *
   * @param aUser - String
   */
  private void addUsersToParticipantList(String aUser) {
    // Here we first need to resolve any group aliases to multiple users
    final List<String> resolvedUsers = R4EPreferencePage.getParticipantsFromList(aUser.trim());

    for (String user : resolvedUsers) {
      String[] userTokens = user.split(R4EUIConstants.LIST_SEPARATOR);

      // Resolve user in database (if possible)
      R4EParticipant participant = getParticipant(userTokens[0].toLowerCase());
      if (null == participant) {
        return; // Participant already in list
      }

      // Override email with address defined in users group (if any)
      if (2 == userTokens.length && !(userTokens[1].trim().equals(""))) {
        participant.setEmail(userTokens[1]);
      }

      // Override email with address defined in current review (if any)
      if (null != R4EUIModelController.getActiveReview()) {
        R4EParticipant reviewParticipant;
        try {
          reviewParticipant =
              R4EUIModelController.getActiveReview().getParticipant(participant.getId(), false);
          if (null != reviewParticipant) {
            participant.setEmail(reviewParticipant.getEmail());
          }
        } catch (ResourceHandlingException e) {
          UIUtils.displayResourceErrorDialog(e);
        }
      }
      fParticipants.add(participant);
      updateComponents(participant);
    }
  }
  /**
   * Method createContents.
   *
   * @param aParent Composite
   * @return Control
   * @see org.eclipse.compare.CompareEditorInput#createContents(Composite)
   */
  @Override
  public Control createContents(Composite aParent) {
    final Control control = super.createContents(aParent);

    // Go to the correct element in the compare editor
    UIUtils.selectElementInEditor(this);

    // TODO:  This is needed to show annotation highlighting when opening the compare editor.
    //		 It should not be needed so this should be investigated in the future.
    if (null != fCurrentDiffNode) {
      fCurrentDiffNode.refreshAnnotations();
    }
    return control;
  }
  /**
   * Method refresh.
   *
   * @see org.eclipse.ui.views.properties.tabbed.ISection#refresh()
   */
  @Override
  public void refresh() {
    final R4EUIContent uiContent = ((R4EUIContent) fProperties.getElement());
    fRefreshInProgress = true;
    if (null != uiContent.getPosition()) {
      fPositionText.setText(uiContent.getPosition().toString());
    } else {
      fPositionText.setText("");
    }

    final EList<String> assignedParticipants = uiContent.getContent().getAssignedTo();
    fAssignedToText.setText(UIUtils.formatAssignedParticipants(assignedParticipants));
    setEnabledFields();
    fRefreshInProgress = false;
  }
  /**
   * Method addUserToParticipantList.
   *
   * @param aUserInfo - IUserInfo
   */
  private void addUserToParticipantList(IUserInfo aUserInfo) {

    // First check if the participant already exist in the participant list
    for (R4EParticipant tmpPart : fParticipants) {
      if (aUserInfo.getUserId().equalsIgnoreCase(tmpPart.getId())) {
        return;
      }
    }

    // Add User to List
    final R4EParticipant participant = RModelFactory.eINSTANCE.createR4EParticipant();
    participant.setId(aUserInfo.getUserId());
    participant.setEmail(aUserInfo.getEmail());
    fParticipantsDetailsValues.add(UIUtils.buildUserDetailsString(aUserInfo));
    fParticipants.add(participant);

    updateComponents(participant);
  }
  /**
   * Method execute.
   *
   * @param aEvent ExecutionEvent
   * @return Object
   * @see org.eclipse.core.commands.IHandler#execute(ExecutionEvent)
   */
  public Object execute(final ExecutionEvent aEvent) {

    final List<IR4EUIModelElement> selectedElements = UIUtils.getCommandUIElements();

    final Job job =
        new Job(COMMAND_MESSAGE) {

          public String familyName = R4EUIConstants.R4E_UI_JOB_FAMILY;

          @Override
          public boolean belongsTo(Object family) {
            return familyName.equals(family);
          }

          @Override
          public IStatus run(IProgressMonitor monitor) {
            if (!selectedElements.isEmpty()) {
              R4EUIModelController.setJobInProgress(true);
              monitor.beginTask(COMMAND_MESSAGE, selectedElements.size());

              R4EReview review = null;
              if (null != R4EUIModelController.getActiveReview()) {
                review = R4EUIModelController.getActiveReview().getReview();
              }
              final List<R4EReviewComponent> removedItems = new ArrayList<R4EReviewComponent>();
              for (IR4EUIModelElement element : selectedElements) {

                monitor.subTask("Disabling element " + element.getName());
                R4EUIPlugin.Ftracer.traceInfo(
                    "Disabling element " + element.getName()); // $NON-NLS-1$
                final int[] result =
                    new int
                        [1]; // We need this to be able to pass the result value outside.  This is
                             // safe as we are using SyncExec
                final boolean[] fileRemove = new boolean[1];
                final String elementName = element.getName();
                if (R4EUIModelController.getNavigatorView().isAskConfirmation()) {
                  Display.getDefault()
                      .syncExec(
                          new Runnable() {
                            public void run() {
                              MessageDialogWithToggle dialog =
                                  MessageDialogWithToggle.openOkCancelConfirm(
                                      null,
                                      "Disable element",
                                      "Do you really want to disable element " + elementName + "?",
                                      "Don't ask again",
                                      false,
                                      null,
                                      null);
                              result[0] = dialog.getReturnCode();
                              fileRemove[0] = !dialog.getToggleState();
                            }
                          });
                }
                if (result[0] == Window.OK) {
                  R4EUIModelController.getNavigatorView().setAskConfirmation(fileRemove[0]);
                  try {
                    if (element instanceof R4EUIReviewItem) {
                      removedItems.add(((R4EUIReviewItem) element).getItem());
                    } else if (element instanceof R4EUIContent) {
                      removedItems.add(((R4EUIContent) element).getContent());
                    }

                    if (element.isOpen()) {
                      element.close();
                      for (IR4EUIModelElement childElement : element.getChildren()) {
                        if (null != childElement && childElement.isOpen()) {
                          childElement.close();
                          break;
                        }
                      }
                    }
                    element.getParent().removeChildren(element, false);
                  } catch (ResourceHandlingException e) {
                    UIUtils.displayResourceErrorDialog(e);
                  } catch (OutOfSyncException e) {
                    UIUtils.displaySyncErrorDialog(e);
                  } catch (CompatibilityException e) {
                    UIUtils.displayCompatibilityErrorDialog(e);
                  }
                }
                monitor.worked(1);
                if (monitor.isCanceled()) {
                  R4EUIModelController.setJobInProgress(false);
                  UIUtils.setNavigatorViewFocus(element, 0);
                  return Status.CANCEL_STATUS;
                }
              }

              // Send email notification if needed
              if (null != review) {
                if (0 < removedItems.size()
                    && review.getType().equals(R4EReviewType.R4E_REVIEW_TYPE_FORMAL)) {
                  if (((R4EFormalReview) review)
                      .getCurrent()
                      .getType()
                      .equals(R4EReviewPhase.R4E_REVIEW_PHASE_PREPARATION)) {
                    try {
                      MailServicesProxy.sendItemsRemovedNotification(removedItems);
                    } catch (CoreException e) {
                      UIUtils.displayCoreErrorDialog(e);
                    } catch (ResourceHandlingException e) {
                      UIUtils.displayResourceErrorDialog(e);
                    }
                  }
                }
              }
              R4EUIModelController.setJobInProgress(false);
              UIUtils.setNavigatorViewFocus(selectedElements.get(0), 0);
            }
            R4EUIModelController.setJobInProgress(false);
            monitor.done();
            return Status.OK_STATUS;
          }
        };
    job.setUser(true);
    job.schedule();
    return null;
  }
  /**
   * Method createRuleSetSetup
   *
   * @throws ExecutionException
   * @throws NotDefinedException
   * @throws NotEnabledException
   * @throws NotHandledException
   * @throws ResourceHandlingException
   * @throws OutOfSyncException
   */
  public void createRuleSetSetup() {

    // Create a Rule Set
    R4EUIRuleSet newRuleSet =
        fProxy
            .getRuleSetProxy()
            .createRuleSet(
                TestUtils.FSharedFolder,
                TestConstants.RULE_SET_TEST_NAME,
                TestConstants.RULE_SET_TEST_VERSION);
    Assert.assertNotNull(newRuleSet);
    Assert.assertEquals(TestConstants.RULE_SET_TEST_VERSION, newRuleSet.getRuleSet().getVersion());
    Assert.assertEquals(
        new Path(TestUtils.FSharedFolder).toPortableString(), newRuleSet.getRuleSet().getFolder());
    Assert.assertEquals(TestConstants.RULE_SET_TEST_NAME, newRuleSet.getRuleSet().getName());

    // Create a second Rule Set
    R4EUIRuleSet newRuleSet2 =
        fProxy
            .getRuleSetProxy()
            .createRuleSet(
                TestUtils.FSharedFolder,
                TestConstants.RULE_SET_TEST_NAME2,
                TestConstants.RULE_SET_TEST_VERSION);
    String newRuleSet2Name = newRuleSet2.getName();
    Assert.assertNotNull(newRuleSet2);
    Assert.assertEquals(TestConstants.RULE_SET_TEST_VERSION, newRuleSet2.getRuleSet().getVersion());
    Assert.assertEquals(
        new Path(TestUtils.FSharedFolder).toPortableString(), newRuleSet2.getRuleSet().getFolder());
    Assert.assertEquals(TestConstants.RULE_SET_TEST_NAME2, newRuleSet2.getRuleSet().getName());

    // Create Rule Area
    R4EUIRuleArea newRuleArea =
        fProxy.getRuleAreaProxy().createRuleArea(newRuleSet, TestConstants.RULE_AREA_TEST_NAME);
    Assert.assertNotNull(newRuleArea);
    Assert.assertEquals(TestConstants.RULE_AREA_TEST_NAME, newRuleArea.getArea().getName());

    // Create Rule Violation
    R4EUIRuleViolation newRuleViolation =
        fProxy
            .getRuleViolationProxy()
            .createRuleViolation(newRuleArea, TestConstants.RULE_VIOLATION_TEST_NAME);
    Assert.assertNotNull(newRuleViolation);
    Assert.assertEquals(
        TestConstants.RULE_VIOLATION_TEST_NAME, newRuleViolation.getViolation().getName());

    // Create Rule
    R4EUIRule newRule =
        fProxy
            .getRuleProxy()
            .createRule(
                newRuleViolation,
                TestConstants.RULE_TEST_ID,
                TestConstants.RULE_TEST_TITLE,
                TestConstants.RULE_TEST_DESCRIPTION,
                UIUtils.getClassFromString(TestConstants.RULE_TEST_CLASS),
                UIUtils.getRankFromString(TestConstants.RULE_TEST_RANK));
    Assert.assertNotNull(newRule);
    Assert.assertEquals(TestConstants.RULE_TEST_ID, newRule.getRule().getId());
    Assert.assertEquals(TestConstants.RULE_TEST_TITLE, newRule.getRule().getTitle());
    Assert.assertEquals(TestConstants.RULE_TEST_DESCRIPTION, newRule.getRule().getDescription());
    Assert.assertEquals(
        UIUtils.getClassFromString(TestConstants.RULE_TEST_CLASS), newRule.getRule().getClass_());
    Assert.assertEquals(
        UIUtils.getRankFromString(TestConstants.RULE_TEST_RANK), newRule.getRule().getRank());

    // Close a Rule Set
    fProxy.getCommandProxy().closeElement(newRuleSet);
    Assert.assertFalse(newRuleSet.isOpen());

    // Open the closed Rule Set
    fProxy.getCommandProxy().openElement(newRuleSet);
    Assert.assertTrue(newRuleSet.isOpen());
    Assert.assertEquals(
        TestConstants.RULE_TEST_ID,
        ((R4EUIRule) newRuleSet.getChildren()[0].getChildren()[0].getChildren()[0])
            .getRule()
            .getId());

    // Remove Rule Set from preferences
    String prefsRuleSet = newRuleSet2.getRuleSet().eResource().getURI().toFileString();
    fProxy.getPreferencesProxy().removeRuleSetFromPreferences(prefsRuleSet);
    for (R4EUIRuleSet ruleSet : R4EUIModelController.getRootElement().getRuleSets()) {
      if (ruleSet.getRuleSet().getName().equals(newRuleSet2.getRuleSet().getName())) {
        fail(
            "RuleSet "
                + prefsRuleSet
                + " should not be present since it was removed from preferences");
      }
    }

    // Add back Rule Set to preferences
    boolean ruleSetFound = false;
    fProxy.getPreferencesProxy().addRuleSetToPreferences(prefsRuleSet);
    for (R4EUIRuleSet ruleSet : R4EUIModelController.getRootElement().getRuleSets()) {
      if (ruleSet.getRuleSet().getName().equals(newRuleSet2.getRuleSet().getName())) {
        ruleSetFound = true;
        break;
      }
    }
    Assert.assertTrue(ruleSetFound);

    for (IR4EUIModelElement elem : R4EUIModelController.getRootElement().getChildren()) {
      if (newRuleSet2Name.equals(elem.getName())) {
        newRuleSet2 = (R4EUIRuleSet) elem;
      }
    }
    fProxy.getCommandProxy().openElement(newRuleSet2);
    Assert.assertTrue(newRuleSet2.isOpen());
  }