/*
 * conflicts.c: routines for managing conflict data.
 *            NOTE: this code doesn't know where the conflict is
 *            actually stored.
 *
 * ====================================================================
 *    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.
 * ====================================================================
 */



#include <string.h>

#include <apr_pools.h>
#include <apr_tables.h>
#include <apr_hash.h>
#include <apr_errno.h>

#include "svn_hash.h"
#include "svn_types.h"
#include "svn_pools.h"
#include "svn_string.h"
#include "svn_error.h"
#include "svn_dirent_uri.h"
#include "svn_wc.h"
#include "svn_io.h"
#include "svn_diff.h"

#include "wc.h"
#include "wc_db.h"
#include "conflicts.h"
#include "workqueue.h"
#include "props.h"

#include "private/svn_wc_private.h"
#include "private/svn_skel.h"
#include "private/svn_sorts_private.h"
#include "private/svn_string_private.h"

#include "svn_private_config.h"

/* --------------------------------------------------------------------
 * Conflict skel management
 */

svn_skel_t *
svn_wc__conflict_skel_create(apr_pool_t *result_pool)
{
  svn_skel_t *conflict_skel = svn_skel__make_empty_list(result_pool);

  /* Add empty CONFLICTS list */
  svn_skel__prepend(svn_skel__make_empty_list(result_pool), conflict_skel);

  /* Add empty WHY list */
  svn_skel__prepend(svn_skel__make_empty_list(result_pool), conflict_skel);

  return conflict_skel;
}

svn_error_t *
svn_wc__conflict_skel_is_complete(svn_boolean_t *complete,
                                  const svn_skel_t *conflict_skel)
{
  *complete = FALSE;

  if (svn_skel__list_length(conflict_skel) < 2)
    return svn_error_create(SVN_ERR_INCOMPLETE_DATA, NULL,
                            _("Not a conflict skel"));

  if (svn_skel__list_length(conflict_skel->children) < 2)
    return SVN_NO_ERROR; /* WHY is not set */

  if (svn_skel__list_length(conflict_skel->children->next) == 0)
    return SVN_NO_ERROR; /* No conflict set */

  *complete = TRUE;
  return SVN_NO_ERROR;
}

/* Serialize a svn_wc_conflict_version_t before the existing data in skel */
static svn_error_t *
conflict__prepend_location(svn_skel_t *skel,
                           const svn_wc_conflict_version_t *location,
                           svn_boolean_t allow_NULL,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
{
  svn_skel_t *loc;
  SVN_ERR_ASSERT(location || allow_NULL);

  if (!location)
    {
      svn_skel__prepend(svn_skel__make_empty_list(result_pool), skel);
      return SVN_NO_ERROR;
    }

  /* ("subversion" repos_root_url repos_uuid repos_relpath rev kind) */
  loc = svn_skel__make_empty_list(result_pool);

  svn_skel__prepend_str(svn_node_kind_to_word(location->node_kind),
                        loc, result_pool);

  svn_skel__prepend_int(location->peg_rev, loc, result_pool);

  svn_skel__prepend_str(apr_pstrdup(result_pool, location->path_in_repos), loc,
                        result_pool);

  if (!location->repos_uuid) /* Can theoretically be NULL */
    svn_skel__prepend(svn_skel__make_empty_list(result_pool), loc);
  else
    svn_skel__prepend_str(location->repos_uuid, loc, result_pool);

  svn_skel__prepend_str(apr_pstrdup(result_pool, location->repos_url), loc,
                        result_pool);

  svn_skel__prepend_str(SVN_WC__CONFLICT_SRC_SUBVERSION, loc, result_pool);

  svn_skel__prepend(loc, skel);
  return SVN_NO_ERROR;
}

/* Deserialize a svn_wc_conflict_version_t from the skel.
   Set *LOCATION to NULL when the data is not a svn_wc_conflict_version_t. */
static svn_error_t *
conflict__read_location(svn_wc_conflict_version_t **location,
                        const svn_skel_t *skel,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  const char *repos_root_url;
  const char *repos_uuid;
  const char *repos_relpath;
  svn_revnum_t revision;
  apr_int64_t v;
  svn_node_kind_t node_kind;  /* note that 'none' is a legitimate value */
  const char *kind_str;

  const svn_skel_t *c = skel->children;

  if (!svn_skel__matches_atom(c, SVN_WC__CONFLICT_SRC_SUBVERSION))
    {
      *location = NULL;
      return SVN_NO_ERROR;
    }
  c = c->next;

  repos_root_url = apr_pstrmemdup(result_pool, c->data, c->len);
  c = c->next;

  if (c->is_atom)
    repos_uuid = apr_pstrmemdup(result_pool, c->data, c->len);
  else
    repos_uuid = NULL;
  c = c->next;

  repos_relpath = apr_pstrmemdup(result_pool, c->data, c->len);
  c = c->next;

  SVN_ERR(svn_skel__parse_int(&v, c, scratch_pool));
  revision = (svn_revnum_t)v;
  c = c->next;

  kind_str = apr_pstrmemdup(scratch_pool, c->data, c->len);
  node_kind = svn_node_kind_from_word(kind_str);

  *location = svn_wc_conflict_version_create2(repos_root_url,
                                              repos_uuid,
                                              repos_relpath,
                                              revision,
                                              node_kind,
                                              result_pool);
  return SVN_NO_ERROR;
}

/* Get the operation part of CONFLICT_SKELL or NULL if no operation is set
   at this time */
static svn_error_t *
conflict__get_operation(svn_skel_t **why,
                        const svn_skel_t *conflict_skel)
{
  SVN_ERR_ASSERT(conflict_skel
                 && conflict_skel->children
                 && conflict_skel->children->next
                 && !conflict_skel->children->next->is_atom);

  *why = conflict_skel->children;

  if (!(*why)->children)
    *why = NULL; /* Operation is not set yet */

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc__conflict_skel_set_op_update(svn_skel_t *conflict_skel,
                                    const svn_wc_conflict_version_t *original,
                                    const svn_wc_conflict_version_t *target,
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool)
{
  svn_skel_t *why;
  svn_skel_t *origins;

  SVN_ERR_ASSERT(conflict_skel
                 && conflict_skel->children
                 && conflict_skel->children->next
                 && !conflict_skel->children->next->is_atom);

  SVN_ERR(conflict__get_operation(&why, conflict_skel));

  SVN_ERR_ASSERT(why == NULL); /* No operation set */

  why = conflict_skel->children;

  origins = svn_skel__make_empty_list(result_pool);

  SVN_ERR(conflict__prepend_location(origins, target, TRUE,
                                     result_pool, scratch_pool));
  SVN_ERR(conflict__prepend_location(origins, original, TRUE,
                                     result_pool, scratch_pool));

  svn_skel__prepend(origins, why);
  svn_skel__prepend_str(SVN_WC__CONFLICT_OP_UPDATE, why, result_pool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_skel_set_op_switch(svn_skel_t *conflict_skel,
                                    const svn_wc_conflict_version_t *original,
                                    const svn_wc_conflict_version_t *target,
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool)
{
  svn_skel_t *why;
  svn_skel_t *origins;

  SVN_ERR_ASSERT(conflict_skel
                 && conflict_skel->children
                 && conflict_skel->children->next
                 && !conflict_skel->children->next->is_atom);

  SVN_ERR(conflict__get_operation(&why, conflict_skel));

  SVN_ERR_ASSERT(why == NULL); /* No operation set */

  why = conflict_skel->children;

  origins = svn_skel__make_empty_list(result_pool);

  SVN_ERR(conflict__prepend_location(origins, target, TRUE,
                                     result_pool, scratch_pool));
  SVN_ERR(conflict__prepend_location(origins, original, TRUE,
                                     result_pool, scratch_pool));

  svn_skel__prepend(origins, why);
  svn_skel__prepend_str(SVN_WC__CONFLICT_OP_SWITCH, why, result_pool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_skel_set_op_merge(svn_skel_t *conflict_skel,
                                   const svn_wc_conflict_version_t *left,
                                   const svn_wc_conflict_version_t *right,
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool)
{
  svn_skel_t *why;
  svn_skel_t *origins;

  SVN_ERR_ASSERT(conflict_skel
                 && conflict_skel->children
                 && conflict_skel->children->next
                 && !conflict_skel->children->next->is_atom);

  SVN_ERR(conflict__get_operation(&why, conflict_skel));

  SVN_ERR_ASSERT(why == NULL); /* No operation set */

  why = conflict_skel->children;

  origins = svn_skel__make_empty_list(result_pool);

  SVN_ERR(conflict__prepend_location(origins, right, TRUE,
                                     result_pool, scratch_pool));

  SVN_ERR(conflict__prepend_location(origins, left, TRUE,
                                     result_pool, scratch_pool));

  svn_skel__prepend(origins, why);
  svn_skel__prepend_str(SVN_WC__CONFLICT_OP_MERGE, why, result_pool);

  return SVN_NO_ERROR;
}

/* Gets the conflict data of the specified type CONFLICT_TYPE from
   CONFLICT_SKEL, or NULL if no such conflict is recorded */
static svn_error_t *
conflict__get_conflict(svn_skel_t **conflict,
                       const svn_skel_t *conflict_skel,
                       const char *conflict_type)
{
  svn_skel_t *c;

  SVN_ERR_ASSERT(conflict_skel
                 && conflict_skel->children
                 && conflict_skel->children->next
                 && !conflict_skel->children->next->is_atom);

  for(c = conflict_skel->children->next->children;
      c;
      c = c->next)
    {
      if (svn_skel__matches_atom(c->children, conflict_type))
        {
          *conflict = c;
          return SVN_NO_ERROR;
        }
    }

  *conflict = NULL;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_skel_add_text_conflict(svn_skel_t *conflict_skel,
                                        svn_wc__db_t *db,
                                        const char *wri_abspath,
                                        const char *mine_abspath,
                                        const char *their_old_abspath,
                                        const char *their_abspath,
                                        apr_pool_t *result_pool,
                                        apr_pool_t *scratch_pool)
{
  svn_skel_t *text_conflict;
  svn_skel_t *markers;

  SVN_ERR(conflict__get_conflict(&text_conflict, conflict_skel,
                                 SVN_WC__CONFLICT_KIND_TEXT));

  SVN_ERR_ASSERT(!text_conflict); /* ### Use proper error? */

  /* Current skel format
     ("text"
      (OLD MINE OLD-THEIRS THEIRS)) */

  text_conflict = svn_skel__make_empty_list(result_pool);
  markers = svn_skel__make_empty_list(result_pool);

if (their_abspath)
    {
      const char *their_relpath;

      SVN_ERR(svn_wc__db_to_relpath(&their_relpath,
                                    db, wri_abspath, their_abspath,
                                    result_pool, scratch_pool));
      svn_skel__prepend_str(their_relpath, markers, result_pool);
    }
  else
    svn_skel__prepend(svn_skel__make_empty_list(result_pool), markers);

  if (mine_abspath)
    {
      const char *mine_relpath;

      SVN_ERR(svn_wc__db_to_relpath(&mine_relpath,
                                    db, wri_abspath, mine_abspath,
                                    result_pool, scratch_pool));
      svn_skel__prepend_str(mine_relpath, markers, result_pool);
    }
  else
    svn_skel__prepend(svn_skel__make_empty_list(result_pool), markers);

  if (their_old_abspath)
    {
      const char *original_relpath;

      SVN_ERR(svn_wc__db_to_relpath(&original_relpath,
                                    db, wri_abspath, their_old_abspath,
                                    result_pool, scratch_pool));
      svn_skel__prepend_str(original_relpath, markers, result_pool);
    }
  else
    svn_skel__prepend(svn_skel__make_empty_list(result_pool), markers);

  svn_skel__prepend(markers, text_conflict);
  svn_skel__prepend_str(SVN_WC__CONFLICT_KIND_TEXT, text_conflict,
                        result_pool);

  /* And add it to the conflict skel */
  svn_skel__prepend(text_conflict, conflict_skel->children->next);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_skel_add_prop_conflict(svn_skel_t *conflict_skel,
                                        svn_wc__db_t *db,
                                        const char *wri_abspath,
                                        const char *marker_abspath,
                                        const apr_hash_t *mine_props,
                                        const apr_hash_t *their_old_props,
                                        const apr_hash_t *their_props,
                                        const apr_hash_t *conflicted_prop_names,
                                        apr_pool_t *result_pool,
                                        apr_pool_t *scratch_pool)
{
  svn_skel_t *prop_conflict;
  svn_skel_t *props;
  svn_skel_t *conflict_names;
  svn_skel_t *markers;
  apr_hash_index_t *hi;

  SVN_ERR(conflict__get_conflict(&prop_conflict, conflict_skel,
                                 SVN_WC__CONFLICT_KIND_PROP));

  SVN_ERR_ASSERT(!prop_conflict); /* ### Use proper error? */

  /* This function currently implements:
     ("prop"
      ("marker_relpath")
      prop-conflicted_prop_names
      old-props
      mine-props
      their-props)
     NULL lists are recorded as "" */
  /* ### Seems that this may not match what we read out.  Read-out of
   * 'theirs-old' comes as NULL. */

  prop_conflict = svn_skel__make_empty_list(result_pool);

  if (their_props)
    {
      SVN_ERR(svn_skel__unparse_proplist(&props, their_props, result_pool));
      svn_skel__prepend(props, prop_conflict);
    }
  else
    svn_skel__prepend_str("", prop_conflict, result_pool); /* No their_props */

  if (mine_props)
    {
      SVN_ERR(svn_skel__unparse_proplist(&props, mine_props, result_pool));
      svn_skel__prepend(props, prop_conflict);
    }
  else
    svn_skel__prepend_str("", prop_conflict, result_pool); /* No mine_props */

  if (their_old_props)
    {
      SVN_ERR(svn_skel__unparse_proplist(&props, their_old_props,
                                         result_pool));
      svn_skel__prepend(props, prop_conflict);
    }
  else
    svn_skel__prepend_str("", prop_conflict, result_pool); /* No old_props */

  conflict_names = svn_skel__make_empty_list(result_pool);
  for (hi = apr_hash_first(scratch_pool, (apr_hash_t *)conflicted_prop_names);
       hi;
       hi = apr_hash_next(hi))
    {
      svn_skel__prepend_str(apr_pstrdup(result_pool, apr_hash_this_key(hi)),
                            conflict_names,
                            result_pool);
    }
  svn_skel__prepend(conflict_names, prop_conflict);

  markers = svn_skel__make_empty_list(result_pool);

  if (marker_abspath)
    {
      const char *marker_relpath;
      SVN_ERR(svn_wc__db_to_relpath(&marker_relpath, db, wri_abspath,
                                    marker_abspath,
                                    result_pool, scratch_pool));

      svn_skel__prepend_str(marker_relpath, markers, result_pool);
    }
/*else // ### set via svn_wc__conflict_create_markers
    svn_skel__prepend(svn_skel__make_empty_list(result_pool), markers);*/

  svn_skel__prepend(markers, prop_conflict);

  svn_skel__prepend_str(SVN_WC__CONFLICT_KIND_PROP, prop_conflict, result_pool);

  /* And add it to the conflict skel */
  svn_skel__prepend(prop_conflict, conflict_skel->children->next);

  return SVN_NO_ERROR;
}

/* A map for svn_wc_conflict_reason_t values. */
static const svn_token_map_t reason_map[] =
{
  { "edited",           svn_wc_conflict_reason_edited },
  { "obstructed",       svn_wc_conflict_reason_obstructed },
  { "deleted",          svn_wc_conflict_reason_deleted },
  { "missing",          svn_wc_conflict_reason_missing },
  { "unversioned",      svn_wc_conflict_reason_unversioned },
  { "added",            svn_wc_conflict_reason_added },
  { "replaced",         svn_wc_conflict_reason_replaced },
  { "moved-away",       svn_wc_conflict_reason_moved_away },
  { "moved-here",       svn_wc_conflict_reason_moved_here },
  { NULL }
};

static const svn_token_map_t action_map[] =
{
  { "edited",           svn_wc_conflict_action_edit },
  { "added",            svn_wc_conflict_action_add },
  { "deleted",          svn_wc_conflict_action_delete },
  { "replaced",         svn_wc_conflict_action_replace },
  { NULL }
};

svn_error_t *
svn_wc__conflict_skel_add_tree_conflict(svn_skel_t *conflict_skel,
                                        svn_wc__db_t *db,
                                        const char *wri_abspath,
                                        svn_wc_conflict_reason_t reason,
                                        svn_wc_conflict_action_t action,
                                        const char *move_src_op_root_abspath,
                                        apr_pool_t *result_pool,
                                        apr_pool_t *scratch_pool)
{
  svn_skel_t *tree_conflict;
  svn_skel_t *markers;

  SVN_ERR(conflict__get_conflict(&tree_conflict, conflict_skel,
                                 SVN_WC__CONFLICT_KIND_TREE));

  SVN_ERR_ASSERT(!tree_conflict); /* ### Use proper error? */

  SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_moved_away
                 || !move_src_op_root_abspath); /* ### Use proper error? */

  tree_conflict = svn_skel__make_empty_list(result_pool);

  if (reason == svn_wc_conflict_reason_moved_away
      && move_src_op_root_abspath)
    {
      const char *move_src_op_root_relpath;

      SVN_ERR(svn_wc__db_to_relpath(&move_src_op_root_relpath,
                                    db, wri_abspath,
                                    move_src_op_root_abspath,
                                    result_pool, scratch_pool));

      svn_skel__prepend_str(move_src_op_root_relpath, tree_conflict,
                            result_pool);
    }

  svn_skel__prepend_str(svn_token__to_word(action_map, action),
                        tree_conflict, result_pool);

  svn_skel__prepend_str(svn_token__to_word(reason_map, reason),
                        tree_conflict, result_pool);

  /* Tree conflicts have no marker files */
  markers = svn_skel__make_empty_list(result_pool);
  svn_skel__prepend(markers, tree_conflict);

  svn_skel__prepend_str(SVN_WC__CONFLICT_KIND_TREE, tree_conflict,
                        result_pool);

  /* And add it to the conflict skel */
  svn_skel__prepend(tree_conflict, conflict_skel->children->next);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_skel_resolve(svn_boolean_t *completely_resolved,
                              svn_skel_t *conflict_skel,
                              svn_wc__db_t *db,
                              const char *wri_abspath,
                              svn_boolean_t resolve_text,
                              const char *resolve_prop,
                              svn_boolean_t resolve_tree,
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool)
{
  svn_skel_t *op;
  svn_skel_t **pconflict;
  SVN_ERR(conflict__get_operation(&op, conflict_skel));

  if (!op)
    return svn_error_create(SVN_ERR_INCOMPLETE_DATA, NULL,
                            _("Not a completed conflict skel"));

  /* We are going to drop items from a linked list. Instead of keeping
     a pointer to the item we want to drop we store a pointer to the
     pointer of what we may drop, to allow setting it to the next item. */

  pconflict = &(conflict_skel->children->next->children);
  while (*pconflict)
    {
      svn_skel_t *c = (*pconflict)->children;

      if (resolve_text
          && svn_skel__matches_atom(c, SVN_WC__CONFLICT_KIND_TEXT))
        {
          /* Remove the text conflict from the linked list */
          *pconflict = (*pconflict)->next;
          continue;
        }
      else if (resolve_prop
               && svn_skel__matches_atom(c, SVN_WC__CONFLICT_KIND_PROP))
        {
          svn_skel_t **ppropnames = &(c->next->next->children);

          if (resolve_prop[0] == '\0')
            *ppropnames = NULL; /* remove all conflicted property names */
          else
            while (*ppropnames)
              {
                if (svn_skel__matches_atom(*ppropnames, resolve_prop))
                  {
                    *ppropnames = (*ppropnames)->next;
                    break;
                  }
                ppropnames = &((*ppropnames)->next);
              }

          /* If no conflicted property names left */
          if (!c->next->next->children)
            {
              /* Remove the propery conflict skel from the linked list */
             *pconflict = (*pconflict)->next;
             continue;
            }
        }
      else if (resolve_tree
               && svn_skel__matches_atom(c, SVN_WC__CONFLICT_KIND_TREE))
        {
          /* Remove the tree conflict from the linked list */
          *pconflict = (*pconflict)->next;
          continue;
        }

      pconflict = &((*pconflict)->next);
    }

  if (completely_resolved)
    {
      /* Nice, we can just call the complete function */
      svn_boolean_t complete_conflict;
      SVN_ERR(svn_wc__conflict_skel_is_complete(&complete_conflict,
                                                conflict_skel));

      *completely_resolved = !complete_conflict;
    }
  return SVN_NO_ERROR;
}


/* A map for svn_wc_operation_t values. */
static const svn_token_map_t operation_map[] =
{
  { "",   svn_wc_operation_none },
  { SVN_WC__CONFLICT_OP_UPDATE, svn_wc_operation_update },
  { SVN_WC__CONFLICT_OP_SWITCH, svn_wc_operation_switch },
  { SVN_WC__CONFLICT_OP_MERGE,  svn_wc_operation_merge },
  { NULL }
};

svn_error_t *
svn_wc__conflict_read_info(svn_wc_operation_t *operation,
                           const apr_array_header_t **locations,
                           svn_boolean_t *text_conflicted,
                           svn_boolean_t *prop_conflicted,
                           svn_boolean_t *tree_conflicted,
                           svn_wc__db_t *db,
                           const char *wri_abspath,
                           const svn_skel_t *conflict_skel,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
{
  svn_skel_t *op;
  const svn_skel_t *c;

  SVN_ERR(conflict__get_operation(&op, conflict_skel));

  if (!op)
    return svn_error_create(SVN_ERR_INCOMPLETE_DATA, NULL,
                            _("Not a completed conflict skel"));

  c = op->children;
  if (operation)
    {
      int value = svn_token__from_mem(operation_map, c->data, c->len);

      if (value != SVN_TOKEN_UNKNOWN)
        *operation = value;
      else
        *operation = svn_wc_operation_none;
    }
  c = c->next;

  if (locations && c->children)
    {
      const svn_skel_t *loc_skel;
      svn_wc_conflict_version_t *loc;
      apr_array_header_t *locs = apr_array_make(result_pool, 2, sizeof(loc));

      for (loc_skel = c->children; loc_skel; loc_skel = loc_skel->next)
        {
          SVN_ERR(conflict__read_location(&loc, loc_skel, result_pool,
                                          scratch_pool));

          APR_ARRAY_PUSH(locs, svn_wc_conflict_version_t *) = loc;
        }

      *locations = locs;
    }
  else if (locations)
    *locations = NULL;

  if (text_conflicted)
    {
      svn_skel_t *c_skel;
      SVN_ERR(conflict__get_conflict(&c_skel, conflict_skel,
                                     SVN_WC__CONFLICT_KIND_TEXT));

      *text_conflicted = (c_skel != NULL);
    }

  if (prop_conflicted)
    {
      svn_skel_t *c_skel;
      SVN_ERR(conflict__get_conflict(&c_skel, conflict_skel,
                                     SVN_WC__CONFLICT_KIND_PROP));

      *prop_conflicted = (c_skel != NULL);
    }

  if (tree_conflicted)
    {
      svn_skel_t *c_skel;
      SVN_ERR(conflict__get_conflict(&c_skel, conflict_skel,
                                     SVN_WC__CONFLICT_KIND_TREE));

      *tree_conflicted = (c_skel != NULL);
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc__conflict_read_text_conflict(const char **mine_abspath,
                                    const char **their_old_abspath,
                                    const char **their_abspath,
                                    svn_wc__db_t *db,
                                    const char *wri_abspath,
                                    const svn_skel_t *conflict_skel,
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool)
{
  svn_skel_t *text_conflict;
  const svn_skel_t *m;

  SVN_ERR(conflict__get_conflict(&text_conflict, conflict_skel,
                                 SVN_WC__CONFLICT_KIND_TEXT));

  if (!text_conflict)
    return svn_error_create(SVN_ERR_WC_MISSING, NULL, _("Conflict not set"));

  m = text_conflict->children->next->children;

  if (their_old_abspath)
    {
      if (m->is_atom)
        {
          const char *original_relpath;

          original_relpath = apr_pstrmemdup(scratch_pool, m->data, m->len);
          SVN_ERR(svn_wc__db_from_relpath(their_old_abspath,
                                          db, wri_abspath, original_relpath,
                                          result_pool, scratch_pool));
        }
      else
        *their_old_abspath = NULL;
    }
  m = m->next;

  if (mine_abspath)
    {
      if (m->is_atom)
        {
          const char *mine_relpath;

          mine_relpath = apr_pstrmemdup(scratch_pool, m->data, m->len);
          SVN_ERR(svn_wc__db_from_relpath(mine_abspath,
                                          db, wri_abspath, mine_relpath,
                                          result_pool, scratch_pool));
        }
      else
        *mine_abspath = NULL;
    }
  m = m->next;

  if (their_abspath)
    {
      if (m->is_atom)
        {
          const char *their_relpath;

          their_relpath = apr_pstrmemdup(scratch_pool, m->data, m->len);
          SVN_ERR(svn_wc__db_from_relpath(their_abspath,
                                          db, wri_abspath, their_relpath,
                                          result_pool, scratch_pool));
        }
      else
        *their_abspath = NULL;
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_read_prop_conflict(const char **marker_abspath,
                                    apr_hash_t **mine_props,
                                    apr_hash_t **their_old_props,
                                    apr_hash_t **their_props,
                                    apr_hash_t **conflicted_prop_names,
                                    svn_wc__db_t *db,
                                    const char *wri_abspath,
                                    const svn_skel_t *conflict_skel,
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool)
{
  svn_skel_t *prop_conflict;
  const svn_skel_t *c;

  SVN_ERR(conflict__get_conflict(&prop_conflict, conflict_skel,
                                 SVN_WC__CONFLICT_KIND_PROP));

  if (!prop_conflict)
    return svn_error_create(SVN_ERR_WC_MISSING, NULL, _("Conflict not set"));

  c = prop_conflict->children;

  c = c->next; /* Skip "prop" */

  /* Get marker file */
  if (marker_abspath)
    {
      const char *marker_relpath;

      if (c->children && c->children->is_atom)
        {
          marker_relpath = apr_pstrmemdup(result_pool, c->children->data,
                                        c->children->len);

          SVN_ERR(svn_wc__db_from_relpath(marker_abspath, db, wri_abspath,
                                          marker_relpath,
                                          result_pool, scratch_pool));
        }
      else
        *marker_abspath = NULL;
    }
  c = c->next;

  /* Get conflicted properties */
  if (conflicted_prop_names)
    {
      const svn_skel_t *name;
      *conflicted_prop_names = apr_hash_make(result_pool);

      for (name = c->children; name; name = name->next)
        {
          svn_hash_sets(*conflicted_prop_names,
                        apr_pstrmemdup(result_pool, name->data, name->len),
                        "");
        }
    }
  c = c->next;

  /* Get original properties */
  if (their_old_props)
    {
      if (c->is_atom)
        *their_old_props = apr_hash_make(result_pool);
      else
        SVN_ERR(svn_skel__parse_proplist(their_old_props, c, result_pool));
    }
  c = c->next;

  /* Get mine properties */
  if (mine_props)
    {
      if (c->is_atom)
        *mine_props = apr_hash_make(result_pool);
      else
        SVN_ERR(svn_skel__parse_proplist(mine_props, c, result_pool));
    }
  c = c->next;

  /* Get their properties */
  if (their_props)
    {
      if (c->is_atom)
        *their_props = apr_hash_make(result_pool);
      else
        SVN_ERR(svn_skel__parse_proplist(their_props, c, result_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_read_tree_conflict(svn_wc_conflict_reason_t *reason,
                                    svn_wc_conflict_action_t *action,
                                    const char **move_src_op_root_abspath,
                                    svn_wc__db_t *db,
                                    const char *wri_abspath,
                                    const svn_skel_t *conflict_skel,
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool)
{
  svn_skel_t *tree_conflict;
  const svn_skel_t *c;
  svn_boolean_t is_moved_away = FALSE;

  SVN_ERR(conflict__get_conflict(&tree_conflict, conflict_skel,
                                 SVN_WC__CONFLICT_KIND_TREE));

  if (!tree_conflict)
    return svn_error_create(SVN_ERR_WC_MISSING, NULL, _("Conflict not set"));

  c = tree_conflict->children;

  c = c->next; /* Skip "tree" */

  c = c->next; /* Skip markers */

  {
    int value = svn_token__from_mem(reason_map, c->data, c->len);

    if (reason)
      {
        if (value != SVN_TOKEN_UNKNOWN)
          *reason = value;
        else
          *reason = svn_wc_conflict_reason_edited;
      }

      is_moved_away = (value == svn_wc_conflict_reason_moved_away);
    }
  c = c->next;

  if (action)
    {
      int value = svn_token__from_mem(action_map, c->data, c->len);

      if (value != SVN_TOKEN_UNKNOWN)
        *action = value;
      else
        *action = svn_wc_conflict_action_edit;
    }

  c = c->next;

  if (move_src_op_root_abspath)
    {
      /* Only set for update and switch tree conflicts */
      if (c && is_moved_away)
        {
          const char *move_src_op_root_relpath
                            = apr_pstrmemdup(scratch_pool, c->data, c->len);

          SVN_ERR(svn_wc__db_from_relpath(move_src_op_root_abspath,
                                          db, wri_abspath,
                                          move_src_op_root_relpath,
                                          result_pool, scratch_pool));
        }
      else
        *move_src_op_root_abspath = NULL;
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_read_markers(const apr_array_header_t **markers,
                              svn_wc__db_t *db,
                              const char *wri_abspath,
                              const svn_skel_t *conflict_skel,
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool)
{
  const svn_skel_t *conflict;
  apr_array_header_t *list = NULL;

  SVN_ERR_ASSERT(conflict_skel != NULL);

  /* Walk the conflicts */
  for (conflict = conflict_skel->children->next->children;
       conflict;
       conflict = conflict->next)
    {
      const svn_skel_t *marker;

      /* Get the list of markers stored per conflict */
      for (marker = conflict->children->next->children;
           marker;
           marker = marker->next)
        {
          /* Skip placeholders */
          if (! marker->is_atom)
            continue;

          if (! list)
            list = apr_array_make(result_pool, 4, sizeof(const char *));

          SVN_ERR(svn_wc__db_from_relpath(
                        &APR_ARRAY_PUSH(list, const char*),
                        db, wri_abspath,
                        apr_pstrmemdup(scratch_pool, marker->data,
                                       marker->len),
                        result_pool, scratch_pool));
        }
    }
  *markers = list;

  return SVN_NO_ERROR;
}

/* --------------------------------------------------------------------
 */


svn_error_t *
svn_wc__conflict_create_markers(svn_skel_t **work_items,
                                svn_wc__db_t *db,
                                const char *local_abspath,
                                svn_skel_t *conflict_skel,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
{
  svn_boolean_t prop_conflicted;
  svn_wc_operation_t operation;
  *work_items = NULL;

  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL,
                                     NULL, &prop_conflicted, NULL,
                                     db, local_abspath,
                                     conflict_skel,
                                     scratch_pool, scratch_pool));

  if (prop_conflicted)
    {
      const char *marker_abspath = NULL;
      svn_node_kind_t kind;
      const char *marker_dir;
      const char *marker_name;
      const char *marker_relpath;

      /* Ok, currently we have to do a few things for property conflicts:
         - Create a marker file
         - Store the name in the conflict_skel
         - Create a WQ item that fills the marker with the expected data */

      SVN_ERR(svn_io_check_path(local_abspath, &kind, scratch_pool));

      if (kind == svn_node_dir)
        {
          marker_dir = local_abspath;
          marker_name = SVN_WC__THIS_DIR_PREJ;
        }
      else
        svn_dirent_split(&marker_dir, &marker_name, local_abspath,
                         scratch_pool);

      SVN_ERR(svn_io_open_uniquely_named(NULL, &marker_abspath,
                                         marker_dir,
                                         marker_name,
                                         SVN_WC__PROP_REJ_EXT,
                                         svn_io_file_del_none,
                                         scratch_pool, scratch_pool));

      SVN_ERR(svn_wc__db_to_relpath(&marker_relpath, db, local_abspath,
                                    marker_abspath, result_pool, result_pool));

      /* And store the marker in the skel */
      {
        svn_skel_t *prop_conflict;
        SVN_ERR(conflict__get_conflict(&prop_conflict, conflict_skel,
                                       SVN_WC__CONFLICT_KIND_PROP));

        svn_skel__prepend_str(marker_relpath, prop_conflict->children->next,
                            result_pool);
      }
      SVN_ERR(svn_wc__wq_build_prej_install(work_items,
                                            db, local_abspath,
                                            scratch_pool, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Helper function for the three apply_* functions below, used when
 * merging properties together.
 *
 * Given property PROPNAME on LOCAL_ABSPATH, and four possible property
 * values, generate four tmpfiles and pass them to CONFLICT_FUNC callback.
 * This gives the client an opportunity to interactively resolve the
 * property conflict.
 *
 * BASE_VAL/WORKING_VAL represent the current state of the working
 * copy, and INCOMING_OLD_VAL/INCOMING_NEW_VAL represents the incoming
 * propchange.  Any of these values might be NULL, indicating either
 * non-existence or intent-to-delete.
 *
 * If the callback isn't available, or if it responds with
 * 'choose_postpone', then set *CONFLICT_REMAINS to TRUE and return.
 *
 * If the callback responds with a choice of 'base', 'theirs', 'mine',
 * or 'merged', then install the proper value into ACTUAL_PROPS and
 * set *CONFLICT_REMAINS to FALSE.
 */
static svn_error_t *
generate_propconflict(svn_boolean_t *conflict_remains,
                      svn_wc__db_t *db,
                      const char *local_abspath,
                      svn_node_kind_t kind,
                      svn_wc_operation_t operation,
                      const svn_wc_conflict_version_t *left_version,
                      const svn_wc_conflict_version_t *right_version,
                      const char *propname,
                      const svn_string_t *base_val,
                      const svn_string_t *working_val,
                      const svn_string_t *incoming_old_val,
                      const svn_string_t *incoming_new_val,
                      svn_wc_conflict_resolver_func2_t conflict_func,
                      void *conflict_baton,
                      svn_cancel_func_t cancel_func,
                      void *cancel_baton,
                      apr_pool_t *scratch_pool)
{
  svn_wc_conflict_result_t *result = NULL;
  svn_wc_conflict_description2_t *cdesc;
  const char *dirpath = svn_dirent_dirname(local_abspath, scratch_pool);
  const svn_string_t *new_value = NULL;

  cdesc = svn_wc_conflict_description_create_prop2(
                local_abspath,
                kind,
                propname, scratch_pool);

  cdesc->operation = operation;
  cdesc->src_left_version = left_version;
  cdesc->src_right_version = right_version;

  /* Create a tmpfile for each of the string_t's we've got.  */
  if (working_val)
    {
      const char *file_name;

      SVN_ERR(svn_io_write_unique(&file_name, dirpath, working_val->data,
                                  working_val->len,
                                  svn_io_file_del_on_pool_cleanup,
                                  scratch_pool));
      cdesc->my_abspath = svn_dirent_join(dirpath, file_name, scratch_pool);
      cdesc->prop_value_working = working_val;
    }

  if (incoming_new_val)
    {
      const char *file_name;

      SVN_ERR(svn_io_write_unique(&file_name, dirpath, incoming_new_val->data,
                                  incoming_new_val->len,
                                  svn_io_file_del_on_pool_cleanup,
                                  scratch_pool));

      /* ### For property conflicts, cd2 stores prop_reject_abspath in
       * ### their_abspath, and stores theirs_abspath in merged_file. */
      cdesc->merged_file = svn_dirent_join(dirpath, file_name, scratch_pool);
      cdesc->prop_value_incoming_new = incoming_new_val;
    }

  if (!base_val && !incoming_old_val)
    {
      /* If base and old are both NULL, then that's fine, we just let
         base_file stay NULL as-is.  Both agents are attempting to add a
         new property.  */
    }
  else if ((base_val && !incoming_old_val)
           || (!base_val && incoming_old_val))
    {
      /* If only one of base and old are defined, then we've got a
         situation where one agent is attempting to add the property
         for the first time, and the other agent is changing a
         property it thinks already exists.  In this case, we return
         whichever older-value happens to be defined, so that the
         conflict-callback can still attempt a 3-way merge. */

      const svn_string_t *conflict_base_val = base_val ? base_val
                                                       : incoming_old_val;
      const char *file_name;

      SVN_ERR(svn_io_write_unique(&file_name, dirpath,
                                  conflict_base_val->data,
                                  conflict_base_val->len,
                                  svn_io_file_del_on_pool_cleanup,
                                  scratch_pool));
      cdesc->base_abspath = svn_dirent_join(dirpath, file_name, scratch_pool);
    }
  else  /* base and old are both non-NULL */
    {
      const svn_string_t *conflict_base_val;
      const char *file_name;

      if (! svn_string_compare(base_val, incoming_old_val))
        {
          /* What happens if 'base' and 'old' don't match up?  In an
             ideal situation, they would.  But if they don't, this is
             a classic example of a patch 'hunk' failing to apply due
             to a lack of context.  For example: imagine that the user
             is busy changing the property from a value of "cat" to
             "dog", but the incoming propchange wants to change the
             same property value from "red" to "green".  Total context
             mismatch.

             HOWEVER: we can still pass one of the two base values as
             'base_file' to the callback anyway.  It's still useful to
             present the working and new values to the user to
             compare. */

          if (working_val && svn_string_compare(base_val, working_val))
            conflict_base_val = incoming_old_val;
          else
            conflict_base_val = base_val;
        }
      else
        {
          conflict_base_val = base_val;
        }

      SVN_ERR(svn_io_write_unique(&file_name, dirpath, conflict_base_val->data,
                                  conflict_base_val->len,
                                  svn_io_file_del_on_pool_cleanup, scratch_pool));
      cdesc->base_abspath = svn_dirent_join(dirpath, file_name, scratch_pool);

      cdesc->prop_value_base = base_val;
      cdesc->prop_value_incoming_old = incoming_old_val;

      if (working_val && incoming_new_val)
        {
          svn_stream_t *mergestream;
          svn_diff_t *diff;
          svn_diff_file_options_t *options =
            svn_diff_file_options_create(scratch_pool);

          SVN_ERR(svn_stream_open_unique(&mergestream, &cdesc->prop_reject_abspath,
                                         NULL, svn_io_file_del_on_pool_cleanup,
                                         scratch_pool, scratch_pool));
          SVN_ERR(svn_diff_mem_string_diff3(&diff, conflict_base_val,
                                            working_val,
                                            incoming_new_val, options, scratch_pool));
          SVN_ERR(svn_diff_mem_string_output_merge3(mergestream, diff,
                   conflict_base_val, working_val,
                   incoming_new_val, NULL, NULL, NULL, NULL,
                   svn_diff_conflict_display_modified_latest,
                   cancel_func, cancel_baton, scratch_pool));
          SVN_ERR(svn_stream_close(mergestream));

          /* ### For property conflicts, cd2 stores prop_reject_abspath in
           * ### their_abspath, and stores theirs_abspath in merged_file. */
          cdesc->their_abspath = cdesc->prop_reject_abspath;
        }
    }

  if (!incoming_old_val && incoming_new_val)
    cdesc->action = svn_wc_conflict_action_add;
  else if (incoming_old_val && !incoming_new_val)
    cdesc->action = svn_wc_conflict_action_delete;
  else
    cdesc->action = svn_wc_conflict_action_edit;

  if (base_val && !working_val)
    cdesc->reason = svn_wc_conflict_reason_deleted;
  else if (!base_val && working_val)
    cdesc->reason = svn_wc_conflict_reason_obstructed;
  else
    cdesc->reason = svn_wc_conflict_reason_edited;

  /* Invoke the interactive conflict callback. */
  SVN_ERR(conflict_func(&result, cdesc, conflict_baton, scratch_pool,
                        scratch_pool));
  if (result == NULL)
    {
      *conflict_remains = TRUE;
      return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                              NULL, _("Conflict callback violated API:"
                                      " returned no results"));
    }


  switch (result->choice)
    {
      default:
      case svn_wc_conflict_choose_postpone:
        {
          *conflict_remains = TRUE;
          break;
        }
      case svn_wc_conflict_choose_mine_full:
        {
          /* No need to change actual_props; it already contains working_val */
          *conflict_remains = FALSE;
          new_value = working_val;
          break;
        }
      /* I think _mine_full and _theirs_full are appropriate for prop
         behavior as well as the text behavior.  There should even be
         analogous behaviors for _mine and _theirs when those are
         ready, namely: fold in all non-conflicting prop changes, and
         then choose _mine side or _theirs side for conflicting ones. */
      case svn_wc_conflict_choose_theirs_full:
        {
          *conflict_remains = FALSE;
          new_value = incoming_new_val;
          break;
        }
      case svn_wc_conflict_choose_base:
        {
          *conflict_remains = FALSE;
          new_value = base_val;
          break;
        }
      case svn_wc_conflict_choose_merged:
        {
          if (!cdesc->merged_file 
              && (!result->merged_file && !result->merged_value))
            return svn_error_create
                (SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                 NULL, _("Conflict callback violated API:"
                         " returned no merged file"));

          if (result->merged_value)
            new_value = result->merged_value;
          else
            {
              svn_stringbuf_t *merged_stringbuf;

              SVN_ERR(svn_stringbuf_from_file2(&merged_stringbuf,
                                               result->merged_file ?
                                                    result->merged_file :
                                                    cdesc->merged_file,
                                               scratch_pool));
              new_value = svn_stringbuf__morph_into_string(merged_stringbuf);
            }
          *conflict_remains = FALSE;
          break;
        }
    }

  if (!*conflict_remains)
    {
      apr_hash_t *props;

      /* For now, just set the property values. This should really do some of the
         more advanced things from svn_wc_prop_set() */

      SVN_ERR(svn_wc__db_read_props(&props, db, local_abspath, scratch_pool,
                                    scratch_pool));

      svn_hash_sets(props, propname, new_value);

      SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, props,
                                      FALSE, NULL, NULL,
                                      scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Perform a 3-way merge in which conflicts are expected, showing the
 * conflicts in the way specified by STYLE, and using MERGE_OPTIONS.
 *
 * The three input files are LEFT_ABSPATH (the base), DETRANSLATED_TARGET
 * and RIGHT_ABSPATH.  The output is stored in a new temporary file,
 * whose name is put into *CHOSEN_ABSPATH.
 *
 * The output file will be deleted according to DELETE_WHEN.  If
 * DELETE_WHEN is 'on pool cleanup', it refers to RESULT_POOL.
 *
 * DB and WRI_ABSPATH are used to choose a directory for the output file.
 *
 * Allocate *CHOSEN_ABSPATH in RESULT_POOL.  Use SCRATCH_POOL for temporary
 * allocations.
 */
static svn_error_t *
merge_showing_conflicts(const char **chosen_abspath,
                        svn_wc__db_t *db,
                        const char *wri_abspath,
                        svn_diff_conflict_display_style_t style,
                        const apr_array_header_t *merge_options,
                        const char *left_abspath,
                        const char *detranslated_target,
                        const char *right_abspath,
                        svn_io_file_del_t delete_when,
                        svn_cancel_func_t cancel_func,
                        void *cancel_baton,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  const char *temp_dir;
  svn_stream_t *chosen_stream;
  svn_diff_t *diff;
  svn_diff_file_options_t *diff3_options;

  diff3_options = svn_diff_file_options_create(scratch_pool);
  if (merge_options)
    SVN_ERR(svn_diff_file_options_parse(diff3_options,
                                        merge_options,
                                        scratch_pool));

  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir, db,
                                         wri_abspath,
                                         scratch_pool, scratch_pool));
  /* We need to open the stream in RESULT_POOL because that controls the
   * lifetime of the file if DELETE_WHEN is 'on pool cleanup'.  (We also
   * want to allocate CHOSEN_ABSPATH in RESULT_POOL, but we don't care
   * about the stream itself.) */
  SVN_ERR(svn_stream_open_unique(&chosen_stream, chosen_abspath,
                                 temp_dir, delete_when,
                                 result_pool, scratch_pool));
  SVN_ERR(svn_diff_file_diff3_2(&diff,
                                left_abspath,
                                detranslated_target, right_abspath,
                                diff3_options, scratch_pool));
  SVN_ERR(svn_diff_file_output_merge3(chosen_stream, diff,
                                      left_abspath,
                                      detranslated_target,
                                      right_abspath,
                                      NULL, NULL, NULL, NULL, /* markers */
                                      style, cancel_func, cancel_baton,
                                      scratch_pool));
  SVN_ERR(svn_stream_close(chosen_stream));

  return SVN_NO_ERROR;
}

/* Prepare to delete an artifact file at ARTIFACT_FILE_ABSPATH in the
 * working copy at DB/WRI_ABSPATH.
 *
 * Set *WORK_ITEMS to a new work item that, when run, will delete the
 * artifact file; or to NULL if there is no file to delete.
 *
 * Set *FILE_FOUND to TRUE if the artifact file is found on disk and its
 * node kind is 'file'; otherwise do not change *FILE_FOUND.  FILE_FOUND
 * may be NULL if not required.
 */
static svn_error_t *
remove_artifact_file_if_exists(svn_skel_t **work_items,
                               svn_boolean_t *file_found,
                               svn_wc__db_t *db,
                               const char *wri_abspath,
                               const char *artifact_file_abspath,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
{
  *work_items = NULL;
  if (artifact_file_abspath)
    {
      svn_node_kind_t node_kind;

      SVN_ERR(svn_io_check_path(artifact_file_abspath, &node_kind,
                                scratch_pool));
      if (node_kind == svn_node_file)
        {
          SVN_ERR(svn_wc__wq_build_file_remove(work_items,
                                               db, wri_abspath,
                                               artifact_file_abspath,
                                               result_pool, scratch_pool));
          if (file_found)
            *file_found = TRUE;
        }
    }

  return SVN_NO_ERROR;
}

/* Create a new file in the same directory as LOCAL_ABSPATH, with the
   same basename as LOCAL_ABSPATH, with a ".edited" extension, and set
   *WORK_ITEM to a new work item that will copy and translate from the file
   SOURCE_ABSPATH to that new file.  It will be translated from repository-
   normal form to working-copy form according to the versioned properties
   of LOCAL_ABSPATH that are current when the work item is executed.

   DB should have a write lock for the directory containing SOURCE.

   Allocate *WORK_ITEM in RESULT_POOL. */
static svn_error_t *
save_merge_result(svn_skel_t **work_item,
                  svn_wc__db_t *db,
                  const char *local_abspath,
                  const char *source_abspath,
                  apr_pool_t *result_pool,
                  apr_pool_t *scratch_pool)
{
  const char *edited_copy_abspath;
  const char *dir_abspath;
  const char *filename;

  svn_dirent_split(&dir_abspath, &filename, local_abspath, scratch_pool);

  /* ### Should use preserved-conflict-file-exts. */
  /* Create the .edited file within this file's DIR_ABSPATH  */
  SVN_ERR(svn_io_open_uniquely_named(NULL,
                                     &edited_copy_abspath,
                                     dir_abspath,
                                     filename,
                                     ".edited",
                                     svn_io_file_del_none,
                                     scratch_pool, scratch_pool));
  SVN_ERR(svn_wc__wq_build_file_copy_translated(work_item,
                                                db, local_abspath,
                                                source_abspath,
                                                edited_copy_abspath,
                                                result_pool, scratch_pool));
  return SVN_NO_ERROR;
}



/* Resolve the text conflict in CONFLICT, which is currently recorded
 * on DB/LOCAL_ABSPATH in the manner specified by CHOICE.
 *
 * Set *WORK_ITEMS to new work items that will make the on-disk changes
 * needed to complete the resolution (but not to mark it as resolved).
 *
 * Set *FOUND_ARTIFACT to true if conflict markers are removed; otherwise
 * (which is only if CHOICE is 'postpone') to false.
 *
 * CHOICE, MERGED_FILE and SAVE_MERGED are typically values provided by
 * the conflict resolver.
 *
 * MERGE_OPTIONS allows customizing the diff handling when using
 * per hunk conflict resolving.
 */
static svn_error_t *
build_text_conflict_resolve_items(svn_skel_t **work_items,
                                  svn_boolean_t *found_artifact,
                                  svn_wc__db_t *db,
                                  const char *local_abspath,
                                  const svn_skel_t *conflict,
                                  svn_wc_conflict_choice_t choice,
                                  const char *merged_file,
                                  svn_boolean_t save_merged,
                                  const apr_array_header_t *merge_options,
                                  svn_cancel_func_t cancel_func,
                                  void *cancel_baton,
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
{
  const char *mine_abspath;
  const char *their_old_abspath;
  const char *their_abspath;
  svn_skel_t *work_item;
  const char *install_from_abspath = NULL;
  svn_boolean_t remove_source = FALSE;

  *work_items = NULL;

  if (found_artifact)
    *found_artifact = FALSE;

  SVN_ERR(svn_wc__conflict_read_text_conflict(&mine_abspath,
                                              &their_old_abspath,
                                              &their_abspath,
                                              db, local_abspath,
                                              conflict,
                                              scratch_pool, scratch_pool));

  if (save_merged)
    SVN_ERR(save_merge_result(work_items,
                              db, local_abspath,
                              merged_file
                                ? merged_file
                                : local_abspath,
                              result_pool, scratch_pool));

  if (choice == svn_wc_conflict_choose_postpone)
    return SVN_NO_ERROR;

  switch (choice)
    {
      /* If the callback wants to use one of the fulltexts
         to resolve the conflict, so be it.*/
      case svn_wc_conflict_choose_base:
        {
          install_from_abspath = their_old_abspath;
          break;
        }
      case svn_wc_conflict_choose_theirs_full:
        {
          install_from_abspath = their_abspath;
          break;
        }
      case svn_wc_conflict_choose_mine_full:
        {
          install_from_abspath = mine_abspath;
          break;
        }
      case svn_wc_conflict_choose_theirs_conflict:
      case svn_wc_conflict_choose_mine_conflict:
        {
          svn_diff_conflict_display_style_t style
            = choice == svn_wc_conflict_choose_theirs_conflict
                ? svn_diff_conflict_display_latest
                : svn_diff_conflict_display_modified;

          if (mine_abspath == NULL)
            return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                     _("Conflict on '%s' cannot be resolved to "
                                       "'theirs-conflict' or 'mine-conflict' "
                                       "because a merged version of the file "
                                       "cannot be created."),
                                     svn_dirent_local_style(local_abspath,
                                                            scratch_pool));

          SVN_ERR(merge_showing_conflicts(&install_from_abspath,
                                          db, local_abspath,
                                          style, merge_options,
                                          their_old_abspath,
                                          mine_abspath,
                                          their_abspath,
                                          /* ### why not same as other caller? */
                                          svn_io_file_del_none,
                                          cancel_func, cancel_baton,
                                          scratch_pool, scratch_pool));
          remove_source = TRUE;
          break;
        }

        /* For the case of 3-way file merging, we don't
           really distinguish between these return values;
           if the callback claims to have "generally
           resolved" the situation, we still interpret
           that as "OK, we'll assume the merged version is
           good to use". */
      case svn_wc_conflict_choose_merged:
        {
          install_from_abspath = merged_file
                                  ? merged_file
                                  : local_abspath;
          break;
        }
      case svn_wc_conflict_choose_postpone:
        {
          /* Assume conflict remains. */
          return SVN_NO_ERROR;
        }
      default:
        SVN_ERR_ASSERT(choice == svn_wc_conflict_choose_postpone);
    }

  if (install_from_abspath == NULL)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Conflict on '%s' could not be resolved "
                               "because the chosen version of the file "
                               "is not available."),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  /* ### It would be nice if we could somehow pass RECORD_FILEINFO
         as true in some easy cases. */
  SVN_ERR(svn_wc__wq_build_file_install(&work_item,
                                        db, local_abspath,
                                        install_from_abspath,
                                        FALSE /* use_commit_times */,
                                        FALSE /* record_fileinfo */,
                                        result_pool, scratch_pool));
  *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);

  if (remove_source)
    {
      SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
                                           db, local_abspath,
                                           install_from_abspath,
                                           result_pool, scratch_pool));
      *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
    }

  SVN_ERR(remove_artifact_file_if_exists(&work_item, found_artifact,
                                         db, local_abspath,
                                         their_old_abspath,
                                         result_pool, scratch_pool));
  *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);

  SVN_ERR(remove_artifact_file_if_exists(&work_item, found_artifact,
                                         db, local_abspath,
                                         their_abspath,
                                         result_pool, scratch_pool));
  *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);

  SVN_ERR(remove_artifact_file_if_exists(&work_item, found_artifact,
                                         db, local_abspath,
                                         mine_abspath,
                                         result_pool, scratch_pool));
  *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);

  return SVN_NO_ERROR;
}


/* Set *DESC to a new description of the text conflict in
 * CONFLICT_SKEL.  If there is no text conflict in CONFLICT_SKEL, return
 * an error.
 *
 * Use OPERATION and shallow copies of LEFT_VERSION and RIGHT_VERSION,
 * rather than reading them from CONFLICT_SKEL.  Use IS_BINARY and
 * MIME_TYPE for the corresponding fields of *DESC.
 *
 * Allocate results in RESULT_POOL.  SCRATCH_POOL is used for temporary
 * allocations. */
static svn_error_t *
read_text_conflict_desc(svn_wc_conflict_description2_t **desc,
                        svn_wc__db_t *db,
                        const char *local_abspath,
                        const svn_skel_t *conflict_skel,
                        const char *mime_type,
                        svn_wc_operation_t operation,
                        const svn_wc_conflict_version_t *left_version,
                        const svn_wc_conflict_version_t *right_version,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  *desc = svn_wc_conflict_description_create_text2(local_abspath, result_pool);
  (*desc)->mime_type = mime_type;
  (*desc)->is_binary = mime_type ? svn_mime_type_is_binary(mime_type) : FALSE;
  (*desc)->operation = operation;
  (*desc)->src_left_version = left_version;
  (*desc)->src_right_version = right_version;

  SVN_ERR(svn_wc__conflict_read_text_conflict(&(*desc)->my_abspath,
                                              &(*desc)->base_abspath,
                                              &(*desc)->their_abspath,
                                              db, local_abspath,
                                              conflict_skel,
                                              result_pool, scratch_pool));
  (*desc)->merged_file = apr_pstrdup(result_pool, local_abspath);

  return SVN_NO_ERROR;
}

/* Set *CONFLICT_DESC to a new description of the tree conflict in
 * CONFLICT_SKEL.  If there is no tree conflict in CONFLICT_SKEL, return
 * an error.
 *
 * Use OPERATION and shallow copies of LEFT_VERSION and RIGHT_VERSION,
 * rather than reading them from CONFLICT_SKEL.
 *
 * Allocate results in RESULT_POOL.  SCRATCH_POOL is used for temporary
 * allocations. */
static svn_error_t *
read_tree_conflict_desc(svn_wc_conflict_description2_t **desc,
                        svn_wc__db_t *db,
                        const char *local_abspath,
                        svn_node_kind_t node_kind,
                        const svn_skel_t *conflict_skel,
                        svn_wc_operation_t operation,
                        const svn_wc_conflict_version_t *left_version,
                        const svn_wc_conflict_version_t *right_version,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  svn_node_kind_t local_kind;
  svn_wc_conflict_reason_t reason;
  svn_wc_conflict_action_t action;

  SVN_ERR(svn_wc__conflict_read_tree_conflict(
            &reason, &action, NULL,
            db, local_abspath, conflict_skel, scratch_pool, scratch_pool));

  if (reason == svn_wc_conflict_reason_missing)
    local_kind = svn_node_none;
  else if (reason == svn_wc_conflict_reason_unversioned ||
           reason == svn_wc_conflict_reason_obstructed)
    SVN_ERR(svn_io_check_path(local_abspath, &local_kind, scratch_pool));
  else if (action == svn_wc_conflict_action_delete
           && left_version
           && (operation == svn_wc_operation_update
               ||operation == svn_wc_operation_switch)
           && (reason == svn_wc_conflict_reason_deleted
               || reason == svn_wc_conflict_reason_moved_away))
    {
      /* We have nothing locally to take the kind from */
      local_kind = left_version->node_kind;
    }
  else
    local_kind = node_kind;

  *desc = svn_wc_conflict_description_create_tree2(local_abspath, local_kind,
                                                   operation,
                                                   left_version, right_version,
                                                   result_pool);
  (*desc)->reason = reason;
  (*desc)->action = action;

  return SVN_NO_ERROR;
}

/* Forward definition */
static svn_error_t *
resolve_tree_conflict_on_node(svn_boolean_t *did_resolve,
                              svn_wc__db_t *db,
                              const char *local_abspath,
                              const svn_skel_t *conflict,
                              svn_wc_conflict_choice_t conflict_choice,
                              apr_hash_t *resolve_later,
                              svn_wc_notify_func2_t notify_func,
                              void *notify_baton,
                              svn_cancel_func_t cancel_func,
                              void *cancel_baton,
                              apr_pool_t *scratch_pool);

svn_error_t *
svn_wc__conflict_invoke_resolver(svn_wc__db_t *db,
                                 const char *local_abspath,
                                 svn_node_kind_t kind,
                                 const svn_skel_t *conflict_skel,
                                 const apr_array_header_t *merge_options,
                                 svn_wc_conflict_resolver_func2_t resolver_func,
                                 void *resolver_baton,
                                 svn_cancel_func_t cancel_func,
                                 void *cancel_baton,
                                 apr_pool_t *scratch_pool)
{
  svn_boolean_t text_conflicted;
  svn_boolean_t prop_conflicted;
  svn_boolean_t tree_conflicted;
  svn_wc_operation_t operation;
  const apr_array_header_t *locations;
  const svn_wc_conflict_version_t *left_version = NULL;
  const svn_wc_conflict_version_t *right_version = NULL;

  SVN_ERR(svn_wc__conflict_read_info(&operation, &locations,
                                     &text_conflicted, &prop_conflicted,
                                     &tree_conflicted,
                                     db, local_abspath, conflict_skel,
                                     scratch_pool, scratch_pool));

  if (locations && locations->nelts > 0)
    left_version = APR_ARRAY_IDX(locations, 0, const svn_wc_conflict_version_t *);

  if (locations && locations->nelts > 1)
    right_version = APR_ARRAY_IDX(locations, 1, const svn_wc_conflict_version_t *);

  /* Quick and dirty compatibility wrapper. My guess would be that most resolvers
     would want to look at all properties at the same time.

     ### svn currently only invokes this from the merge code to collect the list of
     ### conflicted paths. Eventually this code will be the base for 'svn resolve'
     ### and at that time the test coverage will improve
     */
  if (prop_conflicted)
    {
      apr_hash_t *old_props;
      apr_hash_t *mine_props;
      apr_hash_t *their_props;
      apr_hash_t *old_their_props;
      apr_hash_t *conflicted;
      apr_pool_t *iterpool;
      apr_hash_index_t *hi;
      svn_boolean_t mark_resolved = TRUE;

      SVN_ERR(svn_wc__conflict_read_prop_conflict(NULL,
                                                  &mine_props,
                                                  &old_their_props,
                                                  &their_props,
                                                  &conflicted,
                                                  db, local_abspath,
                                                  conflict_skel,
                                                  scratch_pool, scratch_pool));

      if (operation == svn_wc_operation_merge)
        SVN_ERR(svn_wc__db_read_pristine_props(&old_props, db, local_abspath,
                                               scratch_pool, scratch_pool));
      else
        old_props = old_their_props;

      iterpool = svn_pool_create(scratch_pool);

      for (hi = apr_hash_first(scratch_pool, conflicted);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *propname = apr_hash_this_key(hi);
          svn_boolean_t conflict_remains = TRUE;

          svn_pool_clear(iterpool);

          if (cancel_func)
            SVN_ERR(cancel_func(cancel_baton));

          SVN_ERR(generate_propconflict(&conflict_remains,
                                        db, local_abspath, kind,
                                        operation,
                                        left_version,
                                        right_version,
                                        propname,
                                        old_props
                                          ? svn_hash_gets(old_props, propname)
                                          : NULL,
                                        mine_props
                                          ? svn_hash_gets(mine_props, propname)
                                          : NULL,
                                        old_their_props
                                          ? svn_hash_gets(old_their_props, propname)
                                          : NULL,
                                        their_props
                                          ? svn_hash_gets(their_props, propname)
                                          : NULL,
                                        resolver_func, resolver_baton,
                                        cancel_func, cancel_baton,
                                        iterpool));

          if (conflict_remains)
            mark_resolved = FALSE;
        }

      if (mark_resolved)
        {
          SVN_ERR(svn_wc__mark_resolved_prop_conflicts(db, local_abspath,
                                                       scratch_pool));
        }
      svn_pool_destroy(iterpool);
    }

  if (text_conflicted)
    {
      svn_skel_t *work_items;
      svn_boolean_t was_resolved;
      svn_wc_conflict_description2_t *desc;
      apr_hash_t *props;
      svn_wc_conflict_result_t *result;

      SVN_ERR(svn_wc__db_read_props(&props, db, local_abspath,
                                    scratch_pool, scratch_pool));

      SVN_ERR(read_text_conflict_desc(&desc,
                                      db, local_abspath, conflict_skel,
                                      svn_prop_get_value(props,
                                                         SVN_PROP_MIME_TYPE),
                                      operation, left_version, right_version,
                                      scratch_pool, scratch_pool));


      work_items = NULL;
      was_resolved = FALSE;

      /* Give the conflict resolution callback a chance to clean
         up the conflicts before we mark the file 'conflicted' */

      SVN_ERR(resolver_func(&result, desc, resolver_baton, scratch_pool,
                            scratch_pool));
      if (result == NULL)
        return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                _("Conflict callback violated API:"
                                  " returned no results"));

      SVN_ERR(build_text_conflict_resolve_items(&work_items, &was_resolved,
                                                db, local_abspath,
                                                conflict_skel, result->choice,
                                                result->merged_file,
                                                result->save_merged,
                                                merge_options,
                                                cancel_func, cancel_baton,
                                                scratch_pool, scratch_pool));

      if (result->choice != svn_wc_conflict_choose_postpone)
        {
          SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
                                              TRUE, FALSE, FALSE,
                                              work_items, scratch_pool));
          SVN_ERR(svn_wc__wq_run(db, local_abspath,
                                 cancel_func, cancel_baton,
                                 scratch_pool));
        }
    }

  if (tree_conflicted)
    {
      svn_wc_conflict_result_t *result;
      svn_wc_conflict_description2_t *desc;
      svn_boolean_t resolved;
      svn_node_kind_t node_kind;

      SVN_ERR(svn_wc__db_read_kind(&node_kind, db, local_abspath, TRUE,
                                   TRUE, FALSE, scratch_pool));

      SVN_ERR(read_tree_conflict_desc(&desc,
                                      db, local_abspath, node_kind,
                                      conflict_skel,
                                      operation, left_version, right_version,
                                      scratch_pool, scratch_pool));

      /* Tell the resolver func about this conflict. */
      SVN_ERR(resolver_func(&result, desc, resolver_baton, scratch_pool,
                            scratch_pool));

      if (result == NULL)
        return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                _("Conflict callback violated API:"
                                  " returned no results"));

      /* Pass retry hash to avoid erroring out on cases where update
         can continue safely. ### Need notify handling */
      if (result->choice != svn_wc_conflict_choose_postpone)
        SVN_ERR(resolve_tree_conflict_on_node(&resolved,
                                              db, local_abspath, conflict_skel,
                                              result->choice,
                                              apr_hash_make(scratch_pool),
                                              NULL, NULL, /* ### notify */
                                              cancel_func, cancel_baton,
                                              scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Read all property conflicts contained in CONFLICT_SKEL into
 * individual conflict descriptions, and append those descriptions
 * to the CONFLICTS array.  If there is no property conflict in
 * CONFLICT_SKEL, return an error.
 *
 * If NOT create_tempfiles, always create a legacy property conflict
 * descriptor.
 *
 * Use NODE_KIND, OPERATION and shallow copies of LEFT_VERSION and
 * RIGHT_VERSION, rather than reading them from CONFLICT_SKEL.
 *
 * Allocate results in RESULT_POOL. SCRATCH_POOL is used for temporary
 * allocations. */
static svn_error_t *
read_prop_conflict_descs(apr_array_header_t *conflicts,
                         svn_wc__db_t *db,
                         const char *local_abspath,
                         svn_skel_t *conflict_skel,
                         svn_boolean_t create_tempfiles,
                         svn_node_kind_t node_kind,
                         svn_wc_operation_t operation,
                         const svn_wc_conflict_version_t *left_version,
                         const svn_wc_conflict_version_t *right_version,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
{
  const char *prop_reject_abspath;
  apr_hash_t *base_props;
  apr_hash_t *my_props;
  apr_hash_t *their_old_props;
  apr_hash_t *their_props;
  apr_hash_t *conflicted_props;
  apr_hash_index_t *hi;
  apr_pool_t *iterpool;
  svn_boolean_t prop_conflicted;

  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, &prop_conflicted,
                                     NULL, db, local_abspath, conflict_skel,
                                     scratch_pool, scratch_pool));

  if (!prop_conflicted)
    return SVN_NO_ERROR;

  SVN_ERR(svn_wc__conflict_read_prop_conflict(&prop_reject_abspath,
                                              &my_props,
                                              &their_old_props,
                                              &their_props,
                                              &conflicted_props,
                                              db, local_abspath,
                                              conflict_skel,
                                              scratch_pool, scratch_pool));

  prop_reject_abspath = apr_pstrdup(result_pool, prop_reject_abspath);

  if (apr_hash_count(conflicted_props) == 0)
    {
      /* Legacy prop conflict with only a .reject file. */
      svn_wc_conflict_description2_t *desc;

      desc  = svn_wc_conflict_description_create_prop2(local_abspath,
                                                       node_kind,
                                                       "", result_pool);

      /* ### For property conflicts, cd2 stores prop_reject_abspath in
       * ### their_abspath, and stores theirs_abspath in merged_file. */
      desc->prop_reject_abspath = prop_reject_abspath; /* in result_pool */
      desc->their_abspath = desc->prop_reject_abspath;

      desc->operation = operation;
      desc->src_left_version = left_version;
      desc->src_right_version = right_version;

      APR_ARRAY_PUSH(conflicts, svn_wc_conflict_description2_t *) = desc;

      return SVN_NO_ERROR;
    }

  if (operation == svn_wc_operation_merge)
    SVN_ERR(svn_wc__db_read_pristine_props(&base_props, db, local_abspath,
                                           result_pool, scratch_pool));
  else
    base_props = NULL;
  iterpool = svn_pool_create(scratch_pool);
  for (hi = apr_hash_first(scratch_pool, conflicted_props);
       hi;
       hi = apr_hash_next(hi))
    {
      const char *propname = apr_hash_this_key(hi);
      svn_string_t *old_value;
      svn_string_t *my_value;
      svn_string_t *their_value;
      svn_wc_conflict_description2_t *desc;

      svn_pool_clear(iterpool);

      desc = svn_wc_conflict_description_create_prop2(local_abspath,
                                                      node_kind,
                                                      propname,
                                                      result_pool);

      desc->operation = operation;
      desc->src_left_version = left_version;
      desc->src_right_version = right_version;

      desc->property_name = apr_pstrdup(result_pool, propname);

      my_value = svn_hash_gets(my_props, propname);
      their_value = svn_hash_gets(their_props, propname);
      old_value = svn_hash_gets(their_old_props, propname);

      /* Compute the incoming side of the conflict ('action'). */
      if (their_value == NULL)
        desc->action = svn_wc_conflict_action_delete;
      else if (old_value == NULL)
        desc->action = svn_wc_conflict_action_add;
      else
        desc->action = svn_wc_conflict_action_edit;

      /* Compute the local side of the conflict ('reason'). */
      if (my_value == NULL)
        desc->reason = svn_wc_conflict_reason_deleted;
      else if (old_value == NULL)
        desc->reason = svn_wc_conflict_reason_added;
      else
        desc->reason = svn_wc_conflict_reason_edited;

      /* ### For property conflicts, cd2 stores prop_reject_abspath in
       * ### their_abspath, and stores theirs_abspath in merged_file. */
      desc->prop_reject_abspath = prop_reject_abspath; /* in result_pool */
      desc->their_abspath = desc->prop_reject_abspath;

      desc->prop_value_base = base_props ? svn_hash_gets(base_props, propname)
                                         : desc->prop_value_incoming_old;

      if (my_value)
        {
          svn_stream_t *s;
          apr_size_t len;

          if (create_tempfiles)
            {
              SVN_ERR(svn_stream_open_unique(&s, &desc->my_abspath, NULL,
                                             svn_io_file_del_on_pool_cleanup,
                                             result_pool, iterpool));
              len = my_value->len;
              SVN_ERR(svn_stream_write(s, my_value->data, &len));
              SVN_ERR(svn_stream_close(s));
            }

          desc->prop_value_working = svn_string_dup(my_value, result_pool);
        }

      if (their_value)
        {
          svn_stream_t *s;
          apr_size_t len;

          /* ### For property conflicts, cd2 stores prop_reject_abspath in
           * ### their_abspath, and stores theirs_abspath in merged_file. */
          if (create_tempfiles)
            {
              SVN_ERR(svn_stream_open_unique(&s, &desc->merged_file, NULL,
                                             svn_io_file_del_on_pool_cleanup,
                                             result_pool, iterpool));
              len = their_value->len;
              SVN_ERR(svn_stream_write(s, their_value->data, &len));
              SVN_ERR(svn_stream_close(s));
            }

          desc->prop_value_incoming_new = svn_string_dup(their_value, result_pool);
        }

      if (old_value)
        {
          svn_stream_t *s;
          apr_size_t len;

          if (create_tempfiles)
            {
              SVN_ERR(svn_stream_open_unique(&s, &desc->base_abspath, NULL,
                                             svn_io_file_del_on_pool_cleanup,
                                             result_pool, iterpool));
              len = old_value->len;
              SVN_ERR(svn_stream_write(s, old_value->data, &len));
              SVN_ERR(svn_stream_close(s));
            }

          desc->prop_value_incoming_old = svn_string_dup(old_value, result_pool);
        }

      APR_ARRAY_PUSH(conflicts, svn_wc_conflict_description2_t *) = desc;
    }
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__read_conflicts(const apr_array_header_t **conflicts,
                       svn_skel_t **conflict_skel,
                       svn_wc__db_t *db,
                       const char *local_abspath,
                       svn_boolean_t create_tempfiles,
                       svn_boolean_t only_tree_conflict,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  svn_skel_t *the_conflict_skel;
  apr_array_header_t *cflcts;
  svn_boolean_t prop_conflicted;
  svn_boolean_t text_conflicted;
  svn_boolean_t tree_conflicted;
  svn_wc_operation_t operation;
  const apr_array_header_t *locations;
  const svn_wc_conflict_version_t *left_version = NULL;
  const svn_wc_conflict_version_t *right_version = NULL;
  svn_node_kind_t node_kind;
  apr_hash_t *props;

  if (!conflict_skel)
    conflict_skel = &the_conflict_skel;

  SVN_ERR(svn_wc__db_read_conflict(conflict_skel, &node_kind, &props,
                                   db, local_abspath,
                                   (conflict_skel == &the_conflict_skel)
                                        ? scratch_pool
                                        : result_pool,
                                   scratch_pool));

  if (!*conflict_skel)
    {
      /* Some callers expect not NULL */
      *conflicts = apr_array_make(result_pool, 0,
                                  sizeof(svn_wc_conflict_description2_t *));
      return SVN_NO_ERROR;
    }

  SVN_ERR(svn_wc__conflict_read_info(&operation, &locations, &text_conflicted,
                                     &prop_conflicted, &tree_conflicted,
                                     db, local_abspath, *conflict_skel,
                                     result_pool, scratch_pool));

  cflcts = apr_array_make(result_pool, 4,
                          sizeof(svn_wc_conflict_description2_t *));

  if (locations && locations->nelts > 0)
    left_version = APR_ARRAY_IDX(locations, 0, const svn_wc_conflict_version_t *);
  if (locations && locations->nelts > 1)
    right_version = APR_ARRAY_IDX(locations, 1, const svn_wc_conflict_version_t *);

  if (prop_conflicted && !only_tree_conflict)
    {
      SVN_ERR(read_prop_conflict_descs(cflcts,
                                       db, local_abspath, *conflict_skel,
                                       create_tempfiles, node_kind,
                                       operation, left_version, right_version,
                                       result_pool, scratch_pool));
    }

  if (text_conflicted && !only_tree_conflict)
    {
      svn_wc_conflict_description2_t *desc;

      SVN_ERR(read_text_conflict_desc(&desc,
                                      db, local_abspath, *conflict_skel,
                                      svn_prop_get_value(props,
                                                         SVN_PROP_MIME_TYPE),
                                      operation, left_version, right_version,
                                      result_pool, scratch_pool));
      APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t *) = desc;
    }

  if (tree_conflicted)
    {
      svn_wc_conflict_description2_t *desc;

      SVN_ERR(read_tree_conflict_desc(&desc,
                                      db, local_abspath, node_kind,
                                      *conflict_skel,
                                      operation, left_version, right_version,
                                      result_pool, scratch_pool));

      APR_ARRAY_PUSH(cflcts, const svn_wc_conflict_description2_t *) = desc;
    }

  *conflicts = cflcts;
  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__read_conflict_descriptions2_t(const apr_array_header_t **conflicts,
                                      svn_wc_context_t *wc_ctx,
                                      const char *local_abspath,
                                      apr_pool_t *result_pool,
                                      apr_pool_t *scratch_pool)
{
  return svn_wc__read_conflicts(conflicts, NULL, wc_ctx->db, local_abspath, 
                                FALSE, FALSE, result_pool, scratch_pool);
}


/*** Resolving a conflict automatically ***/

/*
 * Resolve the property conflicts found in DB/LOCAL_ABSPATH according
 * to CONFLICT_CHOICE.
 *
 * It is not an error if there is no prop conflict. If a prop conflict
 * existed and was resolved, set *DID_RESOLVE to TRUE, else set it to FALSE.
 *
 * Note: When there are no conflict markers on-disk to remove there is
 * no existing text conflict (unless we are still in the process of
 * creating the text conflict and we didn't register a marker file yet).
 * In this case the database contains old information, which we should
 * remove to avoid checking the next time. Resolving a property conflict
 * by just removing the marker file is a fully supported scenario since
 * Subversion 1.0.
 *
 * ### TODO [JAF] The '*_full' and '*_conflict' choices should differ.
 *     In my opinion, 'mine_full'/'theirs_full' should select
 *     the entire set of properties from 'mine' or 'theirs' respectively,
 *     while 'mine_conflict'/'theirs_conflict' should select just the
 *     properties that are in conflict.  Or, '_full' should select the
 *     entire property whereas '_conflict' should do a text merge within
 *     each property, selecting hunks.  Or all three kinds of behaviour
 *     should be available (full set of props, full value of conflicting
 *     props, or conflicting text hunks).
 * ### BH: If we make *_full select the full set of properties, we should
 *     check if we shouldn't make it also select the full text for files.
 *
 * ### TODO [JAF] All this complexity should not be down here in libsvn_wc
 *     but in a layer above.
 *
 * ### TODO [JAF] Options for 'base' should be like options for 'mine' and
 *     for 'theirs' -- choose full set of props, full value of conflicting
 *     props, or conflicting text hunks.
 *
 */
static svn_error_t *
resolve_prop_conflict_on_node(svn_boolean_t *did_resolve,
                              svn_wc__db_t *db,
                              const char *local_abspath,
                              svn_skel_t *conflicts,
                              const char *conflicted_propname,
                              svn_wc_conflict_choice_t conflict_choice,
                              const char *merged_file,
                              const svn_string_t *merged_value,
                              svn_cancel_func_t cancel_func,
                              void *cancel_baton,
                              apr_pool_t *scratch_pool)
{
  const char *prop_reject_file;
  apr_hash_t *mine_props;
  apr_hash_t *their_old_props;
  apr_hash_t *their_props;
  apr_hash_t *conflicted_props;
  apr_hash_t *old_props;
  apr_hash_t *resolve_from = NULL;
  svn_skel_t *work_items = NULL;
  svn_wc_operation_t operation;
  svn_boolean_t prop_conflicted;
  apr_hash_t *actual_props;
  svn_boolean_t resolved_all, resolved_all_prop;

  *did_resolve = FALSE;

  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, &prop_conflicted,
                                     NULL, db, local_abspath, conflicts,
                                     scratch_pool, scratch_pool));
  if (!prop_conflicted)
    return SVN_NO_ERROR;

  SVN_ERR(svn_wc__conflict_read_prop_conflict(&prop_reject_file,
                                              &mine_props, &their_old_props,
                                              &their_props, &conflicted_props,
                                              db, local_abspath, conflicts,
                                              scratch_pool, scratch_pool));

  if (!conflicted_props)
    {
      /* We have a pre 1.8 property conflict. Just mark it resolved */

      SVN_ERR(remove_artifact_file_if_exists(&work_items, did_resolve,
                                             db, local_abspath, prop_reject_file,
                                             scratch_pool, scratch_pool));
      SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, TRUE, FALSE,
                                      work_items, scratch_pool));
      SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
                             scratch_pool));
      return SVN_NO_ERROR;
    }

  if (conflicted_propname[0] != '\0'
      && !svn_hash_gets(conflicted_props, conflicted_propname))
    {
      return SVN_NO_ERROR; /* This property is not conflicted! */
    }

  if (operation == svn_wc_operation_merge)
      SVN_ERR(svn_wc__db_read_pristine_props(&old_props, db, local_abspath,
                                             scratch_pool, scratch_pool));
    else
      old_props = their_old_props;

  SVN_ERR(svn_wc__db_read_props(&actual_props, db, local_abspath,
                                scratch_pool, scratch_pool));

  /* We currently handle *_conflict as *_full as this argument is currently
     always applied for all conflicts on a node at the same time. Giving
     an error would break some tests that assumed that this would just
     resolve property conflicts to working.

     An alternative way to handle these conflicts would be to just copy all
     property state from mine/theirs on the _full option instead of just the
     conflicted properties. In some ways this feels like a sensible option as
     that would take both properties and text from mine/theirs, but when not
     both properties and text are conflicted we would fail in doing so.
   */
  switch (conflict_choice)
    {
    case svn_wc_conflict_choose_base:
      resolve_from = their_old_props ? their_old_props : old_props;
      break;
    case svn_wc_conflict_choose_mine_full:
    case svn_wc_conflict_choose_mine_conflict:
      resolve_from = mine_props;
      break;
    case svn_wc_conflict_choose_theirs_full:
    case svn_wc_conflict_choose_theirs_conflict:
      resolve_from = their_props;
      break;
    case svn_wc_conflict_choose_merged:
      if ((merged_file || merged_value) && conflicted_propname[0] != '\0')
        {
          resolve_from = apr_hash_copy(scratch_pool, actual_props);

          if (!merged_value)
            {
              svn_stringbuf_t *merged_propval;

              SVN_ERR(svn_stringbuf_from_file2(&merged_propval, merged_file,
                                               scratch_pool));

              merged_value = svn_stringbuf__morph_into_string(merged_propval);
            }
          svn_hash_sets(resolve_from, conflicted_propname, merged_value);
        }
      else
        resolve_from = NULL;
      break;
    default:
      return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
                              _("Invalid 'conflict_result' argument"));
    }


  if (resolve_from)
    {
      apr_hash_index_t *hi;
      apr_hash_t *apply_on_props;

      if (conflicted_propname[0] == '\0')
        {
          /* Apply to all conflicted properties */
          apply_on_props = conflicted_props;
        }
      else
        {
          /* Apply to a single property */
          apply_on_props = apr_hash_make(scratch_pool);
          svn_hash_sets(apply_on_props, conflicted_propname, "");
        }

      /* Apply the selected changes */
      for (hi = apr_hash_first(scratch_pool, apply_on_props);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *propname = apr_hash_this_key(hi);
          svn_string_t *new_value = NULL;

          new_value = svn_hash_gets(resolve_from, propname);

          svn_hash_sets(actual_props, propname, new_value);
        }
    }
  /*else the user accepted the properties as-is */

  /* This function handles conflicted_propname "" as resolving
     all property conflicts... Just what we need here */
  SVN_ERR(svn_wc__conflict_skel_resolve(&resolved_all, conflicts,
                                        db, local_abspath,
                                        FALSE, conflicted_propname,
                                        FALSE,
                                        scratch_pool, scratch_pool));

  if (!resolved_all)
    {
      /* Are there still property conflicts left? (or only...) */
      SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, NULL, &prop_conflicted,
                                         NULL, db, local_abspath, conflicts,
                                         scratch_pool, scratch_pool));

      resolved_all_prop = (! prop_conflicted);
    }
  else
    {
      resolved_all_prop = TRUE;
      conflicts = NULL;
    }

  if (resolved_all_prop)
    {
      /* Legacy behavior: Only report property conflicts as resolved when the
         property reject file exists

         If not the UI shows the conflict as already resolved
         (and in this case we just remove the in-db conflict) */
      SVN_ERR(remove_artifact_file_if_exists(&work_items, did_resolve,
                                             db, local_abspath,
                                             prop_reject_file,
                                             scratch_pool, scratch_pool));
    }
  else
    {
      /* Create a new prej file, based on the remaining conflicts */
      SVN_ERR(svn_wc__wq_build_prej_install(&work_items,
                                            db, local_abspath,
                                            scratch_pool, scratch_pool));
      *did_resolve = TRUE; /* We resolved a property conflict */
    }

  /* This installs the updated conflict skel */
  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
                                  FALSE, conflicts, work_items,
                                  scratch_pool));

  if (resolved_all)
    {
      /* Remove the whole conflict. Should probably be integrated
         into the op_set_props() call */
      SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
                                          FALSE, TRUE, FALSE,
                                          NULL, scratch_pool));
    }

  SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
                         scratch_pool));

  return SVN_NO_ERROR;
}

/* 
 * Record a tree conflict resolution failure due to error condition ERR
 * in the RESOLVE_LATER hash table. If the hash table is not available
 * (meaning the caller does not wish to retry resolution later), or if
 * the error condition does not indicate circumstances where another
 * existing tree conflict is blocking the resolution attempt, then
 * return the error ERR itself.
 */
static svn_error_t *
handle_tree_conflict_resolution_failure(const char *local_abspath,
                                        svn_error_t *err,
                                        apr_hash_t *resolve_later)
{
  const char *dup_abspath;

  if (!resolve_later
      || (err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE
          && err->apr_err != SVN_ERR_WC_FOUND_CONFLICT))
    return svn_error_trace(err); /* Give up. Do not retry resolution later. */

  svn_error_clear(err);
  dup_abspath = apr_pstrdup(apr_hash_pool_get(resolve_later),
                            local_abspath);

  svn_hash_sets(resolve_later, dup_abspath, dup_abspath);

  return SVN_NO_ERROR; /* Caller may retry after resolving other conflicts. */
}

/*
 * Resolve the tree conflict found in DB/LOCAL_ABSPATH according to
 * CONFLICT_CHOICE.
 *
 * It is not an error if there is no tree conflict. If a tree conflict
 * existed and was resolved, set *DID_RESOLVE to TRUE, else set it to FALSE.
 *
 * It is not an error if there is no tree conflict.
 *
 * If the conflict can't be resolved yet (e.g. because another tree conflict
 * is blocking a storage location), and RESOLVE_LATER is not NULL, store the
 * tree conflict in RESOLVE_LATER and do not mark the conflict resolved.
 * Else if RESOLVE_LATER is NULL, do not mark the conflict resolved and
 * return the error which prevented the conflict from being marked resolved.
 */
static svn_error_t *
resolve_tree_conflict_on_node(svn_boolean_t *did_resolve,
                              svn_wc__db_t *db,
                              const char *local_abspath,
                              const svn_skel_t *conflicts,
                              svn_wc_conflict_choice_t conflict_choice,
                              apr_hash_t *resolve_later,
                              svn_wc_notify_func2_t notify_func,
                              void *notify_baton,
                              svn_cancel_func_t cancel_func,
                              void *cancel_baton,
                              apr_pool_t *scratch_pool)
{
  svn_wc_conflict_reason_t reason;
  svn_wc_conflict_action_t action;
  svn_wc_operation_t operation;
  svn_boolean_t tree_conflicted;
  const char *src_op_root_abspath;

  *did_resolve = FALSE;

  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL,
                                     &tree_conflicted, db, local_abspath,
                                     conflicts, scratch_pool, scratch_pool));
  if (!tree_conflicted)
    return SVN_NO_ERROR;

  SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
                                              &src_op_root_abspath,
                                              db, local_abspath,
                                              conflicts,
                                              scratch_pool, scratch_pool));

  if (operation == svn_wc_operation_update
      || operation == svn_wc_operation_switch)
    {
      svn_error_t *err;
      if (reason == svn_wc_conflict_reason_deleted ||
          reason == svn_wc_conflict_reason_replaced)
        {
          if (conflict_choice == svn_wc_conflict_choose_merged)
            {
              /* Break moves for any children moved out of this directory,
               * and leave this directory deleted. */

              if (action != svn_wc_conflict_action_delete)
                {
                  SVN_ERR(svn_wc__db_op_break_moved_away(
                                  db, local_abspath, src_op_root_abspath, TRUE,
                                  notify_func, notify_baton,
                                  scratch_pool));
                  *did_resolve = TRUE;
                  return SVN_NO_ERROR; /* Marked resolved by function*/
                }
              /* else # The move is/moves are already broken */


              *did_resolve = TRUE;
            }
          else if (conflict_choice == svn_wc_conflict_choose_mine_conflict)
            {
              svn_skel_t *new_conflicts;

              /* Raise local moved-away vs. incoming edit conflicts on
               * any children moved out of this directory, and leave
               * this directory as-is.
               *
               * The newly conflicted moved-away children will be updated
               * if they are resolved with 'mine_conflict' as well. */
              err = svn_wc__db_op_raise_moved_away(
                        db, local_abspath, notify_func, notify_baton,
                        scratch_pool);

              if (err)
                SVN_ERR(handle_tree_conflict_resolution_failure(
                          local_abspath, err, resolve_later));

              /* We might now have a moved-away on *this* path, let's
                 try to resolve that directly if that is the case */
              SVN_ERR(svn_wc__db_read_conflict(&new_conflicts, NULL, NULL,
                                               db, local_abspath,
                                               scratch_pool, scratch_pool));

              if (new_conflicts)
                SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, NULL, NULL,
                                                   &tree_conflicted,
                                                   db, local_abspath,
                                                   new_conflicts,
                                                   scratch_pool,
                                                   scratch_pool));

              if (!new_conflicts || !tree_conflicted)
                {
                  /* TC is marked resolved by calling
                     svn_wc__db_op_raise_moved_away */
                  *did_resolve = TRUE;
                  return SVN_NO_ERROR;
                }

              SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
                                                          &src_op_root_abspath,
                                                          db, local_abspath,
                                                          new_conflicts,
                                                          scratch_pool,
                                                          scratch_pool));

              if (reason != svn_wc_conflict_reason_moved_away)
                {
                  *did_resolve = TRUE;
                  return SVN_NO_ERROR; /* We fixed one, but... */
                }

              conflicts = new_conflicts;
              /* Fall through in moved_away handling */
            }
          else
            return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                                     NULL,
                                     _("Tree conflict can only be resolved to "
                                       "'working' or 'mine-conflict' state; "
                                       "'%s' not resolved"),
                                     svn_dirent_local_style(local_abspath,
                                                            scratch_pool));
        }

      if (reason == svn_wc_conflict_reason_moved_away
           && action == svn_wc_conflict_action_edit)
        {
          /* After updates, we can resolve local moved-away
           * vs. any incoming change, either by updating the
           * moved-away node (mine-conflict) or by breaking the
           * move (theirs-conflict). */
          if (conflict_choice == svn_wc_conflict_choose_mine_conflict)
            {
              err = svn_wc__db_update_moved_away_conflict_victim(
                        db, local_abspath, src_op_root_abspath,
                        operation, action, reason,
                        cancel_func, cancel_baton,
                        notify_func, notify_baton,
                        scratch_pool);

              if (err)
                SVN_ERR(handle_tree_conflict_resolution_failure(
                          local_abspath, err, resolve_later));
              else
                *did_resolve = TRUE;
            }
          else if (conflict_choice == svn_wc_conflict_choose_merged)
            {
              /* We must break the move if the user accepts the current
               * working copy state instead of updating the move.
               * Else the move would be left in an invalid state. */

              SVN_ERR(svn_wc__db_op_break_moved_away(db, local_abspath,
                                                     src_op_root_abspath, TRUE,
                                                     notify_func, notify_baton,
                                                     scratch_pool));
              *did_resolve = TRUE;
              return SVN_NO_ERROR; /* Conflict is marked resolved */
            }
          else
            return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                                     NULL,
                                     _("Tree conflict can only be resolved to "
                                       "'working' or 'mine-conflict' state; "
                                       "'%s' not resolved"),
                                     svn_dirent_local_style(local_abspath,
                                                            scratch_pool));
        }
      else if (reason == svn_wc_conflict_reason_moved_away
               && action != svn_wc_conflict_action_edit)
        {
          /* action added is impossible, because that would imply that
             something was added, but before that already moved...
             (which would imply a replace) */
          SVN_ERR_ASSERT(action == svn_wc_conflict_action_delete
                         || action == svn_wc_conflict_action_replace);

          if (conflict_choice == svn_wc_conflict_choose_merged)
            {
              /* Whatever was moved is removed at its original location by the
                 update. That must also remove the recording of the move, so
                 we don't have to do anything here. */

              *did_resolve = TRUE;
            }
          else if (conflict_choice == svn_wc_conflict_choose_mine_conflict)
            {
              return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                                       NULL,
                                       _("Tree conflict can only be "
                                         "resolved to 'working' state; "
                                         "'%s' is no longer moved"),
                                       svn_dirent_local_style(local_abspath,
                                                              scratch_pool));
            }
        }
    }

  if (! *did_resolve)
    {
      if (conflict_choice != svn_wc_conflict_choose_merged)
        {
          /* For other tree conflicts, there is no way to pick
           * theirs-full or mine-full, etc. Throw an error if the
           * user expects us to be smarter than we really are. */
          return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                                   NULL,
                                   _("Tree conflict can only be "
                                     "resolved to 'working' state; "
                                     "'%s' not resolved"),
                                   svn_dirent_local_style(local_abspath,
                                                          scratch_pool));
        }
      else
        *did_resolve = TRUE;
    }

  SVN_ERR_ASSERT(*did_resolve);

  SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, FALSE, TRUE,
                                      NULL, scratch_pool));
  SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
                         scratch_pool));
  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__mark_resolved_text_conflict(svn_wc__db_t *db,
                                    const char *local_abspath,
                                    svn_cancel_func_t cancel_func,
                                    void *cancel_baton,
                                    apr_pool_t *scratch_pool)
{
  svn_skel_t *work_items;
  svn_skel_t *conflict;

  SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL,
                                   db, local_abspath,
                                   scratch_pool, scratch_pool));

  if (!conflict)
    return SVN_NO_ERROR;

  SVN_ERR(build_text_conflict_resolve_items(&work_items, NULL,
                                            db, local_abspath, conflict,
                                            svn_wc_conflict_choose_merged,
                                            NULL, FALSE, NULL,
                                            cancel_func, cancel_baton,
                                            scratch_pool, scratch_pool));

  SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, TRUE, FALSE, FALSE,
                                      work_items, scratch_pool));

  return svn_error_trace(svn_wc__wq_run(db, local_abspath,
                                        cancel_func, cancel_baton,
                                        scratch_pool));
}

svn_error_t *
svn_wc__mark_resolved_prop_conflicts(svn_wc__db_t *db,
                                     const char *local_abspath,
                                     apr_pool_t *scratch_pool)
{
  svn_boolean_t ignored_result;
  svn_skel_t *conflicts;

  SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL,
                                   db, local_abspath,
                                   scratch_pool, scratch_pool));

  if (!conflicts)
    return SVN_NO_ERROR;

  return svn_error_trace(resolve_prop_conflict_on_node(
                           &ignored_result,
                           db, local_abspath, conflicts, "",
                           svn_wc_conflict_choose_merged,
                           NULL, NULL,
                           NULL, NULL,
                           scratch_pool));
}


/* Baton for conflict_status_walker */
struct conflict_status_walker_baton
{
  svn_wc__db_t *db;
  svn_boolean_t resolve_text;
  const char *resolve_prop;
  svn_boolean_t resolve_tree;
  svn_wc_conflict_choice_t conflict_choice;
  svn_wc_conflict_resolver_func2_t conflict_func;
  void *conflict_baton;
  svn_cancel_func_t cancel_func;
  void *cancel_baton;
  svn_wc_notify_func2_t notify_func;
  void *notify_baton;
  svn_boolean_t resolved_one;
  apr_hash_t *resolve_later;
};

/* Implements svn_wc_notify_func2_t to collect new conflicts caused by
   resolving a tree conflict. */
static void
tree_conflict_collector(void *baton,
                        const svn_wc_notify_t *notify,
                        apr_pool_t *pool)
{
  struct conflict_status_walker_baton *cswb = baton;

  if (cswb->notify_func)
    cswb->notify_func(cswb->notify_baton, notify, pool);

  if (cswb->resolve_later
      && (notify->action == svn_wc_notify_tree_conflict
          || notify->prop_state == svn_wc_notify_state_conflicted
          || notify->content_state == svn_wc_notify_state_conflicted))
    {
      if (!svn_hash_gets(cswb->resolve_later, notify->path))
        {
          const char *dup_path;

          dup_path = apr_pstrdup(apr_hash_pool_get(cswb->resolve_later),
                                 notify->path);

          svn_hash_sets(cswb->resolve_later, dup_path, dup_path);
        }
    }
}

/* Implements svn_wc_status4_t to walk all conflicts to resolve.
 */
static svn_error_t *
conflict_status_walker(void *baton,
                       const char *local_abspath,
                       const svn_wc_status3_t *status,
                       apr_pool_t *scratch_pool)
{
  struct conflict_status_walker_baton *cswb = baton;
  svn_wc__db_t *db = cswb->db;
  svn_wc_notify_action_t notify_action = svn_wc_notify_resolved;
  const apr_array_header_t *conflicts;
  apr_pool_t *iterpool;
  int i;
  svn_boolean_t resolved = FALSE;
  svn_skel_t *conflict;
  const svn_wc_conflict_description2_t *cd;

  if (!status->conflicted)
    return SVN_NO_ERROR;

  iterpool = svn_pool_create(scratch_pool);

  SVN_ERR(svn_wc__read_conflicts(&conflicts, &conflict,
                                 db, local_abspath,
                                 (cswb->conflict_func != NULL) /* tmp files */,
                                 FALSE /* only tree conflicts */,
                                 scratch_pool, iterpool));

  for (i = 0; i < conflicts->nelts; i++)
    {
      svn_boolean_t did_resolve;
      svn_wc_conflict_choice_t my_choice = cswb->conflict_choice;
      svn_wc_conflict_result_t *result = NULL;
      svn_skel_t *work_items;

      cd = APR_ARRAY_IDX(conflicts, i, const svn_wc_conflict_description2_t *);

      if ((cd->kind == svn_wc_conflict_kind_property
           && (!cswb->resolve_prop
               || (*cswb->resolve_prop != '\0'
                   && strcmp(cswb->resolve_prop, cd->property_name) != 0)))
          || (cd->kind == svn_wc_conflict_kind_text && !cswb->resolve_text)
          || (cd->kind == svn_wc_conflict_kind_tree && !cswb->resolve_tree))
        {
          continue; /* Easy out. Don't call resolver func and ignore result */
        }

      svn_pool_clear(iterpool);

      if (my_choice == svn_wc_conflict_choose_unspecified)
        {
          if (!cswb->conflict_func)
            return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                    _("No conflict-callback and no "
                                      "pre-defined conflict-choice provided"));

          SVN_ERR(cswb->conflict_func(&result, cd, cswb->conflict_baton,
                                      iterpool, iterpool));

          my_choice = result->choice;
        }


      if (my_choice == svn_wc_conflict_choose_postpone)
        continue;

      switch (cd->kind)
        {
          case svn_wc_conflict_kind_tree:
            SVN_ERR(resolve_tree_conflict_on_node(&did_resolve,
                                                  db,
                                                  local_abspath, conflict,
                                                  my_choice,
                                                  cswb->resolve_later,
                                                  tree_conflict_collector,
                                                  cswb,
                                                  cswb->cancel_func,
                                                  cswb->cancel_baton,
                                                  iterpool));

            if (did_resolve)
              {
                resolved = TRUE;
                notify_action = svn_wc_notify_resolved_tree;
              }
            break;

          case svn_wc_conflict_kind_text:
            SVN_ERR(build_text_conflict_resolve_items(
                                        &work_items,
                                        &resolved,
                                        db, local_abspath, conflict,
                                        my_choice,
                                        result ? result->merged_file
                                               : NULL,
                                        result ? result->save_merged
                                               : FALSE,
                                        NULL /* merge_options */,
                                        cswb->cancel_func,
                                        cswb->cancel_baton,
                                        iterpool, iterpool));

            SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
                                                TRUE, FALSE, FALSE,
                                                work_items, iterpool));
            SVN_ERR(svn_wc__wq_run(db, local_abspath,
                                   cswb->cancel_func, cswb->cancel_baton,
                                   iterpool));
            if (resolved)
                notify_action = svn_wc_notify_resolved_text;
            break;

          case svn_wc_conflict_kind_property:
            SVN_ERR(resolve_prop_conflict_on_node(&did_resolve,
                                                  db,
                                                  local_abspath,
                                                  conflict,
                                                  cd->property_name,
                                                  my_choice,
                                                  result
                                                    ? result->merged_file
                                                    : NULL,
                                                  result
                                                    ? result->merged_value
                                                    : NULL,
                                                  cswb->cancel_func,
                                                  cswb->cancel_baton,
                                                  iterpool));

            if (did_resolve)
              {
                resolved = TRUE;
                notify_action = svn_wc_notify_resolved_prop;
              }
            break;

          default:
            /* We can't resolve other conflict types */
            break;
        }
    }

  /* Notify */
  if (cswb->notify_func && resolved)
    {
      svn_wc_notify_t *notify;

      /* If our caller asked for all conflicts to be resolved,
       * send a general 'resolved' notification. */
      if (cswb->resolve_text && cswb->resolve_tree &&
          (cswb->resolve_prop == NULL || cswb->resolve_prop[0] == '\0'))
        notify_action = svn_wc_notify_resolved;

      /* If we resolved a property conflict, but no specific property was
       * requested by the caller, send a general 'resolved' notification. */
      if (notify_action == svn_wc_notify_resolved_prop &&
          (cswb->resolve_prop == NULL || cswb->resolve_prop[0] == '\0'))
        notify_action = svn_wc_notify_resolved;

      notify = svn_wc_create_notify(local_abspath, notify_action, iterpool);

      /* Add the property name for property-specific notifications. */
      if (notify_action == svn_wc_notify_resolved_prop)
        {
          notify->prop_name = cd->property_name;
          SVN_ERR_ASSERT(strlen(notify->prop_name) > 0);
        }

      cswb->notify_func(cswb->notify_baton, notify, iterpool);

    }
  if (resolved)
    cswb->resolved_one = TRUE;

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__resolve_conflicts(svn_wc_context_t *wc_ctx,
                          const char *local_abspath,
                          svn_depth_t depth,
                          svn_boolean_t resolve_text,
                          const char *resolve_prop,
                          svn_boolean_t resolve_tree,
                          svn_wc_conflict_choice_t conflict_choice,
                          svn_wc_conflict_resolver_func2_t conflict_func,
                          void *conflict_baton,
                          svn_cancel_func_t cancel_func,
                          void *cancel_baton,
                          svn_wc_notify_func2_t notify_func,
                          void *notify_baton,
                          apr_pool_t *scratch_pool)
{
  struct conflict_status_walker_baton cswb;
  apr_pool_t *iterpool = NULL;
  svn_error_t *err;

  if (depth == svn_depth_unknown)
    depth = svn_depth_infinity;

  cswb.db = wc_ctx->db;
  cswb.resolve_text = resolve_text;
  cswb.resolve_prop = resolve_prop;
  cswb.resolve_tree = resolve_tree;
  cswb.conflict_choice = conflict_choice;

  cswb.conflict_func = conflict_func;
  cswb.conflict_baton = conflict_baton;

  cswb.cancel_func = cancel_func;
  cswb.cancel_baton = cancel_baton;

  cswb.notify_func = notify_func;
  cswb.notify_baton = notify_baton;

  cswb.resolved_one = FALSE;
  cswb.resolve_later = (depth != svn_depth_empty)
                          ? apr_hash_make(scratch_pool)
                          : NULL;

  if (notify_func)
    notify_func(notify_baton,
                svn_wc_create_notify(local_abspath,
                                    svn_wc_notify_conflict_resolver_starting,
                                    scratch_pool),
                scratch_pool);

  err = svn_wc_walk_status(wc_ctx,
                           local_abspath,
                           depth,
                           FALSE /* get_all */,
                           FALSE /* no_ignore */,
                           TRUE /* ignore_text_mods */,
                           NULL /* ignore_patterns */,
                           conflict_status_walker, &cswb,
                           cancel_func, cancel_baton,
                           scratch_pool);

  /* If we got new tree conflicts (or delayed conflicts) during the initial
     walk, we now walk them one by one as closure. */
  while (!err && cswb.resolve_later && apr_hash_count(cswb.resolve_later))
    {
      apr_hash_index_t *hi;
      svn_wc_status3_t *status = NULL;
      const char *tc_abspath = NULL;

      if (iterpool)
        svn_pool_clear(iterpool);
      else
        iterpool = svn_pool_create(scratch_pool);

      hi = apr_hash_first(scratch_pool, cswb.resolve_later);
      cswb.resolve_later = apr_hash_make(scratch_pool);
      cswb.resolved_one = FALSE;

      for (; hi && !err; hi = apr_hash_next(hi))
        {
          const char *relpath;
          svn_pool_clear(iterpool);

          tc_abspath = apr_hash_this_key(hi);

          if (cancel_func)
            SVN_ERR(cancel_func(cancel_baton));

          relpath = svn_dirent_skip_ancestor(local_abspath,
                                             tc_abspath);

          if (!relpath
              || (depth >= svn_depth_empty
                  && depth < svn_depth_infinity
                  && strchr(relpath, '/')))
            {
              continue;
            }

          SVN_ERR(svn_wc_status3(&status, wc_ctx, tc_abspath,
                                 iterpool, iterpool));

          if (depth == svn_depth_files
              && status->kind == svn_node_dir)
            continue;

          err = svn_error_trace(conflict_status_walker(&cswb, tc_abspath,
                                                       status, scratch_pool));
        }

      /* None of the remaining conflicts got resolved, and non did provide
         an error...

         We can fix that if we disable the 'resolve_later' option...
       */
      if (!cswb.resolved_one && !err && tc_abspath
          && apr_hash_count(cswb.resolve_later))
        {
          /* Run the last resolve operation again. We still have status
             and tc_abspath for that one. */

          cswb.resolve_later = NULL; /* Produce proper error! */

          /* Recreate the error */
          err = svn_error_trace(conflict_status_walker(&cswb, tc_abspath,
                                                       status, scratch_pool));

          SVN_ERR_ASSERT(err != NULL);

          err = svn_error_createf(
                    SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, err,
                    _("Unable to resolve pending conflict on '%s'"),
                    svn_dirent_local_style(tc_abspath, scratch_pool));
          break;
        }
    }

  if (iterpool)
    svn_pool_destroy(iterpool);

  if (err && err->apr_err != SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE)
    err = svn_error_createf(
                SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, err,
                _("Unable to resolve conflicts on '%s'"),
                svn_dirent_local_style(local_abspath, scratch_pool));

  SVN_ERR(err);

  if (notify_func)
    notify_func(notify_baton,
                svn_wc_create_notify(local_abspath,
                                    svn_wc_notify_conflict_resolver_done,
                                    scratch_pool),
                scratch_pool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx,
                          const char *local_abspath,
                          svn_depth_t depth,
                          svn_boolean_t resolve_text,
                          const char *resolve_prop,
                          svn_boolean_t resolve_tree,
                          svn_wc_conflict_choice_t conflict_choice,
                          svn_cancel_func_t cancel_func,
                          void *cancel_baton,
                          svn_wc_notify_func2_t notify_func,
                          void *notify_baton,
                          apr_pool_t *scratch_pool)
{
  return svn_error_trace(svn_wc__resolve_conflicts(wc_ctx, local_abspath,
                                                   depth, resolve_text,
                                                   resolve_prop, resolve_tree,
                                                   conflict_choice,
                                                   NULL, NULL,
                                                   cancel_func, cancel_baton,
                                                   notify_func, notify_baton,
                                                   scratch_pool));
}

/* Constructor for the result-structure returned by conflict callbacks. */
svn_wc_conflict_result_t *
svn_wc_create_conflict_result(svn_wc_conflict_choice_t choice,
                              const char *merged_file,
                              apr_pool_t *pool)
{
  svn_wc_conflict_result_t *result = apr_pcalloc(pool, sizeof(*result));
  result->choice = choice;
  result->merged_file = apr_pstrdup(pool, merged_file);
  result->save_merged = FALSE;
  result->merged_value = NULL;

  /* If we add more fields to svn_wc_conflict_result_t, add them here. */

  return result;
}

svn_error_t *
svn_wc__conflict_text_mark_resolved(svn_wc_context_t *wc_ctx,
                                    const char *local_abspath,
                                    svn_wc_conflict_choice_t choice,
                                    svn_cancel_func_t cancel_func,
                                    void *cancel_baton,
                                    svn_wc_notify_func2_t notify_func,
                                    void *notify_baton,
                                    apr_pool_t *scratch_pool)
{
  svn_skel_t *work_items;
  svn_skel_t *conflict;
  svn_boolean_t did_resolve;

  SVN_ERR(svn_wc__db_read_conflict(&conflict, NULL, NULL,
                                   wc_ctx->db, local_abspath,
                                   scratch_pool, scratch_pool));

  if (!conflict)
    return SVN_NO_ERROR;

  SVN_ERR(build_text_conflict_resolve_items(&work_items, &did_resolve,
                                            wc_ctx->db, local_abspath,
                                            conflict, choice,
                                            NULL, FALSE, NULL,
                                            cancel_func, cancel_baton,
                                            scratch_pool, scratch_pool));

  SVN_ERR(svn_wc__db_op_mark_resolved(wc_ctx->db, local_abspath,
                                      TRUE, FALSE, FALSE,
                                      work_items, scratch_pool));

  SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,
                         cancel_func, cancel_baton,
                         scratch_pool));

  if (did_resolve && notify_func)
    notify_func(notify_baton,
                svn_wc_create_notify(local_abspath,
                                     svn_wc_notify_resolved_text,
                                     scratch_pool),
                scratch_pool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_prop_mark_resolved(svn_wc_context_t *wc_ctx,
                                    const char *local_abspath,
                                    const char *propname,
                                    svn_wc_conflict_choice_t choice,
                                    svn_wc_notify_func2_t notify_func,
                                    void *notify_baton,
                                    apr_pool_t *scratch_pool)
{
  svn_boolean_t did_resolve;
  svn_skel_t *conflicts;

  SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL,
                                   wc_ctx->db, local_abspath,
                                   scratch_pool, scratch_pool));

  if (!conflicts)
    return SVN_NO_ERROR;

  SVN_ERR(resolve_prop_conflict_on_node(&did_resolve, wc_ctx->db,
                                        local_abspath, conflicts,
                                        propname, choice, NULL, NULL,
                                        NULL, NULL, scratch_pool));

  if (did_resolve && notify_func)
    {
      svn_wc_notify_t *notify;

      /* Send a general notification if no specific property was requested. */
      if (propname == NULL || propname[0] == '\0')
        {
          notify = svn_wc_create_notify(local_abspath,
                                        svn_wc_notify_resolved,
                                        scratch_pool);
        }
      else
        {
          notify = svn_wc_create_notify(local_abspath,
                                        svn_wc_notify_resolved_prop,
                                        scratch_pool);
          notify->prop_name = propname;
        }

      notify_func(notify_baton, notify, scratch_pool);
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_tree_update_break_moved_away(svn_wc_context_t *wc_ctx,
                                              const char *local_abspath,
                                              svn_cancel_func_t cancel_func,
                                              void *cancel_baton,
                                              svn_wc_notify_func2_t notify_func,
                                              void *notify_baton,
                                              apr_pool_t *scratch_pool)
{
  svn_wc_conflict_reason_t reason;
  svn_wc_conflict_action_t action;
  svn_wc_operation_t operation;
  svn_boolean_t tree_conflicted;
  const char *src_op_root_abspath;
  const apr_array_header_t *conflicts;
  svn_skel_t *conflict_skel;

  SVN_ERR(svn_wc__read_conflicts(&conflicts, &conflict_skel,
                                 wc_ctx->db, local_abspath,
                                 FALSE, /* no tempfiles */
                                 FALSE, /* only tree conflicts */
                                 scratch_pool, scratch_pool));

  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL,
                                     &tree_conflicted, wc_ctx->db,
                                     local_abspath, conflict_skel,
                                     scratch_pool, scratch_pool));
  if (!tree_conflicted)
    return SVN_NO_ERROR;

  SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
                                              &src_op_root_abspath,
                                              wc_ctx->db, local_abspath,
                                              conflict_skel,
                                              scratch_pool, scratch_pool));

  /* Make sure the expected conflict is recorded. */
  if (operation != svn_wc_operation_update &&
      operation != svn_wc_operation_switch)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Unexpected conflict operation '%s' on '%s'"),
                             svn_token__to_word(operation_map, operation),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));
  if (reason != svn_wc_conflict_reason_deleted &&
      reason != svn_wc_conflict_reason_replaced &&
      reason != svn_wc_conflict_reason_moved_away)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Unexpected conflict reason '%s' on '%s'"),
                             svn_token__to_word(reason_map, reason),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  /* Break moves for any children moved out of this directory,
   * and leave this directory deleted. */
  if (action != svn_wc_conflict_action_delete)
    {
      SVN_ERR(svn_wc__db_op_break_moved_away(
                      wc_ctx->db, local_abspath, src_op_root_abspath, TRUE,
                      notify_func, notify_baton, scratch_pool));
      /* Conflict was marked resolved by db_op_break_moved_away() call .*/

      if (notify_func)
        notify_func(notify_baton,
                    svn_wc_create_notify(local_abspath,
                                         svn_wc_notify_resolved_tree,
                                         scratch_pool),
                    scratch_pool);
      return SVN_NO_ERROR;
    }
  /* else # The move is/moves are already broken */

  SVN_ERR(svn_wc__db_op_mark_resolved(wc_ctx->db, local_abspath,
                                      FALSE, FALSE, TRUE,
                                      NULL, scratch_pool));
  SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, cancel_func, cancel_baton,
                         scratch_pool));

  if (notify_func)
    notify_func(notify_baton,
                svn_wc_create_notify(local_abspath,
                                     svn_wc_notify_resolved_tree,
                                     scratch_pool),
                scratch_pool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_tree_update_raise_moved_away(svn_wc_context_t *wc_ctx,
                                              const char *local_abspath,
                                              svn_cancel_func_t cancel_func,
                                              void *cancel_baton,
                                              svn_wc_notify_func2_t notify_func,
                                              void *notify_baton,
                                              apr_pool_t *scratch_pool)
{
  svn_wc_conflict_reason_t reason;
  svn_wc_conflict_action_t action;
  svn_wc_operation_t operation;
  svn_boolean_t tree_conflicted;
  const apr_array_header_t *conflicts;
  svn_skel_t *conflict_skel;

  SVN_ERR(svn_wc__read_conflicts(&conflicts, &conflict_skel,
                                 wc_ctx->db, local_abspath,
                                 FALSE, /* no tempfiles */
                                 FALSE, /* only tree conflicts */
                                 scratch_pool, scratch_pool));

  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL,
                                     &tree_conflicted, wc_ctx->db,
                                     local_abspath, conflict_skel,
                                     scratch_pool, scratch_pool));
  if (!tree_conflicted)
    return SVN_NO_ERROR;

  SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action, NULL,
                                              wc_ctx->db, local_abspath,
                                              conflict_skel,
                                              scratch_pool, scratch_pool));

  /* Make sure the expected conflict is recorded. */
  if (operation != svn_wc_operation_update &&
      operation != svn_wc_operation_switch)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Unexpected conflict operation '%s' on '%s'"),
                             svn_token__to_word(operation_map, operation),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));
  if (reason != svn_wc_conflict_reason_deleted &&
      reason != svn_wc_conflict_reason_replaced)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Unexpected conflict reason '%s' on '%s'"),
                             svn_token__to_word(reason_map, reason),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));
  if (action != svn_wc_conflict_action_edit)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Unexpected conflict action '%s' on '%s'"),
                             svn_token__to_word(action_map, action),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  /* Raise local moved-away vs. incoming edit conflicts on any children
   * moved out of this directory, and leave this directory as-is.
   * The user may choose to update newly conflicted moved-away children
   * when resolving them. If this function raises an error, the conflict
   * cannot be resolved yet because other conflicts or obstructions
   * prevent us from propagating the conflict to moved-away children. */
  SVN_ERR(svn_wc__db_op_raise_moved_away(wc_ctx->db, local_abspath,
                                         notify_func, notify_baton,
                                         scratch_pool));

  /* The conflict was marked resolved by svn_wc__db_op_raise_moved_away(). */
  if (notify_func)
    notify_func(notify_baton,
                svn_wc_create_notify(local_abspath,
                                     svn_wc_notify_resolved_tree,
                                     scratch_pool),
                scratch_pool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__conflict_tree_update_moved_away_node(svn_wc_context_t *wc_ctx,
                                             const char *local_abspath,
                                             svn_cancel_func_t cancel_func,
                                             void *cancel_baton,
                                             svn_wc_notify_func2_t notify_func,
                                             void *notify_baton,
                                             apr_pool_t *scratch_pool)
{
  svn_wc_conflict_reason_t reason;
  svn_wc_conflict_action_t action;
  svn_wc_operation_t operation;
  svn_boolean_t tree_conflicted;
  const char *src_op_root_abspath;
  const apr_array_header_t *conflicts;
  svn_skel_t *conflict_skel;

  SVN_ERR(svn_wc__read_conflicts(&conflicts, &conflict_skel,
                                 wc_ctx->db, local_abspath,
                                 FALSE, /* no tempfiles */
                                 FALSE, /* only tree conflicts */
                                 scratch_pool, scratch_pool));

  SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL,
                                     &tree_conflicted, wc_ctx->db,
                                     local_abspath, conflict_skel,
                                     scratch_pool, scratch_pool));
  if (!tree_conflicted)
    return SVN_NO_ERROR;

  SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
                                              &src_op_root_abspath,
                                              wc_ctx->db, local_abspath,
                                              conflict_skel,
                                              scratch_pool, scratch_pool));

  /* Make sure the expected conflict is recorded. */
  if (operation != svn_wc_operation_update &&
      operation != svn_wc_operation_switch)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Unexpected conflict operation '%s' on '%s'"),
                             svn_token__to_word(operation_map, operation),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));
  if (reason != svn_wc_conflict_reason_moved_away)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Unexpected conflict reason '%s' on '%s'"),
                             svn_token__to_word(reason_map, reason),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));
  if (action != svn_wc_conflict_action_edit)
    return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                             _("Unexpected conflict action '%s' on '%s'"),
                             svn_token__to_word(action_map, action),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  /* Update the moved-away conflict victim. */
  SVN_ERR(svn_wc__db_update_moved_away_conflict_victim(wc_ctx->db,
                                                       local_abspath,
                                                       src_op_root_abspath,
                                                       operation,
                                                       action,
                                                       reason,
                                                       cancel_func,
                                                       cancel_baton,
                                                       notify_func,
                                                       notify_baton,
                                                       scratch_pool));

  SVN_ERR(svn_wc__db_op_mark_resolved(wc_ctx->db, local_abspath,
                                      FALSE, FALSE, TRUE,
                                      NULL, scratch_pool));
  SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, cancel_func, cancel_baton,
                         scratch_pool));

  if (notify_func)
    notify_func(notify_baton,
                svn_wc_create_notify(local_abspath,
                                     svn_wc_notify_resolved_tree,
                                     scratch_pool),
                scratch_pool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__guess_incoming_move_target_nodes(apr_array_header_t **possible_targets,
                                         svn_wc_context_t *wc_ctx,
                                         const char *victim_abspath,
                                         svn_node_kind_t victim_node_kind,
                                         const char *moved_to_repos_relpath,
                                         svn_revnum_t rev,
                                         apr_pool_t *result_pool,
                                         apr_pool_t *scratch_pool)
{
  apr_array_header_t *candidates;
  apr_pool_t *iterpool;
  int i;
  apr_size_t longest_ancestor_len = 0;

  *possible_targets = apr_array_make(result_pool, 1, sizeof(const char *));
  SVN_ERR(svn_wc__find_repos_node_in_wc(&candidates, wc_ctx->db, victim_abspath,
                                        moved_to_repos_relpath, rev,
                                        scratch_pool, scratch_pool));

  /* Find a "useful move target" node in our set of candidates.
   * Since there is no way to be certain, filter out nodes which seem
   * unlikely candidates, and return the first node which is "good enough".
   * Nodes which are tree conflict victims don't count, and nodes which
   * cannot be modified (e.g. replaced or deleted nodes) don't count.
   * Nodes which are of a different node kind don't count either.
   * Ignore switched nodes as well, since that is an unlikely case during
   * update/swtich/merge conflict resolution. And externals shouldn't even
   * be on our candidate list in the first place.
   * If multiple candidates match these criteria, choose the one which
   * shares the longest common ancestor with the victim. */
  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; i < candidates->nelts; i++)
    {
      const char *local_abspath;
      const char *ancestor_abspath;
      apr_size_t ancestor_len;
      svn_boolean_t tree_conflicted;
      svn_wc__db_status_t status;
      svn_boolean_t is_wcroot;
      svn_boolean_t is_switched;
      svn_node_kind_t node_kind;
      const char *moved_to_abspath;
      int insert_index;

      svn_pool_clear(iterpool);

      local_abspath = APR_ARRAY_IDX(candidates, i, const char *);

      SVN_ERR(svn_wc__internal_conflicted_p(NULL, NULL, &tree_conflicted,
                                            wc_ctx->db, local_abspath,
                                            iterpool));
      if (tree_conflicted)
        continue;

      SVN_ERR(svn_wc__db_read_info(&status, &node_kind,
                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                   NULL, NULL, NULL, NULL,
                                   wc_ctx->db, local_abspath, iterpool,
                                   iterpool));
      if (status != svn_wc__db_status_normal &&
          status != svn_wc__db_status_added)
        continue;

      if (node_kind != victim_node_kind)
        continue;

      SVN_ERR(svn_wc__db_is_switched(&is_wcroot, &is_switched, NULL,
                                     wc_ctx->db, local_abspath, iterpool));
      if (is_wcroot || is_switched)
        continue;

      /* This might be a move target. Fingers crossed ;-) */
      moved_to_abspath = apr_pstrdup(result_pool, local_abspath);

      /* Insert the move target into the list. Targets which are closer
       * (path-wise) to the conflict victim are more likely to be a good
       * match, so put them at the front of the list. */
      ancestor_abspath = svn_dirent_get_longest_ancestor(local_abspath,
                                                         victim_abspath,
                                                         iterpool);
      ancestor_len = strlen(ancestor_abspath);
      if (ancestor_len >= longest_ancestor_len)
        {
          longest_ancestor_len = ancestor_len;
          insert_index = 0; /* prepend */
        }
      else
        {
          insert_index = (*possible_targets)->nelts; /* append */
        }
      svn_sort__array_insert(*possible_targets, &moved_to_abspath,
                             insert_index);
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}
