/**
   * Fetches the CAS that the user will be able to edit. In AUTOMATION/CORRECTION mode, this is the
   * CAS for the CORRECTION_USER and in CURATION mode it is the CAS for the CURATION user.
   *
   * @param aBratAnnotatorModel the model.
   * @param aDocument the source document.
   * @param jCases the JCases.
   * @param randomAnnotationDocument an annotation document.
   * @return the JCas.
   * @throws UIMAException hum?
   * @throws ClassNotFoundException hum?
   * @throws IOException if an I/O error occurs.
   * @throws BratAnnotationException hum?
   */
  public JCas getMergeCas(
      BratAnnotatorModel aBratAnnotatorModel,
      SourceDocument aDocument,
      Map<String, JCas> jCases,
      AnnotationDocument randomAnnotationDocument)
      throws UIMAException, ClassNotFoundException, IOException, BratAnnotationException {
    JCas mergeJCas = null;
    try {
      if (aBratAnnotatorModel.getMode().equals(Mode.AUTOMATION)
          || aBratAnnotatorModel.getMode().equals(Mode.CORRECTION)) {
        // 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(aDocument, aBratAnnotatorModel.getMode(),
        // aBratAnnotatorModel.getUser().getUsername());
        mergeJCas = repository.readCorrectionCas(aDocument);
      } else {
        // 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(aDocument, aBratAnnotatorModel.getMode(),
        // aBratAnnotatorModel.getUser().getUsername());
        mergeJCas = repository.readCurationCas(aDocument);
      }
    }
    // Create jcas, if it could not be loaded from the file system
    catch (Exception e) {

      if (aBratAnnotatorModel.getMode().equals(Mode.AUTOMATION)
          || aBratAnnotatorModel.getMode().equals(Mode.CORRECTION)) {
        mergeJCas = createCorrectionCas(mergeJCas, aBratAnnotatorModel, randomAnnotationDocument);
      } else {
        mergeJCas =
            createCurationCas(
                aBratAnnotatorModel.getProject(),
                randomAnnotationDocument,
                jCases,
                aBratAnnotatorModel.getAnnotationLayers());
      }
    }
    return mergeJCas;
  }
  public static void savePreference(BratAnnotatorModel aBModel, RepositoryService aRepository)
      throws FileNotFoundException, IOException {
    AnnotationPreference preference = aBModel.getPreferences();
    ArrayList<Long> layers = new ArrayList<Long>();

    for (AnnotationLayer layer : aBModel.getAnnotationLayers()) {
      layers.add(layer.getId());
    }
    preference.setAnnotationLayers(layers);

    String username = SecurityContextHolder.getContext().getAuthentication().getName();
    aRepository.saveUserSettings(username, aBModel.getProject(), aBModel.getMode(), preference);
  }
  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;
  }