private void showConflictedChunks(SVNMergeFileSet files) throws SVNException {
    byte[] conflictStartMarker = "<<<<<<< MINE (select with 'mc')".getBytes();
    byte[] conflictSeparator = "=======".getBytes();
    byte[] conflictEndMarker = ">>>>>>> THEIRS (select with 'tc')".getBytes();
    byte[] conflictOriginalMarker = "||||||| ORIGINAL".getBytes();

    SVNDiffOptions options = new SVNDiffOptions(false, false, true);
    FSMergerBySequence merger =
        new FSMergerBySequence(
            conflictStartMarker, conflictSeparator, conflictEndMarker, conflictOriginalMarker);
    RandomAccessFile localIS = null;
    RandomAccessFile latestIS = null;
    RandomAccessFile baseIS = null;
    try {
      localIS = new RandomAccessFile(files.getWCFile(), "r");
      latestIS = new RandomAccessFile(files.getRepositoryFile(), "r");
      baseIS = new RandomAccessFile(files.getBaseFile(), "r");

      QSequenceLineRAData baseData = new QSequenceLineRAFileData(baseIS);
      QSequenceLineRAData localData = new QSequenceLineRAFileData(localIS);
      QSequenceLineRAData latestData = new QSequenceLineRAFileData(latestIS);
      merger.merge(
          baseData,
          localData,
          latestData,
          options,
          mySVNEnvironment.getOut(),
          SVNDiffConflictChoiceStyle.CHOOSE_ONLY_CONFLICTS);
    } catch (IOException e) {
      SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e.getLocalizedMessage());
      SVNErrorManager.error(err, e, SVNLogType.WC);
    } finally {
      SVNFileUtil.closeFile(localIS);
      SVNFileUtil.closeFile(baseIS);
      SVNFileUtil.closeFile(latestIS);
    }
  }
  public SVNConflictResult handleConflictNoStats(SVNConflictDescription conflictDescription)
      throws SVNException {
    if (conflictDescription.isTreeConflict()) {
      return null;
    }

    SVNMergeFileSet files = conflictDescription.getMergeFiles();
    if (myAccept == SVNConflictAcceptPolicy.POSTPONE) {
      return new SVNConflictResult(SVNConflictChoice.POSTPONE, null);
    } else if (myAccept == SVNConflictAcceptPolicy.BASE) {
      return new SVNConflictResult(SVNConflictChoice.BASE, null);
    } else if (myAccept == SVNConflictAcceptPolicy.WORKING) {
      return new SVNConflictResult(SVNConflictChoice.MERGED, null);
    } else if (myAccept == SVNConflictAcceptPolicy.MINE_CONFLICT) {
      return new SVNConflictResult(SVNConflictChoice.MINE_CONFLICT, null);
    } else if (myAccept == SVNConflictAcceptPolicy.THEIRS_CONFLICT) {
      return new SVNConflictResult(SVNConflictChoice.THEIRS_CONFLICT, null);
    } else if (myAccept == SVNConflictAcceptPolicy.MINE_FULL) {
      return new SVNConflictResult(SVNConflictChoice.MINE_FULL, null);
    } else if (myAccept == SVNConflictAcceptPolicy.THEIRS_FULL) {
      return new SVNConflictResult(SVNConflictChoice.THEIRS_FULL, null);
    } else if (myAccept == SVNConflictAcceptPolicy.EDIT) {
      if (files.getResultFile() != null) {
        if (myIsExternalFailed) {
          return new SVNConflictResult(SVNConflictChoice.POSTPONE, null);
        }

        try {
          SVNCommandUtil.editFileExternally(
              mySVNEnvironment,
              mySVNEnvironment.getEditorCommand(),
              files.getResultFile().getAbsolutePath());
        } catch (SVNException svne) {
          if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.CL_NO_EXTERNAL_EDITOR) {
            mySVNEnvironment
                .getErr()
                .println(
                    svne.getErrorMessage().getMessage() != null
                        ? svne.getErrorMessage().getMessage()
                        : "No editor found, leaving all conflicts.");
            myIsExternalFailed = true;
          } else if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.EXTERNAL_PROGRAM) {
            String message =
                svne.getErrorMessage().getMessageTemplate() != null
                    ? svne.getErrorMessage().getMessage()
                    : "Error running editor, leaving all conflicts.";
            if (message.startsWith("svn: ")) {
              // hack: use the original message template without any prefixes (like 'svn:',
              // 'svn:warning')
              // added to make update test 42 pass
              message = message.substring("svn: ".length());
            }
            mySVNEnvironment.getErr().println(message);
            myIsExternalFailed = true;
          } else {
            throw svne;
          }
        }
        return new SVNConflictResult(SVNConflictChoice.MERGED, null);
      }
    } else if (myAccept == SVNConflictAcceptPolicy.LAUNCH) {
      if (files.getBaseFile() != null
          && files.getLocalFile() != null
          && files.getRepositoryFile() != null
          && files.getResultFile() != null) {
        if (myIsExternalFailed) {
          return new SVNConflictResult(SVNConflictChoice.POSTPONE, null);
        }

        boolean[] remainsInConflict = {false};
        try {
          SVNCommandUtil.mergeFileExternally(
              mySVNEnvironment,
              files.getBaseFile().getAbsolutePath(),
              files.getRepositoryFile().getAbsolutePath(),
              files.getLocalFile().getAbsolutePath(),
              files.getResultFile().getAbsolutePath(),
              files.getWCPath(),
              remainsInConflict);
        } catch (SVNException svne) {
          if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.CL_NO_EXTERNAL_MERGE_TOOL) {
            mySVNEnvironment
                .getErr()
                .println(
                    svne.getErrorMessage().getMessage() != null
                        ? svne.getErrorMessage().getMessage()
                        : "No merge tool found.");
            myIsExternalFailed = true;
          } else if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.EXTERNAL_PROGRAM) {
            mySVNEnvironment
                .getErr()
                .println(
                    svne.getErrorMessage().getMessage() != null
                        ? svne.getErrorMessage().getMessage()
                        : "Error running merge tool.");
            myIsExternalFailed = true;
          }
          throw svne;
        }

        if (remainsInConflict[0]) {
          return new SVNConflictResult(SVNConflictChoice.POSTPONE, null);
        }

        return new SVNConflictResult(SVNConflictChoice.MERGED, null);
      }
    }

    boolean saveMerged = false;
    SVNConflictChoice choice = SVNConflictChoice.POSTPONE;
    if ((conflictDescription.getNodeKind() == SVNNodeKind.FILE
            && conflictDescription.getConflictAction() == SVNConflictAction.EDIT
            && conflictDescription.getConflictReason() == SVNConflictReason.EDITED)
        || conflictDescription.isPropertyConflict()) {

      boolean performedEdit = false;
      boolean diffAllowed = false;
      boolean knowsSmth = false;
      String path = mySVNEnvironment.getRelativePath(files.getWCFile());
      path = SVNCommandUtil.getLocalPath(path);

      if (conflictDescription.isPropertyConflict()) {
        String message = "Conflict for property ''{0}'' discovered on ''{1}''.";
        message =
            MessageFormat.format(
                message, new Object[] {conflictDescription.getPropertyName(), path});
        mySVNEnvironment.getErr().println(message);

        if ((files.getLocalFile() == null && files.getRepositoryFile() != null)
            || (files.getLocalFile() != null && files.getRepositoryFile() == null)) {
          if (files.getLocalFile() != null) {
            String myVal = SVNFileUtil.readFile(files.getLocalFile());
            message =
                MessageFormat.format(
                    "They want to delete the property, you want to change the value to ''{0}''.",
                    new Object[] {myVal});
            mySVNEnvironment.getErr().println(message);
          } else {
            String reposVal = SVNFileUtil.readFile(files.getRepositoryFile());
            message =
                MessageFormat.format(
                    "They want to change the property value to ''{0}'', you want to delete the property.",
                    new Object[] {reposVal});
            mySVNEnvironment.getErr().println(message);
          }
        }
      } else {
        String message = "Conflict discovered in ''{0}''.";
        message = MessageFormat.format(message, new Object[] {path});
        mySVNEnvironment.getErr().println(message);
      }

      if ((files.getResultFile() != null && files.getBaseFile() != null)
          || (files.getBaseFile() != null
              && files.getLocalFile() != null
              && files.getRepositoryFile() != null)) {
        diffAllowed = true;
      }

      while (true) {
        String message = "Select: (p) postpone";
        if (diffAllowed) {
          message += ", (df) diff-full, (e) edit";

          if (knowsSmth) {
            message += ", (r) resolved";
          }

          if (!files.isBinary() && !conflictDescription.isPropertyConflict()) {
            message += ",\n        (mc) mine-conflict, (tc) theirs-conflict";
          }
        } else {
          if (knowsSmth) {
            message += ", (r) resolved";
          }
          message += ",\n        (mf) mine-full, (tf) theirs-full";
        }

        message += ",\n        (s) show all options: ";

        String answer = SVNCommandUtil.prompt(message, mySVNEnvironment);

        if ("s".equals(answer)) {
          mySVNEnvironment.getErr().println();
          mySVNEnvironment
              .getErr()
              .println("  (e)  edit             - change merged file in an editor");
          mySVNEnvironment
              .getErr()
              .println("  (df) diff-full        - show all changes made to merged file");
          mySVNEnvironment
              .getErr()
              .println("  (r)  resolved         - accept merged version of file");
          mySVNEnvironment.getErr().println();
          mySVNEnvironment
              .getErr()
              .println("  (dc) display-conflict - show all conflicts (ignoring merged version)");
          mySVNEnvironment
              .getErr()
              .println("  (mc) mine-conflict    - accept my version for all conflicts (same)");
          mySVNEnvironment
              .getErr()
              .println("  (tc) theirs-conflict  - accept their version for all conflicts (same)");
          mySVNEnvironment.getErr().println();
          mySVNEnvironment
              .getErr()
              .println(
                  "  (mf) mine-full        - accept my version of entire file (even non-conflicts)");
          mySVNEnvironment
              .getErr()
              .println("  (tf) theirs-full      - accept their version of entire file (same)");
          mySVNEnvironment.getErr().println();
          mySVNEnvironment
              .getErr()
              .println("  (p)  postpone         - mark the conflict to be resolved later");
          mySVNEnvironment
              .getErr()
              .println("  (l)  launch           - launch external tool to resolve conflict");
          mySVNEnvironment.getErr().println("  (s)  show all         - show this list");
          mySVNEnvironment.getErr().println();
        } else if ("p".equals(answer)) {
          choice = SVNConflictChoice.POSTPONE;
          break;
        } else if ("mc".equals(answer)) {
          if (files.isBinary()) {
            mySVNEnvironment
                .getErr()
                .println("Invalid option; cannot choose based on conflicts in a binary file.");
            mySVNEnvironment.getErr().println();
            continue;
          } else if (conflictDescription.isPropertyConflict()) {
            mySVNEnvironment
                .getErr()
                .println("Invalid option; cannot choose based on conflicts for properties.");
            mySVNEnvironment.getErr().println();
            continue;
          }
          choice = SVNConflictChoice.MINE_CONFLICT;
          if (performedEdit) {
            saveMerged = true;
          }
          break;
        } else if ("tc".equals(answer)) {
          if (files.isBinary()) {
            mySVNEnvironment
                .getErr()
                .println("Invalid option; cannot choose based on conflicts in a binary file.");
            mySVNEnvironment.getErr().println();
            continue;
          } else if (conflictDescription.isPropertyConflict()) {
            mySVNEnvironment
                .getErr()
                .println("Invalid option; cannot choose based on conflicts for properties.");
            mySVNEnvironment.getErr().println();
            continue;
          }
          choice = SVNConflictChoice.THEIRS_CONFLICT;
          if (performedEdit) {
            saveMerged = true;
          }
          break;
        } else if ("mf".equals(answer)) {
          choice = SVNConflictChoice.MINE_FULL;
          if (performedEdit) {
            saveMerged = true;
          }
          break;
        } else if ("tf".equals(answer)) {
          choice = SVNConflictChoice.THEIRS_FULL;
          if (performedEdit) {
            saveMerged = true;
          }
          break;
        } else if ("dc".equals(answer)) {
          if (files.isBinary()) {
            mySVNEnvironment
                .getErr()
                .println("Invalid option; cannot display conflicts for a binary file.");
            mySVNEnvironment.getErr().println();
            continue;
          } else if (conflictDescription.isPropertyConflict()) {
            mySVNEnvironment
                .getErr()
                .println("Invalid option; cannot display conflicts for properties.");
            mySVNEnvironment.getErr().println();
            continue;
          } else if (files.getLocalFile() == null
              || files.getBaseFile() == null
              || files.getRepositoryFile() == null) {
            mySVNEnvironment.getErr().println("Invalid option; original files not available.");
            mySVNEnvironment.getErr().println();
            continue;
          }

          // TODO: re-implement in future
          showConflictedChunks(files);
          knowsSmth = true;
          continue;
        } else if ("df".equals(answer)) {
          if (!diffAllowed) {
            mySVNEnvironment.getErr().println("Invalid option; there's no merged version to diff.");
            mySVNEnvironment.getErr().println();
            continue;
          }

          File path1 = null;
          File path2 = null;
          if (files.getResultFile() != null && files.getBaseFile() != null) {
            path1 = files.getBaseFile();
            path2 = files.getResultFile();
          } else {
            path1 = files.getRepositoryFile();
            path2 = files.getLocalFile();
          }

          DefaultSVNCommandLineDiffGenerator diffGenerator =
              new DefaultSVNCommandLineDiffGenerator(path1, path2);
          diffGenerator.setDiffOptions(new SVNDiffOptions(false, false, true));
          diffGenerator.displayFileDiff("", path1, path2, null, null, null, null, System.out);
          knowsSmth = true;
        } else if ("e".equals(answer)) {
          if (files.getResultFile() != null) {
            try {
              String resultPath = files.getResultFile().getAbsolutePath();
              SVNCommandUtil.editFileExternally(
                  mySVNEnvironment, mySVNEnvironment.getEditorCommand(), resultPath);
              performedEdit = true;
            } catch (SVNException svne) {
              if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.CL_NO_EXTERNAL_EDITOR) {
                mySVNEnvironment
                    .getErr()
                    .println(
                        svne.getErrorMessage().getMessage() != null
                            ? svne.getErrorMessage().getMessage()
                            : "No editor found.");
              } else if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.EXTERNAL_PROGRAM) {
                mySVNEnvironment
                    .getErr()
                    .println(
                        svne.getErrorMessage().getMessage() != null
                            ? svne.getErrorMessage().getMessage()
                            : "Error running editor.");
              } else {
                throw svne;
              }
            }
          } else {
            mySVNEnvironment.getErr().println("Invalid option; there's no merged version to edit.");
            mySVNEnvironment.getErr().println();
          }
          if (performedEdit) {
            knowsSmth = true;
          }
        } else if ("l".equals(answer)) {
          if (files.getBaseFile() != null
              && files.getLocalFile() != null
              && files.getRepositoryFile() != null
              && files.getResultFile() != null) {
            try {
              SVNCommandUtil.mergeFileExternally(
                  mySVNEnvironment,
                  files.getBasePath(),
                  files.getRepositoryPath(),
                  files.getLocalPath(),
                  files.getResultPath(),
                  files.getWCPath(),
                  null);
              performedEdit = true;
            } catch (SVNException svne) {
              if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.CL_NO_EXTERNAL_MERGE_TOOL) {
                mySVNEnvironment
                    .getErr()
                    .println(
                        svne.getErrorMessage().getMessage() != null
                            ? svne.getErrorMessage().getMessage()
                            : "No merge tool found.");
                myIsExternalFailed = true;
              } else if (svne.getErrorMessage().getErrorCode() == SVNErrorCode.EXTERNAL_PROGRAM) {
                mySVNEnvironment
                    .getErr()
                    .println(
                        svne.getErrorMessage().getMessage() != null
                            ? svne.getErrorMessage().getMessage()
                            : "Error running merge tool.");
                myIsExternalFailed = true;
              } else {
                throw svne;
              }
            }
          } else {
            mySVNEnvironment.getErr().println("Invalid option.");
            mySVNEnvironment.getErr().println();
          }
        } else if ("r".equals(answer)) {
          if (knowsSmth) {
            choice = SVNConflictChoice.MERGED;
            break;
          }
          mySVNEnvironment.getErr().println("Invalid option.");
          mySVNEnvironment.getErr().println();
        }
      }
    } else if (conflictDescription.getConflictAction() == SVNConflictAction.ADD
        && conflictDescription.getConflictReason() == SVNConflictReason.OBSTRUCTED) {
      String message = "Conflict discovered when trying to add ''{0}''.";
      message = MessageFormat.format(message, new Object[] {files.getWCFile()});
      mySVNEnvironment.getErr().println(message);
      mySVNEnvironment.getErr().println("An object of the same name already exists.");

      String prompt = "Select: (p) postpone, (mf) mine-full, (tf) theirs-full, (h) help:";
      while (true) {
        String answer = SVNCommandUtil.prompt(prompt, mySVNEnvironment);

        if ("h".equals(answer) || "?".equals(answer)) {
          mySVNEnvironment.getErr().println("  (p)  postpone    - resolve the conflict later");
          mySVNEnvironment
              .getErr()
              .println("  (mf) mine-full   - accept pre-existing item (ignore upstream addition)");
          mySVNEnvironment
              .getErr()
              .println("  (tf) theirs-full - accept incoming item (overwrite pre-existing item)");
          mySVNEnvironment.getErr().println("  (h)  help        - show this help");
          mySVNEnvironment.getErr().println();
        }

        if ("p".equals(answer)) {
          choice = SVNConflictChoice.POSTPONE;
          break;
        }
        if ("mf".equals(answer)) {
          choice = SVNConflictChoice.MINE_FULL;
          break;
        }
        if ("tf".equals(answer)) {
          choice = SVNConflictChoice.THEIRS_FULL;
          break;
        }
      }
    } else {
      choice = SVNConflictChoice.POSTPONE;
    }

    return new SVNConflictResult(choice, null, saveMerged);
  }
 private SVNConflictStats getConflictStats() {
   return mySVNEnvironment.getConflictStats();
 }