public Map<String, JCas> listJcasesforCuration(
      List<AnnotationDocument> annotationDocuments,
      AnnotationDocument randomAnnotationDocument,
      Mode aMode)
      throws UIMAException, ClassNotFoundException, IOException {
    Map<String, JCas> jCases = new HashMap<String, JCas>();
    for (AnnotationDocument annotationDocument : annotationDocuments) {
      String username = annotationDocument.getUser();

      if (!annotationDocument.getState().equals(AnnotationDocumentState.FINISHED)) {
        continue;
      }

      if (randomAnnotationDocument == null) {
        randomAnnotationDocument = annotationDocument;
      }

      // Upgrading should be an explicit action during the opening of a document at the end
      // of the open dialog - it must not happen during editing because the CAS addresses
      // are used as IDs in the UI
      // repository.upgradeCasAndSave(annotationDocument.getDocument(), aMode, username);
      JCas jCas = repository.readAnnotationCas(annotationDocument);
      jCases.put(username, jCas);
    }
    return jCases;
  }
 private JCas createCorrectionCas(
     JCas mergeJCas,
     BratAnnotatorModel aBratAnnotatorModel,
     AnnotationDocument randomAnnotationDocument)
     throws UIMAException, ClassNotFoundException, IOException {
   User userLoggedIn =
       userRepository.get(SecurityContextHolder.getContext().getAuthentication().getName());
   mergeJCas = repository.readAnnotationCas(aBratAnnotatorModel.getDocument(), userLoggedIn);
   repository.writeCorrectionCas(mergeJCas, randomAnnotationDocument.getDocument(), userLoggedIn);
   return mergeJCas;
 }
  private void addJCas(List<JCas> jCases, User user, SourceDocument sourceDocument) {
    try {
      // Check if there is an annotation document entry in the database. If there is none,
      // create one.
      AnnotationDocument annotationDocument =
          repository.createOrGetAnnotationDocument(sourceDocument, user);

      // Read the CAS
      JCas jcas = repository.readAnnotationCas(annotationDocument);

      // Update the annotation document CAS
      repository.upgradeCas(jcas.getCas(), annotationDocument);

      // After creating an new CAS or upgrading the CAS, we need to save it
      repository.writeAnnotationCas(
          jcas.getCas().getJCas(), annotationDocument.getDocument(), user);

      jCases.add(jcas);
    } catch (UIMAException e) {
      error(e.getMessage() + " : " + ExceptionUtils.getRootCauseMessage(e));
    } catch (IOException e) {
      error(e.getMessage());
    }
  }
  /**
   * For the first time a curation page is opened, create a MergeCas that contains only agreeing
   * annotations Using the CAS of the curator user.
   *
   * @param aProject the project
   * @param randomAnnotationDocument an annotation document.
   * @param jCases the JCases
   * @param aAnnotationLayers the layers.
   * @return the JCas.
   * @throws IOException if an I/O error occurs.
   */
  public JCas createCurationCas(
      Project aProject,
      AnnotationDocument randomAnnotationDocument,
      Map<String, JCas> jCases,
      List<AnnotationLayer> aAnnotationLayers)
      throws IOException {
    User userLoggedIn =
        userRepository.get(SecurityContextHolder.getContext().getAuthentication().getName());

    JCas mergeJCas = repository.readAnnotationCas(randomAnnotationDocument);
    jCases.put(CurationPanel.CURATION_USER, mergeJCas);

    List<Type> entryTypes = getEntryTypes(mergeJCas, aAnnotationLayers, annotationService);

    DiffResult diff =
        CasDiff2.doDiffSingle(
            annotationService,
            aProject,
            entryTypes,
            jCases,
            0,
            mergeJCas.getDocumentText().length());

    for (Entry<Position, ConfigurationSet> diffEntry :
        diff.getDifferingConfigurationSets().entrySet()) {
      // Remove FSes with differences from the merge CAS
      List<Configuration> cfgsForCurationUser =
          diffEntry.getValue().getConfigurations(CurationPanel.CURATION_USER);
      for (Configuration cfg : cfgsForCurationUser) {
        FeatureStructure fs = cfg.getFs(CurationPanel.CURATION_USER, jCases);
        mergeJCas.removeFsFromIndexes(fs);
      }
    }

    repository.writeCurationCas(mergeJCas, randomAnnotationDocument.getDocument(), userLoggedIn);
    return mergeJCas;
  }
  public CurationContainer buildCurationContainer(BratAnnotatorModel aBModel)
      throws UIMAException, ClassNotFoundException, IOException, BratAnnotationException {
    CurationContainer curationContainer = new CurationContainer();
    // initialize Variables
    SourceDocument sourceDocument = aBModel.getDocument();
    Map<Integer, Integer> segmentBeginEnd = new HashMap<Integer, Integer>();
    Map<Integer, Integer> segmentNumber = new HashMap<Integer, Integer>();
    Map<String, Map<Integer, Integer>> segmentAdress = new HashMap<String, Map<Integer, Integer>>();
    // get annotation documents

    List<AnnotationDocument> finishedAnnotationDocuments = new ArrayList<AnnotationDocument>();

    for (AnnotationDocument annotationDocument :
        repository.listAnnotationDocuments(aBModel.getDocument())) {
      if (annotationDocument.getState().equals(AnnotationDocumentState.FINISHED)) {
        finishedAnnotationDocuments.add(annotationDocument);
      }
    }

    Map<String, JCas> jCases = new HashMap<String, JCas>();

    AnnotationDocument randomAnnotationDocument = null;
    JCas mergeJCas;

    // get the correction/automation JCas for the logged in user
    if (aBModel.getMode().equals(Mode.AUTOMATION) || aBModel.getMode().equals(Mode.CORRECTION)) {
      jCases = listJcasesforCorrection(randomAnnotationDocument, sourceDocument, aBModel.getMode());
      mergeJCas = getMergeCas(aBModel, sourceDocument, jCases, randomAnnotationDocument);
      String username = jCases.keySet().iterator().next();
      updateSegment(
          aBModel,
          segmentBeginEnd,
          segmentNumber,
          segmentAdress,
          jCases.get(username),
          username,
          aBModel.getPreferences().getWindowSize());

    } else {

      jCases =
          listJcasesforCuration(
              finishedAnnotationDocuments, randomAnnotationDocument, aBModel.getMode());
      mergeJCas = getMergeCas(aBModel, sourceDocument, jCases, randomAnnotationDocument);
      updateSegment(
          aBModel,
          segmentBeginEnd,
          segmentNumber,
          segmentAdress,
          mergeJCas,
          CurationPanel.CURATION_USER,
          aBModel.getPreferences().getCurationWindowSize());
    }

    List<Type> entryTypes = null;

    segmentAdress.put(CurationPanel.CURATION_USER, new HashMap<Integer, Integer>());
    for (Sentence sentence : selectCovered(mergeJCas, Sentence.class, begin, end)) {
      segmentAdress.get(CurationPanel.CURATION_USER).put(sentence.getBegin(), getAddr(sentence));
    }

    if (entryTypes == null) {
      entryTypes = getEntryTypes(mergeJCas, aBModel.getAnnotationLayers(), annotationService);
    }

    // for cross-sentences annotation, update the end of the segment
    if (firstload) {
      updateCrossSentAnnoList(segmentBeginEnd, jCases, entryTypes);
      firstload = false;
    }

    for (Integer begin : segmentBeginEnd.keySet()) {
      Integer end = segmentBeginEnd.get(begin);

      DiffResult diff =
          CasDiff2.doDiffSingle(
              annotationService, aBModel.getProject(), entryTypes, jCases, begin, end);
      SourceListView curationSegment = new SourceListView();
      curationSegment.setBegin(begin);
      curationSegment.setEnd(end);
      if (diff.hasDifferences() || !diff.getIncompleteConfigurationSets().isEmpty()) {
        curationSegment.setSentenceState(SentenceState.DISAGREE);
      } else {
        curationSegment.setSentenceState(SentenceState.AGREE);
      }
      curationSegment.setSentenceNumber(segmentNumber.get(begin));

      for (String username : segmentAdress.keySet()) {
        curationSegment.getSentenceAddress().put(username, segmentAdress.get(username).get(begin));
      }
      curationContainer.getCurationViewByBegin().put(begin, curationSegment);
    }
    return curationContainer;
  }