public List<ShelvedChangeList> importChangeLists(
     final Collection<VirtualFile> files, final Consumer<VcsException> exceptionConsumer) {
   final List<ShelvedChangeList> result = new ArrayList<ShelvedChangeList>(files.size());
   try {
     final FilesProgress filesProgress = new FilesProgress(files.size(), "Processing ");
     for (VirtualFile file : files) {
       filesProgress.updateIndicator(file);
       final String description = file.getNameWithoutExtension().replace('_', ' ');
       final File patchPath = getPatchPath(description);
       final ShelvedChangeList list =
           new ShelvedChangeList(
               patchPath.getPath(),
               description,
               new SmartList<ShelvedBinaryFile>(),
               file.getTimeStamp());
       try {
         final List<TextFilePatch> patchesList =
             loadPatches(myProject, file.getPath(), new CommitContext());
         if (!patchesList.isEmpty()) {
           FileUtil.copy(new File(file.getPath()), patchPath);
           // add only if ok to read patch
           myShelvedChangeLists.add(list);
           result.add(list);
         }
       } catch (IOException e) {
         exceptionConsumer.consume(new VcsException(e));
       } catch (PatchSyntaxException e) {
         exceptionConsumer.consume(new VcsException(e));
       }
     }
   } finally {
     notifyStateChanged();
   }
   return result;
 }
 private List<Change> convertPaths(List<Change> changesForPatch) throws VcsException {
   initAddOption();
   final List<Change> changes = new ArrayList<Change>();
   for (Change change : changesForPatch) {
     if (!isUnderOldDir(change, myOldFilePath)) continue;
     ContentRevision before = null;
     ContentRevision after = null;
     if (change.getBeforeRevision() != null) {
       before =
           new SimpleContentRevision(
               change.getBeforeRevision().getContent(),
               rebasePath(myOldFilePath, myNewFilePath, change.getBeforeRevision().getFile()),
               change.getBeforeRevision().getRevisionNumber().asString());
     }
     if (change.getAfterRevision() != null) {
       // if addition or move - do not move to the new path
       if (myAdd
           && (change.getBeforeRevision() == null || change.isMoved() || change.isRenamed())) {
         after = change.getAfterRevision();
       } else {
         after =
             new SimpleContentRevision(
                 change.getAfterRevision().getContent(),
                 rebasePath(myOldFilePath, myNewFilePath, change.getAfterRevision().getFile()),
                 change.getAfterRevision().getRevisionNumber().asString());
       }
     }
     changes.add(new Change(before, after));
   }
   return changes;
 }
 @Override
 public void run(ContinuationContext context) {
   final List<Change> changesForPatch;
   try {
     final List<CommittedChangeList> lst = loadSvnChangeListsForPatch(myDescription);
     changesForPatch = CommittedChangesTreeBrowser.collectChanges(lst, true);
     for (Change change : changesForPatch) {
       if (change.getBeforeRevision() != null) {
         preloadRevisionContents(change.getBeforeRevision());
       }
       if (change.getAfterRevision() != null) {
         preloadRevisionContents(change.getAfterRevision());
       }
     }
   } catch (VcsException e) {
     context.handleException(e, true);
     return;
   }
   final List<Change> binaryChanges = filterOutBinary(changesForPatch);
   if (binaryChanges != null && !binaryChanges.isEmpty()) {
     myTheirsBinaryChanges.addAll(binaryChanges);
   }
   if (!changesForPatch.isEmpty()) {
     myTheirsChanges.addAll(changesForPatch);
   }
 }
  private List<CommittedChangeList> loadSvnChangeListsForPatch(TreeConflictDescription description)
      throws VcsException {
    long max = description.getSourceRightVersion().getPegRevision();
    long min = description.getSourceLeftVersion().getPegRevision();

    final ChangeBrowserSettings settings = new ChangeBrowserSettings();
    settings.USE_CHANGE_BEFORE_FILTER = settings.USE_CHANGE_AFTER_FILTER = true;
    settings.CHANGE_BEFORE = "" + max;
    settings.CHANGE_AFTER = "" + min;
    final List<SvnChangeList> committedChanges =
        myVcs
            .getCachingCommittedChangesProvider()
            .getCommittedChanges(
                settings,
                new SvnRepositoryLocation(
                    description.getSourceRightVersion().getRepositoryRoot().toString()),
                0);
    final List<CommittedChangeList> lst =
        new ArrayList<CommittedChangeList>(committedChanges.size() - 1);
    for (SvnChangeList change : committedChanges) {
      if (change.getNumber() == min) {
        continue;
      }
      lst.add(change);
    }
    return lst;
  }
 public void deleteChangeList(final ShelvedChangeList changeList) {
   deleteListImpl(changeList);
   if (!changeList.isRecycled()) {
     myShelvedChangeLists.remove(changeList);
   } else {
     myRecycledShelvedChangeLists.remove(changeList);
   }
   notifyStateChanged();
 }
  public static void readExternal(
      final Element element,
      final List<ShelvedChangeList> changes,
      final List<ShelvedChangeList> recycled)
      throws InvalidDataException {
    changes.addAll(ShelvedChangeList.readChanges(element, false, true));

    recycled.addAll(ShelvedChangeList.readChanges(element, true, true));
  }
  public ShelvedChangeList shelveChanges(
      final Collection<Change> changes, final String commitMessage, final boolean rollback)
      throws IOException, VcsException {
    final List<Change> textChanges = new ArrayList<Change>();
    final List<ShelvedBinaryFile> binaryFiles = new ArrayList<ShelvedBinaryFile>();
    for (Change change : changes) {
      if (ChangesUtil.getFilePath(change).isDirectory()) {
        continue;
      }
      if (change.getBeforeRevision() instanceof BinaryContentRevision
          || change.getAfterRevision() instanceof BinaryContentRevision) {
        binaryFiles.add(shelveBinaryFile(change));
      } else {
        textChanges.add(change);
      }
    }

    final ShelvedChangeList changeList;
    try {
      File patchPath = getPatchPath(commitMessage);
      ProgressManager.checkCanceled();
      final List<FilePatch> patches =
          IdeaTextPatchBuilder.buildPatch(
              myProject, textChanges, myProject.getBaseDir().getPresentableUrl(), false);
      ProgressManager.checkCanceled();

      CommitContext commitContext = new CommitContext();
      baseRevisionsOfDvcsIntoContext(textChanges, commitContext);
      myFileProcessor.savePathFile(
          new CompoundShelfFileProcessor.ContentProvider() {
            public void writeContentTo(final Writer writer, CommitContext commitContext)
                throws IOException {
              UnifiedDiffWriter.write(myProject, patches, writer, "\n", commitContext);
            }
          },
          patchPath,
          commitContext);

      changeList =
          new ShelvedChangeList(
              patchPath.toString(), commitMessage.replace('\n', ' '), binaryFiles);
      myShelvedChangeLists.add(changeList);
      ProgressManager.checkCanceled();

      if (rollback) {
        new RollbackWorker(myProject, false)
            .doRollback(changes, true, null, VcsBundle.message("shelve.changes.action"));
      }
    } finally {
      notifyStateChanged();
    }

    return changeList;
  }
 private List<Change> filterOutBinary(List<Change> paths) {
   List<Change> result = null;
   for (Iterator<Change> iterator = paths.iterator(); iterator.hasNext(); ) {
     final Change change = iterator.next();
     if (ChangesUtil.isBinaryChange(change)) {
       result = (result == null ? new SmartList<Change>() : result);
       result.add(change);
       iterator.remove();
     }
   }
   return result;
 }
  private void recycleChangeList(
      final ShelvedChangeList listCopy, final ShelvedChangeList newList) {
    if (newList != null) {
      for (Iterator<ShelvedBinaryFile> shelvedChangeListIterator =
              listCopy.getBinaryFiles().iterator();
          shelvedChangeListIterator.hasNext(); ) {
        final ShelvedBinaryFile binaryFile = shelvedChangeListIterator.next();
        for (ShelvedBinaryFile newBinary : newList.getBinaryFiles()) {
          if (Comparing.equal(newBinary.BEFORE_PATH, binaryFile.BEFORE_PATH)
              && Comparing.equal(newBinary.AFTER_PATH, binaryFile.AFTER_PATH)) {
            shelvedChangeListIterator.remove();
          }
        }
      }
      for (Iterator<ShelvedChange> iterator = listCopy.getChanges(myProject).iterator();
          iterator.hasNext(); ) {
        final ShelvedChange change = iterator.next();
        for (ShelvedChange newChange : newList.getChanges(myProject)) {
          if (Comparing.equal(change.getBeforePath(), newChange.getBeforePath())
              && Comparing.equal(change.getAfterPath(), newChange.getAfterPath())) {
            iterator.remove();
          }
        }
      }

      // needed only if partial unshelve
      try {
        final CommitContext commitContext = new CommitContext();
        final List<FilePatch> patches = new ArrayList<FilePatch>();
        for (ShelvedChange change : listCopy.getChanges(myProject)) {
          patches.add(change.loadFilePatch(myProject, commitContext));
        }
        writePatchesToFile(myProject, listCopy.PATH, patches, commitContext);
      } catch (IOException e) {
        LOG.info(e);
        // left file as is
      } catch (PatchSyntaxException e) {
        LOG.info(e);
        // left file as is
      }
    }

    if ((!listCopy.getBinaryFiles().isEmpty()) || (!listCopy.getChanges(myProject).isEmpty())) {
      listCopy.setRecycled(true);
      myRecycledShelvedChangeLists.add(listCopy);
      notifyStateChanged();
    }
  }
  public ShelvedChangeList importFilePatches(
      final String fileName, final List<FilePatch> patches, final PatchEP[] patchTransitExtensions)
      throws IOException {
    try {
      final File patchPath = getPatchPath(fileName);
      myFileProcessor.savePathFile(
          new CompoundShelfFileProcessor.ContentProvider() {
            public void writeContentTo(final Writer writer, CommitContext commitContext)
                throws IOException {
              UnifiedDiffWriter.write(
                  myProject, patches, writer, "\n", patchTransitExtensions, commitContext);
            }
          },
          patchPath,
          new CommitContext());

      final ShelvedChangeList changeList =
          new ShelvedChangeList(
              patchPath.toString(),
              fileName.replace('\n', ' '),
              new SmartList<ShelvedBinaryFile>());
      myShelvedChangeLists.add(changeList);
      return changeList;
    } finally {
      notifyStateChanged();
    }
  }
 public void clearRecycled() {
   for (ShelvedChangeList list : myRecycledShelvedChangeLists) {
     deleteListImpl(list);
   }
   myRecycledShelvedChangeLists.clear();
   notifyStateChanged();
 }
 private static List<ShelvedBinaryFile> getBinaryFilesToUnshelve(
     final ShelvedChangeList changeList,
     final List<ShelvedBinaryFile> binaryFiles,
     final List<ShelvedBinaryFile> remainingBinaries) {
   if (binaryFiles == null) {
     return new ArrayList<ShelvedBinaryFile>(changeList.getBinaryFiles());
   }
   ArrayList<ShelvedBinaryFile> result = new ArrayList<ShelvedBinaryFile>();
   for (ShelvedBinaryFile file : changeList.getBinaryFiles()) {
     if (binaryFiles.contains(file)) {
       result.add(file);
     } else {
       remainingBinaries.add(file);
     }
   }
   return result;
 }
  public List<VirtualFile> gatherPatchFiles(final Collection<VirtualFile> files) {
    final List<VirtualFile> result = new ArrayList<VirtualFile>();

    final LinkedList<VirtualFile> filesQueue = new LinkedList<VirtualFile>(files);
    while (!filesQueue.isEmpty()) {
      ProgressManager.checkCanceled();
      final VirtualFile file = filesQueue.removeFirst();
      if (file.isDirectory()) {
        filesQueue.addAll(Arrays.asList(file.getChildren()));
        continue;
      }
      if (PatchFileType.NAME.equals(file.getFileType().getName())) {
        result.add(file);
      }
    }

    return result;
  }
 private static void readList(final List<Element> children, final List<ShelvedChangeList> sink)
     throws InvalidDataException {
   for (Element child : children) {
     ShelvedChangeList data = new ShelvedChangeList();
     data.readExternal(child);
     if (new File(data.PATH).exists()) {
       sink.add(data);
     }
   }
 }
 @NotNull
 public ApplyPatchStatus apply(
     final List<Pair<VirtualFile, ApplyFilePatchBase<ShelvedBinaryFilePatch>>> patches)
     throws IOException {
   for (Pair<VirtualFile, ApplyFilePatchBase<ShelvedBinaryFilePatch>> patch : patches) {
     final ShelvedBinaryFilePatch shelvedPatch = patch.getSecond().getPatch();
     unshelveBinaryFile(shelvedPatch.getShelvedBinaryFile(), patch.getFirst());
     myAppliedPatches.add(shelvedPatch);
   }
   return ApplyPatchStatus.SUCCESS;
 }
 @Override
 public void run(ContinuationContext context) {
   if (myTheirsBinaryChanges.isEmpty()) return;
   final List<Change> converted;
   try {
     converted = convertPaths(myTheirsBinaryChanges);
   } catch (VcsException e) {
     context.handleException(e, true);
     return;
   }
   if (converted.isEmpty()) return;
   final Map<FilePath, Change> map = new HashMap<FilePath, Change>();
   for (Change change : converted) {
     map.put(ChangesUtil.getFilePath(change), change);
   }
   final Collection<FilePath> selected = chooseBinaryFiles(converted, map.keySet());
   myTheirsBinaryChanges.clear();
   for (FilePath filePath : selected) {
     myTheirsBinaryChanges.add(map.get(filePath));
   }
 }
  private static List<TextFilePatch> loadTextPatches(
      final Project project,
      final ShelvedChangeList changeList,
      final List<ShelvedChange> changes,
      final List<FilePatch> remainingPatches,
      final CommitContext commitContext)
      throws IOException, PatchSyntaxException {
    final List<TextFilePatch> textFilePatches;
    textFilePatches = loadPatches(project, changeList.PATH, commitContext);

    if (changes != null) {
      final Iterator<TextFilePatch> iterator = textFilePatches.iterator();
      while (iterator.hasNext()) {
        TextFilePatch patch = iterator.next();
        if (!needUnshelve(patch, changes)) {
          remainingPatches.add(patch);
          iterator.remove();
        }
      }
    }
    return textFilePatches;
  }
  public void execute() {
    int ok =
        Messages.showOkCancelDialog(
            myVcs.getProject(),
            (myChange.isMoved()
                ? SvnBundle.message(
                    "confirmation.resolve.tree.conflict.merge.moved",
                    myOldPresentation,
                    myNewPresentation)
                : SvnBundle.message(
                    "confirmation.resolve.tree.conflict.merge.renamed",
                    myOldPresentation,
                    myNewPresentation)),
            TreeConflictRefreshablePanel.TITLE,
            Messages.getQuestionIcon());
    if (Messages.OK != ok) return;

    FileDocumentManager.getInstance().saveAllDocuments();
    // final String name = "Merge changes from theirs for: " + myOldPresentation;

    final Continuation fragmented = Continuation.createFragmented(myVcs.getProject(), false);
    fragmented.addExceptionHandler(
        VcsException.class,
        new Consumer<VcsException>() {
          @Override
          public void consume(VcsException e) {
            myWarnings.add(e);
            if (e.isWarning()) {
              return;
            }
            AbstractVcsHelper.getInstance(myVcs.getProject())
                .showErrors(myWarnings, TreeConflictRefreshablePanel.TITLE);
          }
        });

    final List<TaskDescriptor> tasks = new SmartList<TaskDescriptor>();
    tasks.add(
        myDescription.isDirectory()
            ? new PreloadChangesContentsForDir()
            : new PreloadChangesContentsForFile());
    tasks.add(new ConvertTextPaths());
    tasks.add(new PatchCreator());
    tasks.add(new SelectPatchesInApplyPatchDialog());
    tasks.add(new SelectBinaryFiles());

    fragmented.run(tasks);
  }
  private Collection<FilePath> chooseBinaryFiles(List<Change> converted, Set<FilePath> paths) {
    String singleMessage = "";
    if (paths.size() == 1) {
      final Change change = converted.get(0);
      final FileStatus status = change.getFileStatus();
      final FilePath path = ChangesUtil.getFilePath(change);
      final String stringPath = TreeConflictRefreshablePanel.filePath(path);
      if (FileStatus.DELETED.equals(status)) {
        singleMessage = "Delete binary file " + stringPath + " (according to theirs changes)?";
      } else if (FileStatus.ADDED.equals(status)) {
        singleMessage = "Create binary file " + stringPath + " (according to theirs changes)?";
      } else {
        singleMessage =
            "Apply changes to binary file " + stringPath + " (according to theirs changes)?";
      }
    }
    return AbstractVcsHelper.getInstance(myVcs.getProject())
        .selectFilePathsToProcess(
            new ArrayList<FilePath>(paths),
            TreeConflictRefreshablePanel.TITLE,
            "Select binary files to patch",
            TreeConflictRefreshablePanel.TITLE,
            singleMessage,
            new VcsShowConfirmationOption() {

              @Override
              public Value getValue() {
                return null;
              }

              @Override
              public void setValue(Value value) {}

              @Override
              public boolean isPersistent() {
                return false;
              }
            });
  }
 private void recycleChangeList(final ShelvedChangeList changeList) {
   recycleChangeList(changeList, null);
   myShelvedChangeLists.remove(changeList);
   notifyStateChanged();
 }
 public void restoreList(final ShelvedChangeList changeList) {
   myShelvedChangeLists.add(changeList);
   myRecycledShelvedChangeLists.remove(changeList);
   changeList.setRecycled(false);
   notifyStateChanged();
 }