/*
 * conflicts.c:  conflict resolver implementation
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

/* ==================================================================== */



/*** Includes. ***/

#include "svn_types.h"
#include "svn_wc.h"
#include "svn_client.h"
#include "svn_error.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_pools.h"
#include "svn_props.h"
#include "svn_hash.h"
#include "svn_sorts.h"
#include "client.h"
#include "private/svn_sorts_private.h"
#include "private/svn_token.h"
#include "private/svn_wc_private.h"

#include "svn_private_config.h"

#define ARRAY_LEN(ary) ((sizeof (ary)) / (sizeof ((ary)[0])))


/*** Dealing with conflicts. ***/

/* Describe a tree conflict. */
typedef svn_error_t *(*tree_conflict_get_description_func_t)(
  const char **change_description,
  svn_client_conflict_t *conflict,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool);

/* Get more information about a tree conflict.
 * This function may contact the repository. */
typedef svn_error_t *(*tree_conflict_get_details_func_t)(
  svn_client_conflict_t *conflict,
  apr_pool_t *scratch_pool);

struct svn_client_conflict_t
{
  const char *local_abspath;
  svn_client_ctx_t *ctx;
  apr_hash_t *prop_conflicts;

  /* Indicate which options were chosen to resolve a text or tree conflict
   * on the conflited node. */
  svn_client_conflict_option_id_t resolution_text;
  svn_client_conflict_option_id_t resolution_tree;

  /* A mapping from const char* property name to pointers to
   * svn_client_conflict_option_t for all properties which had their
   * conflicts resolved. Indicates which options were chosen to resolve
   * the property conflicts. */
  apr_hash_t *resolved_props;

  /* Ask a tree conflict to describe itself. */
  tree_conflict_get_description_func_t
    tree_conflict_get_incoming_description_func;
  tree_conflict_get_description_func_t
    tree_conflict_get_local_description_func;

  /* Ask a tree conflict to find out more information about itself
   * by contacting the repository. */
  tree_conflict_get_details_func_t tree_conflict_get_incoming_details_func;
  tree_conflict_get_details_func_t tree_conflict_get_local_details_func;

  /* Any additional information found can be stored here and may be used
   * when describing a tree conflict. */
  void *tree_conflict_incoming_details;
  void *tree_conflict_local_details;

  /* The pool this conflict was allocated from. */
  apr_pool_t *pool;

  /* Conflict data provided by libsvn_wc. */
  const svn_wc_conflict_description2_t *legacy_text_conflict;
  const char *legacy_prop_conflict_propname;
  const svn_wc_conflict_description2_t *legacy_tree_conflict;
};

/* Resolves conflict to OPTION and sets CONFLICT->RESOLUTION accordingly.
 *
 * May raise an error in case the conflict could not be resolved. A common
 * case would be a tree conflict the resolution of which depends on other
 * tree conflicts to be resolved first. */
typedef svn_error_t *(*conflict_option_resolve_func_t)(
  svn_client_conflict_option_t *option,
  svn_client_conflict_t *conflict,
  apr_pool_t *scratch_pool);

struct svn_client_conflict_option_t
{
  svn_client_conflict_option_id_t id;
  const char *description;

  svn_client_conflict_t *conflict;
  conflict_option_resolve_func_t do_resolve_func;

  /* The pool this option was allocated from. */
  apr_pool_t *pool;

  /* Data which is specific to particular conflicts and options. */
  union {
    struct {
      /* Indicates the property to resolve in case of a property conflict.
       * If set to "", all properties are resolved to this option. */
      const char *propname;

      /* A merged property value, if supplied by the API user, else NULL. */
      const svn_string_t *merged_propval;
    } prop;
  } type_data;

};

/*
 * Return a legacy conflict choice corresponding to OPTION_ID.
 * Return svn_wc_conflict_choose_undefined if no corresponding
 * legacy conflict choice exists.
 */
static svn_wc_conflict_choice_t
conflict_option_id_to_wc_conflict_choice(
  svn_client_conflict_option_id_t option_id)
{

  switch (option_id)
    {
      case svn_client_conflict_option_undefined:
        return svn_wc_conflict_choose_undefined;

      case svn_client_conflict_option_postpone:
        return svn_wc_conflict_choose_postpone;

      case svn_client_conflict_option_base_text:
        return svn_wc_conflict_choose_base;

      case svn_client_conflict_option_incoming_text:
        return svn_wc_conflict_choose_theirs_full;

      case svn_client_conflict_option_working_text:
        return svn_wc_conflict_choose_mine_full;

      case svn_client_conflict_option_incoming_text_where_conflicted:
        return svn_wc_conflict_choose_theirs_conflict;

      case svn_client_conflict_option_working_text_where_conflicted:
        return svn_wc_conflict_choose_mine_conflict;

      case svn_client_conflict_option_merged_text:
        return svn_wc_conflict_choose_merged;

      case svn_client_conflict_option_unspecified:
        return svn_wc_conflict_choose_unspecified;

      default:
        break;
    }

  return svn_wc_conflict_choose_undefined;
}

static void
add_legacy_desc_to_conflict(const svn_wc_conflict_description2_t *desc,
                            svn_client_conflict_t *conflict,
                            apr_pool_t *result_pool)
{
  switch (desc->kind)
    {
      case svn_wc_conflict_kind_text:
        conflict->legacy_text_conflict = desc;
        break;

      case svn_wc_conflict_kind_property:
        if (conflict->prop_conflicts == NULL)
          conflict->prop_conflicts = apr_hash_make(result_pool);
        svn_hash_sets(conflict->prop_conflicts, desc->property_name, desc);
        conflict->legacy_prop_conflict_propname = desc->property_name;
        break;

      case svn_wc_conflict_kind_tree:
        conflict->legacy_tree_conflict = desc;
        break;

      default:
        SVN_ERR_ASSERT_NO_RETURN(FALSE); /* unknown kind of conflict */
    }
}

/* A map for svn_wc_conflict_action_t values to strings */
static const svn_token_map_t map_conflict_action[] =
{
  { "edit",             svn_wc_conflict_action_edit },
  { "delete",           svn_wc_conflict_action_delete },
  { "add",              svn_wc_conflict_action_add },
  { "replace",          svn_wc_conflict_action_replace },
  { NULL,               0 }
};

/* A map for svn_wc_conflict_reason_t values to strings */
static const svn_token_map_t map_conflict_reason[] =
{
  { "edit",             svn_wc_conflict_reason_edited },
  { "delete",           svn_wc_conflict_reason_deleted },
  { "missing",          svn_wc_conflict_reason_missing },
  { "obstruction",      svn_wc_conflict_reason_obstructed },
  { "add",              svn_wc_conflict_reason_added },
  { "replace",          svn_wc_conflict_reason_replaced },
  { "unversioned",      svn_wc_conflict_reason_unversioned },
  { "moved-away",       svn_wc_conflict_reason_moved_away },
  { "moved-here",       svn_wc_conflict_reason_moved_here },
  { NULL,               0 }
};

/* Describes a server-side move (really a copy+delete within the same
 * revision) which was identified by scanning the revision log.
 * This structure can represent one or more "chains" of moves, i.e.
 * multiple move operations which occurred across a range of revisions. */
struct repos_move_info {
  /* The revision in which this move was committed. */
  svn_revnum_t rev;

  /* The author who commited the revision in which this move was committed. */
  const char *rev_author;

  /* The repository relpath the node was moved from in this revision. */
  const char *moved_from_repos_relpath;

  /* The repository relpath the node was moved to in this revision. */
  const char *moved_to_repos_relpath;

  /* The copyfrom revision of the moved-to path. */
  svn_revnum_t copyfrom_rev;

  /* Prev pointer. NULL if no prior move exists in the chain. */
  struct repos_move_info *prev;

  /* An array of struct repos_move_info * elements, each representing
   * a possible way forward in the move chain. NULL if no next move
   * exists in this chain. If the deleted node was copied only once in
   * this revision, then this array has only one element and the move
   * chain does not fork. But if this revision contains multiple copies of
   * the deleted node, each of these copies appears as an element of this
   * array, and each element represents a different path the next move
   * might have taken. */
  apr_array_header_t *next;
};

/* Set *RELATED to true if the deleted node DELETED_REPOS_RELPATH@DELETED_REV
 * is an ancestor of the copied node COPYFROM_PATH@COPYFROM_REV, and if the
 * copied node is a copy of the deleted node's last-changed revision's content,
 * rather than a copy of some older content. */
static svn_error_t *
check_move_ancestry(svn_boolean_t *related,
                    const char *repos_root_url,
                    const char *deleted_repos_relpath,
                    svn_revnum_t deleted_rev,
                    const char *copyfrom_path,
                    svn_revnum_t copyfrom_rev,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *scratch_pool)
{
  apr_hash_t *locations;
  const char *deleted_url;
  const char *deleted_location;
  svn_ra_session_t *ra_session;
  const char *corrected_url;
  apr_array_header_t *location_revisions;
  svn_dirent_t *dirent;

  *related = FALSE;

  location_revisions = apr_array_make(scratch_pool, 1, sizeof(svn_revnum_t));
  APR_ARRAY_PUSH(location_revisions, svn_revnum_t) = copyfrom_rev;
  deleted_url = svn_uri_canonicalize(apr_pstrcat(scratch_pool,
                                                 repos_root_url, "/",
                                                 deleted_repos_relpath,
                                                 NULL),
                                     scratch_pool);
  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
                                               deleted_url, NULL,
                                               NULL, FALSE, FALSE,
                                               ctx, scratch_pool,
                                               scratch_pool));
  SVN_ERR(svn_ra_get_locations(ra_session, &locations, "",
                               deleted_rev - 1, location_revisions,
                               scratch_pool));

  deleted_location = apr_hash_get(locations, &copyfrom_rev,
                                  sizeof(svn_revnum_t));
  if (deleted_location)
    {
      if (deleted_location[0] == '/')
        deleted_location++;
      if (strcmp(deleted_location, copyfrom_path) != 0)
        return SVN_NO_ERROR;
    }

  /* Verify that copyfrom_rev >= last-changed revision of the deleted node. */
  SVN_ERR(svn_ra_stat(ra_session, "", deleted_rev - 1, &dirent, scratch_pool));
  if (dirent == NULL || copyfrom_rev < dirent->created_rev)
    return SVN_NO_ERROR;

  *related = TRUE;

  return SVN_NO_ERROR;
}

struct copy_info {
  const char *copyto_path;
  const char *copyfrom_path;
  svn_revnum_t copyfrom_rev;
};

/* Update MOVES_TABLE and MOVED_PATHS based on information from
 * revision data in LOG_ENTRY, COPIES, and DELETED_PATHS. */
static svn_error_t *
find_moves_in_revision(apr_hash_t *moves_table,
                       apr_hash_t *moved_paths,
                       svn_log_entry_t *log_entry,
                       apr_hash_t *copies,
                       apr_array_header_t *deleted_paths,
                       const char *repos_root_url,
                       svn_client_ctx_t *ctx,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool;
  apr_array_header_t *copies_with_same_source_path;
  svn_boolean_t related;
  int i, j;

  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; i < deleted_paths->nelts; i++)
    {
      const char *deleted_repos_relpath;

      deleted_repos_relpath = APR_ARRAY_IDX(deleted_paths, i, const char *);

      /* See if we can match any copies to this deleted path. */
      copies_with_same_source_path = apr_hash_get(copies,
                                                  deleted_repos_relpath,
                                                  APR_HASH_KEY_STRING);
      if (copies_with_same_source_path == NULL)
        continue;

      for (j = 0; j < copies_with_same_source_path->nelts; j++)
        {
          struct copy_info *copy;
          struct repos_move_info *move;
          struct repos_move_info *next_move;
          svn_string_t *author;
          apr_array_header_t *moves;
          
          svn_pool_clear(iterpool);

          copy = APR_ARRAY_IDX(copies_with_same_source_path, j,
                               struct copy_info *);

          /* We found a deleted node which matches the copyfrom path of
           * a copied node. Verify that the deleted node is an ancestor
           * of the copied node. When tracing back history of the deleted node
           * from revision log_entry->revision-1 (where the deleted node is
           * guaranteed to exist) to the copyfrom-revision, we must end up
           * at the copyfrom-path. */
          SVN_ERR(check_move_ancestry(&related, repos_root_url,
                                      deleted_repos_relpath,
                                      log_entry->revision,
                                      copy->copyfrom_path,
                                      copy->copyfrom_rev,
                                      ctx, iterpool));
          if (!related)
            continue;

          /* Remember details of this move. */
          move = apr_pcalloc(result_pool, sizeof(*move));
          move->moved_from_repos_relpath = apr_pstrdup(result_pool,
                                                       deleted_repos_relpath);
          move->moved_to_repos_relpath = apr_pstrdup(result_pool,
                                                     copy->copyto_path);
          move->rev = log_entry->revision;
          author = svn_hash_gets(log_entry->revprops, SVN_PROP_REVISION_AUTHOR);
          move->rev_author = apr_pstrdup(result_pool, author->data);
          move->copyfrom_rev = copy->copyfrom_rev;

          /* Link together multiple moves of the same node.
           * Note that we're traversing history backwards, so moves already
           * present in the list happened in younger revisions. */
          next_move = svn_hash_gets(moved_paths, move->moved_to_repos_relpath);
          if (next_move)
            {
              /* Tracing back history of the delete-half of the next move
               * to the copyfrom-revision of the prior move we must end up
               * at the delete-half of the prior move. */
              SVN_ERR(check_move_ancestry(&related, repos_root_url,
                                          next_move->moved_from_repos_relpath,
                                          next_move->rev,
                                          move->moved_from_repos_relpath,
                                          move->copyfrom_rev,
                                          ctx, iterpool));
              if (related)
                {
                  SVN_ERR_ASSERT(move->rev < next_move->rev);

                  /* Prepend this move to the linked list. */
                  if (move->next == NULL)
                    move->next = apr_array_make(
                                   result_pool, 1,
                                   sizeof (struct repos_move_info *));
                  APR_ARRAY_PUSH(move->next,
                                 struct repos_move_info *) = next_move;
                  next_move->prev = move;
                }
            }

          /* Make this move the head of our next-move linking map. */
          svn_hash_sets(moved_paths, move->moved_from_repos_relpath, move);

          /* Add this move to the list of moves in this revision. */
          moves = apr_hash_get(moves_table, &move->rev, sizeof(svn_revnum_t));
          if (moves == NULL)
            {
              /* This is the first move in this revision. Create the list. */
              moves = apr_array_make(result_pool, 1,
                                     sizeof(struct repos_move_info *));
              apr_hash_set(moves_table, &move->rev, sizeof(svn_revnum_t),
                           moves);
            }
          APR_ARRAY_PUSH(moves, struct repos_move_info *) = move;
        }
    }
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

struct find_deleted_rev_baton
{
  /* Variables below are arguments provided by the caller of
   * svn_ra_get_log2(). */
  const char *deleted_repos_relpath;
  const char *related_repos_relpath;
  svn_revnum_t related_repos_peg_rev;
  const char *repos_root_url;
  const char *repos_uuid;
  svn_client_ctx_t *ctx;
  const char *victim_abspath; /* for notifications */

  /* Variables below are results for the caller of svn_ra_get_log2(). */
  svn_revnum_t deleted_rev;
  const char *deleted_rev_author;
  svn_node_kind_t replacing_node_kind;
  apr_pool_t *result_pool;

  /* A hash table mapping a revision number to an array of struct
   * repos_move_info * elements, describing moves.
   *
   * Must be allocated in RESULT_POOL by the caller of svn_ra_get_log2().
   *
   * If the node was moved, the DELETED_REV is present in this table,
   * perhaps along with additional revisions.
   *
   * Given a sequence of moves which happened in the repository, such as:
   *   rA: mv x->z
   *   rA: mv a->b
   *   rB: mv b->c
   *   rC: mv c->d
   * we map each revision number to all the moves which happened in the
   * revision, which looks as follows: 
   *   rA : [(x->z), (a->b)]
   *   rB : [(b->c)]
   *   rC : [(c->d)]
   * This allows us to later find relevant moves based on a revision number.
   *
   * Additionally, we embed the number of the revision in which a move was
   * found inside the repos_move_info structure:
   *   rA : [(rA, x->z), (rA, a->b)]
   *   rB : [(rB, b->c)]
   *   rC : [(rC, c->d)]
   * And also, all moves pertaining to the same node are chained into a
   * doubly-linked list via 'next' and 'prev' pointers (see definition of
   * struct repos_move_info). This can be visualized as follows:
   *   rA : [(rA, x->z, prev=>NULL, next=>NULL),
   *         (rA, a->b, prev=>NULL, next=>(rB, b->c))]
   *   rB : [(rB, b->c), prev=>(rA, a->b), next=>(rC, c->d)]
   *   rC : [(rC, c->d), prev=>(rB, c->d), next=>NULL]
   * This way, we can look up all moves relevant to a node, forwards and
   * backwards in history, once we have located one move in the chain.
   *
   * In the above example, the data tells us that within the revision
   * range rA:C, a was moved to d. However, within the revision range
   * rA;B, a was moved to b.
   */
  apr_hash_t *moves_table;

  /* Variables below hold state for find_deleted_rev() and are not
   * intended to be used by the caller of svn_ra_get_log2().
   * Like all other variables, they must be initialized, however. */

  /* Temporary map of moved paths to struct repos_move_info.
   * Used to link multiple moves of the same node across revisions. */
  apr_hash_t *moved_paths;
};

/* Implements svn_log_entry_receiver_t.
 *
 * Find the revision in which a node, optionally ancestrally related to the
 * node specified via find_deleted_rev_baton, was deleted, When the revision
 * was found, store it in BATON->DELETED_REV and abort the log operation
 * by raising SVN_ERR_CANCELLED.
 *
 * If no such revision can be found, leave BATON->DELETED_REV and
 * BATON->REPLACING_NODE_KIND alone.
 *
 * If the node was replaced, set BATON->REPLACING_NODE_KIND to the node
 * kind of the node which replaced the original node. If the node was not
 * replaced, set BATON->REPLACING_NODE_KIND to svn_node_none.
 *
 * This function answers the same question as svn_ra_get_deleted_rev() but
 * works in cases where we do not already know a revision in which the deleted
 * node once used to exist.
 * 
 * If the node node was moved, rather than deleted, return move information
 * in BATON->MOVE.
 */
static svn_error_t *
find_deleted_rev(void *baton,
                 svn_log_entry_t *log_entry,
                 apr_pool_t *scratch_pool)
{
  struct find_deleted_rev_baton *b = baton;
  apr_hash_index_t *hi;
  apr_pool_t *iterpool;
  svn_boolean_t deleted_node_found = FALSE;
  apr_array_header_t *deleted_paths;
  apr_hash_t *copies;

  if (b->ctx->notify_func2)
    {
      svn_wc_notify_t *notify;

      notify = svn_wc_create_notify(
                 b->victim_abspath,
                 svn_wc_notify_tree_conflict_details_progress,
                 scratch_pool),
      notify->revision = log_entry->revision;
      b->ctx->notify_func2(b->ctx->notify_baton2, notify, scratch_pool);
    }

  /* No paths were changed in this revision.  Nothing to do. */
  if (! log_entry->changed_paths2)
    return SVN_NO_ERROR;

  copies = apr_hash_make(scratch_pool);
  deleted_paths = apr_array_make(scratch_pool, 0, sizeof(const char *));
  iterpool = svn_pool_create(scratch_pool);
  for (hi = apr_hash_first(scratch_pool, log_entry->changed_paths2);
       hi != NULL;
       hi = apr_hash_next(hi))
    {
      const char *changed_path = apr_hash_this_key(hi);
      svn_log_changed_path2_t *log_item = apr_hash_this_val(hi);

      svn_pool_clear(iterpool);

      /* ### Remove leading slash from paths in log entries. */
      if (changed_path[0] == '/')
          changed_path++;

      /* For move detection, scan for copied nodes in this revision. */
      if (log_item->action == 'A' && log_item->copyfrom_path)
        {
          struct copy_info *copy;
          apr_array_header_t *copies_with_same_source_path;

          if (log_item->copyfrom_path[0] == '/')
            log_item->copyfrom_path++;

          copy = apr_palloc(scratch_pool, sizeof(*copy));
          copy->copyto_path = changed_path;
          copy->copyfrom_path = log_item->copyfrom_path;
          copy->copyfrom_rev = log_item->copyfrom_rev;
          copies_with_same_source_path = apr_hash_get(copies,
                                                      log_item->copyfrom_path,
                                                      APR_HASH_KEY_STRING);
          if (copies_with_same_source_path == NULL)
            {
              copies_with_same_source_path = apr_array_make(
                                               scratch_pool, 1,
                                               sizeof(struct copy_info *));
              apr_hash_set(copies, copy->copyfrom_path, APR_HASH_KEY_STRING,
                           copies_with_same_source_path);
            }
          APR_ARRAY_PUSH(copies_with_same_source_path,
                         struct copy_info *) = copy;
        }

      /* For move detection, store all deleted_paths.
       *
       * ### This also stores deletions which happened inside copies.
       * ### But we are not able to handle them at present.
       * ### Consider: cp A B; mv B/foo C/foo
       * ### Copyfrom for C/foo is now A/foo, even though C/foo was moved
       * ### here from B/foo. We don't detect such moves at present since
       * ### A/foo was not deleted. It is B/foo which was deleted.
       */
      if (log_item->action == 'D' || log_item->action == 'R')
        APR_ARRAY_PUSH(deleted_paths, const char *) =
          apr_pstrdup(scratch_pool, changed_path);

      /* Check if we found the deleted node we're looking for. */
      if (!deleted_node_found &&
          svn_path_compare_paths(b->deleted_repos_relpath, changed_path) == 0 &&
          (log_item->action == 'D' || log_item->action == 'R'))
        {
          deleted_node_found = TRUE;

          if (b->related_repos_relpath != NULL &&
              b->related_repos_peg_rev != SVN_INVALID_REVNUM)
            {
              svn_client__pathrev_t *yca_loc = NULL;
              svn_client__pathrev_t *loc1;
              svn_client__pathrev_t *loc2;

              /* We found a deleted node which occupies the correct path.
               * To be certain that this is the deleted node we're looking for,
               * we must establish whether it is ancestrally related to the
               * "related node" specified in our baton. */
              loc1 = svn_client__pathrev_create_with_relpath(
                       b->repos_root_url, b->repos_uuid,
                       b->related_repos_peg_rev,
                       b->related_repos_relpath, iterpool);
              loc2 = svn_client__pathrev_create_with_relpath(
                       b->repos_root_url, b->repos_uuid,
                       log_entry->revision - 1,
                       b->deleted_repos_relpath, iterpool);
              SVN_ERR(svn_client__get_youngest_common_ancestor(&yca_loc,
                                                               loc1, loc2,
                                                               NULL, b->ctx,
                                                               iterpool,
                                                               iterpool));
              deleted_node_found = (yca_loc != NULL);
            }

          if (deleted_node_found)
            {
              svn_string_t *author;

              b->deleted_rev = log_entry->revision;
              author = svn_hash_gets(log_entry->revprops,
                                     SVN_PROP_REVISION_AUTHOR);
              b->deleted_rev_author = apr_pstrdup(b->result_pool, author->data);
                  
              if (log_item->action == 'R')
                b->replacing_node_kind = log_item->node_kind;
              else
                b->replacing_node_kind = svn_node_none;
            }
        }
    }
  svn_pool_destroy(iterpool);

  /* Check for moves in this revision */
  SVN_ERR(find_moves_in_revision(b->moves_table, b->moved_paths,
                                 log_entry, copies, deleted_paths,
                                 b->repos_root_url, b->ctx,
                                 b->result_pool, scratch_pool));
  if (deleted_node_found)
    {
      /* We're done. Abort the log operation. */
      return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
    }

  return SVN_NO_ERROR;
}

/* Return a localised string representation of the local part of a tree
   conflict on a file. */
static svn_error_t *
describe_local_file_node_change(const char **description,
                                svn_client_conflict_t *conflict,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
{
  svn_wc_conflict_reason_t local_change;
  svn_wc_operation_t operation;

  local_change = svn_client_conflict_get_local_change(conflict);
  operation = svn_client_conflict_get_operation(conflict);

  switch (local_change)
    {
      case svn_wc_conflict_reason_edited:
        if (operation == svn_wc_operation_update ||
            operation == svn_wc_operation_switch)
          *description = _("A file containing uncommitted changes was "
                           "found in the working copy.");
        else if (operation == svn_wc_operation_merge)
          *description = _("A file which differs from the corresponding "
                           "file on the merge source branch was found "
                           "in the working copy.");
        break;
      case svn_wc_conflict_reason_obstructed:
        *description = _("A file which already occupies this path was found "
                         "in the working copy.");
        break;
      case svn_wc_conflict_reason_unversioned:
        *description = _("An unversioned file was found in the working "
                         "copy.");
        break;
      case svn_wc_conflict_reason_deleted:
        *description = _("A deleted file was found in the working copy.");
        break;
      case svn_wc_conflict_reason_missing:
        if (operation == svn_wc_operation_update ||
            operation == svn_wc_operation_switch)
          *description = _("No such file was found in the working copy.");
        else if (operation == svn_wc_operation_merge)
          {
            /* ### display deleted revision */
            *description = _("No such file was found in the merge target "
                             "working copy.\nPerhaps the file has been "
                             "deleted or moved away in the repository's "
                             "history?");
          }
        break;
      case svn_wc_conflict_reason_added:
      case svn_wc_conflict_reason_replaced:
        {
          /* ### show more details about copies or replacements? */
          *description = _("A file scheduled to be added to the "
                           "repository in the next commit was found in "
                           "the working copy.");
        }
        break;
      case svn_wc_conflict_reason_moved_away:
        {
          const char *moved_to_abspath;

          SVN_ERR(svn_wc__node_was_moved_away(&moved_to_abspath, NULL, 
                                              conflict->ctx->wc_ctx,
                                              conflict->local_abspath,
                                              scratch_pool,
                                              scratch_pool));
          if (operation == svn_wc_operation_update ||
              operation == svn_wc_operation_switch)
            {
              if (moved_to_abspath == NULL)
                {
                  /* The move no longer exists. */
                  *description = _("The file in the working copy had "
                                   "been moved away at the time this "
                                   "conflict was recorded.");
                }
              else
                {
                  const char *wcroot_abspath;

                  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath,
                                             conflict->ctx->wc_ctx,
                                             conflict->local_abspath,
                                             scratch_pool,
                                             scratch_pool));
                  *description = apr_psprintf(
                                   result_pool,
                                   _("The file in the working copy was "
                                     "moved away to\n'%s'."),
                                   svn_dirent_local_style(
                                     svn_dirent_skip_ancestor(
                                       wcroot_abspath,
                                       moved_to_abspath),
                                     scratch_pool));
                }
            }
          else if (operation == svn_wc_operation_merge)
            {
              if (moved_to_abspath == NULL)
                {
                  /* The move probably happened in branch history.
                   * This case cannot happen until we detect incoming
                   * moves, which we currently don't do. */
                  /* ### find deleted/moved revision? */
                  *description = _("The file in the working copy had "
                                   "been moved away at the time this "
                                   "conflict was recorded.");
                }
              else
                {
                  /* This is a local move in the working copy. */
                  const char *wcroot_abspath;

                  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath,
                                             conflict->ctx->wc_ctx,
                                             conflict->local_abspath,
                                             scratch_pool,
                                             scratch_pool));
                  *description = apr_psprintf(
                                   result_pool,
                                   _("The file in the working copy was "
                                     "moved away to\n'%s'."),
                                   svn_dirent_local_style(
                                     svn_dirent_skip_ancestor(
                                       wcroot_abspath,
                                       moved_to_abspath),
                                     scratch_pool));
                }
            }
          break;
        }
      case svn_wc_conflict_reason_moved_here:
        {
          const char *moved_from_abspath;

          SVN_ERR(svn_wc__node_was_moved_here(&moved_from_abspath, NULL, 
                                              conflict->ctx->wc_ctx,
                                              conflict->local_abspath,
                                              scratch_pool,
                                              scratch_pool));
          if (operation == svn_wc_operation_update ||
              operation == svn_wc_operation_switch)
            {
              if (moved_from_abspath == NULL)
                {
                  /* The move no longer exists. */
                  *description = _("A file had been moved here in the "
                                   "working copy at the time this "
                                   "conflict was recorded.");
                }
              else
                {
                  const char *wcroot_abspath;

                  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath,
                                             conflict->ctx->wc_ctx,
                                             conflict->local_abspath,
                                             scratch_pool,
                                             scratch_pool));
                  *description = apr_psprintf(
                                   result_pool,
                                   _("A file was moved here in the "
                                     "working copy from\n'%s'."),
                                   svn_dirent_local_style(
                                     svn_dirent_skip_ancestor(
                                       wcroot_abspath,
                                       moved_from_abspath),
                                     scratch_pool));
                }
            }
          else if (operation == svn_wc_operation_merge)
            {
              if (moved_from_abspath == NULL)
                {
                  /* The move probably happened in branch history.
                   * This case cannot happen until we detect incoming
                   * moves, which we currently don't do. */
                  /* ### find deleted/moved revision? */
                  *description = _("A file had been moved here in the "
                                   "working copy at the time this "
                                   "conflict was recorded.");
                }
              else
                {
                  const char *wcroot_abspath;

                  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath,
                                             conflict->ctx->wc_ctx,
                                             conflict->local_abspath,
                                             scratch_pool,
                                             scratch_pool));
                  /* This is a local move in the working copy. */
                  *description = apr_psprintf(
                                   result_pool,
                                   _("A file was moved here in the "
                                     "working copy from\n'%s'."),
                                   svn_dirent_local_style(
                                     svn_dirent_skip_ancestor(
                                       wcroot_abspath,
                                       moved_from_abspath),
                                     scratch_pool));
                }
            }
          break;
        }
    }

  return SVN_NO_ERROR;
}

/* Return a localised string representation of the local part of a tree
   conflict on a directory. */
static svn_error_t *
describe_local_dir_node_change(const char **description,
                               svn_client_conflict_t *conflict,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
{
  svn_wc_conflict_reason_t local_change;
  svn_wc_operation_t operation;

  local_change = svn_client_conflict_get_local_change(conflict);
  operation = svn_client_conflict_get_operation(conflict);

  switch (local_change)
    {
      case svn_wc_conflict_reason_edited:
        if (operation == svn_wc_operation_update ||
            operation == svn_wc_operation_switch)
          *description = _("A directory containing uncommitted changes "
                           "was found in the working copy.");
        else if (operation == svn_wc_operation_merge)
          *description = _("A directory which differs from the "
                           "corresponding directory on the merge source "
                           "branch was found in the working copy.");
        break;
      case svn_wc_conflict_reason_obstructed:
        *description = _("A directory which already occupies this path was "
                         "found in the working copy.");
        break;
      case svn_wc_conflict_reason_unversioned:
        *description = _("An unversioned directory was found in the "
                         "working copy.");
        break;
      case svn_wc_conflict_reason_deleted:
        *description = _("A deleted directory was found in the "
                         "working copy.");
        break;
      case svn_wc_conflict_reason_missing:
        if (operation == svn_wc_operation_update ||
            operation == svn_wc_operation_switch)
          *description = _("No such directory was found in the working copy.");
        else if (operation == svn_wc_operation_merge)
          {
            /* ### display deleted revision */
            *description = _("No such directory was found in the merge "
                             "target working copy.\nPerhaps the "
                             "directory has been deleted or moved away "
                             "in the repository's history?");
          }
        break;
      case svn_wc_conflict_reason_added:
      case svn_wc_conflict_reason_replaced:
        {
          /* ### show more details about copies or replacements? */
          *description = _("A directory scheduled to be added to the "
                           "repository in the next commit was found in "
                           "the working copy.");
        }
        break;
      case svn_wc_conflict_reason_moved_away:
        {
          const char *moved_to_abspath;

          SVN_ERR(svn_wc__node_was_moved_away(&moved_to_abspath, NULL, 
                                              conflict->ctx->wc_ctx,
                                              conflict->local_abspath,
                                              scratch_pool,
                                              scratch_pool));
          if (operation == svn_wc_operation_update ||
              operation == svn_wc_operation_switch)
            {
              if (moved_to_abspath == NULL)
                {
                  /* The move no longer exists. */
                  *description = _("The directory in the working copy "
                                   "had been moved away at the time "
                                   "this conflict was recorded.");
                }
              else
                {
                  const char *wcroot_abspath;

                  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath,
                                             conflict->ctx->wc_ctx,
                                             conflict->local_abspath,
                                             scratch_pool,
                                             scratch_pool));
                  *description = apr_psprintf(
                                   result_pool,
                                   _("The directory in the working copy "
                                     "was moved away to\n'%s'."),
                                   svn_dirent_local_style(
                                     svn_dirent_skip_ancestor(
                                       wcroot_abspath,
                                       moved_to_abspath),
                                     scratch_pool));
                }
            }
          else if (operation == svn_wc_operation_merge)
            {
              if (moved_to_abspath == NULL)
                {
                  /* The move probably happened in branch history.
                   * This case cannot happen until we detect incoming
                   * moves, which we currently don't do. */
                  /* ### find deleted/moved revision? */
                  *description = _("The directory had been moved away "
                                   "at the time this conflict was "
                                   "recorded.");
                }
              else
                {
                  /* This is a local move in the working copy. */
                  const char *wcroot_abspath;

                  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath,
                                             conflict->ctx->wc_ctx,
                                             conflict->local_abspath,
                                             scratch_pool,
                                             scratch_pool));
                  *description = apr_psprintf(
                                   result_pool,
                                   _("The directory was moved away to\n"
                                     "'%s'."),
                                   svn_dirent_local_style(
                                     svn_dirent_skip_ancestor(
                                       wcroot_abspath,
                                       moved_to_abspath),
                                     scratch_pool));
                }
            }
          }
          break;
      case svn_wc_conflict_reason_moved_here:
        {
          const char *moved_from_abspath;

          SVN_ERR(svn_wc__node_was_moved_here(&moved_from_abspath, NULL, 
                                              conflict->ctx->wc_ctx,
                                              conflict->local_abspath,
                                              scratch_pool,
                                              scratch_pool));
          if (operation == svn_wc_operation_update ||
              operation == svn_wc_operation_switch)
            {
              if (moved_from_abspath == NULL)
                {
                  /* The move no longer exists. */
                  *description = _("A directory had been moved here at "
                                   "the time this conflict was "
                                   "recorded.");
                }
              else
                {
                  const char *wcroot_abspath;

                  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath,
                                             conflict->ctx->wc_ctx,
                                             conflict->local_abspath,
                                             scratch_pool,
                                             scratch_pool));
                  *description = apr_psprintf(
                                   result_pool,
                                   _("A directory was moved here from\n"
                                     "'%s'."),
                                   svn_dirent_local_style(
                                     svn_dirent_skip_ancestor(
                                       wcroot_abspath,
                                       moved_from_abspath),
                                     scratch_pool));
                }
            }
          else if (operation == svn_wc_operation_merge)
            {
              if (moved_from_abspath == NULL)
                {
                  /* The move probably happened in branch history.
                   * This case cannot happen until we detect incoming
                   * moves, which we currently don't do. */
                  /* ### find deleted/moved revision? */
                  *description = _("A directory had been moved here at "
                                   "the time this conflict was "
                                   "recorded.");
                }
              else
                {
                  /* This is a local move in the working copy. */
                  const char *wcroot_abspath;

                  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath,
                                             conflict->ctx->wc_ctx,
                                             conflict->local_abspath,
                                             scratch_pool,
                                             scratch_pool));
                  *description = apr_psprintf(
                                   result_pool,
                                   _("A directory was moved here in "
                                     "the working copy from\n'%s'."),
                                   svn_dirent_local_style(
                                     svn_dirent_skip_ancestor(
                                       wcroot_abspath,
                                       moved_from_abspath),
                                     scratch_pool));
                }
            }
        }
    }

  return SVN_NO_ERROR;
}

/* Try to find a revision older than START_REV, and its author, which deleted
 * DELETED_BASENAME in the directory PARENT_REPOS_RELPATH. Assume the deleted
 * node is ancestrally related to RELATED_REPOS_RELPATH@RELATED_PEG_REV.
 * If no such revision can be found, set *DELETED_REV to SVN_INVALID_REVNUM
 * and *DELETED_REV_AUTHOR to NULL.
 * If the node was replaced rather than deleted, set *REPLACING_NODE_KIND to
 * the node kind of the replacing node. Else, set it to svn_node_unknown.
 * Only request the log for revisions up to END_REV from the server.
 * If the deleted node was moved, provide heads of move chains in *MOVES.
 * If the node was not moved,set *MOVES to NULL.
 */
static svn_error_t *
find_revision_for_suspected_deletion(svn_revnum_t *deleted_rev,
                                     const char **deleted_rev_author,
                                     svn_node_kind_t *replacing_node_kind,
                                     struct apr_array_header_t **moves,
                                     svn_client_conflict_t *conflict,
                                     const char *deleted_basename,
                                     const char *parent_repos_relpath,
                                     svn_revnum_t start_rev,
                                     svn_revnum_t end_rev,
                                     const char *related_repos_relpath,
                                     svn_revnum_t related_peg_rev,
                                     apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool)
{
  svn_ra_session_t *ra_session;
  const char *url;
  const char *corrected_url;
  apr_array_header_t *paths;
  apr_array_header_t *revprops;
  const char *repos_root_url;
  const char *repos_uuid;
  struct find_deleted_rev_baton b;
  const char *victim_abspath;
  svn_error_t *err;

  SVN_ERR_ASSERT(start_rev > end_rev);

  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
                                             conflict, scratch_pool,
                                             scratch_pool));
  url = svn_path_url_add_component2(repos_root_url, parent_repos_relpath,
                                    scratch_pool);
  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
                                               url, NULL, NULL, FALSE, FALSE,
                                               conflict->ctx, scratch_pool,
                                               scratch_pool));

  paths = apr_array_make(scratch_pool, 1, sizeof(const char *));
  APR_ARRAY_PUSH(paths, const char *) = "";

  revprops = apr_array_make(scratch_pool, 1, sizeof(const char *));
  APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_AUTHOR;

  victim_abspath = svn_client_conflict_get_local_abspath(conflict);
  b.victim_abspath = victim_abspath;
  b.deleted_repos_relpath = svn_relpath_join(parent_repos_relpath,
                                             deleted_basename, scratch_pool);
  b.related_repos_relpath = related_repos_relpath;
  b.related_repos_peg_rev = related_peg_rev;
  b.deleted_rev = SVN_INVALID_REVNUM;
  b.replacing_node_kind = svn_node_unknown;
  b.repos_root_url = repos_root_url;
  b.repos_uuid = repos_uuid;
  b.ctx = conflict->ctx;
  b.moves_table = apr_hash_make(result_pool);
  b.moved_paths = apr_hash_make(scratch_pool);
  b.result_pool = result_pool;

  err = svn_ra_get_log2(ra_session, paths, start_rev, end_rev,
                        0, /* no limit */
                        TRUE, /* need the changed paths list */
                        FALSE, /* need to traverse copies */
                        FALSE, /* no need for merged revisions */
                        revprops,
                        find_deleted_rev, &b,
                        scratch_pool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_CANCELLED &&
          b.deleted_rev != SVN_INVALID_REVNUM)

        {
          /* Log operation was aborted because we found deleted rev. */
          svn_error_clear(err);
        }
      else
        return svn_error_trace(err);
    }

  if (b.deleted_rev == SVN_INVALID_REVNUM)
    {
      /* We could not determine the revision in which the node was
       * deleted. */
      *deleted_rev = SVN_INVALID_REVNUM;
      *deleted_rev_author = NULL;
      *replacing_node_kind = svn_node_unknown;
      *moves = NULL;
      return SVN_NO_ERROR;
    }
  else
    {
      apr_array_header_t *all_moves_in_deleted_rev;

      *deleted_rev = b.deleted_rev;
      *deleted_rev_author = b.deleted_rev_author;
      *replacing_node_kind = b.replacing_node_kind;

      /* Look for a moves which affect the deleted node. */
      all_moves_in_deleted_rev = apr_hash_get(b.moves_table, &b.deleted_rev,
                                             sizeof(svn_revnum_t));
      if (all_moves_in_deleted_rev)
        {
          int i;

          *moves = apr_array_make(result_pool, 1, sizeof(const char *));
          for (i = 0; i < all_moves_in_deleted_rev->nelts; i++)
            {
              struct repos_move_info *this_move;
              
              this_move = APR_ARRAY_IDX(all_moves_in_deleted_rev, i,
                                        struct repos_move_info *);
              if (strcmp(b.deleted_repos_relpath,
                         this_move->moved_from_repos_relpath) == 0)
                {
                  /* Because b->moves_table lives in result_pool
                   * there is no need to deep-copy here. */
                   APR_ARRAY_PUSH(*moves, struct repos_move_info *) = this_move;
                }
            }

          /* If we didn't find any applicable moves, return NULL. */
          if ((*moves)->nelts == 0)
            *moves = NULL;
        }
      else
        *moves = NULL;
    }

  return SVN_NO_ERROR;
}

/* Details for tree conflicts involving a locally missing node. */
struct conflict_tree_local_missing_details
{
  /* If not SVN_INVALID_REVNUM, the node was deleted in DELETED_REV. */
  svn_revnum_t deleted_rev;

  /* Author who committed DELETED_REV. */
  const char *deleted_rev_author;

  /* The path which was deleted relative to the repository root. */
  const char *deleted_repos_relpath;

  /* Move information. If not NULL, this is an array of repos_move_info *
   * elements. Each element is the head of a move chain which starts in
   * DELETED_REV. */
  apr_array_header_t *moves;
};

/* Implements tree_conflict_get_details_func_t. */
static svn_error_t *
conflict_tree_get_details_local_missing(svn_client_conflict_t *conflict,
                                        apr_pool_t *scratch_pool)
{
  const char *old_repos_relpath;
  const char *new_repos_relpath;
  const char *parent_repos_relpath;
  svn_revnum_t old_rev;
  svn_revnum_t new_rev;
  svn_revnum_t deleted_rev;
  const char *deleted_rev_author;
  svn_node_kind_t replacing_node_kind;
  const char *deleted_basename;
  struct conflict_tree_local_missing_details *details;
  apr_array_header_t *moves;
  const char *related_repos_relpath;
  svn_revnum_t related_peg_rev;

  /* We only handle merges here. */
  if (svn_client_conflict_get_operation(conflict) != svn_wc_operation_merge)
    return SVN_NO_ERROR;

  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &old_repos_relpath, &old_rev, NULL, conflict,
            scratch_pool, scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &new_repos_relpath, &new_rev, NULL, conflict,
            scratch_pool, scratch_pool));

  /* A deletion of the node may have happened on the branch we
   * merged to. Scan the conflict victim's parent's log to find
   * a revision which deleted the node. */
  deleted_basename = svn_dirent_basename(conflict->local_abspath,
                                         scratch_pool);
  SVN_ERR(svn_wc__node_get_repos_info(NULL, &parent_repos_relpath,
                                      NULL, NULL,
                                      conflict->ctx->wc_ctx,
                                      svn_dirent_dirname(
                                        conflict->local_abspath,
                                        scratch_pool),
                                      scratch_pool,
                                      scratch_pool));

  /* Pick the younger incoming node as our 'related node' which helps
   * pin-pointing the deleted conflict victim in history. */
  related_repos_relpath = 
            (old_rev < new_rev ? new_repos_relpath : old_repos_relpath);
  related_peg_rev = (old_rev < new_rev ? new_rev : old_rev);

  /* Make sure we're going to search the related node in a revision where
   * it exists. The younger incoming node might have been deleted in HEAD. */
  if (related_repos_relpath != NULL && related_peg_rev != SVN_INVALID_REVNUM)
    {
      const char *repos_root_url;
      const char *repos_uuid;
      const char *related_url;
      const char *corrected_url;
      svn_node_kind_t related_node_kind;
      svn_ra_session_t *ra_session;

      SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url,
                                                 &repos_uuid,
                                                 conflict,
                                                 scratch_pool, scratch_pool));
      related_url = svn_path_url_add_component2(repos_root_url,
                                                related_repos_relpath,
                                                scratch_pool);
      SVN_ERR(svn_client__open_ra_session_internal(&ra_session,
                                                   &corrected_url,
                                                   related_url, NULL,
                                                   NULL,
                                                   FALSE,
                                                   FALSE,
                                                   conflict->ctx,
                                                   scratch_pool,
                                                   scratch_pool));
      SVN_ERR(svn_ra_check_path(ra_session, "", related_peg_rev,
                                &related_node_kind, scratch_pool));
      if (related_node_kind == svn_node_none)
        {
          svn_revnum_t related_deleted_rev;
          const char *related_deleted_rev_author;
          svn_node_kind_t related_replacing_node_kind;
          const char *related_basename;
          const char *related_parent_repos_relpath;
          apr_array_header_t *related_moves;
          const char *older_incoming_repos_relpath;
          svn_revnum_t older_incoming_peg_rev;

          /* Looks like the younger incoming node, which we'd like to use as
           * our 'related node', was also deleted. Try to find its deleted
           * revision so we can calculate a peg revision at which it exists.
           * The younger incoming node is related to the older incoming node,
           * so we can use the older incoming node to guide us in our search. */
          related_basename = svn_relpath_basename(related_repos_relpath,
                                                  scratch_pool);
          related_parent_repos_relpath =
            svn_relpath_dirname(related_repos_relpath, scratch_pool);
          older_incoming_repos_relpath =
                    (old_rev < new_rev ? old_repos_relpath : new_repos_relpath);
          older_incoming_peg_rev = (old_rev < new_rev ? old_rev : new_rev);
          SVN_ERR(find_revision_for_suspected_deletion(
                    &related_deleted_rev, &related_deleted_rev_author,
                    &related_replacing_node_kind, &related_moves,
                    conflict, related_basename,
                    related_parent_repos_relpath,
                    old_rev < new_rev ? new_rev : old_rev, 0,
                    older_incoming_repos_relpath, older_incoming_peg_rev,
                    conflict->pool, scratch_pool));

          /* If we can't find a related node, bail. */
          if (related_deleted_rev == SVN_INVALID_REVNUM)
            return SVN_NO_ERROR;

          /* The node should exist in the revision before it was deleted. */
          related_peg_rev = related_deleted_rev - 1;
        }
    }
    
  SVN_ERR(find_revision_for_suspected_deletion(
            &deleted_rev, &deleted_rev_author, &replacing_node_kind, &moves,
            conflict, deleted_basename, parent_repos_relpath,
            old_rev < new_rev ? new_rev : old_rev, 0,
            related_repos_relpath,
            related_peg_rev,
            conflict->pool, scratch_pool));

  if (deleted_rev == SVN_INVALID_REVNUM)
    return SVN_NO_ERROR;

  details = apr_pcalloc(conflict->pool, sizeof(*details));
  details->deleted_rev = deleted_rev;
  details->deleted_rev_author = deleted_rev_author;
  details->deleted_repos_relpath = svn_relpath_join(parent_repos_relpath,
                                                    deleted_basename,
                                                    conflict->pool); 
  details->moves = moves;
                                         
  conflict->tree_conflict_local_details = details;

  return SVN_NO_ERROR;
}

/* Return a localised string representation of the local part of a tree
   conflict on a non-existent node. */
static svn_error_t *
describe_local_none_node_change(const char **description,
                                svn_client_conflict_t *conflict,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
{
  svn_wc_conflict_reason_t local_change;
  svn_wc_operation_t operation;

  local_change = svn_client_conflict_get_local_change(conflict);
  operation = svn_client_conflict_get_operation(conflict);

  switch (local_change)
    {
    case svn_wc_conflict_reason_edited:
      *description = _("An item containing uncommitted changes was "
                       "found in the working copy.");
      break;
    case svn_wc_conflict_reason_obstructed:
      *description = _("An item which already occupies this path was found in "
                       "the working copy.");
      break;
    case svn_wc_conflict_reason_deleted:
      *description = _("A deleted item was found in the working copy.");
      break;
    case svn_wc_conflict_reason_missing:
      if (operation == svn_wc_operation_update ||
          operation == svn_wc_operation_switch)
        *description = _("No such file or directory was found in the "
                         "working copy.");
      else if (operation == svn_wc_operation_merge)
        {
          /* ### display deleted revision */
          *description = _("No such file or directory was found in the "
                           "merge target working copy.\nThe item may "
                           "have been deleted or moved away in the "
                           "repository's history.");
        }
      break;
    case svn_wc_conflict_reason_unversioned:
      *description = _("An unversioned item was found in the working "
                       "copy.");
      break;
    case svn_wc_conflict_reason_added:
    case svn_wc_conflict_reason_replaced:
      *description = _("An item scheduled to be added to the repository "
                       "in the next commit was found in the working "
                       "copy.");
      break;
    case svn_wc_conflict_reason_moved_away:
      *description = _("The item in the working copy had been moved "
                       "away at the time this conflict was recorded.");
      break;
    case svn_wc_conflict_reason_moved_here:
      *description = _("An item had been moved here in the working copy "
                       "at the time this conflict was recorded.");
      break;
    }

  return SVN_NO_ERROR;
}

/* Append a description of a move chain beginning at NEXT to DESCRIPTION. */
static const char *
append_moved_to_chain_description(const char *description,
                                  apr_array_header_t *next,
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
{
  if (next == NULL)
    return description;

  while (next)
    {
      struct repos_move_info *move;

      /* Describe the first possible move chain only. Adding multiple chains
       * to the description would just be confusing. The user may select a
       * different move destination while resolving the conflict. */
      move = APR_ARRAY_IDX(next, 0, struct repos_move_info *);

      description = apr_psprintf(scratch_pool,
                                 _("%s\nAnd then moved away to '^/%s' by "
                                   "%s in r%ld."),
                                 description, move->moved_to_repos_relpath,
                                 move->rev_author, move->rev);
      next = move->next;
    }

  return apr_pstrdup(result_pool, description);
}

/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
conflict_tree_get_local_description_generic(const char **description,
                                            svn_client_conflict_t *conflict,
                                            apr_pool_t *result_pool,
                                            apr_pool_t *scratch_pool)
{
  svn_node_kind_t victim_node_kind;

  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);

  *description = NULL;

  switch (victim_node_kind)
    {
      case svn_node_file:
      case svn_node_symlink:
        SVN_ERR(describe_local_file_node_change(description, conflict,
                                                result_pool, scratch_pool));
        break;
      case svn_node_dir:
        SVN_ERR(describe_local_dir_node_change(description, conflict,
                                               result_pool, scratch_pool));
        break;
      case svn_node_none:
      case svn_node_unknown:
        SVN_ERR(describe_local_none_node_change(description, conflict,
                                                result_pool, scratch_pool));
        break;
    }

  return SVN_NO_ERROR;
}

/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
conflict_tree_get_description_local_missing(const char **description,
                                            svn_client_conflict_t *conflict,
                                            apr_pool_t *result_pool,
                                            apr_pool_t *scratch_pool)
{
  struct conflict_tree_local_missing_details *details;

  details = conflict->tree_conflict_local_details;
  if (details == NULL)
    return svn_error_trace(conflict_tree_get_local_description_generic(
                             description, conflict, result_pool, scratch_pool));

  if (details->moves)
    {
      struct repos_move_info *move;

      move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
      *description = apr_psprintf(
                       result_pool,
                       _("No such file or directory was found in the "
                         "merge target working copy.\nThe item was "
                         "moved away to '^/%s' in r%ld by %s."),
                       move->moved_to_repos_relpath,
                       move->rev, move->rev_author);
      *description = append_moved_to_chain_description(*description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
    }
  else
    *description = apr_psprintf(
                     result_pool,
                     _("No such file or directory was found in the "
                       "merge target working copy.\n'^/%s' was deleted "
                       "in r%ld by %s."),
                     details->deleted_repos_relpath,
                     details->deleted_rev, details->deleted_rev_author);

  return SVN_NO_ERROR;
}

/* Return a localised string representation of the incoming part of a
   conflict; NULL for non-localised odd cases. */
static const char *
describe_incoming_change(svn_node_kind_t kind, svn_wc_conflict_action_t action,
                         svn_wc_operation_t operation)
{
  switch (kind)
    {
      case svn_node_file:
      case svn_node_symlink:
        if (operation == svn_wc_operation_update)
          {
            switch (action)
              {
                case svn_wc_conflict_action_edit:
                  return _("An update operation tried to edit a file.");
                case svn_wc_conflict_action_add:
                  return _("An update operation tried to add a file.");
                case svn_wc_conflict_action_delete:
                  return _("An update operation tried to delete or move "
                           "a file.");
                case svn_wc_conflict_action_replace:
                  return _("An update operation tried to replace a file.");
              }
          }
        else if (operation == svn_wc_operation_switch)
          {
            switch (action)
              {
                case svn_wc_conflict_action_edit:
                  return _("A switch operation tried to edit a file.");
                case svn_wc_conflict_action_add:
                  return _("A switch operation tried to add a file.");
                case svn_wc_conflict_action_delete:
                  return _("A switch operation tried to delete or move "
                           "a file.");
                case svn_wc_conflict_action_replace:
                  return _("A switch operation tried to replace a file.");
              }
          }
        else if (operation == svn_wc_operation_merge)
          {
            switch (action)
              {
                case svn_wc_conflict_action_edit:
                  return _("A merge operation tried to edit a file.");
                case svn_wc_conflict_action_add:
                  return _("A merge operation tried to add a file.");
                case svn_wc_conflict_action_delete:
                  return _("A merge operation tried to delete or move "
                           "a file.");
                case svn_wc_conflict_action_replace:
                  return _("A merge operation tried to replace a file.");
            }
          }
        break;
      case svn_node_dir:
        if (operation == svn_wc_operation_update)
          {
            switch (action)
              {
                case svn_wc_conflict_action_edit:
                  return _("An update operation tried to change a directory.");
                case svn_wc_conflict_action_add:
                  return _("An update operation tried to add a directory.");
                case svn_wc_conflict_action_delete:
                  return _("An update operation tried to delete or move "
                           "a directory.");
                case svn_wc_conflict_action_replace:
                  return _("An update operation tried to replace a directory.");
              }
          }
        else if (operation == svn_wc_operation_switch)
          {
            switch (action)
              {
                case svn_wc_conflict_action_edit:
                  return _("A switch operation tried to edit a directory.");
                case svn_wc_conflict_action_add:
                  return _("A switch operation tried to add a directory.");
                case svn_wc_conflict_action_delete:
                  return _("A switch operation tried to delete or move "
                           "a directory.");
                case svn_wc_conflict_action_replace:
                  return _("A switch operation tried to replace a directory.");
              }
          }
        else if (operation == svn_wc_operation_merge)
          {
            switch (action)
              {
                case svn_wc_conflict_action_edit:
                  return _("A merge operation tried to edit a directory.");
                case svn_wc_conflict_action_add:
                  return _("A merge operation tried to add a directory.");
                case svn_wc_conflict_action_delete:
                  return _("A merge operation tried to delete or move "
                           "a directory.");
                case svn_wc_conflict_action_replace:
                  return _("A merge operation tried to replace a directory.");
            }
          }
        break;
      case svn_node_none:
      case svn_node_unknown:
        if (operation == svn_wc_operation_update)
          {
            switch (action)
              {
                case svn_wc_conflict_action_edit:
                  return _("An update operation tried to edit an item.");
                case svn_wc_conflict_action_add:
                  return _("An update operation tried to add an item.");
                case svn_wc_conflict_action_delete:
                  return _("An update operation tried to delete or move "
                           "an item.");
                case svn_wc_conflict_action_replace:
                  return _("An update operation tried to replace an item.");
              }
          }
        else if (operation == svn_wc_operation_switch)
          {
            switch (action)
              {
                case svn_wc_conflict_action_edit:
                  return _("A switch operation tried to edit an item.");
                case svn_wc_conflict_action_add:
                  return _("A switch operation tried to add an item.");
                case svn_wc_conflict_action_delete:
                  return _("A switch operation tried to delete or move "
                           "an item.");
                case svn_wc_conflict_action_replace:
                  return _("A switch operation tried to replace an item.");
              }
          }
        else if (operation == svn_wc_operation_merge)
          {
            switch (action)
              {
                case svn_wc_conflict_action_edit:
                  return _("A merge operation tried to edit an item.");
                case svn_wc_conflict_action_add:
                  return _("A merge operation tried to add an item.");
                case svn_wc_conflict_action_delete:
                  return _("A merge operation tried to delete or move "
                           "an item.");
                case svn_wc_conflict_action_replace:
                  return _("A merge operation tried to replace an item.");
              }
          }
        break;
    }

  return NULL;
}

/* Return a localised string representation of the operation part of a
   conflict. */
static const char *
operation_str(svn_wc_operation_t operation)
{
  switch (operation)
    {
    case svn_wc_operation_update: return _("upon update");
    case svn_wc_operation_switch: return _("upon switch");
    case svn_wc_operation_merge:  return _("upon merge");
    case svn_wc_operation_none:   return _("upon none");
    }
  SVN_ERR_MALFUNCTION_NO_RETURN();
  return NULL;
}

svn_error_t *
svn_client_conflict_prop_get_description(const char **description,
                                         svn_client_conflict_t *conflict,
                                         apr_pool_t *result_pool,
                                         apr_pool_t *scratch_pool)
{
  const char *reason_str, *action_str;

  /* We provide separately translatable strings for the values that we
   * know about, and a fall-back in case any other values occur. */
  switch (svn_client_conflict_get_local_change(conflict))
    {
      case svn_wc_conflict_reason_edited:
        reason_str = _("local edit");
        break;
      case svn_wc_conflict_reason_added:
        reason_str = _("local add");
        break;
      case svn_wc_conflict_reason_deleted:
        reason_str = _("local delete");
        break;
      case svn_wc_conflict_reason_obstructed:
        reason_str = _("local obstruction");
        break;
      default:
        reason_str = apr_psprintf(
                       scratch_pool, _("local %s"),
                       svn_token__to_word(
                         map_conflict_reason,
                         svn_client_conflict_get_local_change(conflict)));
        break;
    }
  switch (svn_client_conflict_get_incoming_change(conflict))
    {
      case svn_wc_conflict_action_edit:
        action_str = _("incoming edit");
        break;
      case svn_wc_conflict_action_add:
        action_str = _("incoming add");
        break;
      case svn_wc_conflict_action_delete:
        action_str = _("incoming delete");
        break;
      default:
        action_str = apr_psprintf(
                       scratch_pool, _("incoming %s"),
                       svn_token__to_word(
                         map_conflict_action,
                         svn_client_conflict_get_incoming_change(conflict)));
        break;
    }
  SVN_ERR_ASSERT(reason_str && action_str);

  *description = apr_psprintf(result_pool, _("%s, %s %s"),
                              reason_str, action_str,
                              operation_str(
                                svn_client_conflict_get_operation(conflict)));

  return SVN_NO_ERROR;
}

/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
conflict_tree_get_incoming_description_generic(
  const char **incoming_change_description,
  svn_client_conflict_t *conflict,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  const char *action;
  svn_node_kind_t incoming_kind;
  svn_wc_conflict_action_t conflict_action;
  svn_wc_operation_t conflict_operation;
  svn_node_kind_t conflict_node_kind;

  conflict_action = svn_client_conflict_get_incoming_change(conflict);
  conflict_operation = svn_client_conflict_get_operation(conflict);
  conflict_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);

  /* Determine the node kind of the incoming change. */
  incoming_kind = svn_node_unknown;
  if (conflict_action == svn_wc_conflict_action_edit ||
      conflict_action == svn_wc_conflict_action_delete)
    {
      /* Change is acting on 'src_left' version of the node. */
      SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
                NULL, NULL, &incoming_kind, conflict, scratch_pool,
                scratch_pool));
    }
  else if (conflict_action == svn_wc_conflict_action_add ||
           conflict_action == svn_wc_conflict_action_replace)
    {
      /* Change is acting on 'src_right' version of the node.
       *
       * ### For 'replace', the node kind is ambiguous. However, src_left
       * ### is NULL for replace, so we must use src_right. */
      SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
                NULL, NULL, &incoming_kind, conflict, scratch_pool,
                scratch_pool));
    }

  action = describe_incoming_change(incoming_kind, conflict_action,
                                    conflict_operation);
  if (action)
    {
      *incoming_change_description = apr_pstrdup(result_pool, action);
    }
  else
    {
      /* A catch-all message for very rare or nominally impossible cases.
         It will not be pretty, but is closer to an internal error than
         an ordinary user-facing string. */
      *incoming_change_description = apr_psprintf(result_pool,
                                       _("incoming %s %s"),
                                       svn_node_kind_to_word(incoming_kind),
                                       svn_token__to_word(map_conflict_action,
                                                          conflict_action));
    }
  return SVN_NO_ERROR;
}

/* Details for tree conflicts involving incoming deletions and replacements. */
struct conflict_tree_incoming_delete_details
{
  /* If not SVN_INVALID_REVNUM, the node was deleted in DELETED_REV. */
  svn_revnum_t deleted_rev;

  /* If not SVN_INVALID_REVNUM, the node was added in ADDED_REV. The incoming
   * delete is the result of a reverse application of this addition. */
  svn_revnum_t added_rev;

  /* The path which was deleted/added relative to the repository root. */
  const char *repos_relpath;

  /* Author who committed DELETED_REV/ADDED_REV. */
  const char *rev_author;

  /* New node kind for a replaced node. This is svn_node_none for deletions. */
  svn_node_kind_t replacing_node_kind;

  /* Move information. If not NULL, this is an array of repos_move_info *
   * elements. Each element is the head of a move chain which starts in
   * DELETED_REV or in ADDED_REV (in which case moves should be interpreted
   * in reverse). */
  apr_array_header_t *moves;

  /* A map of repos_relpaths and working copy nodes for an incoming move.
   *
   * Each key is a "const char *" repository relpath corresponding to a
   * possible repository-side move destination node in the revision which
   * is the target revision in case of update and switch, or the merge-right
   * revision in case of a merge.
   *
   * Each value is an apr_array_header_t *.
   * Each array consists of "const char *" absolute paths to working copy
   * nodes which correspond to the repository node selected by the map key.
   * Each such working copy node is a potential local move target which can
   * be chosen to "follow" the incoming move when resolving a tree conflict.
   *
   * This may be an empty hash map in case if there is no move target path
   * in the working copy. */
  apr_hash_t *wc_move_targets;

  /* The preferred move target repository relpath. This is our key into
   * the WC_MOVE_TARGETS map above (can be overridden by the user). */
  const char *move_target_repos_relpath;

  /* The current index into the list of working copy nodes corresponding to
   * MOVE_TARGET_REPOS_REPLATH (can be overridden by the user). */
  int wc_move_target_idx;
};

static const char *
describe_incoming_deletion_upon_update(
  struct conflict_tree_incoming_delete_details *details,
  svn_node_kind_t victim_node_kind,
  svn_revnum_t old_rev,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  if (details->replacing_node_kind == svn_node_file ||
      details->replacing_node_kind == svn_node_symlink)
    {
      if (victim_node_kind == svn_node_dir)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Directory updated from r%ld to r%ld was "
                           "replaced with a file by %s in r%ld."),
                         old_rev, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced directory was moved to "
                               "'^/%s'."), description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("File updated from r%ld to r%ld was replaced "
                           "with a file from another line of history by "
                           "%s in r%ld."),
                         old_rev, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced file was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Item updated from r%ld to r%ld was replaced "
                           "with a file by %s in r%ld."), old_rev, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced item was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
    }
  else if (details->replacing_node_kind == svn_node_dir)
    {
      if (victim_node_kind == svn_node_dir)
        {
          const char *description =
            apr_psprintf(result_pool,
                          _("Directory updated from r%ld to r%ld was "
                            "replaced with a directory from another line "
                            "of history by %s in r%ld."),
                          old_rev, new_rev,
                          details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced directory was moved to "
                               "'^/%s'."), description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("File updated from r%ld to r%ld was "
                           "replaced with a directory by %s in r%ld."),
                         old_rev, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced file was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Item updated from r%ld to r%ld was replaced "
                           "by %s in r%ld."), old_rev, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced item was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
    }
  else
    {
      if (victim_node_kind == svn_node_dir)
        {
          if (details->moves)
            {
              const char *description;
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("Directory updated from r%ld to r%ld was "
                               "moved to '^/%s' by %s in r%ld."),
                             old_rev, new_rev,
                             move->moved_to_repos_relpath,
                             details->rev_author, details->deleted_rev);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          else
            return apr_psprintf(result_pool,
                                _("Directory updated from r%ld to r%ld was "
                                  "deleted by %s in r%ld."),
                                old_rev, new_rev,
                                details->rev_author, details->deleted_rev);
        }
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        {
          if (details->moves)
            {
              struct repos_move_info *move;
              const char *description;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("File updated from r%ld to r%ld was moved "
                               "to '^/%s' by %s in r%ld."), old_rev, new_rev,
                             move->moved_to_repos_relpath,
                             details->rev_author, details->deleted_rev);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          else
            return apr_psprintf(result_pool,
                                _("File updated from r%ld to r%ld was "
                                  "deleted by %s in r%ld."), old_rev, new_rev,
                                details->rev_author, details->deleted_rev);
        }
      else
        {
          if (details->moves)
            {
              const char *description;
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description = 
                apr_psprintf(result_pool,
                             _("Item updated from r%ld to r%ld was moved "
                               "to '^/%s' by %s in r%ld."), old_rev, new_rev,
                             move->moved_to_repos_relpath,
                             details->rev_author, details->deleted_rev);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          else
            return apr_psprintf(result_pool,
                                _("Item updated from r%ld to r%ld was "
                                  "deleted by %s in r%ld."), old_rev, new_rev,
                                details->rev_author, details->deleted_rev);
        }
    }
}

static const char *
describe_incoming_reverse_addition_upon_update(
  struct conflict_tree_incoming_delete_details *details,
  svn_node_kind_t victim_node_kind,
  svn_revnum_t old_rev,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool)
{
  if (details->replacing_node_kind == svn_node_file ||
      details->replacing_node_kind == svn_node_symlink)
    {
      if (victim_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Directory updated backwards from r%ld to r%ld "
                              "was a file before the replacement made by %s "
                              "in r%ld."), old_rev, new_rev,
                            details->rev_author, details->added_rev);
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("File updated backwards from r%ld to r%ld was a "
                              "file from another line of history before the "
                              "replacement made by %s in r%ld."),
                            old_rev, new_rev,
                            details->rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("Item updated backwards from r%ld to r%ld was "
                              "replaced with a file by %s in r%ld."),
                            old_rev, new_rev,
                            details->rev_author, details->added_rev);
    }
  else if (details->replacing_node_kind == svn_node_dir)
    {
      if (victim_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Directory updated backwards from r%ld to r%ld "
                              "was a directory from another line of history "
                              "before the replacement made by %s in "
                              "r%ld."), old_rev, new_rev,
                            details->rev_author, details->added_rev);
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("File updated backwards from r%ld to r%ld was a "
                              "directory before the replacement made by %s "
                              "in r%ld."), old_rev, new_rev,
                            details->rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("Item updated backwards from r%ld to r%ld was "
                              "replaced with a directory by %s in r%ld."),
                            old_rev, new_rev,
                            details->rev_author, details->added_rev);
    }
  else
    {
      if (victim_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Directory updated backwards from r%ld to r%ld "
                              "did not exist before it was added by %s in "
                              "r%ld."), old_rev, new_rev,
                            details->rev_author, details->added_rev);
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("File updated backwards from r%ld to r%ld did "
                              "not exist before it was added by %s in r%ld."),
                            old_rev, new_rev,
                            details->rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("Item updated backwards from r%ld to r%ld did "
                              "not exist before it was added by %s in r%ld."),
                            old_rev, new_rev,
                            details->rev_author, details->added_rev);
    }
}

static const char *
describe_incoming_deletion_upon_switch(
  struct conflict_tree_incoming_delete_details *details,
  svn_node_kind_t victim_node_kind,
  const char *old_repos_relpath,
  svn_revnum_t old_rev,
  const char *new_repos_relpath,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  if (details->replacing_node_kind == svn_node_file ||
      details->replacing_node_kind == svn_node_symlink)
    {
      if (victim_node_kind == svn_node_dir)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Directory switched from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                           "was replaced with a file by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced directory was moved "
                               "to '^/%s'."), description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;    
        }
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("File switched from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                           "replaced with a file from another line of "
                           "history by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced file was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Item switched from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                           "replaced with a file by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced item was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
    }
  else if (details->replacing_node_kind == svn_node_dir)
    {
      if (victim_node_kind == svn_node_dir)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Directory switched from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                           "was replaced with a directory from another "
                           "line of history by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced directory was moved to "
                               "'^/%s'."), description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("File switched from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                           "was replaced with a directory by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced file was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Item switched from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                           "replaced with a directory by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced item was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
    }
  else
    {
      if (victim_node_kind == svn_node_dir)
        {
          if (details->moves)
            {
              struct repos_move_info *move;
              const char *description;
              
              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("Directory switched from\n"
                               "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                               "was moved to '^/%s' by %s in r%ld."),
                             old_repos_relpath, old_rev,
                             new_repos_relpath, new_rev,
                             move->moved_to_repos_relpath,
                             details->rev_author, details->deleted_rev);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          else
            return apr_psprintf(result_pool,
                                _("Directory switched from\n"
                                  "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                                  "was deleted by %s in r%ld."),
                                old_repos_relpath, old_rev,
                                new_repos_relpath, new_rev,
                                details->rev_author, details->deleted_rev);
        }
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        {
          if (details->moves)
            {
              struct repos_move_info *move;
              const char *description;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("File switched from\n"
                               "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                               "moved to '^/%s' by %s in r%ld."),
                             old_repos_relpath, old_rev,
                             new_repos_relpath, new_rev,
                             move->moved_to_repos_relpath,
                             details->rev_author, details->deleted_rev);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          else
            return apr_psprintf(result_pool,
                                _("File switched from\n"
                                  "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                                  "deleted by %s in r%ld."),
                                old_repos_relpath, old_rev,
                                new_repos_relpath, new_rev,
                                details->rev_author, details->deleted_rev);
        }
      else
        {
          if (details->moves)
            {
              struct repos_move_info *move;
              const char *description;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("Item switched from\n"
                               "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                               "moved to '^/%s' by %s in r%ld."),
                             old_repos_relpath, old_rev,
                             new_repos_relpath, new_rev,
                             move->moved_to_repos_relpath,
                             details->rev_author, details->deleted_rev);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          else
            return apr_psprintf(result_pool,
                                _("Item switched from\n"
                                  "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                                  "deleted by %s in r%ld."),
                                old_repos_relpath, old_rev,
                                new_repos_relpath, new_rev,
                                details->rev_author, details->deleted_rev);
        }
    }
}

static const char *
describe_incoming_reverse_addition_upon_switch(
  struct conflict_tree_incoming_delete_details *details,
  svn_node_kind_t victim_node_kind,
  const char *old_repos_relpath,
  svn_revnum_t old_rev,
  const char *new_repos_relpath,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool)
{
  if (details->replacing_node_kind == svn_node_file ||
      details->replacing_node_kind == svn_node_symlink)
    {
      if (victim_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Directory switched from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                              "was a file before the replacement made by %s "
                              "in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("File switched from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas a "
                              "file from another line of history before the "
                              "replacement made by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("Item switched from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                              "replaced with a file by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
    }
  else if (details->replacing_node_kind == svn_node_dir)
    {
      if (victim_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Directory switched from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                              "was a directory from another line of history "
                              "before the replacement made by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("Directory switched from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                              "was a file before the replacement made by %s "
                              "in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("Item switched from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                              "replaced with a directory by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
    }
  else
    {
      if (victim_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Directory switched from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                              "did not exist before it was added by %s in "
                              "r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("File switched from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\ndid "
                              "not exist before it was added by %s in "
                              "r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("Item switched from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\ndid "
                              "not exist before it was added by %s in "
                              "r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
    }
}

static const char *
describe_incoming_deletion_upon_merge(
  struct conflict_tree_incoming_delete_details *details,
  svn_node_kind_t victim_node_kind,
  const char *old_repos_relpath,
  svn_revnum_t old_rev,
  const char *new_repos_relpath,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  if (details->replacing_node_kind == svn_node_file ||
      details->replacing_node_kind == svn_node_symlink)
    {
      if (victim_node_kind == svn_node_dir)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Directory merged from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                           "was replaced with a file by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced directory was moved to "
                               "'^/%s'."), description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("File merged from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                           "replaced with a file from another line of "
                           "history by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced file was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else
        return apr_psprintf(result_pool,
                            _("Item merged from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                              "replaced with a file by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->deleted_rev);
    }
  else if (details->replacing_node_kind == svn_node_dir)
    {
      if (victim_node_kind == svn_node_dir)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Directory merged from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                           "was replaced with a directory from another "
                           "line of history by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced directory was moved to "
                               "'^/%s'."), description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("File merged from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                           "was replaced with a directory by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced file was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
      else
        {
          const char *description =
            apr_psprintf(result_pool,
                         _("Item merged from\n"
                           "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                           "replaced with a directory by %s in r%ld."),
                         old_repos_relpath, old_rev,
                         new_repos_relpath, new_rev,
                         details->rev_author, details->deleted_rev);
          if (details->moves)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("%s\nThe replaced item was moved to '^/%s'."),
                             description,
                             move->moved_to_repos_relpath);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          return description;
        }
    }
  else
    {
      if (victim_node_kind == svn_node_dir)
        {
          if (details->moves)
            {
              struct repos_move_info *move;
              const char *description;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("Directory merged from\n"
                               "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                               "moved to '^/%s' by %s in r%ld."),
                             old_repos_relpath, old_rev,
                             new_repos_relpath, new_rev,
                             move->moved_to_repos_relpath,
                             details->rev_author, details->deleted_rev);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          else
            return apr_psprintf(result_pool,
                                _("Directory merged from\n"
                                  "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                                  "deleted by %s in r%ld."),
                                old_repos_relpath, old_rev,
                                new_repos_relpath, new_rev,
                                details->rev_author, details->deleted_rev);
        }
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        {
          if (details->moves)
            {
              struct repos_move_info *move;
              const char *description;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("File merged from\n"
                               "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                               "moved to '^/%s' by %s in r%ld."),
                             old_repos_relpath, old_rev,
                             new_repos_relpath, new_rev,
                             move->moved_to_repos_relpath,
                             details->rev_author, details->deleted_rev);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          else
            return apr_psprintf(result_pool,
                                _("File merged from\n"
                                  "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                                  "deleted by %s in r%ld."),
                                old_repos_relpath, old_rev,
                                new_repos_relpath, new_rev,
                                details->rev_author, details->deleted_rev);
        }
      else
        {
          if (details->moves)
            {
              struct repos_move_info *move;
              const char *description;

              move = APR_ARRAY_IDX(details->moves, 0, struct repos_move_info *);
              description =
                apr_psprintf(result_pool,
                             _("Item merged from\n"
                               "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                               "moved to '^/%s' by %s in r%ld."),
                             old_repos_relpath, old_rev,
                             new_repos_relpath, new_rev,
                             move->moved_to_repos_relpath,
                             details->rev_author, details->deleted_rev);
              return append_moved_to_chain_description(description,
                                                       move->next,
                                                       result_pool,
                                                       scratch_pool);
            }
          else
            return apr_psprintf(result_pool,
                                _("Item merged from\n"
                                  "'^/%s@%ld'\nto\n'^/%s@%ld'\nwas "
                                  "deleted by %s in r%ld."),
                                old_repos_relpath, old_rev,
                                new_repos_relpath, new_rev,
                                details->rev_author, details->deleted_rev);
        }
    }
}

static const char *
describe_incoming_reverse_addition_upon_merge(
  struct conflict_tree_incoming_delete_details *details,
  svn_node_kind_t victim_node_kind,
  const char *old_repos_relpath,
  svn_revnum_t old_rev,
  const char *new_repos_relpath,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool)
{
  if (details->replacing_node_kind == svn_node_file ||
      details->replacing_node_kind == svn_node_symlink)
    {
      if (victim_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Directory reverse-merged from\n'^/%s@%ld'\nto "
                              "^/%s@%ld was a file before the replacement "
                              "made by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("File reverse-merged from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                              "was a file from another line of history before "
                              "the replacement made by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("Item reverse-merged from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                              "was replaced with a file by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
    }
  else if (details->replacing_node_kind == svn_node_dir)
    {
      if (victim_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Directory reverse-merged from\n'^/%s@%ld'\nto "
                              "^/%s@%ld was a directory from another line "
                              "of history before the replacement made by %s "
                              "in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("Directory reverse-merged from\n'^/%s@%ld'\nto "
                              "^/%s@%ld was a file before the replacement "
                              "made by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("Item reverse-merged from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                              "was replaced with a directory by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
    }
  else
    {
      if (victim_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Directory reverse-merged from\n'^/%s@%ld'\nto "
                              "^/%s@%ld did not exist before it was added "
                              "by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else if (victim_node_kind == svn_node_file ||
               victim_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("File reverse-merged from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                              "did not exist before it was added by %s in "
                              "r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("Item reverse-merged from\n"
                              "'^/%s@%ld'\nto\n'^/%s@%ld'\n"
                              "did not exist before it was added by %s in "
                              "r%ld."),
                            old_repos_relpath, old_rev,
                            new_repos_relpath, new_rev,
                            details->rev_author, details->added_rev);
    }
}

/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
conflict_tree_get_description_incoming_delete(
  const char **incoming_change_description,
  svn_client_conflict_t *conflict,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  const char *action;
  svn_node_kind_t victim_node_kind;
  svn_wc_operation_t conflict_operation;
  const char *old_repos_relpath;
  svn_revnum_t old_rev;
  const char *new_repos_relpath;
  svn_revnum_t new_rev;
  struct conflict_tree_incoming_delete_details *details;

  if (conflict->tree_conflict_incoming_details == NULL)
    return svn_error_trace(conflict_tree_get_incoming_description_generic(
                             incoming_change_description,
                             conflict, result_pool, scratch_pool));

  conflict_operation = svn_client_conflict_get_operation(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &old_repos_relpath, &old_rev, NULL, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &new_repos_relpath, &new_rev, NULL, conflict, scratch_pool,
            scratch_pool));

  details = conflict->tree_conflict_incoming_details;

  if (conflict_operation == svn_wc_operation_update)
    {
      if (details->deleted_rev != SVN_INVALID_REVNUM)
        {
          action = describe_incoming_deletion_upon_update(details,
                                                          victim_node_kind,
                                                          old_rev,
                                                          new_rev,
                                                          result_pool,
                                                          scratch_pool);
        }
      else /* details->added_rev != SVN_INVALID_REVNUM */
        {
          /* This deletion is really the reverse change of an addition. */
          action = describe_incoming_reverse_addition_upon_update(
                     details, victim_node_kind, old_rev, new_rev, result_pool);
        }
    }
  else if (conflict_operation == svn_wc_operation_switch)
    {
      if (details->deleted_rev != SVN_INVALID_REVNUM)
        {
          action = describe_incoming_deletion_upon_switch(details,
                                                          victim_node_kind,
                                                          old_repos_relpath,
                                                          old_rev,
                                                          new_repos_relpath,
                                                          new_rev,
                                                          result_pool,
                                                          scratch_pool);
        }
      else /* details->added_rev != SVN_INVALID_REVNUM */
        {
          /* This deletion is really the reverse change of an addition. */
          action = describe_incoming_reverse_addition_upon_switch(
                     details, victim_node_kind, old_repos_relpath, old_rev,
                     new_repos_relpath, new_rev, result_pool);
            
        }
      }
  else if (conflict_operation == svn_wc_operation_merge)
    {
      if (details->deleted_rev != SVN_INVALID_REVNUM)
        {
          action = describe_incoming_deletion_upon_merge(details,
                                                         victim_node_kind,
                                                         old_repos_relpath,
                                                         old_rev,
                                                         new_repos_relpath,
                                                         new_rev,
                                                         result_pool,
                                                         scratch_pool);
        }
      else /* details->added_rev != SVN_INVALID_REVNUM */
        {
          /* This deletion is really the reverse change of an addition. */
          action = describe_incoming_reverse_addition_upon_merge(
                     details, victim_node_kind, old_repos_relpath, old_rev,
                     new_repos_relpath, new_rev, result_pool);
        }
      }

  *incoming_change_description = apr_pstrdup(result_pool, action);

  return SVN_NO_ERROR;
}

/* Baton for find_added_rev(). */
struct find_added_rev_baton
{
  const char *victim_abspath;
  svn_client_ctx_t *ctx;
  svn_revnum_t added_rev;
  const char *repos_relpath;
  const char *parent_repos_relpath;
  apr_pool_t *pool;
};

/* Implements svn_location_segment_receiver_t.
 * Finds the revision in which a node was added by tracing 'start'
 * revisions in location segments reported for the node.
 * If the PARENT_REPOS_RELPATH in the baton is not NULL, only consider
 * segments in which the node existed somwhere beneath this path. */
static svn_error_t *
find_added_rev(svn_location_segment_t *segment,
               void *baton,
               apr_pool_t *scratch_pool)
{
  struct find_added_rev_baton *b = baton;

  if (b->ctx->notify_func2)
    {
      svn_wc_notify_t *notify;

      notify = svn_wc_create_notify(
                 b->victim_abspath,
                 svn_wc_notify_tree_conflict_details_progress,
                 scratch_pool),
      notify->revision = segment->range_start;
      b->ctx->notify_func2(b->ctx->notify_baton2, notify, scratch_pool);
    }

  if (segment->path) /* not interested in gaps */
    {
      if (b->parent_repos_relpath == NULL ||
          svn_relpath_skip_ancestor(b->parent_repos_relpath,
                                    segment->path) != NULL)
        {
          b->added_rev = segment->range_start;
          b->repos_relpath = apr_pstrdup(b->pool, segment->path);
        }
    }

  return SVN_NO_ERROR;
}

/* Find conflict details in the case where a revision which added a node was
 * applied in reverse, resulting in an incoming deletion. */
static svn_error_t *
get_incoming_delete_details_for_reverse_addition(
  struct conflict_tree_incoming_delete_details **details,
  const char *repos_root_url,
  const char *old_repos_relpath,
  svn_revnum_t old_rev,
  svn_revnum_t new_rev,
  svn_client_ctx_t *ctx,
  const char *victim_abspath,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  svn_ra_session_t *ra_session;
  const char *url;
  const char *corrected_url;
  svn_string_t *author_revprop;
  struct find_added_rev_baton b;

  url = svn_path_url_add_component2(repos_root_url, old_repos_relpath,
                                    scratch_pool);
  SVN_ERR(svn_client__open_ra_session_internal(&ra_session,
                                               &corrected_url,
                                               url, NULL, NULL,
                                               FALSE,
                                               FALSE,
                                               ctx,
                                               scratch_pool,
                                               scratch_pool));

  *details = apr_pcalloc(result_pool, sizeof(**details));
  b.ctx = ctx;
  b.victim_abspath = victim_abspath;
  b.added_rev = SVN_INVALID_REVNUM;
  b.repos_relpath = NULL;
  b.parent_repos_relpath = NULL;
  b.pool = scratch_pool;

  /* Figure out when this node was added. */
  SVN_ERR(svn_ra_get_location_segments(ra_session, "", old_rev,
                                       old_rev, new_rev,
                                       find_added_rev, &b,
                                       scratch_pool));

  SVN_ERR(svn_ra_rev_prop(ra_session, b.added_rev,
                          SVN_PROP_REVISION_AUTHOR,
                          &author_revprop, scratch_pool));
  (*details)->deleted_rev = SVN_INVALID_REVNUM;
  (*details)->added_rev = b.added_rev;
  (*details)->repos_relpath = apr_pstrdup(result_pool, b.repos_relpath);
  (*details)->rev_author = apr_pstrdup(result_pool, author_revprop->data);

  /* Check for replacement. */
  (*details)->replacing_node_kind = svn_node_none;
  if ((*details)->added_rev > 0)
    {
      svn_node_kind_t replaced_node_kind;

      SVN_ERR(svn_ra_check_path(ra_session, "", (*details)->added_rev - 1,
                                &replaced_node_kind, scratch_pool));
      if (replaced_node_kind != svn_node_none)
        SVN_ERR(svn_ra_check_path(ra_session, "", (*details)->added_rev,
                                  &(*details)->replacing_node_kind,
                                  scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Implements tree_conflict_get_details_func_t.
 * Find the revision in which the victim was deleted in the repository. */
static svn_error_t *
conflict_tree_get_details_incoming_delete(svn_client_conflict_t *conflict,
                                          apr_pool_t *scratch_pool)
{
  const char *old_repos_relpath;
  const char *new_repos_relpath;
  const char *repos_root_url;
  const char *repos_uuid;
  svn_revnum_t old_rev;
  svn_revnum_t new_rev;
  struct conflict_tree_incoming_delete_details *details;
  svn_wc_operation_t operation;

  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &old_repos_relpath, &old_rev, NULL, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &new_repos_relpath, &new_rev, NULL, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
                                             conflict,
                                             scratch_pool, scratch_pool));
  operation = svn_client_conflict_get_operation(conflict);

  if (operation == svn_wc_operation_update)
    {
      if (old_rev < new_rev)
        {
          const char *parent_repos_relpath;
          svn_revnum_t deleted_rev;
          const char *deleted_rev_author;
          svn_node_kind_t replacing_node_kind;
          apr_array_header_t *moves;

          /* The update operation went forward in history. */

          SVN_ERR(svn_wc__node_get_repos_info(NULL, &parent_repos_relpath,
                                              NULL, NULL,
                                              conflict->ctx->wc_ctx,
                                              svn_dirent_dirname(
                                                conflict->local_abspath,
                                                scratch_pool),
                                              scratch_pool,
                                              scratch_pool));
          SVN_ERR(find_revision_for_suspected_deletion(
                    &deleted_rev, &deleted_rev_author, &replacing_node_kind,
                    &moves, conflict,
                    svn_dirent_basename(conflict->local_abspath, scratch_pool),
                    parent_repos_relpath, new_rev, old_rev,
                    NULL, SVN_INVALID_REVNUM, /* related to self */
                    conflict->pool, scratch_pool));
          if (deleted_rev == SVN_INVALID_REVNUM)
            {
              /* We could not determine the revision in which the node was
               * deleted. We cannot provide the required details so the best
               * we can do is fall back to the default description. */
              return SVN_NO_ERROR;
            }

          details = apr_pcalloc(conflict->pool, sizeof(*details));
          details->deleted_rev = deleted_rev;
          details->added_rev = SVN_INVALID_REVNUM;
          details->repos_relpath = apr_pstrdup(conflict->pool,
                                               new_repos_relpath);
          details->rev_author = deleted_rev_author;
          details->replacing_node_kind = replacing_node_kind;
          details->moves = moves;
        }
      else /* new_rev < old_rev */
        {
          /* The update operation went backwards in history.
           * Figure out when this node was added. */
          SVN_ERR(get_incoming_delete_details_for_reverse_addition(
                    &details, repos_root_url, old_repos_relpath,
                    old_rev, new_rev, conflict->ctx,
                    svn_client_conflict_get_local_abspath(conflict),
                    conflict->pool, scratch_pool));
        }
    }
  else if (operation == svn_wc_operation_switch ||
           operation == svn_wc_operation_merge)
    {
      if (old_rev < new_rev)
        {
          svn_revnum_t deleted_rev;
          const char *deleted_rev_author;
          svn_node_kind_t replacing_node_kind;
          apr_array_header_t *moves;

          /* The switch/merge operation went forward in history.
           *
           * The deletion of the node happened on the branch we switched to
           * or merged from. Scan new_repos_relpath's parent's log to find
           * the revision which deleted the node. */
          SVN_ERR(find_revision_for_suspected_deletion(
                    &deleted_rev, &deleted_rev_author, &replacing_node_kind,
                    &moves, conflict,
                    svn_relpath_basename(new_repos_relpath, scratch_pool),
                    svn_relpath_dirname(new_repos_relpath, scratch_pool),
                    new_rev, old_rev, old_repos_relpath, old_rev,
                    scratch_pool, scratch_pool));
          if (deleted_rev == SVN_INVALID_REVNUM)
            {
              /* We could not determine the revision in which the node was
               * deleted. We cannot provide the required details so the best
               * we can do is fall back to the default description. */
              return SVN_NO_ERROR;
            }

          details = apr_pcalloc(conflict->pool, sizeof(*details));
          details->deleted_rev = deleted_rev;
          details->added_rev = SVN_INVALID_REVNUM;
          details->repos_relpath = apr_pstrdup(conflict->pool,
                                               new_repos_relpath);
          details->rev_author = apr_pstrdup(conflict->pool,
                                            deleted_rev_author);
          details->replacing_node_kind = replacing_node_kind;
          details->moves = moves;
        }
      else /* new_rev < old_rev */
        {
          /* The switch/merge operation went backwards in history.
           * Figure out when the node we switched away from, or merged
           * from another branch, was added. */
          SVN_ERR(get_incoming_delete_details_for_reverse_addition(
                    &details, repos_root_url, old_repos_relpath,
                    old_rev, new_rev, conflict->ctx,
                    svn_client_conflict_get_local_abspath(conflict),
                    conflict->pool, scratch_pool));
        }
    }
  else
    {
      details = NULL;
    }

  conflict->tree_conflict_incoming_details = details;

  return SVN_NO_ERROR;
}

/* Details for tree conflicts involving incoming additions. */
struct conflict_tree_incoming_add_details
{
  /* If not SVN_INVALID_REVNUM, the node was added in ADDED_REV. */
  svn_revnum_t added_rev;

  /* If not SVN_INVALID_REVNUM, the node was deleted in DELETED_REV.
   * Note that both ADDED_REV and DELETED_REV may be valid for update/switch.
   * See comment in conflict_tree_get_details_incoming_add() for details. */
  svn_revnum_t deleted_rev;

  /* The path which was added/deleted relative to the repository root. */
  const char *repos_relpath;

  /* Authors who committed ADDED_REV/DELETED_REV. */
  const char *added_rev_author;
  const char *deleted_rev_author;

  /* Move information. If not NULL, this is an array of repos_move_info *
   * elements. Each element is the head of a move chain which starts in
   * ADDED_REV or in DELETED_REV (in which case moves should be interpreted
   * in reverse). */
  apr_array_header_t *moves;
};

/* Implements tree_conflict_get_details_func_t.
 * Find the revision in which the victim was added in the repository. */
static svn_error_t *
conflict_tree_get_details_incoming_add(svn_client_conflict_t *conflict,
                                       apr_pool_t *scratch_pool)
{
  const char *old_repos_relpath;
  const char *new_repos_relpath;
  const char *repos_root_url;
  const char *repos_uuid;
  svn_revnum_t old_rev;
  svn_revnum_t new_rev;
  struct conflict_tree_incoming_add_details *details;
  svn_wc_operation_t operation;

  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &old_repos_relpath, &old_rev, NULL, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &new_repos_relpath, &new_rev, NULL, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
                                             conflict,
                                             scratch_pool, scratch_pool));
  operation = svn_client_conflict_get_operation(conflict);

  if (operation == svn_wc_operation_update ||
      operation == svn_wc_operation_switch)
    {
      /* Only the new repository location is recorded for the node which
       * caused an incoming addition. There is no pre-update/pre-switch
       * revision to be recorded for the node since it does not exist in
       * the repository at that revision.
       * The implication is that we cannot know whether the operation went
       * forward or backwards in history. So always try to find an added
       * and a deleted revision for the node. Users must figure out by whether
       * the addition or deletion caused the conflict. */
      const char *url;
      const char *corrected_url;
      svn_string_t *author_revprop;
      struct find_added_rev_baton b;
      svn_ra_session_t *ra_session;
      svn_revnum_t deleted_rev;
      svn_revnum_t head_rev;

      url = svn_path_url_add_component2(repos_root_url, new_repos_relpath,
                                        scratch_pool);
      SVN_ERR(svn_client__open_ra_session_internal(&ra_session,
                                                   &corrected_url,
                                                   url, NULL, NULL,
                                                   FALSE,
                                                   FALSE,
                                                   conflict->ctx,
                                                   scratch_pool,
                                                   scratch_pool));

      details = apr_pcalloc(conflict->pool, sizeof(*details));
      b.ctx = conflict->ctx,
      b.victim_abspath = svn_client_conflict_get_local_abspath(conflict),
      b.added_rev = SVN_INVALID_REVNUM;
      b.repos_relpath = NULL;
      b.parent_repos_relpath = NULL;
      b.pool = scratch_pool;

      /* Figure out when this node was added. */
      SVN_ERR(svn_ra_get_location_segments(ra_session, "", new_rev,
                                           new_rev, SVN_INVALID_REVNUM,
                                           find_added_rev, &b,
                                           scratch_pool));

      SVN_ERR(svn_ra_rev_prop(ra_session, b.added_rev,
                              SVN_PROP_REVISION_AUTHOR,
                              &author_revprop, scratch_pool));
      details->repos_relpath = apr_pstrdup(conflict->pool, b.repos_relpath);
      details->added_rev = b.added_rev;
      details->added_rev_author = apr_pstrdup(conflict->pool,
                                        author_revprop->data);

      details->deleted_rev = SVN_INVALID_REVNUM;
      details->deleted_rev_author = NULL;

      /* Figure out whether this node was deleted later.
       * ### Could probably optimize by infering both addition and deletion
       * ### from svn_ra_get_location_segments() call above. */
      SVN_ERR(svn_ra_get_latest_revnum(ra_session, &head_rev, scratch_pool));
      if (new_rev < head_rev)
        {
          SVN_ERR(svn_ra_get_deleted_rev(ra_session, "", new_rev, head_rev,
                                         &deleted_rev, scratch_pool));
          if (SVN_IS_VALID_REVNUM(deleted_rev))
           {
              SVN_ERR(svn_ra_rev_prop(ra_session, deleted_rev,
                                      SVN_PROP_REVISION_AUTHOR,
                                      &author_revprop, scratch_pool));
              details->deleted_rev = deleted_rev;
              details->deleted_rev_author = apr_pstrdup(conflict->pool,
                                                        author_revprop->data);
            }
        }
    }
  else if (operation == svn_wc_operation_merge)
    {
      if (old_rev < new_rev)
        {
          /* The merge operation went forwards in history.
           * The addition of the node happened on the branch we merged form.
           * Scan the nodes's history to find the revision which added it. */
          const char *url;
          const char *corrected_url;
          svn_string_t *author_revprop;
          struct find_added_rev_baton b;
          svn_ra_session_t *ra_session;

          url = svn_path_url_add_component2(repos_root_url, new_repos_relpath,
                                            scratch_pool);
          SVN_ERR(svn_client__open_ra_session_internal(&ra_session,
                                                       &corrected_url,
                                                       url, NULL, NULL,
                                                       FALSE,
                                                       FALSE,
                                                       conflict->ctx,
                                                       scratch_pool,
                                                       scratch_pool));

          details = apr_pcalloc(conflict->pool, sizeof(*details));
          b.victim_abspath = svn_client_conflict_get_local_abspath(conflict);
          b.ctx = conflict->ctx;
          b.added_rev = SVN_INVALID_REVNUM;
          b.repos_relpath = NULL;
          b.parent_repos_relpath = NULL;
          b.pool = scratch_pool;

          /* Figure out when this node was added. */
          SVN_ERR(svn_ra_get_location_segments(ra_session, "", new_rev,
                                               new_rev, old_rev,
                                               find_added_rev, &b,
                                               scratch_pool));

          SVN_ERR(svn_ra_rev_prop(ra_session, b.added_rev,
                                  SVN_PROP_REVISION_AUTHOR,
                                  &author_revprop, scratch_pool));
          details->repos_relpath = apr_pstrdup(conflict->pool, b.repos_relpath);
          details->added_rev = b.added_rev;
          details->added_rev_author = apr_pstrdup(conflict->pool,
                                                  author_revprop->data);

          details->deleted_rev = SVN_INVALID_REVNUM;
          details->deleted_rev_author = NULL;
        }
      else
        {
          /* The merge operation was a reverse-merge.
           * This addition is in fact a deletion, applied in reverse,
           * which happened on the branch we merged from.
           * Find the revision which deleted the node. */
          svn_revnum_t deleted_rev;
          const char *deleted_rev_author;
          svn_node_kind_t replacing_node_kind;
          apr_array_header_t *moves;

          SVN_ERR(find_revision_for_suspected_deletion(
                    &deleted_rev, &deleted_rev_author, &replacing_node_kind,
                    &moves, conflict,
                    svn_relpath_basename(old_repos_relpath, scratch_pool),
                    svn_relpath_dirname(old_repos_relpath, scratch_pool),
                    old_rev, new_rev,
                    NULL, SVN_INVALID_REVNUM, /* related to self */
                    conflict->pool, scratch_pool));
          if (deleted_rev == SVN_INVALID_REVNUM)
            {
              /* We could not determine the revision in which the node was
               * deleted. We cannot provide the required details so the best
               * we can do is fall back to the default description. */
              return SVN_NO_ERROR;
            }

          details = apr_pcalloc(conflict->pool, sizeof(*details));
          details->repos_relpath = apr_pstrdup(conflict->pool,
                                               new_repos_relpath);
          details->deleted_rev = deleted_rev;
          details->deleted_rev_author = apr_pstrdup(conflict->pool,
                                                    deleted_rev_author);

          details->added_rev = SVN_INVALID_REVNUM;
          details->added_rev_author = NULL;
          details->moves = moves;
        }
    }
  else
    {
      details = NULL;
    }

  conflict->tree_conflict_incoming_details = details;

  return SVN_NO_ERROR;
}

static const char *
describe_incoming_add_upon_update(
  struct conflict_tree_incoming_add_details *details,
  svn_node_kind_t new_node_kind,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool)
{
  if (new_node_kind == svn_node_dir)
    {
      if (SVN_IS_VALID_REVNUM(details->added_rev) &&
          SVN_IS_VALID_REVNUM(details->deleted_rev))
        return apr_psprintf(result_pool,
                            _("A new directory appeared during update to r%ld; "
                              "it was added by %s in r%ld and later deleted "
                              "by %s in r%ld."), new_rev,
                            details->added_rev_author, details->added_rev,
                            details->deleted_rev_author, details->deleted_rev);
      else if (SVN_IS_VALID_REVNUM(details->added_rev))
        return apr_psprintf(result_pool,
                            _("A new directory appeared during update to r%ld; "
                              "it was added by %s in r%ld."), new_rev,
                            details->added_rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new directory appeared during update to r%ld; "
                              "it was deleted by %s in r%ld."), new_rev,
                            details->deleted_rev_author, details->deleted_rev);
    }
  else if (new_node_kind == svn_node_file ||
           new_node_kind == svn_node_symlink)
    {
      if (SVN_IS_VALID_REVNUM(details->added_rev) &&
          SVN_IS_VALID_REVNUM(details->deleted_rev))
        return apr_psprintf(result_pool,
                            _("A new file appeared during update to r%ld; "
                              "it was added by %s in r%ld and later deleted "
                              "by %s in r%ld."), new_rev,
                            details->added_rev_author, details->added_rev,
                            details->deleted_rev_author, details->deleted_rev);
      else if (SVN_IS_VALID_REVNUM(details->added_rev))
        return apr_psprintf(result_pool,
                            _("A new file appeared during update to r%ld; "
                              "it was added by %s in r%ld."), new_rev,
                            details->added_rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new file appeared during update to r%ld; "
                              "it was deleted by %s in r%ld."), new_rev,
                            details->deleted_rev_author, details->deleted_rev);
    }
  else
    {
      if (SVN_IS_VALID_REVNUM(details->added_rev) &&
          SVN_IS_VALID_REVNUM(details->deleted_rev))
        return apr_psprintf(result_pool,
                            _("A new item appeared during update to r%ld; "
                              "it was added by %s in r%ld and later deleted "
                              "by %s in r%ld."), new_rev,
                            details->added_rev_author, details->added_rev,
                            details->deleted_rev_author, details->deleted_rev);
      else if (SVN_IS_VALID_REVNUM(details->added_rev))
        return apr_psprintf(result_pool,
                            _("A new item appeared during update to r%ld; "
                              "it was added by %s in r%ld."), new_rev,
                            details->added_rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new item appeared during update to r%ld; "
                              "it was deleted by %s in r%ld."), new_rev,
                            details->deleted_rev_author, details->deleted_rev);
    }
}

static const char *
describe_incoming_add_upon_switch(
  struct conflict_tree_incoming_add_details *details,
  svn_node_kind_t victim_node_kind,
  const char *new_repos_relpath,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool)
{
  if (victim_node_kind == svn_node_dir)
    {
      if (SVN_IS_VALID_REVNUM(details->added_rev) &&
          SVN_IS_VALID_REVNUM(details->deleted_rev))
        return apr_psprintf(result_pool,
                            _("A new directory appeared during switch to\n"
                              "'^/%s@%ld'.\n"
                              "It was added by %s in r%ld and later deleted "
                              "by %s in r%ld."), new_repos_relpath, new_rev,
                            details->added_rev_author, details->added_rev,
                            details->deleted_rev_author, details->deleted_rev);
      else if (SVN_IS_VALID_REVNUM(details->added_rev))
        return apr_psprintf(result_pool,
                            _("A new directory appeared during switch to\n"
                             "'^/%s@%ld'.\nIt was added by %s in r%ld."),
                            new_repos_relpath, new_rev,
                            details->added_rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new directory appeared during switch to\n"
                              "'^/%s@%ld'.\nIt was deleted by %s in r%ld."),
                            new_repos_relpath, new_rev,
                            details->deleted_rev_author, details->deleted_rev);
    }
  else if (victim_node_kind == svn_node_file ||
           victim_node_kind == svn_node_symlink)
    {
      if (SVN_IS_VALID_REVNUM(details->added_rev) &&
          SVN_IS_VALID_REVNUM(details->deleted_rev))
        return apr_psprintf(result_pool,
                            _("A new file appeared during switch to\n"
                              "'^/%s@%ld'.\n"
                              "It was added by %s in r%ld and later deleted "
                              "by %s in r%ld."), new_repos_relpath, new_rev,
                            details->added_rev_author, details->added_rev,
                            details->deleted_rev_author, details->deleted_rev);
      else if (SVN_IS_VALID_REVNUM(details->added_rev))
        return apr_psprintf(result_pool,
                            _("A new file appeared during switch to\n"
                              "'^/%s@%ld'.\n"
                              "It was added by %s in r%ld."),
                            new_repos_relpath, new_rev,
                            details->added_rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new file appeared during switch to\n"
                              "'^/%s@%ld'.\n"
                              "It was deleted by %s in r%ld."),
                            new_repos_relpath, new_rev,
                            details->deleted_rev_author, details->deleted_rev);
    }
  else
    {
      if (SVN_IS_VALID_REVNUM(details->added_rev) &&
          SVN_IS_VALID_REVNUM(details->deleted_rev))
        return apr_psprintf(result_pool,
                            _("A new item appeared during switch to\n"
                              "'^/%s@%ld'.\n"
                              "It was added by %s in r%ld and later deleted "
                              "by %s in r%ld."), new_repos_relpath, new_rev,
                            details->added_rev_author, details->added_rev,
                            details->deleted_rev_author, details->deleted_rev);
      else if (SVN_IS_VALID_REVNUM(details->added_rev))
        return apr_psprintf(result_pool,
                            _("A new item appeared during switch to\n"
                              "'^/%s@%ld'.\n"
                              "It was added by %s in r%ld."),
                            new_repos_relpath, new_rev,
                            details->added_rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new item appeared during switch to\n"
                              "'^/%s@%ld'.\n"
                              "It was deleted by %s in r%ld."),
                            new_repos_relpath, new_rev,
                            details->deleted_rev_author, details->deleted_rev);
    }
}

static const char *
describe_incoming_add_upon_merge(
  struct conflict_tree_incoming_add_details *details,
  svn_node_kind_t new_node_kind,
  svn_revnum_t old_rev,
  const char *new_repos_relpath,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool)
{
  if (new_node_kind == svn_node_dir)
    {
      if (old_rev + 1 == new_rev)
        return apr_psprintf(result_pool,
                            _("A new directory appeared during merge of\n"
                              "'^/%s:%ld'.\nIt was added by %s in r%ld."),
                            new_repos_relpath, new_rev,
                            details->added_rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new directory appeared during merge of\n"
                              "'^/%s:%ld-%ld'.\nIt was added by %s in r%ld."),
                            new_repos_relpath, old_rev + 1, new_rev,
                            details->added_rev_author, details->added_rev);
    }
  else if (new_node_kind == svn_node_file ||
           new_node_kind == svn_node_symlink)
    {
      if (old_rev + 1 == new_rev)
        return apr_psprintf(result_pool,
                            _("A new file appeared during merge of\n"
                              "'^/%s:%ld'.\nIt was added by %s in r%ld."),
                            new_repos_relpath, new_rev,
                            details->added_rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new file appeared during merge of\n"
                              "'^/%s:%ld-%ld'.\nIt was added by %s in r%ld."),
                            new_repos_relpath, old_rev + 1, new_rev,
                            details->added_rev_author, details->added_rev);
    }
  else
    {
      if (old_rev + 1 == new_rev)
        return apr_psprintf(result_pool,
                            _("A new item appeared during merge of\n"
                              "'^/%s:%ld'.\nIt was added by %s in r%ld."),
                            new_repos_relpath, new_rev,
                            details->added_rev_author, details->added_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new item appeared during merge of\n"
                              "'^/%s:%ld-%ld'.\nIt was added by %s in r%ld."),
                            new_repos_relpath, old_rev + 1, new_rev,
                            details->added_rev_author, details->added_rev);
    }
}

static const char *
describe_incoming_reverse_deletion_upon_merge(
  struct conflict_tree_incoming_add_details *details,
  svn_node_kind_t new_node_kind,
  const char *old_repos_relpath,
  svn_revnum_t old_rev,
  svn_revnum_t new_rev,
  apr_pool_t *result_pool)
{
  if (new_node_kind == svn_node_dir)
    {
      if (new_rev + 1 == old_rev)
        return apr_psprintf(result_pool,
                            _("A new directory appeared during reverse-merge of"
                              "\n'^/%s:%ld'.\nIt was deleted by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            details->deleted_rev_author,
                            details->deleted_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new directory appeared during reverse-merge "
                              "of\n'^/%s:%ld-%ld'.\n"
                              "It was deleted by %s in r%ld."),
                            old_repos_relpath, new_rev, old_rev - 1,
                            details->deleted_rev_author,
                            details->deleted_rev);
    }
  else if (new_node_kind == svn_node_file ||
           new_node_kind == svn_node_symlink)
    {
      if (new_rev + 1 == old_rev)
        return apr_psprintf(result_pool,
                            _("A new file appeared during reverse-merge of\n"
                              "'^/%s:%ld'.\nIt was deleted by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            details->deleted_rev_author,
                            details->deleted_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new file appeared during reverse-merge of\n"
                              "'^/%s:%ld-%ld'.\nIt was deleted by %s in r%ld."),
                            old_repos_relpath, new_rev + 1, old_rev,
                            details->deleted_rev_author,
                            details->deleted_rev);
    }
  else
    {
      if (new_rev + 1 == old_rev)
        return apr_psprintf(result_pool,
                            _("A new item appeared during reverse-merge of\n"
                              "'^/%s:%ld'.\nIt was deleted by %s in r%ld."),
                            old_repos_relpath, old_rev,
                            details->deleted_rev_author,
                            details->deleted_rev);
      else
        return apr_psprintf(result_pool,
                            _("A new item appeared during reverse-merge of\n"
                              "'^/%s:%ld-%ld'.\nIt was deleted by %s in r%ld."),
                            old_repos_relpath, new_rev + 1, old_rev,
                            details->deleted_rev_author,
                            details->deleted_rev);
    }
}

/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
conflict_tree_get_description_incoming_add(
  const char **incoming_change_description,
  svn_client_conflict_t *conflict,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  const char *action;
  svn_node_kind_t victim_node_kind;
  svn_wc_operation_t conflict_operation;
  const char *old_repos_relpath;
  svn_revnum_t old_rev;
  svn_node_kind_t old_node_kind;
  const char *new_repos_relpath;
  svn_revnum_t new_rev;
  svn_node_kind_t new_node_kind;
  struct conflict_tree_incoming_add_details *details;

  if (conflict->tree_conflict_incoming_details == NULL)
    return svn_error_trace(conflict_tree_get_incoming_description_generic(
                             incoming_change_description,
                             conflict, result_pool, scratch_pool));

  conflict_operation = svn_client_conflict_get_operation(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);

  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &old_repos_relpath, &old_rev, &old_node_kind, conflict,
            scratch_pool, scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &new_repos_relpath, &new_rev, &new_node_kind, conflict,
            scratch_pool, scratch_pool));

  details = conflict->tree_conflict_incoming_details;

  if (conflict_operation == svn_wc_operation_update)
    {
      action = describe_incoming_add_upon_update(details,
                                                 new_node_kind,
                                                 new_rev,
                                                 result_pool);
    }
  else if (conflict_operation == svn_wc_operation_switch)
    {
      action = describe_incoming_add_upon_switch(details,
                                                 victim_node_kind,
                                                 new_repos_relpath,
                                                 new_rev,
                                                 result_pool);
    }
  else if (conflict_operation == svn_wc_operation_merge)
    {
      if (old_rev < new_rev)
        action = describe_incoming_add_upon_merge(details,
                                                  new_node_kind,
                                                  old_rev,
                                                  new_repos_relpath,
                                                  new_rev,
                                                  result_pool);
      else
        action = describe_incoming_reverse_deletion_upon_merge(
                   details, new_node_kind, old_repos_relpath,
                   old_rev, new_rev, result_pool);
    }

  *incoming_change_description = apr_pstrdup(result_pool, action);

  return SVN_NO_ERROR;
}

/* Details for tree conflicts involving incoming edits.
 * Note that we store an array of these. Each element corresponds to a
 * revision within the old/new range in which a modification occured. */
struct conflict_tree_incoming_edit_details
{
  /* The revision in which the edit ocurred. */
  svn_revnum_t rev;

  /* The author of the revision. */
  const char *author;

  /** Is the text modified? May be svn_tristate_unknown. */
  svn_tristate_t text_modified;

  /** Are properties modified? May be svn_tristate_unknown. */
  svn_tristate_t props_modified;

  /** For directories, are children modified?
   * May be svn_tristate_unknown. */
  svn_tristate_t children_modified;

  /* The path which was edited, relative to the repository root. */
  const char *repos_relpath;
};

/* Baton for find_modified_rev(). */
struct find_modified_rev_baton {
  const char *victim_abspath;
  svn_client_ctx_t *ctx;
  apr_array_header_t *edits;
  const char *repos_relpath;
  svn_node_kind_t node_kind;
  apr_pool_t *result_pool;
  apr_pool_t *scratch_pool;
};

/* Implements svn_log_entry_receiver_t. */
static svn_error_t *
find_modified_rev(void *baton,
                  svn_log_entry_t *log_entry,
                  apr_pool_t *scratch_pool)
{
  struct find_modified_rev_baton *b = baton;
  struct conflict_tree_incoming_edit_details *details = NULL;
  svn_string_t *author;
  apr_hash_index_t *hi;
  apr_pool_t *iterpool;

  if (b->ctx->notify_func2)
    {
      svn_wc_notify_t *notify;

      notify = svn_wc_create_notify(
                 b->victim_abspath,
                 svn_wc_notify_tree_conflict_details_progress,
                 scratch_pool),
      notify->revision = log_entry->revision;
      b->ctx->notify_func2(b->ctx->notify_baton2, notify, scratch_pool);
    }

  /* No paths were changed in this revision.  Nothing to do. */
  if (! log_entry->changed_paths2)
    return SVN_NO_ERROR;

  details = apr_pcalloc(b->result_pool, sizeof(*details));
  details->rev = log_entry->revision;
  author = svn_hash_gets(log_entry->revprops, SVN_PROP_REVISION_AUTHOR);
  details->author = apr_pstrdup(b->result_pool, author->data);

  details->text_modified = svn_tristate_unknown;
  details->props_modified = svn_tristate_unknown;
  details->children_modified = svn_tristate_unknown;

  iterpool = svn_pool_create(scratch_pool);
  for (hi = apr_hash_first(scratch_pool, log_entry->changed_paths2);
       hi != NULL;
       hi = apr_hash_next(hi))
    {
      void *val;
      const char *path;
      svn_log_changed_path2_t *log_item;

      svn_pool_clear(iterpool);

      apr_hash_this(hi, (void *) &path, NULL, &val);
      log_item = val;

      /* ### Remove leading slash from paths in log entries. */
      if (path[0] == '/')
          path = svn_relpath_canonicalize(path, iterpool);

      if (svn_path_compare_paths(b->repos_relpath, path) == 0 &&
          (log_item->action == 'M' || log_item->action == 'A'))
        {
          details->text_modified = log_item->text_modified;
          details->props_modified = log_item->props_modified;
          details->repos_relpath = apr_pstrdup(b->result_pool, path);

          if (log_item->copyfrom_path)
            b->repos_relpath = apr_pstrdup(b->scratch_pool,
                                           log_item->copyfrom_path);
        }
      else if (b->node_kind == svn_node_dir &&
               svn_relpath_skip_ancestor(b->repos_relpath, path) != NULL)
        details->children_modified = svn_tristate_true;
    }

  if (details)
    {
      if (b->node_kind == svn_node_dir &&
          details->children_modified == svn_tristate_unknown)
            details->children_modified = svn_tristate_false;

      APR_ARRAY_PUSH(b->edits, struct conflict_tree_incoming_edit_details *) =
        details;
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* Implements tree_conflict_get_details_func_t.
 * Find one or more revisions in which the victim was modified in the
 * repository. */
static svn_error_t *
conflict_tree_get_details_incoming_edit(svn_client_conflict_t *conflict,
                                        apr_pool_t *scratch_pool)
{
  const char *old_repos_relpath;
  const char *new_repos_relpath;
  const char *repos_root_url;
  const char *repos_uuid;
  svn_revnum_t old_rev;
  svn_revnum_t new_rev;
  svn_node_kind_t old_node_kind;
  svn_node_kind_t new_node_kind;
  svn_wc_operation_t operation;
  const char *url;
  const char *corrected_url;
  svn_ra_session_t *ra_session;
  apr_array_header_t *paths;
  apr_array_header_t *revprops;
  struct find_modified_rev_baton b;

  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &old_repos_relpath, &old_rev, &old_node_kind, conflict,
            scratch_pool, scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &new_repos_relpath, &new_rev, &new_node_kind, conflict,
            scratch_pool, scratch_pool));
  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
                                             conflict,
                                             scratch_pool, scratch_pool));
  operation = svn_client_conflict_get_operation(conflict);

  b.ctx = conflict->ctx;
  b.victim_abspath = svn_client_conflict_get_local_abspath(conflict);
  b.result_pool = conflict->pool;
  b.scratch_pool = scratch_pool;
  b.edits = apr_array_make(
               conflict->pool, 0,
               sizeof(struct conflict_tree_incoming_edit_details *));
  paths = apr_array_make(scratch_pool, 1, sizeof(const char *));
  APR_ARRAY_PUSH(paths, const char *) = "";

  revprops = apr_array_make(scratch_pool, 1, sizeof(const char *));
  APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_AUTHOR;

  if (operation == svn_wc_operation_update)
    {
      url = svn_path_url_add_component2(repos_root_url,
                                        old_rev < new_rev ? new_repos_relpath
                                                          : old_repos_relpath,
                                        scratch_pool);

      b.repos_relpath = old_rev < new_rev ? new_repos_relpath
                                          : old_repos_relpath;
      b.node_kind = old_rev < new_rev ? new_node_kind : old_node_kind;
    }
  else if (operation == svn_wc_operation_switch ||
           operation == svn_wc_operation_merge)
    {
      url = svn_path_url_add_component2(repos_root_url, new_repos_relpath,
                                        scratch_pool);

      b.repos_relpath = new_repos_relpath;
      b.node_kind = new_node_kind;
    }

  SVN_ERR(svn_client__open_ra_session_internal(&ra_session,
                                               &corrected_url,
                                               url, NULL, NULL,
                                               FALSE,
                                               FALSE,
                                               conflict->ctx,
                                               scratch_pool,
                                               scratch_pool));

  SVN_ERR(svn_ra_get_log2(ra_session, paths,
                          old_rev < new_rev ? old_rev : new_rev,
                          old_rev < new_rev ? new_rev : old_rev,
                          0, /* no limit */
                          TRUE, /* need the changed paths list */
                          FALSE, /* need to traverse copies */
                          FALSE, /* no need for merged revisions */
                          revprops,
                          find_modified_rev, &b,
                          scratch_pool));

  conflict->tree_conflict_incoming_details = b.edits;

  return SVN_NO_ERROR;
}

static const char *
describe_incoming_edit_upon_update(svn_revnum_t old_rev,
                                   svn_revnum_t new_rev,
                                   svn_node_kind_t old_node_kind,
                                   svn_node_kind_t new_node_kind,
                                   apr_pool_t *result_pool)
{
  if (old_rev < new_rev)
    {
      if (new_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Changes destined for a directory arrived "
                              "via the following revisions during update "
                              "from r%ld to r%ld."), old_rev, new_rev);
      else if (new_node_kind == svn_node_file ||
               new_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("Changes destined for a file arrived "
                              "via the following revisions during update "
                              "from r%ld to r%ld"), old_rev, new_rev);
      else
        return apr_psprintf(result_pool,
                            _("Changes from the following revisions arrived "
                              "during update from r%ld to r%ld"),
                            old_rev, new_rev);
    }
  else
    {
      if (new_node_kind == svn_node_dir)
        return apr_psprintf(result_pool,
                            _("Changes destined for a directory arrived "
                              "via the following revisions during backwards "
                              "update from r%ld to r%ld"),
                            old_rev, new_rev);
      else if (new_node_kind == svn_node_file ||
               new_node_kind == svn_node_symlink)
        return apr_psprintf(result_pool,
                            _("Changes destined for a file arrived "
                              "via the following revisions during backwards "
                              "update from r%ld to r%ld"),
                            old_rev, new_rev);
      else
        return apr_psprintf(result_pool,
                            _("Changes from the following revisions arrived "
                              "during backwards update from r%ld to r%ld"),
                            old_rev, new_rev);
    }
}

static const char *
describe_incoming_edit_upon_switch(const char *new_repos_relpath,
                                   svn_revnum_t new_rev,
                                   svn_node_kind_t new_node_kind,
                                   apr_pool_t *result_pool)
{
  if (new_node_kind == svn_node_dir)
    return apr_psprintf(result_pool,
                        _("Changes destined for a directory arrived via "
                          "the following revisions during switch to\n"
                          "'^/%s@r%ld'"),
                        new_repos_relpath, new_rev);
  else if (new_node_kind == svn_node_file ||
           new_node_kind == svn_node_symlink)
    return apr_psprintf(result_pool,
                        _("Changes destined for a directory arrived via "
                          "the following revisions during switch to\n"
                          "'^/%s@r%ld'"),
                        new_repos_relpath, new_rev);
  else
    return apr_psprintf(result_pool,
                        _("Changes from the following revisions arrived "
                          "during switch to\n'^/%s@r%ld'"),
                        new_repos_relpath, new_rev);
}

/* Return a string showing the list of revisions in EDITS, ensuring
 * the string won't grow too large for display. */
static const char *
describe_incoming_edit_list_modified_revs(apr_array_header_t *edits,
                                          apr_pool_t *result_pool)
{
  int num_revs_to_skip;
  static const int min_revs_for_skipping = 5;
  static const int max_revs_to_display = 8;
  const char *s = "";
  int i;

  if (edits->nelts <= max_revs_to_display)
    num_revs_to_skip = 0;
  else
    {
      /* Check if we should insert a placeholder for some revisions because
       * the string would grow too long for display otherwise. */
      num_revs_to_skip = edits->nelts - max_revs_to_display;
      if (num_revs_to_skip < min_revs_for_skipping)
        {
          /* Don't bother with the placeholder. Just list all revisions. */
          num_revs_to_skip = 0;
        }
    }

  for (i = 0; i < edits->nelts; i++)
    {
      struct conflict_tree_incoming_edit_details *details;

      details = APR_ARRAY_IDX(edits, i,
                              struct conflict_tree_incoming_edit_details *);
      if (num_revs_to_skip > 0)
        {
          /* Insert a placeholder for revisions falling into the middle of
           * the range so we'll get something that looks like:
           * 1, 2, 3, 4, 5 [ placeholder ] 95, 96, 97, 98, 99 */
          if (i < max_revs_to_display / 2)
            s = apr_psprintf(result_pool, _("%s r%ld by %s%s"), s,
                             details->rev, details->author,
                             i < edits->nelts - 1 ? "," : "");
          else if (i >= max_revs_to_display / 2 &&
                   i < edits->nelts - (max_revs_to_display / 2))
              continue;
          else
            {
              if (i == edits->nelts - (max_revs_to_display / 2))
                  s = apr_psprintf(result_pool,
                                   _("%s\n [%d revisions omitted for "
                                     "brevity],\n"),
                                   s, num_revs_to_skip);

              s = apr_psprintf(result_pool, _("%s r%ld by %s%s"), s,
                               details->rev, details->author,
                               i < edits->nelts - 1 ? "," : "");
            }
        } 
      else
        s = apr_psprintf(result_pool, _("%s r%ld by %s%s"), s,
                         details->rev, details->author,
                         i < edits->nelts - 1 ? "," : "");
    }

  return s;
}

/* Implements tree_conflict_get_description_func_t. */
static svn_error_t *
conflict_tree_get_description_incoming_edit(
  const char **incoming_change_description,
  svn_client_conflict_t *conflict,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  const char *action;
  svn_node_kind_t victim_node_kind;
  svn_wc_operation_t conflict_operation;
  const char *old_repos_relpath;
  svn_revnum_t old_rev;
  svn_node_kind_t old_node_kind;
  const char *new_repos_relpath;
  svn_revnum_t new_rev;
  svn_node_kind_t new_node_kind;
  apr_array_header_t *edits;

  if (conflict->tree_conflict_incoming_details == NULL)
    return svn_error_trace(conflict_tree_get_incoming_description_generic(
                             incoming_change_description,
                             conflict, result_pool, scratch_pool));

  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &old_repos_relpath, &old_rev, &old_node_kind, conflict,
            scratch_pool, scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &new_repos_relpath, &new_rev, &new_node_kind, conflict,
            scratch_pool, scratch_pool));

  conflict_operation = svn_client_conflict_get_operation(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);

  edits = conflict->tree_conflict_incoming_details;

  if (conflict_operation == svn_wc_operation_update)
    action = describe_incoming_edit_upon_update(old_rev, new_rev,
                                                old_node_kind, new_node_kind,
                                                scratch_pool);
  else if (conflict_operation == svn_wc_operation_switch)
    action = describe_incoming_edit_upon_switch(new_repos_relpath, new_rev,
                                                new_node_kind, scratch_pool);
  else if (conflict_operation == svn_wc_operation_merge)
    {
      /* Handle merge inline because it returns early sometimes. */
      if (old_rev < new_rev)
        {
          if (old_rev + 1 == new_rev)
            {
              if (new_node_kind == svn_node_dir)
                action = apr_psprintf(scratch_pool,
                                      _("Changes destined for a directory "
                                        "arrived during merge of\n"
                                        "'^/%s:%ld'."),
                                        new_repos_relpath, new_rev);
              else if (new_node_kind == svn_node_file ||
                       new_node_kind == svn_node_symlink)
                action = apr_psprintf(scratch_pool,
                                      _("Changes destined for a file "
                                        "arrived during merge of\n"
                                        "'^/%s:%ld'."),
                                      new_repos_relpath, new_rev);
              else
                action = apr_psprintf(scratch_pool,
                                      _("Changes arrived during merge of\n"
                                        "'^/%s:%ld'."),
                                      new_repos_relpath, new_rev);

              *incoming_change_description = apr_pstrdup(result_pool, action);

              return SVN_NO_ERROR;
            }
          else
            {
              if (new_node_kind == svn_node_dir)
                action = apr_psprintf(scratch_pool,
                                      _("Changes destined for a directory "
                                        "arrived via the following revisions "
                                        "during merge of\n'^/%s:%ld-%ld'"),
                                      new_repos_relpath, old_rev + 1, new_rev);
              else if (new_node_kind == svn_node_file ||
                       new_node_kind == svn_node_symlink)
                action = apr_psprintf(scratch_pool,
                                      _("Changes destined for a file "
                                        "arrived via the following revisions "
                                        "during merge of\n'^/%s:%ld-%ld'"),
                                      new_repos_relpath, old_rev + 1, new_rev);
              else
                action = apr_psprintf(scratch_pool,
                                      _("Changes from the following revisions "
                                        "arrived during merge of\n"
                                        "'^/%s:%ld-%ld'"),
                                      new_repos_relpath, old_rev + 1, new_rev);
            }
        }
      else
        {
          if (new_rev + 1 == old_rev)
            {
              if (new_node_kind == svn_node_dir)
                action = apr_psprintf(scratch_pool,
                                      _("Changes destined for a directory "
                                        "arrived during reverse-merge of\n"
                                        "'^/%s:%ld'."),
                                      new_repos_relpath, old_rev);
              else if (new_node_kind == svn_node_file ||
                       new_node_kind == svn_node_symlink)
                action = apr_psprintf(scratch_pool,
                                      _("Changes destined for a file "
                                        "arrived during reverse-merge of\n"
                                        "'^/%s:%ld'."),
                                      new_repos_relpath, old_rev);
              else
                action = apr_psprintf(scratch_pool,
                                      _("Changes arrived during reverse-merge "
                                        "of\n'^/%s:%ld'."),
                                      new_repos_relpath, old_rev);

              *incoming_change_description = apr_pstrdup(result_pool, action);

              return SVN_NO_ERROR;
            }
          else
            {
              if (new_node_kind == svn_node_dir)
                action = apr_psprintf(scratch_pool,
                                      _("Changes destined for a directory "
                                        "arrived via the following revisions "
                                        "during reverse-merge of\n"
                                        "'^/%s:%ld-%ld'"),
                                      new_repos_relpath, new_rev + 1, old_rev);
              else if (new_node_kind == svn_node_file ||
                       new_node_kind == svn_node_symlink)
                action = apr_psprintf(scratch_pool,
                                      _("Changes destined for a file "
                                        "arrived via the following revisions "
                                        "during reverse-merge of\n"
                                        "'^/%s:%ld-%ld'"),
                                      new_repos_relpath, new_rev + 1, old_rev);
                
              else
                action = apr_psprintf(scratch_pool,
                                      _("Changes from the following revisions "
                                        "arrived during reverse-merge of\n"
                                        "'^/%s:%ld-%ld'"),
                                      new_repos_relpath, new_rev + 1, old_rev);
            }
        }
    }

  action = apr_psprintf(scratch_pool, "%s:\n%s", action,
                        describe_incoming_edit_list_modified_revs(
                          edits, scratch_pool));
  *incoming_change_description = apr_pstrdup(result_pool, action);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_tree_get_description(
  const char **incoming_change_description,
  const char **local_change_description,
  svn_client_conflict_t *conflict,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  SVN_ERR(conflict->tree_conflict_get_incoming_description_func(
            incoming_change_description,
            conflict, result_pool, scratch_pool));

  SVN_ERR(conflict->tree_conflict_get_local_description_func(
            local_change_description,
            conflict, result_pool, scratch_pool));
  
  return SVN_NO_ERROR;
}

void
svn_client_conflict_option_set_merged_propval(
  svn_client_conflict_option_t *option,
  const svn_string_t *merged_propval)
{
  option->type_data.prop.merged_propval = svn_string_dup(merged_propval,
                                                         option->pool);
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_postpone(svn_client_conflict_option_t *option,
                      svn_client_conflict_t *conflict,
                      apr_pool_t *scratch_pool)
{
  return SVN_NO_ERROR; /* Nothing to do. */
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_text_conflict(svn_client_conflict_option_t *option,
                      svn_client_conflict_t *conflict,
                      apr_pool_t *scratch_pool)
{
  svn_client_conflict_option_id_t option_id;
  const char *local_abspath;
  const char *lock_abspath;
  svn_wc_conflict_choice_t conflict_choice;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;

  option_id = svn_client_conflict_option_get_id(option);
  conflict_choice = conflict_option_id_to_wc_conflict_choice(option_id);
  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));
  err = svn_wc__conflict_text_mark_resolved(conflict->ctx->wc_ctx,
                                            local_abspath,
                                            conflict_choice,
                                            conflict->ctx->cancel_func,
                                            conflict->ctx->cancel_baton,
                                            conflict->ctx->notify_func2,
                                            conflict->ctx->notify_baton2,
                                            scratch_pool);
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
  SVN_ERR(err);

  conflict->resolution_text = option_id;

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_prop_conflict(svn_client_conflict_option_t *option,
                      svn_client_conflict_t *conflict,
                      apr_pool_t *scratch_pool)
{
  svn_client_conflict_option_id_t option_id;
  svn_wc_conflict_choice_t conflict_choice;
  const char *local_abspath;
  const char *lock_abspath;
  const char *propname = option->type_data.prop.propname;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;

  option_id = svn_client_conflict_option_get_id(option);
  conflict_choice = conflict_option_id_to_wc_conflict_choice(option_id);
  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));
  err = svn_wc__conflict_prop_mark_resolved(ctx->wc_ctx, local_abspath,
                                            propname, conflict_choice,
                                            conflict->ctx->notify_func2,
                                            conflict->ctx->notify_baton2,
                                            scratch_pool);
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
  SVN_ERR(err);

  if (propname[0] == '\0')
    {
      apr_hash_index_t *hi;

      /* All properties have been resolved to the same option. */
      for (hi = apr_hash_first(scratch_pool, conflict->prop_conflicts);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *this_propname = apr_hash_this_key(hi);

          svn_hash_sets(conflict->resolved_props,
                        apr_pstrdup(apr_hash_pool_get(conflict->resolved_props),
                                    this_propname),
                        option);
          svn_hash_sets(conflict->prop_conflicts, this_propname, NULL);
        }

      conflict->legacy_prop_conflict_propname = NULL;
    }
  else
    {
      svn_hash_sets(conflict->resolved_props,
                    apr_pstrdup(apr_hash_pool_get(conflict->resolved_props),
                                propname),
                   option);
      svn_hash_sets(conflict->prop_conflicts, propname, NULL);

      if (apr_hash_count(conflict->prop_conflicts) > 0)
        conflict->legacy_prop_conflict_propname =
            apr_hash_this_key(apr_hash_first(scratch_pool,
                                             conflict->prop_conflicts));
      else
        conflict->legacy_prop_conflict_propname = NULL;
    }

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_accept_current_wc_state(svn_client_conflict_option_t *option,
                                svn_client_conflict_t *conflict,
                                apr_pool_t *scratch_pool)
{
  svn_client_conflict_option_id_t option_id;
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;

  option_id = svn_client_conflict_option_get_id(option);
  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  if (option_id != svn_client_conflict_option_accept_current_wc_state)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Tree conflict on '%s' can only be resolved "
                               "to the current working copy state"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));

  /* Resolve to current working copy state. */
  err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);

  /* svn_wc__del_tree_conflict doesn't handle notification for us */
  if (ctx->notify_func2)
    ctx->notify_func2(ctx->notify_baton2,
                      svn_wc_create_notify(local_abspath,
                                           svn_wc_notify_resolved_tree,
                                           scratch_pool),
                      scratch_pool);

  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  SVN_ERR(err);

  conflict->resolution_tree = option_id;

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_update_break_moved_away(svn_client_conflict_option_t *option,
                                svn_client_conflict_t *conflict,
                                apr_pool_t *scratch_pool)
{
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));
  err = svn_wc__conflict_tree_update_break_moved_away(ctx->wc_ctx,
                                                      local_abspath,
                                                      ctx->cancel_func,
                                                      ctx->cancel_baton,
                                                      ctx->notify_func2,
                                                      ctx->notify_baton2,
                                                      scratch_pool);
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  SVN_ERR(err);

  conflict->resolution_tree = svn_client_conflict_option_get_id(option);

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_update_raise_moved_away(svn_client_conflict_option_t *option,
                                svn_client_conflict_t *conflict,
                                apr_pool_t *scratch_pool)
{
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));
  err = svn_wc__conflict_tree_update_raise_moved_away(ctx->wc_ctx,
                                                      local_abspath,
                                                      ctx->cancel_func,
                                                      ctx->cancel_baton,
                                                      ctx->notify_func2,
                                                      ctx->notify_baton2,
                                                      scratch_pool);
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  SVN_ERR(err);

  conflict->resolution_tree = svn_client_conflict_option_get_id(option);

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_update_moved_away_node(svn_client_conflict_option_t *option,
                               svn_client_conflict_t *conflict,
                               apr_pool_t *scratch_pool)
{
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));
  err = svn_wc__conflict_tree_update_moved_away_node(ctx->wc_ctx,
                                                     local_abspath,
                                                     ctx->cancel_func,
                                                     ctx->cancel_baton,
                                                     ctx->notify_func2,
                                                     ctx->notify_baton2,
                                                     scratch_pool);
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
  SVN_ERR(err);

  conflict->resolution_tree = svn_client_conflict_option_get_id(option);

  return SVN_NO_ERROR;
}

/* Verify the local working copy state matches what we expect when an
 * incoming add vs add tree conflict exists after an update operation.
 * We assume the update operation leaves the working copy in a state which
 * prefers the local change and cancels the incoming addition.
 * Run a quick sanity check and error out if it looks as if the
 * working copy was modified since, even though it's not easy to make
 * such modifications without also clearing the conflict marker. */
static svn_error_t *
verify_local_state_for_incoming_add_upon_update(
  svn_client_conflict_t *conflict,
  svn_client_conflict_option_t *option,
  apr_pool_t *scratch_pool)
{
  const char *local_abspath;
  svn_client_conflict_option_id_t option_id;
  const char *wcroot_abspath;
  svn_wc_operation_t operation;
  svn_client_ctx_t *ctx = conflict->ctx;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  svn_node_kind_t incoming_new_kind;
  const char *base_repos_relpath;
  svn_revnum_t base_rev;
  svn_node_kind_t base_kind;
  const char *local_style_relpath;
  svn_boolean_t is_added;
  svn_error_t *err;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);
  option_id = svn_client_conflict_option_get_id(option);
  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, ctx->wc_ctx,
                             local_abspath, scratch_pool,
                             scratch_pool));
  operation = svn_client_conflict_get_operation(conflict);
  SVN_ERR_ASSERT(operation == svn_wc_operation_update);

  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            &incoming_new_kind, conflict, scratch_pool,
            scratch_pool));

  local_style_relpath = svn_dirent_local_style(
                          svn_dirent_skip_ancestor(wcroot_abspath,
                                                   local_abspath),
                          scratch_pool);

  /* Check if a local addition addition replaces the incoming new node. */
  err = svn_wc__node_get_base(&base_kind, &base_rev, &base_repos_relpath,
                              NULL, NULL, NULL, ctx->wc_ctx, local_abspath,
                              FALSE, scratch_pool, scratch_pool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
        {
          if (option_id == svn_client_conflict_option_incoming_add_ignore)
            return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, err,
                                     _("Cannot resolve tree conflict on '%s' "
                                       "by ignoring the incoming addition "
                                       "(expected a base node but found none)"),
                                     local_style_relpath);
          else if (option_id ==
                   svn_client_conflict_option_incoming_added_file_replace ||
                   option_id ==
                   svn_client_conflict_option_incoming_added_dir_replace)
            return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, err,
                                     _("Cannot resolve tree conflict on '%s' "
                                       "by replacing the locally added node "
                                       "(expected a base node but found none)"),
                                     local_style_relpath);
          else
            return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, err,
                                     _("Unexpected option id '%d'"), option_id);
        }
      else
        return svn_error_trace(err);
    }

  if (base_kind != incoming_new_kind)
    {
      if (option_id == svn_client_conflict_option_incoming_add_ignore)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' by "
                                   "ignoring the incoming addition "
                                   "(expected base node kind '%s', "
                                   "but found '%s')"),
                                 local_style_relpath,
                                 svn_node_kind_to_word(incoming_new_kind),
                                 svn_node_kind_to_word(base_kind));
      else if (option_id ==
               svn_client_conflict_option_incoming_added_file_replace ||
               option_id ==
               svn_client_conflict_option_incoming_added_dir_replace)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' "
                                   "by replacing the locally added node "
                                   "(expected base node kind '%s', "
                                   "but found '%s')"),
                                  local_style_relpath,
                                 svn_node_kind_to_word(incoming_new_kind),
                                 svn_node_kind_to_word(base_kind));
      else
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Unexpected option id '%d'"), option_id);
    }

  if (strcmp(base_repos_relpath, incoming_new_repos_relpath) != 0 ||
      base_rev != incoming_new_pegrev)
    {
      if (option_id == svn_client_conflict_option_incoming_add_ignore)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' by "
                                   "ignoring the incoming addition "
                                   "(expected base node from '^/%s@%ld', "
                                   "but found '^/%s@%ld')"),
                                 local_style_relpath,
                                 incoming_new_repos_relpath,
                                 incoming_new_pegrev,
                                 base_repos_relpath, base_rev);
      else if (option_id ==
               svn_client_conflict_option_incoming_added_file_replace ||
               option_id ==
               svn_client_conflict_option_incoming_added_dir_replace)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' "
                                   "by replacing the locally added node "
                                   "(expected base node from '^/%s@%ld', "
                                   "but found '^/%s@%ld')"),
                                 local_style_relpath,
                                 incoming_new_repos_relpath,
                                 incoming_new_pegrev,
                                 base_repos_relpath, base_rev);
      else
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Unexpected option id '%d'"), option_id);
    }

  SVN_ERR(svn_wc__node_is_added(&is_added, ctx->wc_ctx, local_abspath,
                                scratch_pool));
  if (!is_added)
    {
      if (option_id == svn_client_conflict_option_incoming_add_ignore)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' by "
                                   "ignoring the incoming addition "
                                   "(expected an added item, but the item "
                                   "is not added)"),
                                 local_style_relpath);

      else if (option_id ==
               svn_client_conflict_option_incoming_added_file_replace ||
               option_id ==
               svn_client_conflict_option_incoming_added_dir_replace)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' "
                                   "by replacing the locally added node "
                                   "(expected an added item, but the item "
                                   "is not added)"),
                                 local_style_relpath);
      else
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Unexpected option id '%d'"), option_id);
    }

  return SVN_NO_ERROR;
}


/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_incoming_add_ignore(svn_client_conflict_option_t *option,
                            svn_client_conflict_t *conflict,
                            apr_pool_t *scratch_pool)
{
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_wc_operation_t operation;
  svn_error_t *err;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);
  operation = svn_client_conflict_get_operation(conflict);

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));

  if (operation == svn_wc_operation_update)
    {
      err = verify_local_state_for_incoming_add_upon_update(conflict, option,
                                                            scratch_pool);
      if (err)
        goto unlock_wc;
    }

  /* All other options for this conflict actively fetch the incoming
   * new node. We can ignore the incoming new node by doing nothing. */

  /* Resolve to current working copy state. */
  err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);

  /* svn_wc__del_tree_conflict doesn't handle notification for us */
  if (ctx->notify_func2)
    ctx->notify_func2(ctx->notify_baton2,
                      svn_wc_create_notify(local_abspath,
                                           svn_wc_notify_resolved_tree,
                                           scratch_pool),
                      scratch_pool);

unlock_wc:
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  SVN_ERR(err);

  conflict->resolution_tree = svn_client_conflict_option_get_id(option);

  return SVN_NO_ERROR;
}
/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_merge_incoming_added_file_text_merge(
  svn_client_conflict_option_t *option,
  svn_client_conflict_t *conflict,
  apr_pool_t *scratch_pool)
{
  svn_ra_session_t *ra_session;
  const char *url;
  const char *corrected_url;
  const char *repos_root_url;
  const char *repos_uuid;
  const char *wc_tmpdir;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_wc_merge_outcome_t merge_content_outcome;
  svn_wc_notify_state_t merge_props_outcome;
  apr_file_t *incoming_new_file;
  const char *incoming_new_tmp_abspath;
  apr_file_t *empty_file;
  const char *empty_file_abspath;
  svn_stream_t *incoming_new_stream;
  apr_hash_t *incoming_new_props;
  apr_hash_index_t *hi;
  apr_array_header_t *propdiffs;
  svn_error_t *err;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  /* Set up temporary storage for the repository version of file. */
  SVN_ERR(svn_wc__get_tmpdir(&wc_tmpdir, ctx->wc_ctx, local_abspath,
                             scratch_pool, scratch_pool));
  SVN_ERR(svn_io_open_unique_file3(&incoming_new_file,
                                   &incoming_new_tmp_abspath, wc_tmpdir,
                                   svn_io_file_del_on_pool_cleanup,
                                   scratch_pool, scratch_pool));
  incoming_new_stream = svn_stream_from_aprfile2(incoming_new_file, TRUE,
                                                 scratch_pool);

  /* Fetch the incoming added file from the repository. */
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            NULL, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
                                             conflict, scratch_pool,
                                             scratch_pool));
  url = svn_path_url_add_component2(repos_root_url, incoming_new_repos_relpath,
                                    scratch_pool);
  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
                                               url, NULL, NULL, FALSE, FALSE,
                                               conflict->ctx, scratch_pool,
                                               scratch_pool));
  SVN_ERR(svn_ra_get_file(ra_session, "", incoming_new_pegrev,
                          incoming_new_stream, NULL, /* fetched_rev */
                          &incoming_new_props, scratch_pool));

  /* Flush file to disk. */
  SVN_ERR(svn_stream_close(incoming_new_stream));
  SVN_ERR(svn_io_file_flush(incoming_new_file, scratch_pool));

  /* Delete entry and wc props from the returned set of properties.. */
  for (hi = apr_hash_first(scratch_pool, incoming_new_props);
       hi != NULL;
       hi = apr_hash_next(hi))
    {
      const char *propname = apr_hash_this_key(hi);

      if (!svn_wc_is_normal_prop(propname))
        svn_hash_sets(incoming_new_props, propname, NULL);
    }

  /* Create an empty file as fake "merge-base" for the two added files.
   * The files are not ancestrally related so this is the best we can do. */
  SVN_ERR(svn_io_open_unique_file3(&empty_file, &empty_file_abspath, NULL,
                                   svn_io_file_del_on_pool_cleanup,
                                   scratch_pool, scratch_pool));

  /* Create a property diff which shows all props as added. */
  SVN_ERR(svn_prop_diffs(&propdiffs, incoming_new_props,
                         apr_hash_make(scratch_pool), scratch_pool));

  /* ### The following WC modifications should be atomic. */
  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));
  /* Resolve to current working copy state. svn_wc_merge5() requires this. */
  err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);
  if (err)
    return svn_error_compose_create(err,
                                    svn_wc__release_write_lock(ctx->wc_ctx,
                                                               lock_abspath,
                                                               scratch_pool));
  /* Perform the file merge. ### Merge into tempfile and then rename on top? */
  err = svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
                      ctx->wc_ctx, empty_file_abspath,
                      incoming_new_tmp_abspath, local_abspath,
                      NULL, NULL, NULL, /* labels */
                      NULL, NULL, /* conflict versions */
                      FALSE, /* dry run */
                      NULL, NULL, /* diff3_cmd, merge_options */
                      NULL, propdiffs,
                      NULL, NULL, /* conflict func/baton */
                      NULL, NULL, /* don't allow user to cancel here */
                      scratch_pool);
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
  SVN_ERR(err);

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify;

      /* Tell the world about the file merge that just happened. */
      notify = svn_wc_create_notify(local_abspath,
                                    svn_wc_notify_update_update,
                                    scratch_pool);
      if (merge_content_outcome == svn_wc_merge_conflict)
        notify->content_state = svn_wc_notify_state_conflicted;
      else
        notify->content_state = svn_wc_notify_state_merged;
      notify->prop_state = merge_props_outcome;
      notify->kind = svn_node_file;
      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);

      /* And also about the successfully resolved tree conflict. */
      notify = svn_wc_create_notify(local_abspath, svn_wc_notify_resolved_tree,
                                    scratch_pool);
      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
    }

  conflict->resolution_tree = svn_client_conflict_option_get_id(option);

  return SVN_NO_ERROR;
}

/* Resolve a file/file "incoming add vs local obstruction" tree conflict by
 * replacing the local file with the incoming file. If MERGE_FILES is set,
 * also merge the files after replacing. */
static svn_error_t *
merge_incoming_added_file_replace(svn_client_conflict_option_t *option,
                                  svn_client_conflict_t *conflict,
                                  svn_boolean_t merge_files,
                                  apr_pool_t *scratch_pool)
{
  svn_ra_session_t *ra_session;
  const char *url;
  const char *corrected_url;
  const char *repos_root_url;
  const char *repos_uuid;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  apr_file_t *incoming_new_file;
  svn_stream_t *incoming_new_stream;
  apr_hash_t *incoming_new_props;
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  const char *wc_tmpdir;
  apr_file_t *working_file_tmp;
  svn_stream_t *working_file_tmp_stream;
  const char *working_file_tmp_abspath;
  svn_stream_t *working_file_stream;
  apr_hash_t *working_props;
  svn_error_t *err;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  /* Set up tempory storage for the working version of file. */
  SVN_ERR(svn_wc__get_tmpdir(&wc_tmpdir, ctx->wc_ctx, local_abspath,
                             scratch_pool, scratch_pool));
  SVN_ERR(svn_io_open_unique_file3(&working_file_tmp,
                                   &working_file_tmp_abspath, wc_tmpdir,
                                   svn_io_file_del_on_pool_cleanup,
                                   scratch_pool, scratch_pool));
  working_file_tmp_stream = svn_stream_from_aprfile2(working_file_tmp,
                                                     FALSE, scratch_pool);

  /* Copy the working file to temporary storage. */
  SVN_ERR(svn_stream_open_readonly(&working_file_stream, local_abspath,
                                   scratch_pool, scratch_pool));
  SVN_ERR(svn_stream_copy3(working_file_stream, working_file_tmp_stream,
                           ctx->cancel_baton, ctx->cancel_baton,
                           scratch_pool));
  SVN_ERR(svn_io_file_flush(working_file_tmp, scratch_pool));

  /* Get a copy of the working file's properties. */
  SVN_ERR(svn_wc_prop_list2(&working_props, ctx->wc_ctx, local_abspath,
                            scratch_pool, scratch_pool));

  /* Fetch the incoming added file from the repository. */
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            NULL, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
                                             conflict, scratch_pool,
                                             scratch_pool));
  url = svn_path_url_add_component2(repos_root_url, incoming_new_repos_relpath,
                                    scratch_pool);
  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
                                               url, NULL, NULL, FALSE, FALSE,
                                               conflict->ctx, scratch_pool,
                                               scratch_pool));
  if (corrected_url)
    url = corrected_url;
  SVN_ERR(svn_io_open_unique_file3(&incoming_new_file, NULL, wc_tmpdir,
                                   svn_io_file_del_on_pool_cleanup,
                                   scratch_pool, scratch_pool));
  incoming_new_stream = svn_stream_from_aprfile2(incoming_new_file, TRUE,
                                                 scratch_pool);
  SVN_ERR(svn_ra_get_file(ra_session, "", incoming_new_pegrev,
                          incoming_new_stream, NULL, /* fetched_rev */
                          &incoming_new_props, scratch_pool));
  /* Flush file to disk. */
  SVN_ERR(svn_io_file_flush(incoming_new_file, scratch_pool));

  /* Reset the stream in preparation for adding its content to WC. */
  SVN_ERR(svn_stream_reset(incoming_new_stream));

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));

  /* ### The following WC modifications should be atomic. */

  /* Replace the working file with the file from the repository. */
  err = svn_wc_delete4(ctx->wc_ctx, local_abspath, FALSE, FALSE,
                       NULL, NULL, /* don't allow user to cancel here */
                       ctx->notify_func2, ctx->notify_baton2,
                       scratch_pool);
  if (err)
    goto unlock_wc;
  err = svn_wc_add_repos_file4(ctx->wc_ctx, local_abspath,
                               incoming_new_stream,
                               NULL, /* ### could we merge first, then set
                                        ### the merged content here? */
                               incoming_new_props,
                               NULL, /* ### merge props first, set here? */
                               url, incoming_new_pegrev,
                               NULL, NULL, /* don't allow user to cancel here */
                               scratch_pool);
  if (err)
    goto unlock_wc;

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify = svn_wc_create_notify(local_abspath,
                                                     svn_wc_notify_add,
                                                     scratch_pool);
      notify->kind = svn_node_file;
      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
    }

  /* Resolve to current working copy state. svn_wc_merge5() requires this. */
  err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);
  if (err)
    goto unlock_wc;

  if (merge_files)
    {
      svn_wc_merge_outcome_t merge_content_outcome;
      svn_wc_notify_state_t merge_props_outcome;
      apr_file_t *empty_file;
      const char *empty_file_abspath;
      apr_array_header_t *propdiffs;
      apr_hash_index_t *hi;

      /* Create an empty file as fake "merge-base" for the two added files.
       * The files are not ancestrally related so this is the best we can do. */
      err = svn_io_open_unique_file3(&empty_file, &empty_file_abspath, NULL,
                                     svn_io_file_del_on_pool_cleanup,
                                     scratch_pool, scratch_pool);
      if (err)
        goto unlock_wc;

      /* Delete entry and wc props from the returned set of properties.. */
      for (hi = apr_hash_first(scratch_pool, incoming_new_props);
           hi != NULL;
           hi = apr_hash_next(hi))
        {
          const char *propname = apr_hash_this_key(hi);

          if (!svn_wc_is_normal_prop(propname))
            svn_hash_sets(incoming_new_props, propname, NULL);
        }

      /* Create a property diff for the files. */
      err = svn_prop_diffs(&propdiffs, incoming_new_props,
                           working_props, scratch_pool);
      if (err)
        goto unlock_wc;

      /* Perform the file merge. */
      err = svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
                          ctx->wc_ctx, empty_file_abspath,
                          working_file_tmp_abspath, local_abspath,
                          NULL, NULL, NULL, /* labels */
                          NULL, NULL, /* conflict versions */
                          FALSE, /* dry run */
                          NULL, NULL, /* diff3_cmd, merge_options */
                          NULL, propdiffs,
                          NULL, NULL, /* conflict func/baton */
                          NULL, NULL, /* don't allow user to cancel here */
                          scratch_pool);
      if (err)
        goto unlock_wc;

      if (ctx->notify_func2)
        {
          svn_wc_notify_t *notify = svn_wc_create_notify(
                                       local_abspath,
                                       svn_wc_notify_update_update,
                                       scratch_pool);

          if (merge_content_outcome == svn_wc_merge_conflict)
            notify->content_state = svn_wc_notify_state_conflicted;
          else
            notify->content_state = svn_wc_notify_state_merged;
          notify->prop_state = merge_props_outcome;
          notify->kind = svn_node_file;
          ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
        }
    }

unlock_wc:
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
  SVN_ERR(err);

  SVN_ERR(svn_stream_close(incoming_new_stream));

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify = svn_wc_create_notify(
                                  local_abspath,
                                  svn_wc_notify_resolved_tree,
                                  scratch_pool);

      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
    }

  conflict->resolution_tree = svn_client_conflict_option_get_id(option);

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_merge_incoming_added_file_replace(
  svn_client_conflict_option_t *option,
  svn_client_conflict_t *conflict,
  apr_pool_t *scratch_pool)
{
  return svn_error_trace(merge_incoming_added_file_replace(option,
                                                           conflict,
                                                           FALSE,
                                                           scratch_pool));
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_merge_incoming_added_file_replace_and_merge(
  svn_client_conflict_option_t *option,
  svn_client_conflict_t *conflict,
  apr_pool_t *scratch_pool)
{
  return svn_error_trace(merge_incoming_added_file_replace(option,
                                                           conflict,
                                                           TRUE,
                                                           scratch_pool));
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_update_incoming_added_file_replace(svn_client_conflict_option_t *option,
                                           svn_client_conflict_t *conflict,
                                           apr_pool_t *scratch_pool)
{
  svn_client_conflict_option_id_t option_id;
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;
  apr_file_t *backup_file;
  const char *backup_path;

  option_id = svn_client_conflict_option_get_id(option);
  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  /* ### The following WC modifications should be atomic. */
  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));

  err = verify_local_state_for_incoming_add_upon_update(conflict, option,
                                                        scratch_pool);
  if (err)
    goto unlock_wc;

  /* We create a backup of the original file. This file is a local addition
   * which means it does not exist in the repository. So it's a good idea 
   * to keep a backup, just in case someone picks this option by accident.
   * First, reserve a name in the filesystem. */
  err = svn_io_open_uniquely_named(&backup_file, &backup_path,
                                   svn_dirent_dirname(local_abspath,
                                                      scratch_pool), 
                                   svn_dirent_basename(local_abspath,
                                                       scratch_pool),
                                   ".local-add.bak",
                                   svn_io_file_del_none,
                                   scratch_pool,scratch_pool);
  if (err)
    goto unlock_wc;

  /* Close and remove the file. We're going to move the conflict victim
   * on top and, at least on Windows, open files can't be replaced.
   * The WC is locked so anything racing us here is external to SVN. */ 
  err = svn_io_file_close(backup_file, scratch_pool);
  if (err)
    goto unlock_wc;

  err = svn_error_compose_create(err, svn_io_remove_file2(backup_path, TRUE,
                                                          scratch_pool));
  if (err)
    goto unlock_wc;

  /* Create a backup by renaming the file on top of the 'reserved' name.
   * Renaming is equally fast for big and small files. */
  err = svn_io_file_rename2(local_abspath, backup_path, TRUE, scratch_pool);
  if (err)
    goto unlock_wc;

  /* Revert to the BASE working copy node to restore the incoming new node.
   * This also clears the conflict marker. */
  err = svn_wc_revert5(ctx->wc_ctx, local_abspath, svn_depth_empty, FALSE,
                       NULL, FALSE, FALSE,
                       NULL, NULL, /* do not allow the user to cancel here */
                       ctx->notify_func2, ctx->notify_baton2,
                       scratch_pool);

  if (ctx->notify_func2)
    ctx->notify_func2(ctx->notify_baton2,
                      svn_wc_create_notify(local_abspath,
                                           svn_wc_notify_resolved_tree,
                                           scratch_pool),
                      scratch_pool);

unlock_wc:
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  SVN_ERR(err);

  conflict->resolution_tree = option_id;

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_merge_incoming_added_dir_merge(svn_client_conflict_option_t *option,
                                       svn_client_conflict_t *conflict,
                                       apr_pool_t *scratch_pool)
{
  const char *repos_root_url;
  const char *repos_uuid;
  const char *incoming_old_repos_relpath;
  svn_revnum_t incoming_old_pegrev;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  struct conflict_tree_incoming_add_details *details;
  svn_client__conflict_report_t *conflict_report;
  const char *source1;
  svn_opt_revision_t revision1;
  const char *source2;
  svn_opt_revision_t revision2;
  svn_error_t *err;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  details = conflict->tree_conflict_incoming_details;
  if (details == NULL)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Conflict resolution option '%d' requires "
                               "details for tree conflict at '%s' to be "
                               "fetched from the repository"),
                            option->id,
                            svn_dirent_local_style(local_abspath,
                                                   scratch_pool));

  /* Set up merge sources to merge the entire incoming added directory tree. */
  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
                                             conflict, scratch_pool,
                                             scratch_pool));
  source1 = svn_path_url_add_component2(repos_root_url,
                                        details->repos_relpath,
                                        scratch_pool);
  revision1.kind = svn_opt_revision_number;
  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &incoming_old_repos_relpath, &incoming_old_pegrev,
            NULL, conflict, scratch_pool, scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            NULL, conflict, scratch_pool, scratch_pool));
  if (incoming_old_pegrev < incoming_new_pegrev) /* forward merge */
    {
      if (details->added_rev == SVN_INVALID_REVNUM)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Could not determine when '%s' was "
                                   "added the repository"),
                                 svn_dirent_local_style(local_abspath,
                                                        scratch_pool));
      revision1.value.number = details->added_rev;

      source2 = svn_path_url_add_component2(repos_root_url,
                                            incoming_new_repos_relpath,
                                            scratch_pool);
      revision2.kind = svn_opt_revision_number;
      revision2.value.number = incoming_new_pegrev;
    }
  else /* reverse-merge */
    {
      if (details->deleted_rev == SVN_INVALID_REVNUM)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Could not determine when '%s' was "
                                   "deleted from the repository"),
                                 svn_dirent_local_style(local_abspath,
                                                        scratch_pool));
      revision1.value.number = details->deleted_rev;

      source2 = svn_path_url_add_component2(repos_root_url,
                                            incoming_old_repos_relpath,
                                            scratch_pool);
      revision2.kind = svn_opt_revision_number;
      revision2.value.number = incoming_old_pegrev;
    }

  /* ### The following WC modifications should be atomic. */
  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));

  /* Resolve to current working copy state. The merge requires this. */
  err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);
  if (err)
    return svn_error_compose_create(err,
                                    svn_wc__release_write_lock(ctx->wc_ctx,
                                                               lock_abspath,
                                                               scratch_pool));

  /* ### Should we do anything about mergeinfo? We need to run a no-ancestry
   * ### merge to get a useful result because mergeinfo-aware merges may split
   * ### this merge into several ranges and then abort early as soon as a
   * ### conflict occurs (which will happen invariably when merging unrelated
   * ### trees). The original merge which raised the tree conflict in the
   * ### first place created mergeinfo which also describes this merge,
   * ### unless 1) the working copy's mergeinfo was changed since, or
   * ### 2) the newly added directory's history has location segments with
   * ### paths outside the original merge source's natural history's path
   * ### (see the test_option_merge_incoming_added_dir_merge3() test). */
  err = svn_client__merge_locked(&conflict_report,
                                 source1, &revision1,
                                 source2, &revision2,
                                 local_abspath, svn_depth_infinity,
                                 TRUE, TRUE, /* do a no-ancestry merge */
                                 FALSE, FALSE, FALSE,
                                 TRUE, /* Allow mixed-rev just in case, since
                                        * conflict victims can't be updated to
                                        * straighten out mixed-rev trees. */
                                 NULL, ctx, scratch_pool, scratch_pool);

  err = svn_error_compose_create(err,
                                 svn_client__make_merge_conflict_error(
                                   conflict_report, scratch_pool));
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
  SVN_ERR(err);

  if (ctx->notify_func2)
    ctx->notify_func2(ctx->notify_baton2,
                      svn_wc_create_notify(local_abspath,
                                           svn_wc_notify_resolved_tree,
                                           scratch_pool),
                      scratch_pool);

  conflict->resolution_tree = svn_client_conflict_option_get_id(option);

  return SVN_NO_ERROR;
}

/* A baton for notification_adjust_func(). */
struct notification_adjust_baton
{
  svn_wc_notify_func2_t inner_func;
  void *inner_baton;
  const char *checkout_abspath;
  const char *final_abspath;
};

/* A svn_wc_notify_func2_t function that wraps BATON->inner_func (whose
 * baton is BATON->inner_baton) and adjusts the notification paths that
 * start with BATON->checkout_abspath to start instead with
 * BATON->final_abspath. */
static void
notification_adjust_func(void *baton,
                         const svn_wc_notify_t *notify,
                         apr_pool_t *pool)
{
  struct notification_adjust_baton *nb = baton;
  svn_wc_notify_t *inner_notify = svn_wc_dup_notify(notify, pool);
  const char *relpath;

  relpath = svn_dirent_skip_ancestor(nb->checkout_abspath, notify->path);
  inner_notify->path = svn_dirent_join(nb->final_abspath, relpath, pool);

  if (nb->inner_func)
    nb->inner_func(nb->inner_baton, inner_notify, pool);
}

/* Resolve a dir/dir "incoming add vs local obstruction" tree conflict by
 * replacing the local directory with the incoming directory.
 * If MERGE_DIRS is set, also merge the directories after replacing. */
static svn_error_t *
merge_incoming_added_dir_replace(svn_client_conflict_option_t *option,
                                 svn_client_conflict_t *conflict,
                                 svn_boolean_t merge_dirs,
                                 apr_pool_t *scratch_pool)
{
  svn_ra_session_t *ra_session;
  const char *url;
  const char *corrected_url;
  const char *repos_root_url;
  const char *repos_uuid;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  const char *tmpdir_abspath, *tmp_abspath;
  svn_error_t *err;
  svn_revnum_t copy_src_revnum;
  svn_opt_revision_t copy_src_peg_revision;
  svn_boolean_t timestamp_sleep;
  svn_wc_notify_func2_t old_notify_func2 = ctx->notify_func2;
  void *old_notify_baton2 = ctx->notify_baton2;
  struct notification_adjust_baton nb;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  /* Find the URL of the incoming added directory in the repository. */
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            NULL, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
                                             conflict, scratch_pool,
                                             scratch_pool));
  url = svn_path_url_add_component2(repos_root_url, incoming_new_repos_relpath,
                                    scratch_pool);
  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
                                               url, NULL, NULL, FALSE, FALSE,
                                               conflict->ctx, scratch_pool,
                                               scratch_pool));
  if (corrected_url)
    url = corrected_url;


  /* Find a temporary location in which to check out the copy source. */
  SVN_ERR(svn_wc__get_tmpdir(&tmpdir_abspath, ctx->wc_ctx, local_abspath,
                             scratch_pool, scratch_pool));

  SVN_ERR(svn_io_open_unique_file3(NULL, &tmp_abspath, tmpdir_abspath,
                                   svn_io_file_del_on_close,
                                   scratch_pool, scratch_pool));

  /* Make a new checkout of the requested source. While doing so,
   * resolve copy_src_revnum to an actual revision number in case it
   * was until now 'invalid' meaning 'head'.  Ask this function not to
   * sleep for timestamps, by passing a sleep_needed output param.
   * Send notifications for all nodes except the root node, and adjust
   * them to refer to the destination rather than this temporary path. */

  nb.inner_func = ctx->notify_func2;
  nb.inner_baton = ctx->notify_baton2;
  nb.checkout_abspath = tmp_abspath;
  nb.final_abspath = local_abspath;
  ctx->notify_func2 = notification_adjust_func;
  ctx->notify_baton2 = &nb;

  copy_src_peg_revision.kind = svn_opt_revision_number;
  copy_src_peg_revision.value.number = incoming_new_pegrev;

  err = svn_client__checkout_internal(&copy_src_revnum, &timestamp_sleep,
                                      url, tmp_abspath,
                                      &copy_src_peg_revision,
                                      &copy_src_peg_revision,
                                      svn_depth_infinity,
                                      TRUE, /* we want to ignore externals */
                                      FALSE, /* we don't allow obstructions */
                                      ra_session, ctx, scratch_pool);

  ctx->notify_func2 = old_notify_func2;
  ctx->notify_baton2 = old_notify_baton2;

  SVN_ERR(err);

  /* ### The following WC modifications should be atomic. */

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 svn_dirent_dirname(
                                                   local_abspath,
                                                   scratch_pool),
                                                 scratch_pool, scratch_pool));

  /* Remove the working directory. */
  err = svn_wc_delete4(ctx->wc_ctx, local_abspath, FALSE, FALSE,
                       NULL, NULL, /* don't allow user to cancel here */
                       ctx->notify_func2, ctx->notify_baton2,
                       scratch_pool);
  if (err)
    goto unlock_wc;

  /* Schedule dst_path for addition in parent, with copy history.
     Don't send any notification here.
     Then remove the temporary checkout's .svn dir in preparation for
     moving the rest of it into the final destination. */
  err = svn_wc_copy3(ctx->wc_ctx, tmp_abspath, local_abspath,
                     TRUE /* metadata_only */,
                     NULL, NULL, /* don't allow user to cancel here */
                     NULL, NULL, scratch_pool);
  if (err)
    goto unlock_wc;

  err = svn_wc__acquire_write_lock(NULL, ctx->wc_ctx, tmp_abspath,
                                   FALSE, scratch_pool, scratch_pool);
  if (err)
    goto unlock_wc;
  err = svn_wc_remove_from_revision_control2(ctx->wc_ctx,
                                             tmp_abspath,
                                             FALSE, FALSE,
                                             NULL, NULL, /* don't cancel */
                                             scratch_pool);
  if (err)
    goto unlock_wc;

  /* Move the temporary disk tree into place. */
  err = svn_io_file_rename2(tmp_abspath, local_abspath, FALSE, scratch_pool);
  if (err)
    goto unlock_wc;

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify = svn_wc_create_notify(local_abspath,
                                                     svn_wc_notify_add,
                                                     scratch_pool);
      notify->kind = svn_node_dir;
      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
    }

  /* Resolve to current working copy state.
  * svn_client__merge_locked() requires this. */
  err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);
  if (err)
    goto unlock_wc;

  if (merge_dirs)
    {
      svn_client__conflict_report_t *conflict_report;
      const char *source1;
      svn_opt_revision_t revision1;
      const char *source2;
      svn_opt_revision_t revision2;
      svn_revnum_t base_revision;
      const char *base_repos_relpath;
      struct find_added_rev_baton b;

      /* Find the URL and revision of the directory we have just replaced. */
      err = svn_wc__node_get_base(NULL, &base_revision, &base_repos_relpath,
                                  NULL, NULL, NULL, ctx->wc_ctx, local_abspath,
                                  FALSE, scratch_pool, scratch_pool);
      if (err)
        goto unlock_wc;

      url = svn_path_url_add_component2(repos_root_url, base_repos_relpath,
                                        scratch_pool);

      /* Trace the replaced directory's history to its origin. */
      err = svn_ra_reparent(ra_session, url, scratch_pool);
      if (err)
        goto unlock_wc;
      b.victim_abspath = local_abspath;
      b.ctx = ctx;
      b.added_rev = SVN_INVALID_REVNUM;
      b.repos_relpath = NULL;
      b.parent_repos_relpath = svn_relpath_dirname(base_repos_relpath,
                                                   scratch_pool);
      b.pool = scratch_pool;

      err = svn_ra_get_location_segments(ra_session, "", base_revision,
                                         base_revision, SVN_INVALID_REVNUM,
                                         find_added_rev, &b,
                                         scratch_pool);
      if (err)
        goto unlock_wc;

      if (b.added_rev == SVN_INVALID_REVNUM)
        {
          err = svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                  _("Could not determine the revision in "
                                    "which '^/%s' was added to the "
                                    "repository.\n"),
                                  base_repos_relpath);
          goto unlock_wc;
        }

      /* Merge the replaced directory into the directory which replaced it.
       * We do not need to consider a reverse-merge here since the source of
       * this merge was part of the merge target working copy, not a branch
       * in the repository. */
      source1 = url;
      revision1.kind = svn_opt_revision_number;
      /* ### Our merge logic doesn't support the merge -c ADDED_REV case.
       * ### It errors out with 'path not found', unlike diff -c ADDED_REV. */
      if (b.added_rev == base_revision)
        revision1.value.number = b.added_rev - 1; /* merge -c ADDED_REV */
      else
        revision1.value.number = b.added_rev; /* merge -r ADDED_REV:BASE_REV */
      source2 = url;
      revision2.kind = svn_opt_revision_number;
      revision2.value.number = base_revision;
      
      err = svn_client__merge_locked(&conflict_report,
                                     source1, &revision1,
                                     source2, &revision2,
                                     local_abspath, svn_depth_infinity,
                                     TRUE, TRUE, /* do a no-ancestry merge */
                                     FALSE, FALSE, FALSE,
                                     FALSE, /* no need to allow mixed-rev */
                                     NULL, ctx, scratch_pool, scratch_pool);
      err = svn_error_compose_create(err,
                                     svn_client__make_merge_conflict_error(
                                       conflict_report, scratch_pool));
    }

unlock_wc:
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
  SVN_ERR(err);

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify = svn_wc_create_notify(
                                  local_abspath,
                                  svn_wc_notify_resolved_tree,
                                  scratch_pool);

      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
    }

  conflict->resolution_tree = svn_client_conflict_option_get_id(option);

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_merge_incoming_added_dir_replace(svn_client_conflict_option_t *option,
                                         svn_client_conflict_t *conflict,
                                         apr_pool_t *scratch_pool)
{
  return svn_error_trace(merge_incoming_added_dir_replace(option,
                                                          conflict,
                                                          FALSE,
                                                          scratch_pool));
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_merge_incoming_added_dir_replace_and_merge(
  svn_client_conflict_option_t *option,
  svn_client_conflict_t *conflict,
  apr_pool_t *scratch_pool)
{
  return svn_error_trace(merge_incoming_added_dir_replace(option,
                                                          conflict,
                                                          TRUE,
                                                          scratch_pool));
}

/* Verify the local working copy state matches what we expect when an
 * incoming deletion tree conflict exists.
 * We assume update/merge/switch operations leave the working copy in a
 * state which prefers the local change and cancels the deletion.
 * Run a quick sanity check and error out if it looks as if the
 * working copy was modified since, even though it's not easy to make
 * such modifications without also clearing the conflict marker. */
static svn_error_t *
verify_local_state_for_incoming_delete(svn_client_conflict_t *conflict,
                                       svn_client_conflict_option_t *option,
                                       apr_pool_t *scratch_pool)
{
  const char *local_abspath;
  const char *wcroot_abspath;
  svn_wc_operation_t operation;
  svn_client_ctx_t *ctx = conflict->ctx;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);
  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, ctx->wc_ctx,
                             local_abspath, scratch_pool,
                             scratch_pool));
  operation = svn_client_conflict_get_operation(conflict);

  if (operation == svn_wc_operation_update ||
      operation == svn_wc_operation_switch)
    {
      struct conflict_tree_incoming_delete_details *details;
      svn_boolean_t is_copy;
      svn_revnum_t copyfrom_rev;
      const char *copyfrom_repos_relpath;

      details = conflict->tree_conflict_incoming_details;
      if (details == NULL)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Conflict resolution option '%d' requires "
                                   "details for tree conflict at '%s' to be "
                                   "fetched from the repository."),
                                option->id,
                                svn_dirent_local_style(local_abspath,
                                                       scratch_pool));

      /* Ensure that the item is a copy of itself from before it was deleted.
       * Update and switch are supposed to set this up when flagging the
       * conflict. */
      SVN_ERR(svn_wc__node_get_origin(&is_copy, &copyfrom_rev,
                                      &copyfrom_repos_relpath,
                                      NULL, NULL, NULL, NULL,
                                      ctx->wc_ctx, local_abspath, FALSE,
                                      scratch_pool, scratch_pool));
      if (!is_copy)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' by "
                                   "ignoring the incoming deletion "
                                   "(expected a copied item, but the item "
                                   "is not a copy)"),
                                 svn_dirent_local_style(
                                   svn_dirent_skip_ancestor(
                                     wcroot_abspath,
                                     conflict->local_abspath),
                                 scratch_pool));
      else if (details->deleted_rev == SVN_INVALID_REVNUM &&
               details->added_rev == SVN_INVALID_REVNUM)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Could not find the revision in which '%s' "
                                   "was deleted from the repository"),
                                 svn_dirent_local_style(
                                   svn_dirent_skip_ancestor(
                                     wcroot_abspath,
                                     conflict->local_abspath),
                                   scratch_pool));
      else if (details->deleted_rev != SVN_INVALID_REVNUM &&
               copyfrom_rev >= details->deleted_rev)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' by "
                                   "ignoring the incoming deletion (expected "
                                   "an item copied from a revision smaller "
                                   "than r%ld, but the item was copied from "
                                   "r%ld)"),
                                 svn_dirent_local_style(
                                   svn_dirent_skip_ancestor(
                                     wcroot_abspath, conflict->local_abspath),
                                   scratch_pool),
                                 details->deleted_rev, copyfrom_rev);

      else if (details->added_rev != SVN_INVALID_REVNUM &&
               copyfrom_rev < details->added_rev)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' by "
                                   "ignoring the incoming deletion (expected "
                                   "an item copied from a revision larger than "
                                   "r%ld, but the item was copied from r%ld)"),
                                 svn_dirent_local_style(
                                   svn_dirent_skip_ancestor(
                                     wcroot_abspath, conflict->local_abspath),
                                   scratch_pool),
                                  details->added_rev, copyfrom_rev);

      else if (operation == svn_wc_operation_update &&
               strcmp(copyfrom_repos_relpath, details->repos_relpath) != 0)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' by "
                                   "ignoring the incoming deletion (expected "
                                   "an item copied from '^/%s', but the item "
                                   "was copied from '^/%s@%ld')"),
                                 svn_dirent_local_style(
                                   svn_dirent_skip_ancestor(
                                     wcroot_abspath, conflict->local_abspath),
                                   scratch_pool),
                                 details->repos_relpath,
                                 copyfrom_repos_relpath, copyfrom_rev);
      else if (operation == svn_wc_operation_switch)
        {
          const char *old_repos_relpath;

          SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
                    &old_repos_relpath, NULL, NULL, conflict,
                    scratch_pool, scratch_pool));

          if (strcmp(copyfrom_repos_relpath, old_repos_relpath) != 0)
            return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                     _("Cannot resolve tree conflict on '%s' "
                                       "by ignoring the incoming deletion "
                                       "(expected an item copied from '^/%s', "
                                       "but the item was copied from "
                                        "'^/%s@%ld')"),
                                     svn_dirent_local_style(
                                       svn_dirent_skip_ancestor(
                                         wcroot_abspath,
                                         conflict->local_abspath),
                                       scratch_pool),
                                     old_repos_relpath,
                                     copyfrom_repos_relpath, copyfrom_rev);
        }
    }
  else if (operation == svn_wc_operation_merge)
    {
      svn_node_kind_t victim_node_kind;
      svn_node_kind_t on_disk_kind;

      /* For merge, all we can do is ensure that the item still exists. */
      victim_node_kind =
        svn_client_conflict_tree_get_victim_node_kind(conflict);
      SVN_ERR(svn_io_check_path(local_abspath, &on_disk_kind, scratch_pool));

      if (victim_node_kind != on_disk_kind)
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("Cannot resolve tree conflict on '%s' by "
                                   "ignoring the incoming deletion (expected "
                                   "node kind '%s' but found '%s')"),
                                 svn_dirent_local_style(
                                   svn_dirent_skip_ancestor(
                                     wcroot_abspath, conflict->local_abspath),
                                   scratch_pool),
                                 svn_node_kind_to_word(victim_node_kind),
                                 svn_node_kind_to_word(on_disk_kind));
    }

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_incoming_delete_ignore(svn_client_conflict_option_t *option,
                               svn_client_conflict_t *conflict,
                               apr_pool_t *scratch_pool)
{
  svn_client_conflict_option_id_t option_id;
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;

  option_id = svn_client_conflict_option_get_id(option);
  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));

  err = verify_local_state_for_incoming_delete(conflict, option, scratch_pool);
  if (err)
    goto unlock_wc;

  /* Resolve to the current working copy state. */
  err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath, scratch_pool);

  /* svn_wc__del_tree_conflict doesn't handle notification for us */
  if (ctx->notify_func2)
    ctx->notify_func2(ctx->notify_baton2,
                      svn_wc_create_notify(local_abspath,
                                           svn_wc_notify_resolved_tree,
                                           scratch_pool),
                      scratch_pool);

unlock_wc:
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  SVN_ERR(err);

  conflict->resolution_tree = option_id;

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_incoming_delete_accept(svn_client_conflict_option_t *option,
                               svn_client_conflict_t *conflict,
                               apr_pool_t *scratch_pool)
{
  svn_client_conflict_option_id_t option_id;
  const char *local_abspath;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;

  option_id = svn_client_conflict_option_get_id(option);
  local_abspath = svn_client_conflict_get_local_abspath(conflict);

  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(&lock_abspath, ctx->wc_ctx,
                                                 local_abspath,
                                                 scratch_pool, scratch_pool));

  err = verify_local_state_for_incoming_delete(conflict, option, scratch_pool);
  if (err)
    goto unlock_wc;

  /* Delete the tree conflict victim. Marks the conflict resolved. */
  err = svn_wc_delete4(ctx->wc_ctx, local_abspath, FALSE, FALSE,
                       NULL, NULL, /* don't allow user to cancel here */
                       ctx->notify_func2, ctx->notify_baton2,
                       scratch_pool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
        {
          /* Not a versioned path. This can happen if the victim has already
           * been deleted in our branche's history, for example. Either way,
           * the item is gone, which is what we want, so don't treat this as
           * a fatal error. */
          svn_error_clear(err);

          /* Resolve to current working copy state. */
          err = svn_wc__del_tree_conflict(ctx->wc_ctx, local_abspath,
                                          scratch_pool);
        }

      if (err)
        goto unlock_wc;
    }

  if (ctx->notify_func2)
    ctx->notify_func2(ctx->notify_baton2,
                      svn_wc_create_notify(local_abspath,
                                           svn_wc_notify_resolved_tree,
                                           scratch_pool),
                      scratch_pool);

unlock_wc:
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  SVN_ERR(err);

  conflict->resolution_tree = option_id;

  return SVN_NO_ERROR;
}

/* Implements conflict_option_resolve_func_t. */
static svn_error_t *
resolve_incoming_move_file_text_merge(svn_client_conflict_option_t *option,
                                      svn_client_conflict_t *conflict,
                                      apr_pool_t *scratch_pool)
{
  svn_client_conflict_option_id_t option_id;
  const char *local_abspath;
  svn_wc_operation_t operation;
  const char *lock_abspath;
  svn_client_ctx_t *ctx = conflict->ctx;
  svn_error_t *err;
  const char *repos_root_url;
  const char *repos_uuid;
  const char *incoming_old_repos_relpath;
  svn_revnum_t incoming_old_pegrev;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  const char *wc_tmpdir;
  apr_file_t *ancestor_file;
  const char *ancestor_abspath;
  svn_stream_t *ancestor_stream;
  apr_hash_t *victim_props;
  apr_hash_t *move_target_props;
  const char *ancestor_url;
  const char *corrected_url;
  svn_ra_session_t *ra_session;
  svn_wc_merge_outcome_t merge_content_outcome;
  svn_wc_notify_state_t merge_props_outcome;
  apr_array_header_t *propdiffs;
  struct conflict_tree_incoming_delete_details *details;
  apr_array_header_t *possible_moved_to_abspaths;
  const char *moved_to_abspath;

  local_abspath = svn_client_conflict_get_local_abspath(conflict);
  operation = svn_client_conflict_get_operation(conflict);
  details = conflict->tree_conflict_incoming_details;
  if (details == NULL || details->moves == NULL)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("The specified conflict resolution option "
                               "requires details for tree conflict at '%s' "
                               "to be fetched from the repository first."),
                            svn_dirent_local_style(local_abspath,
                                                   scratch_pool));

  option_id = svn_client_conflict_option_get_id(option);
  SVN_ERR_ASSERT(option_id ==
                 svn_client_conflict_option_incoming_move_file_text_merge);
                  
  SVN_ERR(svn_client_conflict_get_repos_info(&repos_root_url, &repos_uuid,
                                             conflict, scratch_pool,
                                             scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &incoming_old_repos_relpath, &incoming_old_pegrev,
            NULL, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            NULL, conflict, scratch_pool,
            scratch_pool));

  /* Set up temporary storage for the common ancestor version of the file. */
  SVN_ERR(svn_wc__get_tmpdir(&wc_tmpdir, ctx->wc_ctx, local_abspath,
                             scratch_pool, scratch_pool));
  SVN_ERR(svn_io_open_unique_file3(&ancestor_file,
                                   &ancestor_abspath, wc_tmpdir,
                                   svn_io_file_del_on_pool_cleanup,
                                   scratch_pool, scratch_pool));
  ancestor_stream = svn_stream_from_aprfile2(ancestor_file, TRUE, scratch_pool);

  /* Fetch the ancestor file's content. */
  ancestor_url = svn_path_url_add_component2(repos_root_url,
                                             incoming_old_repos_relpath,
                                             scratch_pool);
  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, &corrected_url,
                                               ancestor_url, NULL, NULL,
                                               FALSE, FALSE, conflict->ctx,
                                               scratch_pool, scratch_pool));
  SVN_ERR(svn_ra_get_file(ra_session, "", incoming_old_pegrev,
                          ancestor_stream, NULL, /* fetched_rev */
                          NULL /* we don't need these props */, scratch_pool));

  /* Flush ancestor file to disk. */
  SVN_ERR(svn_stream_close(ancestor_stream));
  SVN_ERR(svn_io_file_flush(ancestor_file, scratch_pool));

  possible_moved_to_abspaths =
    svn_hash_gets(details->wc_move_targets, details->move_target_repos_relpath);
  moved_to_abspath = APR_ARRAY_IDX(possible_moved_to_abspaths,
                                   details->wc_move_target_idx,
                                   const char *);

  /* ### The following WC modifications should be atomic. */
  SVN_ERR(svn_wc__acquire_write_lock_for_resolve(
            &lock_abspath, ctx->wc_ctx,
            svn_dirent_get_longest_ancestor(local_abspath,
                                            moved_to_abspath,
                                            scratch_pool),
            scratch_pool, scratch_pool));

  err = verify_local_state_for_incoming_delete(conflict, option, scratch_pool);
  if (err)
    goto unlock_wc;

   /* Get a copy of the conflict victim's properties. */
  err = svn_wc_prop_list2(&victim_props, ctx->wc_ctx, local_abspath,
                          scratch_pool, scratch_pool);
  if (err)
    goto unlock_wc;

  /* Get a copy of the move target's properties. */
  err = svn_wc_prop_list2(&move_target_props, ctx->wc_ctx,
                          moved_to_abspath,
                          scratch_pool, scratch_pool);
  if (err)
    goto unlock_wc;

  /* Create a property diff for the files. */
  err = svn_prop_diffs(&propdiffs, victim_props, move_target_props,
                       scratch_pool);
  if (err)
    goto unlock_wc;

  /* Perform the file merge. */
  err = svn_wc_merge5(&merge_content_outcome, &merge_props_outcome,
                      ctx->wc_ctx, ancestor_abspath,
                      local_abspath, moved_to_abspath,
                      NULL, NULL, NULL, /* labels */
                      NULL, NULL, /* conflict versions */
                      FALSE, /* dry run */
                      NULL, NULL, /* diff3_cmd, merge_options */
                      NULL, propdiffs,
                      NULL, NULL, /* conflict func/baton */
                      NULL, NULL, /* don't allow user to cancel here */
                      scratch_pool);
  svn_io_sleep_for_timestamps(moved_to_abspath, scratch_pool);
  if (err)
    goto unlock_wc;

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify;

      /* Tell the world about the file merge that just happened. */
      notify = svn_wc_create_notify(moved_to_abspath,
                                    svn_wc_notify_update_update,
                                    scratch_pool);
      if (merge_content_outcome == svn_wc_merge_conflict)
        notify->content_state = svn_wc_notify_state_conflicted;
      else
        notify->content_state = svn_wc_notify_state_merged;
      notify->prop_state = merge_props_outcome;
      notify->kind = svn_node_file;
      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
    }

  /* The merge is done. Local edits are now at the moved-to location. */
  if (operation == svn_wc_operation_update ||
      operation == svn_wc_operation_switch)
    {
      /* The move operation is part of our natural history.
       * Delete the tree conflict victim (clears the tree conflict marker). */
      err = svn_wc_delete4(ctx->wc_ctx, local_abspath, FALSE, FALSE,
                           NULL, NULL, /* don't allow user to cancel here */
                           NULL, NULL, /* no extra notification */
                           scratch_pool);
      if (err)
        goto unlock_wc;
    }
  else if (operation == svn_wc_operation_merge)
    {
      /* The move operation is not part of natural history. We must replicate
       * this move in our history. Record a move in the working copy. */
      err = svn_wc__move2(ctx->wc_ctx, local_abspath, moved_to_abspath,
                          TRUE, /* this is a meta-data only move */
                          FALSE, /* mixed-revisions don't apply to files */
                          NULL, NULL, /* don't allow user to cancel here */
                          NULL, NULL, /* no extra notification */
                          scratch_pool);
      if (err)
        goto unlock_wc;
    }
  else
    return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
                             _("Invalid operation code '%d' recorded for "
                               "conflict at '%s'"), operation,
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify;

      notify = svn_wc_create_notify(local_abspath, svn_wc_notify_resolved_tree,
                                    scratch_pool);
      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
    }

  conflict->resolution_tree = option_id;

unlock_wc:
  err = svn_error_compose_create(err, svn_wc__release_write_lock(ctx->wc_ctx,
                                                                 lock_abspath,
                                                                 scratch_pool));
  SVN_ERR(err);

  return SVN_NO_ERROR;
}

/* Resolver options for a text conflict */
static const svn_client_conflict_option_t text_conflict_options[] =
{
  {
    svn_client_conflict_option_postpone,
    N_("skip this conflict and leave it unresolved"),
    NULL,
    resolve_postpone
  },

  {
    svn_client_conflict_option_base_text,
    N_("discard local and incoming changes for this file"),
    NULL,
    resolve_text_conflict
  },

  {
    svn_client_conflict_option_incoming_text,
    N_("accept incoming version of entire file"),
    NULL,
    resolve_text_conflict
  },

  {
    svn_client_conflict_option_working_text,
    N_("reject all incoming changes for this file"),
    NULL,
    resolve_text_conflict
  },

  {
    svn_client_conflict_option_incoming_text_where_conflicted,
    N_("accept changes only where they conflict"),
    NULL,
    resolve_text_conflict
  },

  {
    svn_client_conflict_option_working_text_where_conflicted,
    N_("reject changes which conflict and accept the rest"),
    NULL,
    resolve_text_conflict
  },

  {
    svn_client_conflict_option_merged_text,
    N_("accept the file as it appears in the working copy"),
    NULL,
    resolve_text_conflict
  },

};

/* Resolver options for a binary file conflict */
static const svn_client_conflict_option_t binary_conflict_options[] =
{
  {
    svn_client_conflict_option_postpone,
    N_("skip this conflict and leave it unresolved"),
    NULL,
    resolve_postpone,
  },

  {
    svn_client_conflict_option_incoming_text,
    N_("accept incoming version of binary file"),
    NULL,
    resolve_text_conflict
  },

  {
    svn_client_conflict_option_merged_text,
    N_("accept binary file as it appears in the working copy"),
    NULL,
    resolve_text_conflict
  },

};

/* Resolver options for a property conflict */
static const svn_client_conflict_option_t prop_conflict_options[] =
{
  {
    svn_client_conflict_option_postpone,
    N_("skip this conflict and leave it unresolved"),
    NULL,
    resolve_postpone
  },

  {
    svn_client_conflict_option_base_text,
    N_("discard local and incoming changes for this property"),
    NULL,
    resolve_prop_conflict
  },

  {
    svn_client_conflict_option_incoming_text,
    N_("accept incoming version of entire property value"),
    NULL,
    resolve_prop_conflict
  },

  {
    svn_client_conflict_option_working_text,
    N_("accept working copy version of entire property value"),
    NULL,
    resolve_prop_conflict
  },

  {
    svn_client_conflict_option_incoming_text_where_conflicted,
    N_("accept changes only where they conflict"),
    NULL,
    resolve_prop_conflict
  },

  {
    svn_client_conflict_option_working_text_where_conflicted,
    N_("reject changes which conflict and accept the rest"),
    NULL,
    resolve_prop_conflict
  },

  {
    svn_client_conflict_option_merged_text,
    N_("accept merged version of property value"),
    NULL,
    resolve_prop_conflict
  },

};

static svn_error_t *
assert_text_conflict(svn_client_conflict_t *conflict, apr_pool_t *scratch_pool)
{
  svn_boolean_t text_conflicted;

  SVN_ERR(svn_client_conflict_get_conflicted(&text_conflicted, NULL, NULL,
                                             conflict, scratch_pool,
                                             scratch_pool));

  SVN_ERR_ASSERT(text_conflicted); /* ### return proper error? */

  return SVN_NO_ERROR;
}

static svn_error_t *
assert_prop_conflict(svn_client_conflict_t *conflict, apr_pool_t *scratch_pool)
{
  apr_array_header_t *props_conflicted;

  SVN_ERR(svn_client_conflict_get_conflicted(NULL, &props_conflicted, NULL,
                                             conflict, scratch_pool,
                                             scratch_pool));

  /* ### return proper error? */
  SVN_ERR_ASSERT(props_conflicted && props_conflicted->nelts > 0);

  return SVN_NO_ERROR;
}

static svn_error_t *
assert_tree_conflict(svn_client_conflict_t *conflict, apr_pool_t *scratch_pool)
{
  svn_boolean_t tree_conflicted;

  SVN_ERR(svn_client_conflict_get_conflicted(NULL, NULL, &tree_conflicted,
                                             conflict, scratch_pool,
                                             scratch_pool));

  SVN_ERR_ASSERT(tree_conflicted); /* ### return proper error? */

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_text_get_resolution_options(apr_array_header_t **options,
                                                svn_client_conflict_t *conflict,
                                                apr_pool_t *result_pool,
                                                apr_pool_t *scratch_pool)
{
  const char *mime_type;
  int i;

  SVN_ERR(assert_text_conflict(conflict, scratch_pool));

  *options = apr_array_make(result_pool, ARRAY_LEN(text_conflict_options),
                            sizeof(svn_client_conflict_option_t *));

  mime_type = svn_client_conflict_text_get_mime_type(conflict);
  if (mime_type && svn_mime_type_is_binary(mime_type))
    {
      for (i = 0; i < ARRAY_LEN(binary_conflict_options); i++)
        {
          svn_client_conflict_option_t *option;

          /* We must make a copy to make the memory for option->type_data
           * writable and to localize the description. */
          option = apr_pcalloc(result_pool, sizeof(*option));
          *option = binary_conflict_options[i];
          option->pool = result_pool;
          option->description = _(option->description);
          APR_ARRAY_PUSH((*options), const svn_client_conflict_option_t *) =
            option;
        }
    }
  else
    {
      for (i = 0; i < ARRAY_LEN(text_conflict_options); i++)
        {
          svn_client_conflict_option_t *option;

          /* We must make a copy to make the memory for option->type_data
           * writable and to localize the description. */
          option = apr_pcalloc(result_pool, sizeof(*option));
          *option = text_conflict_options[i];
          option->pool = result_pool;
          option->description = _(option->description);
          APR_ARRAY_PUSH((*options), const svn_client_conflict_option_t *) =
            option;
        }
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_prop_get_resolution_options(apr_array_header_t **options,
                                                svn_client_conflict_t *conflict,
                                                apr_pool_t *result_pool,
                                                apr_pool_t *scratch_pool)
{
  int i;

  SVN_ERR(assert_prop_conflict(conflict, scratch_pool));

  *options = apr_array_make(result_pool, ARRAY_LEN(prop_conflict_options),
                            sizeof(svn_client_conflict_option_t *));
  for (i = 0; i < ARRAY_LEN(prop_conflict_options); i++)
    {
      svn_client_conflict_option_t *option;

      /* We must make a copy to make the memory for option->type_data
       * writable and to localize the description. */
      option = apr_pcalloc(result_pool, sizeof(*option));
      *option = prop_conflict_options[i];
      option->pool = result_pool;
      option->description = _(option->description);
      APR_ARRAY_PUSH((*options), const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'accept current wc state' resolution option for a tree conflict. */
static svn_error_t *
configure_option_accept_current_wc_state(svn_client_conflict_t *conflict,
                                         apr_array_header_t *options)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  svn_client_conflict_option_t *option;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);

  option = apr_pcalloc(options->pool, sizeof(*option));
  option->pool = options->pool;
  option->id = svn_client_conflict_option_accept_current_wc_state;
  option->description = _("accept current working copy state");
  option->conflict = conflict;
  if ((operation == svn_wc_operation_update ||
       operation == svn_wc_operation_switch) &&
      (local_change == svn_wc_conflict_reason_moved_away ||
       local_change == svn_wc_conflict_reason_deleted ||
       local_change == svn_wc_conflict_reason_replaced) &&
      incoming_change == svn_wc_conflict_action_edit)
    {
      /* We must break moves if the user accepts the current working copy
       * state instead of updating a moved-away node or updating children
       * moved outside of deleted or replaced directory nodes.
       * Else such moves would be left in an invalid state. */
      option->do_resolve_func = resolve_update_break_moved_away;
    }
  else
    option->do_resolve_func = resolve_accept_current_wc_state;

  APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;

  return SVN_NO_ERROR;
}

/* Configure 'update move destination' resolution option for a tree conflict. */
static svn_error_t *
configure_option_update_move_destination(svn_client_conflict_t *conflict,
                                         apr_array_header_t *options)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);

  if ((operation == svn_wc_operation_update ||
       operation == svn_wc_operation_switch) &&
      incoming_change == svn_wc_conflict_action_edit &&
      local_change == svn_wc_conflict_reason_moved_away)
    {
      svn_client_conflict_option_t *option;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id = svn_client_conflict_option_update_move_destination;
      option->description = _("apply incoming changes to move destination");
      option->conflict = conflict;
      option->do_resolve_func = resolve_update_moved_away_node;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'update raise moved away children' resolution option for a tree
 * conflict. */
static svn_error_t *
configure_option_update_raise_moved_away_children(
  svn_client_conflict_t *conflict,
  apr_array_header_t *options)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  svn_node_kind_t victim_node_kind;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);

  if ((operation == svn_wc_operation_update ||
       operation == svn_wc_operation_switch) &&
      incoming_change == svn_wc_conflict_action_edit &&
      (local_change == svn_wc_conflict_reason_deleted ||
       local_change == svn_wc_conflict_reason_replaced) &&
      victim_node_kind == svn_node_dir)
    {
      svn_client_conflict_option_t *option;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id = svn_client_conflict_option_update_any_moved_away_children;
      option->description = _("prepare for updating moved-away children, "
                              "if any");
      option->conflict = conflict;
      option->do_resolve_func = resolve_update_raise_moved_away;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming add ignore' resolution option for a tree conflict. */
static svn_error_t *
configure_option_incoming_add_ignore(svn_client_conflict_t *conflict,
                                     apr_array_header_t *options,
                                     apr_pool_t *scratch_pool)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  svn_node_kind_t victim_node_kind;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            NULL, conflict, scratch_pool,
            scratch_pool));

  if (incoming_change == svn_wc_conflict_action_add &&
      (local_change == svn_wc_conflict_reason_obstructed ||
       local_change == svn_wc_conflict_reason_added))
    {
      svn_client_conflict_option_t *option;
      const char *wcroot_abspath;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id = svn_client_conflict_option_incoming_add_ignore;
      SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                                 conflict->local_abspath, scratch_pool,
                                 scratch_pool));
      if (operation == svn_wc_operation_merge)
        option->description =
          apr_psprintf(options->pool,
                       _("ignore and do not add '^/%s@%ld' here"),
                       incoming_new_repos_relpath, incoming_new_pegrev);
      else if (operation == svn_wc_operation_update ||
               operation == svn_wc_operation_switch)
        {
          if (victim_node_kind == svn_node_file)
            option->description =
              apr_psprintf(options->pool,
                           _("replace '^/%s@%ld' with the locally added file"),
                           incoming_new_repos_relpath, incoming_new_pegrev);
          else if (victim_node_kind == svn_node_dir)
            option->description =
              apr_psprintf(options->pool,
                           _("replace '^/%s@%ld' with the locally added "
                             "directory"),
                           incoming_new_repos_relpath, incoming_new_pegrev);
          else
            option->description =
              apr_psprintf(options->pool,
                           _("replace '^/%s@%ld' with the locally added item"),
                           incoming_new_repos_relpath, incoming_new_pegrev);
        }
      else
        return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                 _("unexpected operation code '%d'"),
                                 operation);
      option->conflict = conflict;
      option->do_resolve_func = resolve_incoming_add_ignore;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming added file text merge' resolution option for a tree
 * conflict. */
static svn_error_t *
configure_option_incoming_added_file_text_merge(svn_client_conflict_t *conflict,
                                                apr_array_header_t *options,
                                                apr_pool_t *scratch_pool)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  svn_node_kind_t victim_node_kind;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  svn_node_kind_t incoming_new_kind;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            &incoming_new_kind, conflict, scratch_pool,
            scratch_pool));

  if (operation == svn_wc_operation_merge &&
      victim_node_kind == svn_node_file &&
      incoming_new_kind == svn_node_file &&
      incoming_change == svn_wc_conflict_action_add &&
      local_change == svn_wc_conflict_reason_obstructed)
    {
      svn_client_conflict_option_t *option;
      const char *wcroot_abspath;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id =
        svn_client_conflict_option_incoming_added_file_text_merge;
      SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                                 conflict->local_abspath, scratch_pool,
                                 scratch_pool));
      option->description =
        apr_psprintf(options->pool, _("merge '^/%s@%ld' into '%s'"),
          incoming_new_repos_relpath, incoming_new_pegrev,
          svn_dirent_local_style(
            svn_dirent_skip_ancestor(wcroot_abspath,
                                     conflict->local_abspath),
            scratch_pool));
      option->conflict = conflict;
      option->do_resolve_func = resolve_merge_incoming_added_file_text_merge;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming added file replace' resolution option for a tree
 * conflict. */
static svn_error_t *
configure_option_incoming_added_file_replace(svn_client_conflict_t *conflict,
                                             apr_array_header_t *options,
                                             apr_pool_t *scratch_pool)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  svn_node_kind_t victim_node_kind;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  svn_node_kind_t incoming_new_kind;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            &incoming_new_kind, conflict, scratch_pool,
            scratch_pool));

  if ((operation == svn_wc_operation_merge ||
       operation == svn_wc_operation_update) &&
      victim_node_kind == svn_node_file &&
      incoming_new_kind == svn_node_file &&
      incoming_change == svn_wc_conflict_action_add &&
      (local_change == svn_wc_conflict_reason_obstructed ||
       local_change == svn_wc_conflict_reason_added))
    {
      svn_client_conflict_option_t *option;
      const char *wcroot_abspath;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id = svn_client_conflict_option_incoming_added_file_replace;
      SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                                 conflict->local_abspath, scratch_pool,
                                 scratch_pool));
      if (operation == svn_wc_operation_update)
        option->description =
          apr_psprintf(options->pool,
                       _("revert the locally added file to keep '^/%s@%ld'"),
                       incoming_new_repos_relpath, incoming_new_pegrev);
      else
        option->description =
          apr_psprintf(options->pool, _("delete '%s' and copy '^/%s@%ld' here"),
                       svn_dirent_local_style(
                         svn_dirent_skip_ancestor(wcroot_abspath,
                                                  conflict->local_abspath),
                         scratch_pool),
                       incoming_new_repos_relpath, incoming_new_pegrev);
      option->conflict = conflict;
      if (operation == svn_wc_operation_update)
        option->do_resolve_func = resolve_update_incoming_added_file_replace;
      else
        option->do_resolve_func = resolve_merge_incoming_added_file_replace;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming added file replace and merge' resolution option for a
 * tree conflict. */
static svn_error_t *
configure_option_incoming_added_file_replace_and_merge(
  svn_client_conflict_t *conflict,
  apr_array_header_t *options,
  apr_pool_t *scratch_pool)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  svn_node_kind_t victim_node_kind;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  svn_node_kind_t incoming_new_kind;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            &incoming_new_kind, conflict, scratch_pool,
            scratch_pool));

  if (operation == svn_wc_operation_merge &&
      victim_node_kind == svn_node_file &&
      incoming_new_kind == svn_node_file &&
      incoming_change == svn_wc_conflict_action_add &&
      local_change == svn_wc_conflict_reason_obstructed)
    {
      svn_client_conflict_option_t *option;
      const char *wcroot_abspath;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id =
        svn_client_conflict_option_incoming_added_file_replace_and_merge;
      SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                                 conflict->local_abspath, scratch_pool,
                                 scratch_pool));
      option->description =
        apr_psprintf(options->pool,
          _("delete '%s', copy '^/%s@%ld' here, and merge the files"),
          svn_dirent_local_style(
            svn_dirent_skip_ancestor(wcroot_abspath,
                                     conflict->local_abspath),
            scratch_pool),
          incoming_new_repos_relpath, incoming_new_pegrev);
      option->conflict = conflict;
      option->do_resolve_func =
        resolve_merge_incoming_added_file_replace_and_merge;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming added dir merge' resolution option for a tree
 * conflict. */
static svn_error_t *
configure_option_incoming_added_dir_merge(svn_client_conflict_t *conflict,
                                          apr_array_header_t *options,
                                          apr_pool_t *scratch_pool)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  svn_node_kind_t victim_node_kind;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  svn_node_kind_t incoming_new_kind;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            &incoming_new_kind, conflict, scratch_pool,
            scratch_pool));

  if (operation == svn_wc_operation_merge &&
      victim_node_kind == svn_node_dir &&
      incoming_new_kind == svn_node_dir &&
      incoming_change == svn_wc_conflict_action_add &&
      local_change == svn_wc_conflict_reason_obstructed)
    {
      svn_client_conflict_option_t *option;
      const char *wcroot_abspath;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id = svn_client_conflict_option_incoming_added_dir_merge;
      SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                                 conflict->local_abspath, scratch_pool,
                                 scratch_pool));
      option->description =
        apr_psprintf(options->pool, _("merge '^/%s@%ld' into '%s'"),
          incoming_new_repos_relpath, incoming_new_pegrev,
          svn_dirent_local_style(
            svn_dirent_skip_ancestor(wcroot_abspath,
                                     conflict->local_abspath),
            scratch_pool));
      option->conflict = conflict;
      option->do_resolve_func = resolve_merge_incoming_added_dir_merge;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming added dir replace' resolution option for a tree
 * conflict. */
static svn_error_t *
configure_option_incoming_added_dir_replace(svn_client_conflict_t *conflict,
                                            apr_array_header_t *options,
                                            apr_pool_t *scratch_pool)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  svn_node_kind_t victim_node_kind;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  svn_node_kind_t incoming_new_kind;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            &incoming_new_kind, conflict, scratch_pool,
            scratch_pool));

  if (operation == svn_wc_operation_merge &&
      victim_node_kind == svn_node_dir &&
      incoming_new_kind == svn_node_dir &&
      incoming_change == svn_wc_conflict_action_add &&
      local_change == svn_wc_conflict_reason_obstructed)
    {
      svn_client_conflict_option_t *option;
      const char *wcroot_abspath;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id =
        svn_client_conflict_option_incoming_added_dir_replace;
      SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                                 conflict->local_abspath, scratch_pool,
                                 scratch_pool));
      option->description =
        apr_psprintf(options->pool, _("delete '%s' and copy '^/%s@%ld' here"),
          svn_dirent_local_style(
            svn_dirent_skip_ancestor(wcroot_abspath,
                                     conflict->local_abspath),
            scratch_pool),
          incoming_new_repos_relpath, incoming_new_pegrev);
      option->conflict = conflict;
      option->do_resolve_func = resolve_merge_incoming_added_dir_replace;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming added dir replace and merge' resolution option
 * for a tree conflict. */
static svn_error_t *
configure_option_incoming_added_dir_replace_and_merge(
  svn_client_conflict_t *conflict,
  apr_array_header_t *options,
  apr_pool_t *scratch_pool)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  svn_node_kind_t victim_node_kind;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  svn_node_kind_t incoming_new_kind;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            &incoming_new_kind, conflict, scratch_pool,
            scratch_pool));

  if (operation == svn_wc_operation_merge &&
      victim_node_kind == svn_node_dir &&
      incoming_new_kind == svn_node_dir &&
      incoming_change == svn_wc_conflict_action_add &&
      local_change == svn_wc_conflict_reason_obstructed)
    {
      svn_client_conflict_option_t *option;
      const char *wcroot_abspath;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id =
        svn_client_conflict_option_incoming_added_dir_replace_and_merge;
      SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                                 conflict->local_abspath, scratch_pool,
                                 scratch_pool));
      option->description =
        apr_psprintf(options->pool,
          _("delete '%s', copy '^/%s@%ld' here, and merge the directories"),
          svn_dirent_local_style(
            svn_dirent_skip_ancestor(wcroot_abspath,
                                     conflict->local_abspath),
            scratch_pool),
          incoming_new_repos_relpath, incoming_new_pegrev);
      option->conflict = conflict;
      option->do_resolve_func =
        resolve_merge_incoming_added_dir_replace_and_merge;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming delete ignore' resolution option for a tree conflict. */
static svn_error_t *
configure_option_incoming_delete_ignore(svn_client_conflict_t *conflict,
                                        apr_array_header_t *options,
                                        apr_pool_t *scratch_pool)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            NULL, conflict, scratch_pool,
            scratch_pool));

  if (incoming_change == svn_wc_conflict_action_delete)
    {
      svn_client_conflict_option_t *option;
      struct conflict_tree_incoming_delete_details *incoming_details;
      svn_boolean_t is_incoming_move;

      /* If the local item was deleted and conflict details were fetched and
       * indicate that there was no move, then this is an actual 'delete vs
       * delete' situation. An option which ignores the incoming deletion makes
       * no sense in that case because there is no local node to preserve. */
      incoming_details = conflict->tree_conflict_incoming_details;
      is_incoming_move = (incoming_details != NULL &&
                          incoming_details->moves != NULL);
      if (local_change == svn_wc_conflict_reason_deleted)
        {
          if (!is_incoming_move)
            return SVN_NO_ERROR;
        }
      else if (local_change == svn_wc_conflict_reason_missing &&
               operation == svn_wc_operation_merge)
        {
          struct conflict_tree_local_missing_details *local_details;
          svn_boolean_t is_local_move; /* "local" to branch history */

          local_details = conflict->tree_conflict_local_details;
          is_local_move = (local_details != NULL &&
                           local_details->moves != NULL);

          if (!is_incoming_move && !is_local_move)
            return SVN_NO_ERROR;
        }

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id = svn_client_conflict_option_incoming_delete_ignore;
      option->description =
        apr_psprintf(options->pool, _("ignore the deletion of '^/%s@%ld'"),
          incoming_new_repos_relpath, incoming_new_pegrev);
      option->conflict = conflict;
      option->do_resolve_func = resolve_incoming_delete_ignore;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming delete accept' resolution option for a tree conflict. */
static svn_error_t *
configure_option_incoming_delete_accept(svn_client_conflict_t *conflict,
                                        apr_array_header_t *options,
                                        apr_pool_t *scratch_pool)
{
  svn_wc_operation_t operation;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;

  operation = svn_client_conflict_get_operation(conflict);
  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            NULL, conflict, scratch_pool,
            scratch_pool));

  if (incoming_change == svn_wc_conflict_action_delete)
    {
      svn_client_conflict_option_t *option;
      const char *wcroot_abspath;
      const char *local_abspath;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id = svn_client_conflict_option_incoming_delete_accept;
      SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                                 conflict->local_abspath, scratch_pool,
                                 scratch_pool));
      local_abspath = svn_client_conflict_get_local_abspath(conflict);
      option->description =
        apr_psprintf(options->pool, _("accept the deletion of '%s'"),
          svn_dirent_local_style(svn_dirent_skip_ancestor(wcroot_abspath,
                                                          local_abspath),
                                 scratch_pool));
      option->conflict = conflict;
      option->do_resolve_func = resolve_incoming_delete_accept;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

/* Follow each move chain starting a MOVE all the way to the end to find
 * the possible working copy locations for VICTIM_ABSPATH at PEG_REVISION.
 * Add each such location to the WC_MOVE_TARGETS hash table, keyed on the
 * repos_relpath which is the corresponding move destination in the repository.
 * This function is recursive. */
static svn_error_t *
follow_move_chains(apr_hash_t *wc_move_targets,
                   struct repos_move_info *move,
                   svn_client_ctx_t *ctx,
                   const char *victim_abspath,
                   svn_node_kind_t victim_node_kind,
                   svn_revnum_t peg_revision,
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
{
  /* If this is the end of a move chain, look for matching paths in
   * the working copy and add them to our collection if found. */
  if (move->next == NULL)
    {
      apr_array_header_t *moved_to_abspaths;

      /* Gather nodes which represent this moved_to_repos_relpath. */
      SVN_ERR(svn_wc__guess_incoming_move_target_nodes(
                &moved_to_abspaths, ctx->wc_ctx,
                victim_abspath, victim_node_kind,
                move->moved_to_repos_relpath,
                peg_revision, result_pool, scratch_pool));
      if (moved_to_abspaths->nelts > 0)
        svn_hash_sets(wc_move_targets, move->moved_to_repos_relpath,
                      moved_to_abspaths);
    }
  else
    {
      int i;
      apr_pool_t *iterpool;

      /* Recurse into each of the possible move chains. */
      iterpool = svn_pool_create(scratch_pool);
      for (i = 0; i < move->next->nelts; i++)
        {
          struct repos_move_info *next_move;

          svn_pool_clear(iterpool);

          next_move = APR_ARRAY_IDX(move->next, i, struct repos_move_info *);
          SVN_ERR(follow_move_chains(wc_move_targets, next_move,
                                     ctx, victim_abspath, victim_node_kind,
                                     peg_revision, result_pool, iterpool));
                                        
        }
      svn_pool_destroy(iterpool);
    }

  return SVN_NO_ERROR;
}

/* Configure 'incoming move file merge' resolution option for
 * a tree conflict. */
static svn_error_t *
configure_option_incoming_move_file_merge(svn_client_conflict_t *conflict,
                                          apr_array_header_t *options,
                                          apr_pool_t *scratch_pool)
{
  svn_node_kind_t victim_node_kind;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;
  const char *incoming_old_repos_relpath;
  svn_revnum_t incoming_old_pegrev;
  svn_node_kind_t incoming_old_kind;
  const char *incoming_new_repos_relpath;
  svn_revnum_t incoming_new_pegrev;
  svn_node_kind_t incoming_new_kind;
  struct conflict_tree_incoming_delete_details *details;

  details = conflict->tree_conflict_incoming_details;
  if (details == NULL || details->moves == NULL)
    return SVN_NO_ERROR;

  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);
  victim_node_kind = svn_client_conflict_tree_get_victim_node_kind(conflict);
  SVN_ERR(svn_client_conflict_get_incoming_old_repos_location(
            &incoming_old_repos_relpath, &incoming_old_pegrev,
            &incoming_old_kind, conflict, scratch_pool,
            scratch_pool));
  SVN_ERR(svn_client_conflict_get_incoming_new_repos_location(
            &incoming_new_repos_relpath, &incoming_new_pegrev,
            &incoming_new_kind, conflict, scratch_pool,
            scratch_pool));

  if (victim_node_kind == svn_node_file &&
      incoming_old_kind == svn_node_file &&
      incoming_new_kind == svn_node_none &&
      incoming_change == svn_wc_conflict_action_delete)
    {
      svn_client_conflict_option_t *option;
      const char *wcroot_abspath;
      const char *victim_abspath;
      const char *moved_to_abspath;
      apr_array_header_t *move_target_repos_relpaths;
      apr_array_header_t *move_target_wc_abspaths;

      option = apr_pcalloc(options->pool, sizeof(*option));
      option->pool = options->pool;
      option->id = svn_client_conflict_option_incoming_move_file_text_merge;
      victim_abspath = svn_client_conflict_get_local_abspath(conflict);
      SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                                 victim_abspath, scratch_pool,
                                 scratch_pool));

      if (details->wc_move_targets == NULL)
        {
          int i;

          details->wc_move_targets = apr_hash_make(conflict->pool);
          for (i = 0; i < details->moves->nelts; i++)
            {
              struct repos_move_info *move;

              move = APR_ARRAY_IDX(details->moves, i, struct repos_move_info *);
              SVN_ERR(follow_move_chains(details->wc_move_targets, move,
                                         conflict->ctx, victim_abspath,
                                         victim_node_kind,
                                         incoming_new_pegrev,
                                         conflict->pool, scratch_pool));
            }
          if (apr_hash_count(details->wc_move_targets) > 0)
            {
              svn_sort__item_t item;

              /* Initialize to the first possible move target. Hopefully,
               * in most cases there will only be one candidate anyway. */
              move_target_repos_relpaths = 
                svn_sort__hash(details->wc_move_targets,
                               svn_sort_compare_items_as_paths,
                               scratch_pool);
              item = APR_ARRAY_IDX(move_target_repos_relpaths, 0,
                                   svn_sort__item_t);
              details->move_target_repos_relpath = item.key;
              details->wc_move_target_idx = 0;
            }
          else
            {
              details->move_target_repos_relpath = NULL;
              details->wc_move_target_idx = 0;
              return SVN_NO_ERROR;
            }
        }

      if (apr_hash_count(details->wc_move_targets) == 0)
        return SVN_NO_ERROR;

      move_target_wc_abspaths =
        svn_hash_gets(details->wc_move_targets,
                      details->move_target_repos_relpath);
      moved_to_abspath = APR_ARRAY_IDX(move_target_wc_abspaths,
                                       details->wc_move_target_idx,
                                       const char *);
      option->description =
        apr_psprintf(
          options->pool, _("move '%s' to '%s' and merge"),
          svn_dirent_local_style(svn_dirent_skip_ancestor(wcroot_abspath,
                                                          victim_abspath),
                                 scratch_pool),
          svn_dirent_local_style(svn_dirent_skip_ancestor(wcroot_abspath,
                                                          moved_to_abspath),
                                 scratch_pool));
      option->conflict = conflict;
      option->do_resolve_func = resolve_incoming_move_file_text_merge;
      APR_ARRAY_PUSH(options, const svn_client_conflict_option_t *) = option;
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_option_get_moved_to_repos_relpath_candidates(
  apr_array_header_t **possible_moved_to_repos_relpaths,
  svn_client_conflict_option_t *option,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  svn_client_conflict_t *conflict = option->conflict;
  struct conflict_tree_incoming_delete_details *details;
  const char *victim_abspath;
  apr_array_header_t *sorted_repos_relpaths;
  int i;

  SVN_ERR_ASSERT(svn_client_conflict_option_get_id(option) ==
                 svn_client_conflict_option_incoming_move_file_text_merge);

  victim_abspath = svn_client_conflict_get_local_abspath(conflict);
  details = conflict->tree_conflict_incoming_details;
  if (details == NULL || details->wc_move_targets == NULL)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Getting a list of possible move targets "
                               "requires details for tree conflict at '%s' "
                               "to be fetched from the repository first"),
                            svn_dirent_local_style(victim_abspath,
                                                   scratch_pool));

  /* Return a copy of the repos replath candidate list. */
  sorted_repos_relpaths = svn_sort__hash(details->wc_move_targets,
                                         svn_sort_compare_items_as_paths,
                                         scratch_pool);

  *possible_moved_to_repos_relpaths = apr_array_make(
                                        result_pool,
                                        sorted_repos_relpaths->nelts,
                                        sizeof (const char *));
  for (i = 0; i < sorted_repos_relpaths->nelts; i++)
    {
      svn_sort__item_t item;
      const char *repos_relpath;

      item = APR_ARRAY_IDX(sorted_repos_relpaths, i, svn_sort__item_t);
      repos_relpath = item.key;
      APR_ARRAY_PUSH(*possible_moved_to_repos_relpaths, const char *) =
        apr_pstrdup(result_pool, repos_relpath);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_option_set_moved_to_repos_relpath(
  svn_client_conflict_option_t *option,
  int preferred_move_target_idx,
  apr_pool_t *scratch_pool)
{
  svn_client_conflict_t *conflict = option->conflict;
  struct conflict_tree_incoming_delete_details *details;
  const char *victim_abspath;
  apr_array_header_t *move_target_repos_relpaths;
  svn_sort__item_t item;
  const char *move_target_repos_relpath;
  apr_hash_index_t *hi;

  SVN_ERR_ASSERT(svn_client_conflict_option_get_id(option) ==
                 svn_client_conflict_option_incoming_move_file_text_merge);

  victim_abspath = svn_client_conflict_get_local_abspath(conflict);
  details = conflict->tree_conflict_incoming_details;
  if (details == NULL || details->wc_move_targets == NULL)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Setting a move target requires details "
                               "for tree conflict at '%s' to be fetched "
                               "from the repository first"),
                            svn_dirent_local_style(victim_abspath,
                                                   scratch_pool));

  if (preferred_move_target_idx < 0 ||
      preferred_move_target_idx >= apr_hash_count(details->wc_move_targets))
    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
                             _("Index '%d' is out of bounds of the possible "
                               "move target list for '%s'"),
                            preferred_move_target_idx,
                            svn_dirent_local_style(victim_abspath,
                                                   scratch_pool));

  /* Translate the index back into a hash table key. */
  move_target_repos_relpaths =
    svn_sort__hash(details->wc_move_targets,
                   svn_sort_compare_items_as_paths,
                   scratch_pool);
  item = APR_ARRAY_IDX(move_target_repos_relpaths, preferred_move_target_idx,
                       svn_sort__item_t);
  move_target_repos_relpath = item.key;
  /* Find our copy of the hash key and remember the user's preference. */
  for (hi = apr_hash_first(scratch_pool, details->wc_move_targets);
       hi != NULL;
       hi = apr_hash_next(hi))
    {
      const char *repos_relpath = apr_hash_this_key(hi);

      if (strcmp(move_target_repos_relpath, repos_relpath) == 0)
        {
          details->move_target_repos_relpath = repos_relpath;
          return SVN_NO_ERROR;
        }
    }

  return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
                           _("Repository path '%s' not found in list of "
                             "possible move targets for '%s'"),
                           move_target_repos_relpath,
                           svn_dirent_local_style(victim_abspath,
                                                  scratch_pool));
}

svn_error_t *
svn_client_conflict_option_get_moved_to_abspath_candidates(
  apr_array_header_t **possible_moved_to_abspaths,
  svn_client_conflict_option_t *option,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  svn_client_conflict_t *conflict = option->conflict;
  struct conflict_tree_incoming_delete_details *details;
  const char *victim_abspath;
  apr_array_header_t *move_target_wc_abspaths;
  int i;

  SVN_ERR_ASSERT(svn_client_conflict_option_get_id(option) ==
                 svn_client_conflict_option_incoming_move_file_text_merge);

  victim_abspath = svn_client_conflict_get_local_abspath(conflict);
  details = conflict->tree_conflict_incoming_details;
  if (details == NULL || details->wc_move_targets == NULL)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Getting a list of possible move targets "
                               "requires details for tree conflict at '%s' "
                               "to be fetched from the repository first"),
                            svn_dirent_local_style(victim_abspath,
                                                   scratch_pool));

  move_target_wc_abspaths =
    svn_hash_gets(details->wc_move_targets, details->move_target_repos_relpath);

  /* Return a copy of the option's move target candidate list. */
  *possible_moved_to_abspaths =
    apr_array_make(result_pool, move_target_wc_abspaths->nelts,
                   sizeof (const char *));
  for (i = 0; i < move_target_wc_abspaths->nelts; i++)
    {
      const char *moved_to_abspath;

      moved_to_abspath = APR_ARRAY_IDX(move_target_wc_abspaths, i,
                                       const char *);
      APR_ARRAY_PUSH(*possible_moved_to_abspaths, const char *) =
        apr_pstrdup(result_pool, moved_to_abspath);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_option_set_moved_to_abspath(
  svn_client_conflict_option_t *option,
  int preferred_move_target_idx,
  apr_pool_t *scratch_pool)
{
  svn_client_conflict_t *conflict = option->conflict;
  struct conflict_tree_incoming_delete_details *details;
  const char *victim_abspath;
  const char *moved_to_abspath;
  const char *wcroot_abspath;
  apr_array_header_t *move_target_wc_abspaths;

  SVN_ERR_ASSERT(svn_client_conflict_option_get_id(option) ==
                 svn_client_conflict_option_incoming_move_file_text_merge);

  victim_abspath = svn_client_conflict_get_local_abspath(conflict);
  details = conflict->tree_conflict_incoming_details;
  if (details == NULL || details->wc_move_targets == NULL)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Setting a move target requires details "
                               "for tree conflict at '%s' to be fetched "
                               "from the repository first"),
                            svn_dirent_local_style(victim_abspath,
                                                   scratch_pool));

  move_target_wc_abspaths =
    svn_hash_gets(details->wc_move_targets, details->move_target_repos_relpath);

  if (preferred_move_target_idx < 0 ||
      preferred_move_target_idx > move_target_wc_abspaths->nelts)
    return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
                             _("Index '%d' is out of bounds of the possible "
                               "move target list for '%s'"),
                            preferred_move_target_idx,
                            svn_dirent_local_style(victim_abspath,
                                                   scratch_pool));

  /* Record the user's preference and update the option description. */
  details->wc_move_target_idx = preferred_move_target_idx;

  SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, conflict->ctx->wc_ctx,
                             victim_abspath, scratch_pool,
                             scratch_pool));
  moved_to_abspath = APR_ARRAY_IDX(move_target_wc_abspaths,
                                   preferred_move_target_idx,
                                   const char *);
  option->description =
    apr_psprintf(
      option->pool, _("move '%s' to '%s' and merge'"),
      svn_dirent_local_style(svn_dirent_skip_ancestor(wcroot_abspath,
                                                      victim_abspath),
                             scratch_pool),
      svn_dirent_local_style(svn_dirent_skip_ancestor(wcroot_abspath,
                                                      moved_to_abspath),
                             scratch_pool));
  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_tree_get_resolution_options(apr_array_header_t **options,
                                                svn_client_conflict_t *conflict,
                                                apr_pool_t *result_pool,
                                                apr_pool_t *scratch_pool)
{
  svn_client_conflict_option_t *option;

  SVN_ERR(assert_tree_conflict(conflict, scratch_pool));

  *options = apr_array_make(result_pool, 2,
                            sizeof(svn_client_conflict_option_t *));

  /* Add postpone option. */
  option = apr_pcalloc(result_pool, sizeof(*option));
  option->pool = result_pool;
  option->id = svn_client_conflict_option_postpone;
  option->description = _("skip this conflict and leave it unresolved");
  option->conflict = conflict;
  option->do_resolve_func = resolve_postpone;
  APR_ARRAY_PUSH((*options), const svn_client_conflict_option_t *) = option;

  /* Add an option which marks the conflict resolved. */
  SVN_ERR(configure_option_accept_current_wc_state(conflict, *options));

  /* Configure options which offer automatic resolution. */
  SVN_ERR(configure_option_update_move_destination(conflict, *options));
  SVN_ERR(configure_option_update_raise_moved_away_children(conflict,
                                                            *options));
  SVN_ERR(configure_option_incoming_add_ignore(conflict, *options,
                                               scratch_pool));
  SVN_ERR(configure_option_incoming_added_file_text_merge(conflict, *options,
                                                          scratch_pool));
  SVN_ERR(configure_option_incoming_added_file_replace(conflict, *options,
                                                       scratch_pool));
  SVN_ERR(configure_option_incoming_added_file_replace_and_merge(conflict,
                                                                 *options,
                                                                 scratch_pool));
  SVN_ERR(configure_option_incoming_added_dir_merge(conflict, *options,
                                                    scratch_pool));
  SVN_ERR(configure_option_incoming_added_dir_replace(conflict, *options,
                                                      scratch_pool));
  SVN_ERR(configure_option_incoming_added_dir_replace_and_merge(conflict,
                                                                *options,
                                                                scratch_pool));
  SVN_ERR(configure_option_incoming_delete_ignore(conflict, *options,
                                                  scratch_pool));
  SVN_ERR(configure_option_incoming_delete_accept(conflict, *options,
                                                  scratch_pool));
  SVN_ERR(configure_option_incoming_move_file_merge(conflict, *options,
                                                    scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_tree_get_details(svn_client_conflict_t *conflict,
                                     apr_pool_t *scratch_pool)
{
  SVN_ERR(assert_tree_conflict(conflict, scratch_pool));

  if (conflict->ctx->notify_func2)
    {
      svn_wc_notify_t *notify;

      notify = svn_wc_create_notify(
                 svn_client_conflict_get_local_abspath(conflict),
                 svn_wc_notify_begin_search_tree_conflict_details,
                 scratch_pool),
      conflict->ctx->notify_func2(conflict->ctx->notify_baton2, notify,
                                  scratch_pool);
    }

  if (conflict->tree_conflict_get_incoming_details_func)
    SVN_ERR(conflict->tree_conflict_get_incoming_details_func(conflict,
                                                              scratch_pool));

  if (conflict->tree_conflict_get_local_details_func)
    SVN_ERR(conflict->tree_conflict_get_local_details_func(conflict,
                                                           scratch_pool));

  if (conflict->ctx->notify_func2)
    {
      svn_wc_notify_t *notify;

      notify = svn_wc_create_notify(
                 svn_client_conflict_get_local_abspath(conflict),
                 svn_wc_notify_end_search_tree_conflict_details,
                 scratch_pool),
      conflict->ctx->notify_func2(conflict->ctx->notify_baton2, notify,
                                  scratch_pool);
    }

  return SVN_NO_ERROR;
}

svn_client_conflict_option_id_t
svn_client_conflict_option_get_id(svn_client_conflict_option_t *option)
{
  return option->id;
}

svn_error_t *
svn_client_conflict_option_describe(const char **description,
                                    svn_client_conflict_option_t *option,
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool)
{
  *description = apr_pstrdup(result_pool, option->description);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_text_resolve(svn_client_conflict_t *conflict,
                                 svn_client_conflict_option_t *option,
                                 apr_pool_t *scratch_pool)
{
  SVN_ERR(assert_text_conflict(conflict, scratch_pool));
  SVN_ERR(option->do_resolve_func(option, conflict, scratch_pool));

  return SVN_NO_ERROR;
}

svn_client_conflict_option_t *
svn_client_conflict_option_find_by_id(apr_array_header_t *options,
                                      svn_client_conflict_option_id_t option_id)
{
  int i;

  for (i = 0; i < options->nelts; i++)
    {
      svn_client_conflict_option_t *this_option;
      svn_client_conflict_option_id_t this_option_id;
      
      this_option = APR_ARRAY_IDX(options, i, svn_client_conflict_option_t *);
      this_option_id = svn_client_conflict_option_get_id(this_option);

      if (this_option_id == option_id)
        return this_option;
    }

  return NULL;
}

svn_error_t *
svn_client_conflict_text_resolve_by_id(
  svn_client_conflict_t *conflict,
  svn_client_conflict_option_id_t option_id,
  apr_pool_t *scratch_pool)
{
  apr_array_header_t *resolution_options;
  svn_client_conflict_option_t *option;

  SVN_ERR(svn_client_conflict_text_get_resolution_options(
            &resolution_options, conflict,
            scratch_pool, scratch_pool));
  option = svn_client_conflict_option_find_by_id(resolution_options,
                                                 option_id);
  if (option == NULL)
    return svn_error_createf(SVN_ERR_CLIENT_CONFLICT_OPTION_NOT_APPLICABLE,
                             NULL,
                             _("Inapplicable conflict resolution option "
                               "given for conflicted path '%s'"),
                             svn_dirent_local_style(conflict->local_abspath,
                                                    scratch_pool));
  SVN_ERR(svn_client_conflict_text_resolve(conflict, option, scratch_pool));

  return SVN_NO_ERROR;
}

svn_client_conflict_option_id_t
svn_client_conflict_text_get_resolution(svn_client_conflict_t *conflict)
{
  return conflict->resolution_text;
}

svn_error_t *
svn_client_conflict_prop_resolve(svn_client_conflict_t *conflict,
                                 const char *propname,
                                 svn_client_conflict_option_t *option,
                                 apr_pool_t *scratch_pool)
{
  SVN_ERR(assert_prop_conflict(conflict, scratch_pool));
  option->type_data.prop.propname = propname;
  SVN_ERR(option->do_resolve_func(option, conflict, scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_prop_resolve_by_id(
  svn_client_conflict_t *conflict,
  const char *propname,
  svn_client_conflict_option_id_t option_id,
  apr_pool_t *scratch_pool)
{
  apr_array_header_t *resolution_options;
  svn_client_conflict_option_t *option;

  SVN_ERR(svn_client_conflict_prop_get_resolution_options(
            &resolution_options, conflict,
            scratch_pool, scratch_pool));
  option = svn_client_conflict_option_find_by_id(resolution_options,
                                                 option_id);
  if (option == NULL)
    return svn_error_createf(SVN_ERR_CLIENT_CONFLICT_OPTION_NOT_APPLICABLE,
                             NULL,
                             _("Inapplicable conflict resolution option "
                               "given for conflicted path '%s'"),
                             svn_dirent_local_style(conflict->local_abspath,
                                                    scratch_pool));
  SVN_ERR(svn_client_conflict_prop_resolve(conflict, propname, option,
                                           scratch_pool));

  return SVN_NO_ERROR;
}

svn_client_conflict_option_id_t
svn_client_conflict_prop_get_resolution(svn_client_conflict_t *conflict,
                                        const char *propname)
{
  svn_client_conflict_option_t *option;

  option = svn_hash_gets(conflict->resolved_props, propname);
  if (option == NULL)
    return svn_client_conflict_option_unspecified;

  return svn_client_conflict_option_get_id(option);
}

svn_error_t *
svn_client_conflict_tree_resolve(svn_client_conflict_t *conflict,
                                 svn_client_conflict_option_t *option,
                                 apr_pool_t *scratch_pool)
{
  SVN_ERR(assert_tree_conflict(conflict, scratch_pool));
  SVN_ERR(option->do_resolve_func(option, conflict, scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_tree_resolve_by_id(
  svn_client_conflict_t *conflict,
  svn_client_conflict_option_id_t option_id,
  apr_pool_t *scratch_pool)
{
  apr_array_header_t *resolution_options;
  svn_client_conflict_option_t *option;

  /* Backwards compatibility hack: Upper layers may still try to resolve
   * these two tree conflicts as 'mine-conflict' as Subversion 1.9 did.
   * Fix up if necessary... */
  if (option_id == svn_client_conflict_option_working_text_where_conflicted)
    {
      svn_wc_operation_t operation;

      operation = svn_client_conflict_get_operation(conflict);
      if (operation == svn_wc_operation_update ||
          operation == svn_wc_operation_switch)
        {
          svn_wc_conflict_reason_t reason;

          reason = svn_client_conflict_get_local_change(conflict);
          if (reason == svn_wc_conflict_reason_moved_away)
            {
              /* Map 'mine-conflict' to 'update move destination'. */
              option_id = svn_client_conflict_option_update_move_destination;
            }
          else if (reason == svn_wc_conflict_reason_deleted ||
                   reason == svn_wc_conflict_reason_replaced)
            {
              svn_wc_conflict_action_t action;
              svn_node_kind_t node_kind;

              action = svn_client_conflict_get_incoming_change(conflict);
              node_kind =
                svn_client_conflict_tree_get_victim_node_kind(conflict);

              if (action == svn_wc_conflict_action_edit &&
                  node_kind == svn_node_dir)
                {
                  /* Map 'mine-conflict' to 'update any moved away children'. */
                  option_id =
                    svn_client_conflict_option_update_any_moved_away_children;
                }
            }
        }
    }
  else if (option_id == svn_client_conflict_option_merged_text)
    {
      /* Another backwards compatibility hack for 'choose merged'. */
      option_id = svn_client_conflict_option_accept_current_wc_state;
    }
  
  SVN_ERR(svn_client_conflict_tree_get_resolution_options(
            &resolution_options, conflict,
            scratch_pool, scratch_pool));
  option = svn_client_conflict_option_find_by_id(resolution_options,
                                                 option_id);
  if (option == NULL)
    return svn_error_createf(SVN_ERR_CLIENT_CONFLICT_OPTION_NOT_APPLICABLE,
                             NULL,
                             _("Inapplicable conflict resolution option "
                               "given for conflicted path '%s'"),
                             svn_dirent_local_style(conflict->local_abspath,
                                                    scratch_pool));
  SVN_ERR(svn_client_conflict_tree_resolve(conflict, option, scratch_pool));

  return SVN_NO_ERROR;
}

svn_client_conflict_option_id_t
svn_client_conflict_tree_get_resolution(svn_client_conflict_t *conflict)
{
  return conflict->resolution_tree;
}

/* Return the legacy conflict descriptor which is wrapped by CONFLICT. */
static const svn_wc_conflict_description2_t *
get_conflict_desc2_t(svn_client_conflict_t *conflict)
{
  if (conflict->legacy_text_conflict)
    return conflict->legacy_text_conflict;

  if (conflict->legacy_tree_conflict)
    return conflict->legacy_tree_conflict;

  if (conflict->prop_conflicts && conflict->legacy_prop_conflict_propname)
    return svn_hash_gets(conflict->prop_conflicts,
                         conflict->legacy_prop_conflict_propname);

  return NULL;
}

svn_error_t *
svn_client_conflict_get_conflicted(svn_boolean_t *text_conflicted,
                                   apr_array_header_t **props_conflicted,
                                   svn_boolean_t *tree_conflicted,
                                   svn_client_conflict_t *conflict,
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool)
{
  if (text_conflicted)
    *text_conflicted = (conflict->legacy_text_conflict != NULL);

  if (props_conflicted)
    {
      if (conflict->prop_conflicts)
        SVN_ERR(svn_hash_keys(props_conflicted, conflict->prop_conflicts,
                              result_pool));
      else
        *props_conflicted = apr_array_make(result_pool, 0,
                                           sizeof(const char*));
    }

  if (tree_conflicted)
    *tree_conflicted = (conflict->legacy_tree_conflict != NULL);

  return SVN_NO_ERROR;
}

const char *
svn_client_conflict_get_local_abspath(svn_client_conflict_t *conflict)
{
  return conflict->local_abspath;
}

svn_wc_operation_t
svn_client_conflict_get_operation(svn_client_conflict_t *conflict)
{
  return get_conflict_desc2_t(conflict)->operation;
}

svn_wc_conflict_action_t
svn_client_conflict_get_incoming_change(svn_client_conflict_t *conflict)
{
  return get_conflict_desc2_t(conflict)->action;
}

svn_wc_conflict_reason_t
svn_client_conflict_get_local_change(svn_client_conflict_t *conflict)
{
  return get_conflict_desc2_t(conflict)->reason;
}

svn_error_t *
svn_client_conflict_get_repos_info(const char **repos_root_url,
                                   const char **repos_uuid,
                                   svn_client_conflict_t *conflict,
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool)
{
  if (repos_root_url)
    {
      if (get_conflict_desc2_t(conflict)->src_left_version)
        *repos_root_url =
          get_conflict_desc2_t(conflict)->src_left_version->repos_url;
      else if (get_conflict_desc2_t(conflict)->src_right_version)
        *repos_root_url =
          get_conflict_desc2_t(conflict)->src_right_version->repos_url;
      else
        *repos_root_url = NULL;
    }

  if (repos_uuid)
    {
      if (get_conflict_desc2_t(conflict)->src_left_version)
        *repos_uuid =
          get_conflict_desc2_t(conflict)->src_left_version->repos_uuid;
      else if (get_conflict_desc2_t(conflict)->src_right_version)
        *repos_uuid =
          get_conflict_desc2_t(conflict)->src_right_version->repos_uuid;
      else
        *repos_uuid = NULL;
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_get_incoming_old_repos_location(
  const char **incoming_old_repos_relpath,
  svn_revnum_t *incoming_old_pegrev,
  svn_node_kind_t *incoming_old_node_kind,
  svn_client_conflict_t *conflict,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  if (incoming_old_repos_relpath)
    {
      if (get_conflict_desc2_t(conflict)->src_left_version)
        *incoming_old_repos_relpath =
          get_conflict_desc2_t(conflict)->src_left_version->path_in_repos;
      else
        *incoming_old_repos_relpath = NULL;
    }

  if (incoming_old_pegrev)
    {
      if (get_conflict_desc2_t(conflict)->src_left_version)
        *incoming_old_pegrev =
          get_conflict_desc2_t(conflict)->src_left_version->peg_rev;
      else
        *incoming_old_pegrev = SVN_INVALID_REVNUM;
    }

  if (incoming_old_node_kind)
    {
      if (get_conflict_desc2_t(conflict)->src_left_version)
        *incoming_old_node_kind =
          get_conflict_desc2_t(conflict)->src_left_version->node_kind;
      else
        *incoming_old_node_kind = svn_node_none;
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_get_incoming_new_repos_location(
  const char **incoming_new_repos_relpath,
  svn_revnum_t *incoming_new_pegrev,
  svn_node_kind_t *incoming_new_node_kind,
  svn_client_conflict_t *conflict,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  if (incoming_new_repos_relpath)
    {
      if (get_conflict_desc2_t(conflict)->src_right_version)
        *incoming_new_repos_relpath =
          get_conflict_desc2_t(conflict)->src_right_version->path_in_repos;
      else
        *incoming_new_repos_relpath = NULL;
    }

  if (incoming_new_pegrev)
    {
      if (get_conflict_desc2_t(conflict)->src_right_version)
        *incoming_new_pegrev =
          get_conflict_desc2_t(conflict)->src_right_version->peg_rev;
      else
        *incoming_new_pegrev = SVN_INVALID_REVNUM;
    }

  if (incoming_new_node_kind)
    {
      if (get_conflict_desc2_t(conflict)->src_right_version)
        *incoming_new_node_kind =
          get_conflict_desc2_t(conflict)->src_right_version->node_kind;
      else
        *incoming_new_node_kind = svn_node_none;
    }

  return SVN_NO_ERROR;
}

svn_node_kind_t
svn_client_conflict_tree_get_victim_node_kind(svn_client_conflict_t *conflict)
{
  SVN_ERR_ASSERT_NO_RETURN(assert_tree_conflict(conflict, conflict->pool)
                           == SVN_NO_ERROR);

  return get_conflict_desc2_t(conflict)->node_kind;
}

svn_error_t *
svn_client_conflict_prop_get_propvals(const svn_string_t **base_propval,
                                      const svn_string_t **working_propval,
                                      const svn_string_t **incoming_old_propval,
                                      const svn_string_t **incoming_new_propval,
                                      svn_client_conflict_t *conflict,
                                      const char *propname,
                                      apr_pool_t *result_pool)
{
  const svn_wc_conflict_description2_t *desc;

  SVN_ERR(assert_prop_conflict(conflict, conflict->pool));

  desc = svn_hash_gets(conflict->prop_conflicts, propname);
  if (desc == NULL)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Property '%s' is not in conflict."), propname);

  if (base_propval)
    *base_propval =
      svn_string_dup(desc->prop_value_base, result_pool);

  if (working_propval)
    *working_propval =
      svn_string_dup(desc->prop_value_working, result_pool);

  if (incoming_old_propval)
    *incoming_old_propval =
      svn_string_dup(desc->prop_value_incoming_old, result_pool);

  if (incoming_new_propval)
    *incoming_new_propval =
      svn_string_dup(desc->prop_value_incoming_new, result_pool);

  return SVN_NO_ERROR;
}

const char *
svn_client_conflict_prop_get_reject_abspath(svn_client_conflict_t *conflict)
{
  SVN_ERR_ASSERT_NO_RETURN(assert_prop_conflict(conflict, conflict->pool)
                           == SVN_NO_ERROR);

  /* svn_wc_conflict_description2_t stores this path in 'their_abspath' */
  return get_conflict_desc2_t(conflict)->their_abspath;
}

const char *
svn_client_conflict_text_get_mime_type(svn_client_conflict_t *conflict)
{
  SVN_ERR_ASSERT_NO_RETURN(assert_text_conflict(conflict, conflict->pool)
                           == SVN_NO_ERROR);

  return get_conflict_desc2_t(conflict)->mime_type;
}

svn_error_t *
svn_client_conflict_text_get_contents(const char **base_abspath,
                                      const char **working_abspath,
                                      const char **incoming_old_abspath,
                                      const char **incoming_new_abspath,
                                      svn_client_conflict_t *conflict,
                                      apr_pool_t *result_pool,
                                      apr_pool_t *scratch_pool)
{
  SVN_ERR(assert_text_conflict(conflict, scratch_pool));

  if (base_abspath)
    {
      if (svn_client_conflict_get_operation(conflict) ==
          svn_wc_operation_merge)
        *base_abspath = NULL; /* ### WC base contents not available yet */
      else /* update/switch */
        *base_abspath = get_conflict_desc2_t(conflict)->base_abspath;
    }

  if (working_abspath)
    *working_abspath = get_conflict_desc2_t(conflict)->my_abspath;

  if (incoming_old_abspath)
    *incoming_old_abspath = get_conflict_desc2_t(conflict)->base_abspath;

  if (incoming_new_abspath)
    *incoming_new_abspath = get_conflict_desc2_t(conflict)->their_abspath;

  return SVN_NO_ERROR;
}

/* Set up type-specific data for a new conflict object. */
static svn_error_t *
conflict_type_specific_setup(svn_client_conflict_t *conflict,
                             apr_pool_t *scratch_pool)
{
  svn_boolean_t tree_conflicted;
  svn_wc_conflict_action_t incoming_change;
  svn_wc_conflict_reason_t local_change;

  /* For now, we only deal with tree conflicts here. */
  SVN_ERR(svn_client_conflict_get_conflicted(NULL, NULL, &tree_conflicted,
                                             conflict, scratch_pool,
                                             scratch_pool));
  if (!tree_conflicted)
    return SVN_NO_ERROR;

  /* Set a default description function. */
  conflict->tree_conflict_get_incoming_description_func =
    conflict_tree_get_incoming_description_generic;
  conflict->tree_conflict_get_local_description_func =
    conflict_tree_get_local_description_generic;

  incoming_change = svn_client_conflict_get_incoming_change(conflict);
  local_change = svn_client_conflict_get_local_change(conflict);

  /* Set type-specific description and details functions. */
  if (incoming_change == svn_wc_conflict_action_delete ||
      incoming_change == svn_wc_conflict_action_replace)
    {
      conflict->tree_conflict_get_incoming_description_func =
        conflict_tree_get_description_incoming_delete;
      conflict->tree_conflict_get_incoming_details_func =
        conflict_tree_get_details_incoming_delete;
    }
  else if (incoming_change == svn_wc_conflict_action_add)
    {
      conflict->tree_conflict_get_incoming_description_func =
        conflict_tree_get_description_incoming_add;
      conflict->tree_conflict_get_incoming_details_func =
        conflict_tree_get_details_incoming_add;
    }
  else if (incoming_change == svn_wc_conflict_action_edit)
    {
      conflict->tree_conflict_get_incoming_description_func =
        conflict_tree_get_description_incoming_edit;
      conflict->tree_conflict_get_incoming_details_func =
        conflict_tree_get_details_incoming_edit;
    }

  if (local_change == svn_wc_conflict_reason_missing)
    {
      conflict->tree_conflict_get_local_description_func =
        conflict_tree_get_description_local_missing;
      conflict->tree_conflict_get_local_details_func =
        conflict_tree_get_details_local_missing;
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_conflict_get(svn_client_conflict_t **conflict,
                        const char *local_abspath,
                        svn_client_ctx_t *ctx,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  const apr_array_header_t *descs;
  int i;

  *conflict = apr_pcalloc(result_pool, sizeof(**conflict));

  (*conflict)->local_abspath = apr_pstrdup(result_pool, local_abspath);
  (*conflict)->resolution_text = svn_client_conflict_option_unspecified;
  (*conflict)->resolution_tree = svn_client_conflict_option_unspecified;
  (*conflict)->resolved_props = apr_hash_make(result_pool);
  (*conflict)->ctx = ctx;
  (*conflict)->pool = result_pool;

  /* Add all legacy conflict descriptors we can find. Eventually, this code
   * path should stop relying on svn_wc_conflict_description2_t entirely. */
  SVN_ERR(svn_wc__read_conflict_descriptions2_t(&descs, ctx->wc_ctx,
                                                local_abspath,
                                                result_pool, scratch_pool));
  for (i = 0; i < descs->nelts; i++)
    {
      const svn_wc_conflict_description2_t *desc;

      desc = APR_ARRAY_IDX(descs, i, const svn_wc_conflict_description2_t *);
      add_legacy_desc_to_conflict(desc, *conflict, result_pool);
    }

  SVN_ERR(conflict_type_specific_setup(*conflict, scratch_pool));

  return SVN_NO_ERROR;
}
