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

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



/*** Includes. ***/

#include <string.h>
#include "svn_hash.h"
#include "svn_client.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_opt.h"
#include "svn_time.h"
#include "svn_props.h"
#include "svn_mergeinfo.h"
#include "svn_pools.h"

#include "client.h"
#include "mergeinfo.h"

#include "svn_private_config.h"
#include "private/svn_wc_private.h"
#include "private/svn_ra_private.h"
#include "private/svn_mergeinfo_private.h"
#include "private/svn_client_private.h"


/*
 * OUR BASIC APPROACH TO COPIES
 * ============================
 *
 * for each source/destination pair
 *   if (not exist src_path)
 *     return ERR_BAD_SRC error
 *
 *   if (exist dst_path)
 *     return ERR_OBSTRUCTION error
 *   else
 *     copy src_path into parent_of_dst_path as basename (dst_path)
 *
 *   if (this is a move)
 *     delete src_path
 */



/*** Code. ***/

/* Extend the mergeinfo for the single WC path TARGET_WCPATH, adding
   MERGEINFO to any mergeinfo pre-existing in the WC. */
static svn_error_t *
extend_wc_mergeinfo(const char *target_abspath,
                    apr_hash_t *mergeinfo,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *pool)
{
  apr_hash_t *wc_mergeinfo;

  /* Get a fresh copy of the pre-existing state of the WC's mergeinfo
     updating it. */
  SVN_ERR(svn_client__parse_mergeinfo(&wc_mergeinfo, ctx->wc_ctx,
                                      target_abspath, pool, pool));

  /* Combine the provided mergeinfo with any mergeinfo from the WC. */
  if (wc_mergeinfo && mergeinfo)
    SVN_ERR(svn_mergeinfo_merge2(wc_mergeinfo, mergeinfo, pool, pool));
  else if (! wc_mergeinfo)
    wc_mergeinfo = mergeinfo;

  return svn_error_trace(
    svn_client__record_wc_mergeinfo(target_abspath, wc_mergeinfo,
                                    FALSE, ctx, pool));
}

/* Find the longest common ancestor of paths in COPY_PAIRS.  If
   SRC_ANCESTOR is NULL, ignore source paths in this calculation.  If
   DST_ANCESTOR is NULL, ignore destination paths in this calculation.
   COMMON_ANCESTOR will be the common ancestor of both the
   SRC_ANCESTOR and DST_ANCESTOR, and will only be set if it is not
   NULL.
 */
static svn_error_t *
get_copy_pair_ancestors(const apr_array_header_t *copy_pairs,
                        const char **src_ancestor,
                        const char **dst_ancestor,
                        const char **common_ancestor,
                        apr_pool_t *pool)
{
  apr_pool_t *subpool = svn_pool_create(pool);
  svn_client__copy_pair_t *first;
  const char *first_dst;
  const char *first_src;
  const char *top_dst;
  svn_boolean_t src_is_url;
  svn_boolean_t dst_is_url;
  char *top_src;
  int i;

  first = APR_ARRAY_IDX(copy_pairs, 0, svn_client__copy_pair_t *);

  /* Because all the destinations are in the same directory, we can easily
     determine their common ancestor. */
  first_dst = first->dst_abspath_or_url;
  dst_is_url = svn_path_is_url(first_dst);

  if (copy_pairs->nelts == 1)
    top_dst = apr_pstrdup(subpool, first_dst);
  else
    top_dst = dst_is_url ? svn_uri_dirname(first_dst, subpool)
                         : svn_dirent_dirname(first_dst, subpool);

  /* Sources can came from anywhere, so we have to actually do some
     work for them.  */
  first_src = first->src_abspath_or_url;
  src_is_url = svn_path_is_url(first_src);
  top_src = apr_pstrdup(subpool, first_src);
  for (i = 1; i < copy_pairs->nelts; i++)
    {
      /* We don't need to clear the subpool here for several reasons:
         1)  If we do, we can't use it to allocate the initial versions of
             top_src and top_dst (above).
         2)  We don't return any errors in the following loop, so we
             are guanteed to destroy the subpool at the end of this function.
         3)  The number of iterations is likely to be few, and the loop will
             be through quickly, so memory leakage will not be significant,
             in time or space.
      */
      const svn_client__copy_pair_t *pair =
        APR_ARRAY_IDX(copy_pairs, i, svn_client__copy_pair_t *);

      top_src = src_is_url
        ? svn_uri_get_longest_ancestor(top_src, pair->src_abspath_or_url,
                                       subpool)
        : svn_dirent_get_longest_ancestor(top_src, pair->src_abspath_or_url,
                                          subpool);
    }

  if (src_ancestor)
    *src_ancestor = apr_pstrdup(pool, top_src);

  if (dst_ancestor)
    *dst_ancestor = apr_pstrdup(pool, top_dst);

  if (common_ancestor)
    *common_ancestor =
               src_is_url
                    ? svn_uri_get_longest_ancestor(top_src, top_dst, pool)
                    : svn_dirent_get_longest_ancestor(top_src, top_dst, pool);

  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}

/* Quote a string if it would be handled as multiple or different tokens
   during externals parsing */
static const char *
maybe_quote(const char *value,
            apr_pool_t *result_pool)
{
  apr_status_t status;
  char **argv;

  status = apr_tokenize_to_argv(value, &argv, result_pool);

  if (!status && argv[0] && !argv[1] && strcmp(argv[0], value) == 0)
    return apr_pstrdup(result_pool, value);

  {
    svn_stringbuf_t *sb = svn_stringbuf_create_empty(result_pool);
    const char *c;

    svn_stringbuf_appendbyte(sb, '\"');

    for (c = value; *c; c++)
      {
        if (*c == '\\' || *c == '\"' || *c == '\'')
          svn_stringbuf_appendbyte(sb, '\\');

        svn_stringbuf_appendbyte(sb, *c);
      }

    svn_stringbuf_appendbyte(sb, '\"');

#ifdef SVN_DEBUG
    status = apr_tokenize_to_argv(sb->data, &argv, result_pool);

    SVN_ERR_ASSERT_NO_RETURN(!status && argv[0] && !argv[1]
                             && !strcmp(argv[0], value));
#endif

    return sb->data;
  }
}

/* In *NEW_EXTERNALS_DESCRIPTION, return a new external description for
 * use as a line in an svn:externals property, based on the external item
 * ITEM and the additional parser information in INFO. Pin the external
 * to EXTERNAL_PEGREV. Use POOL for all allocations. */
static svn_error_t *
make_external_description(const char **new_external_description,
                          const char *local_abspath_or_url,
                          svn_wc_external_item2_t *item,
                          svn_wc__externals_parser_info_t *info,
                          svn_opt_revision_t external_pegrev,
                          apr_pool_t *pool)
{
  const char *rev_str;
  const char *peg_rev_str;

  switch (info->format)
    {
      case svn_wc__external_description_format_1:
        if (external_pegrev.kind == svn_opt_revision_unspecified)
          {
            /* If info->rev_str is NULL, this yields an empty string. */
            rev_str = apr_pstrcat(pool, info->rev_str, " ", SVN_VA_NULL);
          }
        else if (info->rev_str && item->revision.kind != svn_opt_revision_head)
          rev_str = apr_psprintf(pool, "%s ", info->rev_str);
        else
          {
            /* ### can't handle svn_opt_revision_date without info->rev_str */
            SVN_ERR_ASSERT(external_pegrev.kind == svn_opt_revision_number);
            rev_str = apr_psprintf(pool, "-r%ld ",
                                   external_pegrev.value.number);
          }

        *new_external_description =
          apr_psprintf(pool, "%s %s%s\n", maybe_quote(item->target_dir, pool),
                                          rev_str,
                                          maybe_quote(item->url, pool));
        break;

      case svn_wc__external_description_format_2:
        if (external_pegrev.kind == svn_opt_revision_unspecified)
          {
            /* If info->rev_str is NULL, this yields an empty string. */
            rev_str = apr_pstrcat(pool, info->rev_str, " ", SVN_VA_NULL);
          }
        else if (info->rev_str && item->revision.kind != svn_opt_revision_head)
          rev_str = apr_psprintf(pool, "%s ", info->rev_str);
        else
          rev_str = "";

        if (external_pegrev.kind == svn_opt_revision_unspecified)
          peg_rev_str = info->peg_rev_str ? info->peg_rev_str : "";
        else if (info->peg_rev_str &&
                 item->peg_revision.kind != svn_opt_revision_head)
          peg_rev_str = info->peg_rev_str;
        else
          {
            /* ### can't handle svn_opt_revision_date without info->rev_str */
            SVN_ERR_ASSERT(external_pegrev.kind == svn_opt_revision_number);
            peg_rev_str = apr_psprintf(pool, "@%ld",
                                       external_pegrev.value.number);
          }

        *new_external_description =
          apr_psprintf(pool, "%s%s %s\n", rev_str,
                       maybe_quote(apr_psprintf(pool, "%s%s", item->url,
                                                peg_rev_str),
                                   pool),
                       maybe_quote(item->target_dir, pool));
        break;

      default:
        return svn_error_createf(
                 SVN_ERR_CLIENT_INVALID_EXTERNALS_DESCRIPTION, NULL,
                 _("%s property defined at '%s' is using an unsupported "
                   "syntax"), SVN_PROP_EXTERNALS,
                 svn_dirent_local_style(local_abspath_or_url, pool));
    }

  return SVN_NO_ERROR;
}

/* Pin all externals listed in EXTERNALS_PROP_VAL to their
 * last-changed revision. Set *PINNED_EXTERNALS to a new property
 * value allocated in RESULT_POOL, or to NULL if none of the externals
 * in EXTERNALS_PROP_VAL were changed. LOCAL_ABSPATH_OR_URL is the
 * path or URL defining the svn:externals property. Use SCRATCH_POOL
 * for temporary allocations.
 */
static svn_error_t *
pin_externals_prop(svn_string_t **pinned_externals,
                   svn_string_t *externals_prop_val,
                   const apr_hash_t *externals_to_pin,
                   const char *repos_root_url,
                   const char *local_abspath_or_url,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
{
  svn_stringbuf_t *buf;
  apr_array_header_t *external_items;
  apr_array_header_t *parser_infos;
  apr_array_header_t *items_to_pin;
  int pinned_items;
  int i;
  apr_pool_t *iterpool;

  SVN_ERR(svn_wc__parse_externals_description(&external_items,
                                              &parser_infos,
                                              local_abspath_or_url,
                                              externals_prop_val->data,
                                              FALSE /* canonicalize_url */,
                                              scratch_pool));

  if (externals_to_pin)
    {
      items_to_pin = svn_hash_gets((apr_hash_t *)externals_to_pin,
                                   local_abspath_or_url);
      if (!items_to_pin)
        {
          /* No pinning at all for this path. */
          *pinned_externals = NULL;
          return SVN_NO_ERROR;
        }
    }
  else
    items_to_pin = NULL;

  buf = svn_stringbuf_create_empty(scratch_pool);
  iterpool = svn_pool_create(scratch_pool);
  pinned_items = 0;
  for (i = 0; i < external_items->nelts; i++)
    {
      svn_wc_external_item2_t *item;
      svn_wc__externals_parser_info_t *info;
      svn_opt_revision_t external_pegrev;
      const char *pinned_desc;

      svn_pool_clear(iterpool);

      item = APR_ARRAY_IDX(external_items, i, svn_wc_external_item2_t *);
      info = APR_ARRAY_IDX(parser_infos, i, svn_wc__externals_parser_info_t *);

      if (items_to_pin)
        {
          int j;
          svn_wc_external_item2_t *item_to_pin = NULL;

          for (j = 0; j < items_to_pin->nelts; j++)
            {
              svn_wc_external_item2_t *const current =
                APR_ARRAY_IDX(items_to_pin, j, svn_wc_external_item2_t *);


              if (current
                  && 0 == strcmp(item->url, current->url)
                  && 0 == strcmp(item->target_dir, current->target_dir))
                {
                  item_to_pin = current;
                  break;
                }
            }

          /* If this item is not in our list of external items to pin then
           * simply keep the external at its original value. */
          if (!item_to_pin)
            {
              const char *desc;

              external_pegrev.kind = svn_opt_revision_unspecified;
              SVN_ERR(make_external_description(&desc, local_abspath_or_url,
                                                item, info, external_pegrev,
                                                iterpool));
              svn_stringbuf_appendcstr(buf, desc);
              continue;
            }
        }

      if (item->peg_revision.kind == svn_opt_revision_date)
        {
          /* Already pinned ... copy the peg date. */
          external_pegrev.kind = svn_opt_revision_date;
          external_pegrev.value.date = item->peg_revision.value.date;
        }
      else if (item->peg_revision.kind == svn_opt_revision_number)
        {
          /* Already pinned ... copy the peg revision number. */
          external_pegrev.kind = svn_opt_revision_number;
          external_pegrev.value.number = item->peg_revision.value.number;
        }
      else
        {
          SVN_ERR_ASSERT(
            item->peg_revision.kind == svn_opt_revision_head ||
            item->peg_revision.kind == svn_opt_revision_unspecified);

          /* We're actually going to change the peg revision. */
          ++pinned_items;

          if (svn_path_is_url(local_abspath_or_url))
            {
              const char *resolved_url;
              svn_ra_session_t *external_ra_session;
              svn_revnum_t latest_revnum;

              SVN_ERR(svn_wc__resolve_relative_external_url(
                        &resolved_url, item, repos_root_url,
                        local_abspath_or_url, iterpool, iterpool));
              SVN_ERR(svn_client__open_ra_session_internal(&external_ra_session,
                                                           NULL, resolved_url,
                                                           NULL, NULL, FALSE,
                                                           FALSE, ctx,
                                                           iterpool,
                                                           iterpool));
              SVN_ERR(svn_ra_get_latest_revnum(external_ra_session,
                                               &latest_revnum,
                                               iterpool));

              external_pegrev.kind = svn_opt_revision_number;
              external_pegrev.value.number = latest_revnum;
            }
          else
            {
              const char *external_abspath;
              svn_node_kind_t external_kind;
              svn_revnum_t external_checked_out_rev;

              external_abspath = svn_dirent_join(local_abspath_or_url,
                                                 item->target_dir,
                                                 iterpool);
              SVN_ERR(svn_wc__read_external_info(&external_kind, NULL, NULL,
                                                 NULL, NULL, ctx->wc_ctx,
                                                 local_abspath_or_url,
                                                 external_abspath, TRUE,
                                                 iterpool,
                                                 iterpool));
              if (external_kind == svn_node_none)
                return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS,
                                         NULL,
                                         _("Cannot pin external '%s' defined "
                                           "in %s at '%s' because it is not "
                                           "checked out in the working copy "
                                           "at '%s'"),
                                           item->url, SVN_PROP_EXTERNALS,
                                           svn_dirent_local_style(
                                             local_abspath_or_url, iterpool),
                                           svn_dirent_local_style(
                                             external_abspath, iterpool));
              else if (external_kind == svn_node_dir)
                {
                  svn_boolean_t is_switched;
                  svn_boolean_t is_modified;
                  svn_revnum_t min_rev;
                  svn_revnum_t max_rev;

                  /* Perform some sanity checks on the checked-out external. */

                  SVN_ERR(svn_wc__has_switched_subtrees(&is_switched,
                                                        ctx->wc_ctx,
                                                        external_abspath, NULL,
                                                        iterpool));
                  if (is_switched)
                    return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS,
                                             NULL,
                                             _("Cannot pin external '%s' defined "
                                               "in %s at '%s' because '%s' has "
                                               "switched subtrees (switches "
                                               "cannot be represented in %s)"),
                                             item->url, SVN_PROP_EXTERNALS,
                                             svn_dirent_local_style(
                                               local_abspath_or_url, iterpool),
                                             svn_dirent_local_style(
                                               external_abspath, iterpool),
                                             SVN_PROP_EXTERNALS);

                  SVN_ERR(svn_wc__has_local_mods(&is_modified, ctx->wc_ctx,
                                                 external_abspath, TRUE,
                                                 ctx->cancel_func,
                                                 ctx->cancel_baton,
                                                 iterpool));
                  if (is_modified)
                    return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS,
                                             NULL,
                                             _("Cannot pin external '%s' defined "
                                               "in %s at '%s' because '%s' has "
                                               "local modifications (local "
                                               "modifications cannot be "
                                               "represented in %s)"),
                                             item->url, SVN_PROP_EXTERNALS,
                                             svn_dirent_local_style(
                                               local_abspath_or_url, iterpool),
                                             svn_dirent_local_style(
                                               external_abspath, iterpool),
                                             SVN_PROP_EXTERNALS);

                  SVN_ERR(svn_wc__min_max_revisions(&min_rev, &max_rev, ctx->wc_ctx,
                                                    external_abspath, FALSE,
                                                    iterpool));
                  if (min_rev != max_rev)
                    return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS,
                                             NULL,
                                             _("Cannot pin external '%s' defined "
                                               "in %s at '%s' because '%s' is a "
                                               "mixed-revision working copy "
                                               "(mixed-revisions cannot be "
                                               "represented in %s)"),
                                             item->url, SVN_PROP_EXTERNALS,
                                             svn_dirent_local_style(
                                               local_abspath_or_url, iterpool),
                                             svn_dirent_local_style(
                                               external_abspath, iterpool),
                                             SVN_PROP_EXTERNALS);
                  external_checked_out_rev = min_rev;
                }
              else
                {
                  SVN_ERR_ASSERT(external_kind == svn_node_file);
                  SVN_ERR(svn_wc__node_get_repos_info(&external_checked_out_rev,
                                                      NULL, NULL, NULL,
                                                      ctx->wc_ctx, external_abspath,
                                                      iterpool, iterpool));
                }

              external_pegrev.kind = svn_opt_revision_number;
              external_pegrev.value.number = external_checked_out_rev;
            }
        }

      SVN_ERR_ASSERT(external_pegrev.kind == svn_opt_revision_date ||
                     external_pegrev.kind == svn_opt_revision_number);

      SVN_ERR(make_external_description(&pinned_desc, local_abspath_or_url,
                                        item, info, external_pegrev, iterpool));

      svn_stringbuf_appendcstr(buf, pinned_desc);
    }
  svn_pool_destroy(iterpool);

  if (pinned_items > 0)
    *pinned_externals = svn_string_create_from_buf(buf, result_pool);
  else
    *pinned_externals = NULL;

  return SVN_NO_ERROR;
}

/* Return, in *PINNED_EXTERNALS, a new hash mapping URLs or local abspaths
 * to svn:externals property values (as const char *), where some or all
 * external references have been pinned.
 * If EXTERNALS_TO_PIN is NULL, pin all externals, else pin the externals
 * mentioned in EXTERNALS_TO_PIN.
 * The pinning operation takes place as part of the copy operation for
 * the source/destination pair PAIR. Use RA_SESSION and REPOS_ROOT_URL
 * to contact the repository containing the externals definition, if neccesary.
 * Use CX to fopen additional RA sessions to external repositories, if
 * neccessary. Allocate *NEW_EXTERNALS in RESULT_POOL.
 * Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
resolve_pinned_externals(apr_hash_t **pinned_externals,
                         const apr_hash_t *externals_to_pin,
                         const svn_client__copy_pair_t *pair,
                         svn_ra_session_t *ra_session,
                         const char *repos_root_url,
                         svn_client_ctx_t *ctx,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
{
  const char *old_url = NULL;
  apr_hash_t *externals_props;
  apr_hash_index_t *hi;
  apr_pool_t *iterpool;

  *pinned_externals = apr_hash_make(result_pool);

  if (svn_path_is_url(pair->src_abspath_or_url))
    {
      SVN_ERR(svn_client__ensure_ra_session_url(&old_url, ra_session,
                                                pair->src_abspath_or_url,
                                                scratch_pool));
      externals_props = apr_hash_make(scratch_pool);
      SVN_ERR(svn_client__remote_propget(externals_props, NULL,
                                         SVN_PROP_EXTERNALS,
                                         pair->src_abspath_or_url, "",
                                         svn_node_dir,
                                         pair->src_revnum,
                                         ra_session,
                                         svn_depth_infinity,
                                         scratch_pool,
                                         scratch_pool));
    }
  else
    {
      SVN_ERR(svn_wc__externals_gather_definitions(&externals_props, NULL,
                                                   ctx->wc_ctx,
                                                   pair->src_abspath_or_url,
                                                   svn_depth_infinity,
                                                   scratch_pool, scratch_pool));

      /* ### gather_definitions returns propvals as const char * */
      for (hi = apr_hash_first(scratch_pool, externals_props);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *local_abspath_or_url = apr_hash_this_key(hi);
          const char *propval = apr_hash_this_val(hi);
          svn_string_t *new_propval = svn_string_create(propval, scratch_pool);

          svn_hash_sets(externals_props, local_abspath_or_url, new_propval);
        }
    }

  if (apr_hash_count(externals_props) == 0)
    {
      if (old_url)
        SVN_ERR(svn_ra_reparent(ra_session, old_url, scratch_pool));
      return SVN_NO_ERROR;
    }

  iterpool = svn_pool_create(scratch_pool);
  for (hi = apr_hash_first(scratch_pool, externals_props);
       hi;
       hi = apr_hash_next(hi))
    {
      const char *local_abspath_or_url = apr_hash_this_key(hi);
      svn_string_t *externals_propval = apr_hash_this_val(hi);
      const char *relpath;
      svn_string_t *new_propval;

      svn_pool_clear(iterpool);

      SVN_ERR(pin_externals_prop(&new_propval, externals_propval,
                                 externals_to_pin,
                                 repos_root_url, local_abspath_or_url, ctx,
                                 result_pool, iterpool));
      if (new_propval)
        {
          if (svn_path_is_url(pair->src_abspath_or_url))
            relpath = svn_uri_skip_ancestor(pair->src_abspath_or_url,
                                            local_abspath_or_url,
                                            result_pool);
          else
            relpath = svn_dirent_skip_ancestor(pair->src_abspath_or_url,
                                               local_abspath_or_url);
          SVN_ERR_ASSERT(relpath);

          svn_hash_sets(*pinned_externals, relpath, new_propval);
        }
    }
  svn_pool_destroy(iterpool);

  if (old_url)
    SVN_ERR(svn_ra_reparent(ra_session, old_url, scratch_pool));

  return SVN_NO_ERROR;
}



/* The guts of do_wc_to_wc_copies */
static svn_error_t *
do_wc_to_wc_copies_with_write_lock(svn_boolean_t *timestamp_sleep,
                                   const apr_array_header_t *copy_pairs,
                                   const char *dst_parent,
                                   svn_boolean_t metadata_only,
                                   svn_boolean_t pin_externals,
                                   const apr_hash_t *externals_to_pin,
                                   svn_client_ctx_t *ctx,
                                   apr_pool_t *scratch_pool)
{
  int i;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  svn_error_t *err = SVN_NO_ERROR;

  for (i = 0; i < copy_pairs->nelts; i++)
    {
      const char *dst_abspath;
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      apr_hash_t *pinned_externals = NULL;

      svn_pool_clear(iterpool);

      /* Check for cancellation */
      if (ctx->cancel_func)
        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

      if (pin_externals)
        {
          const char *repos_root_url;

          SVN_ERR(svn_wc__node_get_origin(NULL, NULL, NULL, &repos_root_url,
                                          NULL, NULL, NULL, ctx->wc_ctx,
                                          pair->src_abspath_or_url, FALSE,
                                          scratch_pool, iterpool));
          SVN_ERR(resolve_pinned_externals(&pinned_externals,
                                           externals_to_pin, pair, NULL,
                                           repos_root_url, ctx,
                                           iterpool, iterpool));
        }

      /* Perform the copy */
      dst_abspath = svn_dirent_join(pair->dst_parent_abspath, pair->base_name,
                                    iterpool);
      *timestamp_sleep = TRUE;
      err = svn_wc_copy3(ctx->wc_ctx, pair->src_abspath_or_url, dst_abspath,
                         metadata_only,
                         ctx->cancel_func, ctx->cancel_baton,
                         ctx->notify_func2, ctx->notify_baton2, iterpool);
      if (err)
        break;

      if (pinned_externals)
        {
          apr_hash_index_t *hi;

          for (hi = apr_hash_first(iterpool, pinned_externals);
               hi;
               hi = apr_hash_next(hi))
            {
              const char *dst_relpath = apr_hash_this_key(hi);
              svn_string_t *externals_propval = apr_hash_this_val(hi);
              const char *local_abspath;

              local_abspath = svn_dirent_join(pair->dst_abspath_or_url,
                                              dst_relpath, iterpool);
              /* ### use a work queue? */
              SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, local_abspath,
                                       SVN_PROP_EXTERNALS, externals_propval,
                                       svn_depth_empty, TRUE /* skip_checks */,
                                       NULL  /* changelist_filter */,
                                       ctx->cancel_func, ctx->cancel_baton,
                                       NULL, NULL, /* no extra notification */
                                       iterpool));
            }
        }
    }
  svn_pool_destroy(iterpool);

  SVN_ERR(err);
  return SVN_NO_ERROR;
}

/* Copy each COPY_PAIR->SRC into COPY_PAIR->DST.  Use POOL for temporary
   allocations. */
static svn_error_t *
do_wc_to_wc_copies(svn_boolean_t *timestamp_sleep,
                   const apr_array_header_t *copy_pairs,
                   svn_boolean_t metadata_only,
                   svn_boolean_t pin_externals,
                   const apr_hash_t *externals_to_pin,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *pool)
{
  const char *dst_parent, *dst_parent_abspath;

  SVN_ERR(get_copy_pair_ancestors(copy_pairs, NULL, &dst_parent, NULL, pool));
  if (copy_pairs->nelts == 1)
    dst_parent = svn_dirent_dirname(dst_parent, pool);

  SVN_ERR(svn_dirent_get_absolute(&dst_parent_abspath, dst_parent, pool));

  SVN_WC__CALL_WITH_WRITE_LOCK(
    do_wc_to_wc_copies_with_write_lock(timestamp_sleep, copy_pairs, dst_parent,
                                       metadata_only, pin_externals,
                                       externals_to_pin, ctx, pool),
    ctx->wc_ctx, dst_parent_abspath, FALSE, pool);

  return SVN_NO_ERROR;
}

/* The locked bit of do_wc_to_wc_moves. */
static svn_error_t *
do_wc_to_wc_moves_with_locks2(svn_client__copy_pair_t *pair,
                              const char *dst_parent_abspath,
                              svn_boolean_t lock_src,
                              svn_boolean_t lock_dst,
                              svn_boolean_t allow_mixed_revisions,
                              svn_boolean_t metadata_only,
                              svn_client_ctx_t *ctx,
                              apr_pool_t *scratch_pool)
{
  const char *dst_abspath;

  dst_abspath = svn_dirent_join(dst_parent_abspath, pair->base_name,
                                scratch_pool);

  SVN_ERR(svn_wc__move2(ctx->wc_ctx, pair->src_abspath_or_url,
                        dst_abspath, metadata_only,
                        allow_mixed_revisions,
                        ctx->cancel_func, ctx->cancel_baton,
                        ctx->notify_func2, ctx->notify_baton2,
                        scratch_pool));

  return SVN_NO_ERROR;
}

/* Wrapper to add an optional second lock */
static svn_error_t *
do_wc_to_wc_moves_with_locks1(svn_client__copy_pair_t *pair,
                              const char *dst_parent_abspath,
                              svn_boolean_t lock_src,
                              svn_boolean_t lock_dst,
                              svn_boolean_t allow_mixed_revisions,
                              svn_boolean_t metadata_only,
                              svn_client_ctx_t *ctx,
                              apr_pool_t *scratch_pool)
{
  if (lock_dst)
    SVN_WC__CALL_WITH_WRITE_LOCK(
      do_wc_to_wc_moves_with_locks2(pair, dst_parent_abspath, lock_src,
                                    lock_dst, allow_mixed_revisions,
                                    metadata_only,
                                    ctx, scratch_pool),
      ctx->wc_ctx, dst_parent_abspath, FALSE, scratch_pool);
  else
    SVN_ERR(do_wc_to_wc_moves_with_locks2(pair, dst_parent_abspath, lock_src,
                                          lock_dst, allow_mixed_revisions,
                                          metadata_only,
                                          ctx, scratch_pool));

  return SVN_NO_ERROR;
}

/* Move each COPY_PAIR->SRC into COPY_PAIR->DST, deleting COPY_PAIR->SRC
   afterwards.  Use POOL for temporary allocations. */
static svn_error_t *
do_wc_to_wc_moves(svn_boolean_t *timestamp_sleep,
                  const apr_array_header_t *copy_pairs,
                  const char *dst_path,
                  svn_boolean_t allow_mixed_revisions,
                  svn_boolean_t metadata_only,
                  svn_client_ctx_t *ctx,
                  apr_pool_t *pool)
{
  int i;
  apr_pool_t *iterpool = svn_pool_create(pool);
  svn_error_t *err = SVN_NO_ERROR;

  for (i = 0; i < copy_pairs->nelts; i++)
    {
      const char *src_parent_abspath;
      svn_boolean_t lock_src, lock_dst;
      const char *src_wcroot_abspath;
      const char *dst_wcroot_abspath;

      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      svn_pool_clear(iterpool);

      /* Check for cancellation */
      if (ctx->cancel_func)
        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

      src_parent_abspath = svn_dirent_dirname(pair->src_abspath_or_url,
                                              iterpool);

      SVN_ERR(svn_wc__get_wcroot(&src_wcroot_abspath,
                                 ctx->wc_ctx, src_parent_abspath,
                                 iterpool, iterpool));
      SVN_ERR(svn_wc__get_wcroot(&dst_wcroot_abspath,
                                 ctx->wc_ctx, pair->dst_parent_abspath,
                                 iterpool, iterpool));

      /* We now need to lock the right combination of batons.
         Four cases:
           1) src_parent == dst_parent
           2) src_parent is parent of dst_parent
           3) dst_parent is parent of src_parent
           4) src_parent and dst_parent are disjoint
         We can handle 1) as either 2) or 3) */
      if (strcmp(src_parent_abspath, pair->dst_parent_abspath) == 0
          || (svn_dirent_is_child(src_parent_abspath, pair->dst_parent_abspath,
                                  NULL)
              && !svn_dirent_is_child(src_parent_abspath, dst_wcroot_abspath,
                                      NULL)))
        {
          lock_src = TRUE;
          lock_dst = FALSE;
        }
      else if (svn_dirent_is_child(pair->dst_parent_abspath,
                                   src_parent_abspath, NULL)
               && !svn_dirent_is_child(pair->dst_parent_abspath,
                                       src_wcroot_abspath, NULL))
        {
          lock_src = FALSE;
          lock_dst = TRUE;
        }
      else
        {
          lock_src = TRUE;
          lock_dst = TRUE;
        }

      *timestamp_sleep = TRUE;

      /* Perform the copy and then the delete. */
      if (lock_src)
        SVN_WC__CALL_WITH_WRITE_LOCK(
          do_wc_to_wc_moves_with_locks1(pair, pair->dst_parent_abspath,
                                        lock_src, lock_dst,
                                        allow_mixed_revisions,
                                        metadata_only,
                                        ctx, iterpool),
          ctx->wc_ctx, src_parent_abspath,
          FALSE, iterpool);
      else
        SVN_ERR(do_wc_to_wc_moves_with_locks1(pair, pair->dst_parent_abspath,
                                              lock_src, lock_dst,
                                              allow_mixed_revisions,
                                              metadata_only,
                                              ctx, iterpool));

    }
  svn_pool_destroy(iterpool);

  return svn_error_trace(err);
}

/* Verify that the destinations stored in COPY_PAIRS are valid working copy
   destinations and set pair->dst_parent_abspath and pair->base_name for each
   item to the resulting location if they do */
static svn_error_t *
verify_wc_dsts(const apr_array_header_t *copy_pairs,
               svn_boolean_t make_parents,
               svn_boolean_t is_move,
               svn_boolean_t metadata_only,
               svn_client_ctx_t *ctx,
               apr_pool_t *result_pool,
               apr_pool_t *scratch_pool)
{
  int i;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);

  /* Check that DST does not exist, but its parent does */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      svn_node_kind_t dst_kind, dst_parent_kind;

      svn_pool_clear(iterpool);

      /* If DST_PATH does not exist, then its basename will become a new
         file or dir added to its parent (possibly an implicit '.').
         Else, just error out. */
      SVN_ERR(svn_wc_read_kind2(&dst_kind, ctx->wc_ctx,
                                pair->dst_abspath_or_url,
                                FALSE /* show_deleted */,
                                TRUE /* show_hidden */,
                                iterpool));
      if (dst_kind != svn_node_none)
        {
          svn_boolean_t is_excluded;
          svn_boolean_t is_server_excluded;

          SVN_ERR(svn_wc__node_is_not_present(NULL, &is_excluded,
                                              &is_server_excluded, ctx->wc_ctx,
                                              pair->dst_abspath_or_url, FALSE,
                                              iterpool));

          if (is_excluded || is_server_excluded)
            {
              return svn_error_createf(
                  SVN_ERR_WC_OBSTRUCTED_UPDATE,
                  NULL, _("Path '%s' exists, but is excluded"),
                  svn_dirent_local_style(pair->dst_abspath_or_url, iterpool));
            }
          else
            return svn_error_createf(
                            SVN_ERR_ENTRY_EXISTS, NULL,
                            _("Path '%s' already exists"),
                            svn_dirent_local_style(pair->dst_abspath_or_url,
                                                   scratch_pool));
        }

      /* Check that there is no unversioned obstruction */
      if (metadata_only)
        dst_kind = svn_node_none;
      else
        SVN_ERR(svn_io_check_path(pair->dst_abspath_or_url, &dst_kind,
                                  iterpool));

      if (dst_kind != svn_node_none)
        {
          if (is_move
              && copy_pairs->nelts == 1
              && strcmp(svn_dirent_dirname(pair->src_abspath_or_url, iterpool),
                        svn_dirent_dirname(pair->dst_abspath_or_url,
                                           iterpool)) == 0)
            {
              const char *dst;
              char *dst_apr;
              apr_status_t apr_err;
              /* We have a rename inside a directory, which might collide
                 just because the case insensivity of the filesystem makes
                 the source match the destination. */

              SVN_ERR(svn_path_cstring_from_utf8(&dst,
                                                 pair->dst_abspath_or_url,
                                                 scratch_pool));

              apr_err = apr_filepath_merge(&dst_apr, NULL, dst,
                                           APR_FILEPATH_TRUENAME, iterpool);

              if (!apr_err)
                {
                  /* And now bring it back to our canonical format */
                  SVN_ERR(svn_path_cstring_to_utf8(&dst, dst_apr, iterpool));
                  dst = svn_dirent_canonicalize(dst, iterpool);
                }
              /* else: Don't report this error; just report the normal error */

              if (!apr_err && strcmp(dst, pair->src_abspath_or_url) == 0)
                {
                  /* Ok, we have a single case only rename. Get out of here */
                  svn_dirent_split(&pair->dst_parent_abspath, &pair->base_name,
                                   pair->dst_abspath_or_url, result_pool);

                  svn_pool_destroy(iterpool);
                  return SVN_NO_ERROR;
                }
            }

          return svn_error_createf(
                            SVN_ERR_ENTRY_EXISTS, NULL,
                            _("Path '%s' already exists as unversioned node"),
                            svn_dirent_local_style(pair->dst_abspath_or_url,
                                                   scratch_pool));
        }

      svn_dirent_split(&pair->dst_parent_abspath, &pair->base_name,
                       pair->dst_abspath_or_url, result_pool);

      /* Make sure the destination parent is a directory and produce a clear
         error message if it is not. */
      SVN_ERR(svn_wc_read_kind2(&dst_parent_kind,
                                ctx->wc_ctx, pair->dst_parent_abspath,
                                FALSE, TRUE,
                                iterpool));
      if (dst_parent_kind == svn_node_none)
        {
          if (make_parents)
            SVN_ERR(svn_client__make_local_parents(pair->dst_parent_abspath,
                                                   TRUE, ctx, iterpool));
          else
            {
              SVN_ERR(svn_io_check_path(pair->dst_parent_abspath,
                                        &dst_parent_kind, scratch_pool));
              return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                                       (dst_parent_kind == svn_node_dir)
                                         ? _("Directory '%s' is not under "
                                             "version control")
                                         : _("Path '%s' is not a directory"),
                                       svn_dirent_local_style(
                                         pair->dst_parent_abspath,
                                         scratch_pool));
            }
        }
      else if (dst_parent_kind != svn_node_dir)
        {
          return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                                   _("Path '%s' is not a directory"),
                                   svn_dirent_local_style(
                                     pair->dst_parent_abspath, scratch_pool));
        }

      SVN_ERR(svn_io_check_path(pair->dst_parent_abspath,
                                &dst_parent_kind, scratch_pool));

      if (dst_parent_kind != svn_node_dir)
        return svn_error_createf(SVN_ERR_WC_MISSING, NULL,
                                 _("Path '%s' is not a directory"),
                                 svn_dirent_local_style(
                                     pair->dst_parent_abspath, scratch_pool));
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* Verify that the WC sources in COPY_PAIRS exist, and set pair->src_kind
   for each.
 */
static svn_error_t *
verify_wc_srcs(const apr_array_header_t *copy_pairs,
               svn_client_ctx_t *ctx,
               apr_pool_t *scratch_pool)
{
  int i;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);

  /* Check that all of our SRCs exist. */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      svn_boolean_t deleted_ok;
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      svn_pool_clear(iterpool);

      deleted_ok = (pair->src_peg_revision.kind == svn_opt_revision_base
                    || pair->src_op_revision.kind == svn_opt_revision_base);

      /* Verify that SRC_PATH exists. */
      SVN_ERR(svn_wc_read_kind2(&pair->src_kind, ctx->wc_ctx,
                               pair->src_abspath_or_url,
                               deleted_ok, FALSE, iterpool));
      if (pair->src_kind == svn_node_none)
        return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                                 _("Path '%s' does not exist"),
                                 svn_dirent_local_style(
                                        pair->src_abspath_or_url,
                                        scratch_pool));
    }
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}


/* Path-specific state used as part of path_driver_cb_baton. */
typedef struct path_driver_info_t
{
  const char *src_url;
  const char *src_path;
  const char *dst_path;
  svn_node_kind_t src_kind;
  svn_revnum_t src_revnum;
  svn_boolean_t resurrection;
  svn_boolean_t dir_add;
  svn_string_t *mergeinfo;  /* the new mergeinfo for the target */
  svn_string_t *externals; /* new externals definitions for the target */
  svn_boolean_t only_pin_externals;
} path_driver_info_t;


/* The baton used with the path_driver_cb_func() callback for a copy
   or move operation. */
struct path_driver_cb_baton
{
  /* A hash of path -> path_driver_info_t *'s. */
  apr_hash_t *action_hash;

  /* Whether the operation is a move or copy. */
  svn_boolean_t is_move;
};

static svn_error_t *
path_driver_cb_func(void **dir_baton,
                    const svn_delta_editor_t *editor,
                    void *edit_baton,
                    void *parent_baton,
                    void *callback_baton,
                    const char *path,
                    apr_pool_t *pool)
{
  struct path_driver_cb_baton *cb_baton = callback_baton;
  svn_boolean_t do_delete = FALSE, do_add = FALSE;
  path_driver_info_t *path_info = svn_hash_gets(cb_baton->action_hash, path);

  /* Initialize return value. */
  *dir_baton = NULL;

  /* This function should never get an empty PATH.  We can neither
     create nor delete the empty PATH, so if someone is calling us
     with such, the code is just plain wrong. */
  SVN_ERR_ASSERT(! svn_path_is_empty(path));

  /* Check to see if we need to add the path as a parent directory. */
  if (path_info->dir_add)
    {
      return editor->add_directory(path, parent_baton, NULL,
                                   SVN_INVALID_REVNUM, pool,
                                   dir_baton);
    }

  /* If this is a resurrection, we know the source and dest paths are
     the same, and that our driver will only be calling us once.  */
  if (path_info->resurrection)
    {
      /* If this is a move, we do nothing.  Otherwise, we do the copy.  */
      if (! cb_baton->is_move)
        do_add = TRUE;
    }
  /* Not a resurrection. */
  else
    {
      /* If this is a move, we check PATH to see if it is the source
         or the destination of the move. */
      if (cb_baton->is_move)
        {
          if (strcmp(path_info->src_path, path) == 0)
            do_delete = TRUE;
          else
            do_add = TRUE;
        }
      /* Not a move?  This must just be the copy addition. */
      else
        {
          do_add = !path_info->only_pin_externals;
        }
    }

  if (do_delete)
    {
      SVN_ERR(editor->delete_entry(path, SVN_INVALID_REVNUM,
                                   parent_baton, pool));
    }
  if (do_add)
    {
      SVN_ERR(svn_path_check_valid(path, pool));

      if (path_info->src_kind == svn_node_file)
        {
          void *file_baton;
          SVN_ERR(editor->add_file(path, parent_baton,
                                   path_info->src_url,
                                   path_info->src_revnum,
                                   pool, &file_baton));
          if (path_info->mergeinfo)
            SVN_ERR(editor->change_file_prop(file_baton,
                                             SVN_PROP_MERGEINFO,
                                             path_info->mergeinfo,
                                             pool));
          SVN_ERR(editor->close_file(file_baton, NULL, pool));
        }
      else
        {
          SVN_ERR(editor->add_directory(path, parent_baton,
                                        path_info->src_url,
                                        path_info->src_revnum,
                                        pool, dir_baton));
          if (path_info->mergeinfo)
            SVN_ERR(editor->change_dir_prop(*dir_baton,
                                            SVN_PROP_MERGEINFO,
                                            path_info->mergeinfo,
                                            pool));
        }
    }

  if (path_info->externals)
    {
      if (*dir_baton == NULL)
        SVN_ERR(editor->open_directory(path, parent_baton,
                                       SVN_INVALID_REVNUM,
                                       pool, dir_baton));

      SVN_ERR(editor->change_dir_prop(*dir_baton, SVN_PROP_EXTERNALS,
                                      path_info->externals, pool));
    }

  return SVN_NO_ERROR;
}


/* Starting with the path DIR relative to the RA_SESSION's session
   URL, work up through DIR's parents until an existing node is found.
   Push each nonexistent path onto the array NEW_DIRS, allocating in
   POOL.  Raise an error if the existing node is not a directory.

   ### Multiple requests for HEAD (SVN_INVALID_REVNUM) make this
   ### implementation susceptible to race conditions.  */
static svn_error_t *
find_absent_parents1(svn_ra_session_t *ra_session,
                     const char *dir,
                     apr_array_header_t *new_dirs,
                     apr_pool_t *pool)
{
  svn_node_kind_t kind;
  apr_pool_t *iterpool = svn_pool_create(pool);

  SVN_ERR(svn_ra_check_path(ra_session, dir, SVN_INVALID_REVNUM, &kind,
                            iterpool));

  while (kind == svn_node_none)
    {
      svn_pool_clear(iterpool);

      APR_ARRAY_PUSH(new_dirs, const char *) = dir;
      dir = svn_dirent_dirname(dir, pool);

      SVN_ERR(svn_ra_check_path(ra_session, dir, SVN_INVALID_REVNUM,
                                &kind, iterpool));
    }

  if (kind != svn_node_dir)
    return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
                             _("Path '%s' already exists, but is not a "
                               "directory"), dir);

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Starting with the URL *TOP_DST_URL which is also the root of
   RA_SESSION, work up through its parents until an existing node is
   found. Push each nonexistent URL onto the array NEW_DIRS,
   allocating in POOL.  Raise an error if the existing node is not a
   directory.

   Set *TOP_DST_URL and the RA session's root to the existing node's URL.

   ### Multiple requests for HEAD (SVN_INVALID_REVNUM) make this
   ### implementation susceptible to race conditions.  */
static svn_error_t *
find_absent_parents2(svn_ra_session_t *ra_session,
                     const char **top_dst_url,
                     apr_array_header_t *new_dirs,
                     apr_pool_t *pool)
{
  const char *root_url = *top_dst_url;
  svn_node_kind_t kind;

  SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM, &kind,
                            pool));

  while (kind == svn_node_none)
    {
      APR_ARRAY_PUSH(new_dirs, const char *) = root_url;
      root_url = svn_uri_dirname(root_url, pool);

      SVN_ERR(svn_ra_reparent(ra_session, root_url, pool));
      SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM, &kind,
                                pool));
    }

  if (kind != svn_node_dir)
    return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
                _("Path '%s' already exists, but is not a directory"),
                root_url);

  *top_dst_url = root_url;
  return SVN_NO_ERROR;
}

/* Queue property changes for pinning svn:externals properties set on
 * descendants of the path corresponding to PARENT_INFO. PINNED_EXTERNALS
 * is keyed by the relative path of each descendant which should have some
 * or all of its externals pinned, with the corresponding pinned svn:externals
 * properties as values. Property changes are queued in a new list of path
 * infos *NEW_PATH_INFOS, or in an existing item of the PATH_INFOS list if an
 * existing item is found for the descendant. Allocate results in RESULT_POOL.
 * Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
queue_externals_change_path_infos(apr_array_header_t *new_path_infos,
                                  apr_array_header_t *path_infos,
                                  apr_hash_t *pinned_externals,
                                  path_driver_info_t *parent_info,
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(scratch_pool, pinned_externals);
       hi;
       hi = apr_hash_next(hi))
    {
      const char *dst_relpath = apr_hash_this_key(hi);
      svn_string_t *externals_prop = apr_hash_this_val(hi);
      const char *src_url;
      path_driver_info_t *info;
      int i;

      svn_pool_clear(iterpool);

      src_url = svn_path_url_add_component2(parent_info->src_url,
                                            dst_relpath, iterpool);

      /* Try to find a path info the external change can be applied to. */
      info = NULL;
      for (i = 0; i < path_infos->nelts; i++)
        {
          path_driver_info_t *existing_info;

          existing_info = APR_ARRAY_IDX(path_infos, i, path_driver_info_t *);
          if (strcmp(src_url, existing_info->src_url) == 0)
            {
              info = existing_info;
              break;
            }
        }

      if (info == NULL)
        {
          /* A copied-along child needs its externals pinned.
             Create a new path info for this property change. */
          info = apr_pcalloc(result_pool, sizeof(*info));
          info->src_url = svn_path_url_add_component2(
                                parent_info->src_url, dst_relpath,
                                result_pool);
          info->src_path = NULL; /* Only needed on copied dirs */
          info->dst_path = svn_relpath_join(parent_info->dst_path,
                                            dst_relpath,
                                            result_pool);
          info->src_kind = svn_node_dir;
          info->only_pin_externals = TRUE;
          APR_ARRAY_PUSH(new_path_infos, path_driver_info_t *) = info;
        }

      info->externals = externals_prop;
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

static svn_error_t *
repos_to_repos_copy(const apr_array_header_t *copy_pairs,
                    svn_boolean_t make_parents,
                    const apr_hash_t *revprop_table,
                    svn_commit_callback2_t commit_callback,
                    void *commit_baton,
                    svn_client_ctx_t *ctx,
                    svn_boolean_t is_move,
                    svn_boolean_t pin_externals,
                    const apr_hash_t *externals_to_pin,
                    apr_pool_t *pool)
{
  svn_error_t *err;
  apr_array_header_t *paths = apr_array_make(pool, 2 * copy_pairs->nelts,
                                             sizeof(const char *));
  apr_hash_t *action_hash = apr_hash_make(pool);
  apr_array_header_t *path_infos;
  const char *top_url, *top_url_all, *top_url_dst;
  const char *message, *repos_root;
  svn_ra_session_t *ra_session = NULL;
  const svn_delta_editor_t *editor;
  void *edit_baton;
  struct path_driver_cb_baton cb_baton;
  apr_array_header_t *new_dirs = NULL;
  apr_hash_t *commit_revprops;
  apr_array_header_t *pin_externals_only_infos = NULL;
  int i;
  svn_client__copy_pair_t *first_pair =
    APR_ARRAY_IDX(copy_pairs, 0, svn_client__copy_pair_t *);

  /* Open an RA session to the first copy pair's destination.  We'll
     be verifying that every one of our copy source and destination
     URLs is or is beneath this sucker's repository root URL as a form
     of a cheap(ish) sanity check.  */
  SVN_ERR(svn_client_open_ra_session2(&ra_session,
                                      first_pair->src_abspath_or_url, NULL,
                                      ctx, pool, pool));
  SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, pool));

  /* Verify that sources and destinations are all at or under
     REPOS_ROOT.  While here, create a path_info struct for each
     src/dst pair and initialize portions of it with normalized source
     location information.  */
  path_infos = apr_array_make(pool, copy_pairs->nelts,
                              sizeof(path_driver_info_t *));
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      path_driver_info_t *info = apr_pcalloc(pool, sizeof(*info));
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      apr_hash_t *mergeinfo;

      /* Are the source and destination URLs at or under REPOS_ROOT? */
      if (! (svn_uri__is_ancestor(repos_root, pair->src_abspath_or_url)
             && svn_uri__is_ancestor(repos_root, pair->dst_abspath_or_url)))
        return svn_error_create
          (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
           _("Source and destination URLs appear not to point to the "
             "same repository."));

      /* Run the history function to get the source's URL and revnum in the
         operational revision. */
      SVN_ERR(svn_ra_reparent(ra_session, pair->src_abspath_or_url, pool));
      SVN_ERR(svn_client__repos_locations(&pair->src_abspath_or_url,
                                          &pair->src_revnum,
                                          NULL, NULL,
                                          ra_session,
                                          pair->src_abspath_or_url,
                                          &pair->src_peg_revision,
                                          &pair->src_op_revision, NULL,
                                          ctx, pool));

      /* Go ahead and grab mergeinfo from the source, too. */
      SVN_ERR(svn_ra_reparent(ra_session, pair->src_abspath_or_url, pool));
      SVN_ERR(svn_client__get_repos_mergeinfo(
                &mergeinfo, ra_session,
                pair->src_abspath_or_url, pair->src_revnum,
                svn_mergeinfo_inherited, TRUE /*squelch_incapable*/, pool));
      if (mergeinfo)
        SVN_ERR(svn_mergeinfo_to_string(&info->mergeinfo, mergeinfo, pool));

      /* Plop an INFO structure onto our array thereof. */
      info->src_url = pair->src_abspath_or_url;
      info->src_revnum = pair->src_revnum;
      info->resurrection = FALSE;
      APR_ARRAY_PUSH(path_infos, path_driver_info_t *) = info;
    }

  /* If this is a move, we have to open our session to the longest
     path common to all SRC_URLS and DST_URLS in the repository so we
     can do existence checks on all paths, and so we can operate on
     all paths in the case of a move.  But if this is *not* a move,
     then opening our session at the longest path common to sources
     *and* destinations might be an optimization when the user is
     authorized to access all that stuff, but could cause the
     operation to fail altogether otherwise.  See issue #3242.  */
  SVN_ERR(get_copy_pair_ancestors(copy_pairs, NULL, &top_url_dst, &top_url_all,
                                  pool));
  top_url = is_move ? top_url_all : top_url_dst;

  /* Check each src/dst pair for resurrection, and verify that TOP_URL
     is anchored high enough to cover all the editor_t activities
     required for this operation.  */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
                                               path_driver_info_t *);

      /* Source and destination are the same?  It's a resurrection. */
      if (strcmp(pair->src_abspath_or_url, pair->dst_abspath_or_url) == 0)
        info->resurrection = TRUE;

      /* We need to add each dst_URL, and (in a move) we'll need to
         delete each src_URL.  Our selection of TOP_URL so far ensures
         that all our destination URLs (and source URLs, for moves)
         are at least as deep as TOP_URL, but we need to make sure
         that TOP_URL is an *ancestor* of all our to-be-edited paths.

         Issue #683 is demonstrates this scenario.  If you're
         resurrecting a deleted item like this: 'svn cp -rN src_URL
         dst_URL', then src_URL == dst_URL == top_url.  In this
         situation, we want to open an RA session to be at least the
         *parent* of all three. */
      if ((strcmp(top_url, pair->dst_abspath_or_url) == 0)
          && (strcmp(top_url, repos_root) != 0))
        {
          top_url = svn_uri_dirname(top_url, pool);
        }
      if (is_move
          && (strcmp(top_url, pair->src_abspath_or_url) == 0)
          && (strcmp(top_url, repos_root) != 0))
        {
          top_url = svn_uri_dirname(top_url, pool);
        }
    }

  /* Point the RA session to our current TOP_URL. */
  SVN_ERR(svn_ra_reparent(ra_session, top_url, pool));

  /* If we're allowed to create nonexistent parent directories of our
     destinations, then make a list in NEW_DIRS of the parent
     directories of the destination that don't yet exist.  */
  if (make_parents)
    {
      new_dirs = apr_array_make(pool, 0, sizeof(const char *));

      /* If this is a move, TOP_URL is at least the common ancestor of
         all the paths (sources and destinations) involved.  Assuming
         the sources exist (which is fair, because if they don't, this
         whole operation will fail anyway), TOP_URL must also exist.
         So it's the paths between TOP_URL and the destinations which
         we have to check for existence.  But here, we take advantage
         of the knowledge of our caller.  We know that if there are
         multiple copy/move operations being requested, then the
         destinations of the copies/moves will all be siblings of one
         another.  Therefore, we need only to check for the
         nonexistent paths between TOP_URL and *one* of our
         destinations to find nonexistent parents of all of them.  */
      if (is_move)
        {
          /* Imagine a situation where the user tries to copy an
             existing source directory to nonexistent directory with
             --parents options specified:

                svn copy --parents URL/src URL/dst

             where src exists and dst does not.  If the dirname of the
             destination path is equal to TOP_URL,
             do not try to add dst to the NEW_DIRS list since it
             will be added to the commit items array later in this
             function. */
          const char *dir = svn_uri_skip_ancestor(
                              top_url,
                              svn_uri_dirname(first_pair->dst_abspath_or_url,
                                              pool),
                              pool);
          if (dir && *dir)
            SVN_ERR(find_absent_parents1(ra_session, dir, new_dirs, pool));
        }
      /* If, however, this is *not* a move, TOP_URL only points to the
         common ancestor of our destination path(s), or possibly one
         level higher.  We'll need to do an existence crawl toward the
         root of the repository, starting with one of our destinations
         (see "... take advantage of the knowledge of our caller ..."
         above), and possibly adjusting TOP_URL as we go. */
      else
        {
          apr_array_header_t *new_urls =
            apr_array_make(pool, 0, sizeof(const char *));
          SVN_ERR(find_absent_parents2(ra_session, &top_url, new_urls, pool));

          /* Convert absolute URLs into relpaths relative to TOP_URL. */
          for (i = 0; i < new_urls->nelts; i++)
            {
              const char *new_url = APR_ARRAY_IDX(new_urls, i, const char *);
              const char *dir = svn_uri_skip_ancestor(top_url, new_url, pool);

              APR_ARRAY_PUSH(new_dirs, const char *) = dir;
            }
        }
    }

  /* For each src/dst pair, check to see if that SRC_URL is a child of
     the DST_URL (excepting the case where DST_URL is the repo root).
     If it is, and the parent of DST_URL is the current TOP_URL, then we
     need to reparent the session one directory higher, the parent of
     the DST_URL. */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
                                               path_driver_info_t *);
      const char *relpath = svn_uri_skip_ancestor(pair->dst_abspath_or_url,
                                                  pair->src_abspath_or_url,
                                                  pool);

      if ((strcmp(pair->dst_abspath_or_url, repos_root) != 0)
          && (relpath != NULL && *relpath != '\0'))
        {
          info->resurrection = TRUE;
          top_url = svn_uri_get_longest_ancestor(
                            top_url,
                            svn_uri_dirname(pair->dst_abspath_or_url, pool),
                            pool);
          SVN_ERR(svn_ra_reparent(ra_session, top_url, pool));
        }
    }

  /* Get the portions of the SRC and DST URLs that are relative to
     TOP_URL (URI-decoding them while we're at it), verify that the
     source exists and the proposed destination does not, and toss
     what we've learned into the INFO array.  (For copies -- that is,
     non-moves -- the relative source URL NULL because it isn't a
     child of the TOP_URL at all.  That's okay, we'll deal with
     it.)  */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      svn_client__copy_pair_t *pair =
        APR_ARRAY_IDX(copy_pairs, i, svn_client__copy_pair_t *);
      path_driver_info_t *info =
        APR_ARRAY_IDX(path_infos, i, path_driver_info_t *);
      svn_node_kind_t dst_kind;
      const char *src_rel, *dst_rel;

      src_rel = svn_uri_skip_ancestor(top_url, pair->src_abspath_or_url, pool);
      if (src_rel)
        {
          SVN_ERR(svn_ra_check_path(ra_session, src_rel, pair->src_revnum,
                                    &info->src_kind, pool));
        }
      else
        {
          const char *old_url;

          src_rel = NULL;
          SVN_ERR_ASSERT(! is_move);

          SVN_ERR(svn_client__ensure_ra_session_url(&old_url, ra_session,
                                                    pair->src_abspath_or_url,
                                                    pool));
          SVN_ERR(svn_ra_check_path(ra_session, "", pair->src_revnum,
                                    &info->src_kind, pool));
          SVN_ERR(svn_ra_reparent(ra_session, old_url, pool));
        }
      if (info->src_kind == svn_node_none)
        return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
                                 _("Path '%s' does not exist in revision %ld"),
                                 pair->src_abspath_or_url, pair->src_revnum);

      /* Figure out the basename that will result from this operation,
         and ensure that we aren't trying to overwrite existing paths.  */
      dst_rel = svn_uri_skip_ancestor(top_url, pair->dst_abspath_or_url, pool);
      SVN_ERR(svn_ra_check_path(ra_session, dst_rel, SVN_INVALID_REVNUM,
                                &dst_kind, pool));
      if (dst_kind != svn_node_none)
        return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
                                 _("Path '%s' already exists"),
                                 pair->dst_abspath_or_url);

      /* More info for our INFO structure.  */
      info->src_path = src_rel; /* May be NULL, if outside RA session scope */
      info->dst_path = dst_rel;

      svn_hash_sets(action_hash, info->dst_path, info);
      if (is_move && (! info->resurrection))
        svn_hash_sets(action_hash, info->src_path, info);

      if (pin_externals)
        {
          apr_hash_t *pinned_externals;

          SVN_ERR(resolve_pinned_externals(&pinned_externals,
                                           externals_to_pin, pair,
                                           ra_session, repos_root,
                                           ctx, pool, pool));
          if (pin_externals_only_infos == NULL)
            {
              pin_externals_only_infos =
                apr_array_make(pool, 0, sizeof(path_driver_info_t *));
            }
          SVN_ERR(queue_externals_change_path_infos(pin_externals_only_infos,
                                                    path_infos,
                                                    pinned_externals,
                                                    info, pool, pool));
        }
    }

  if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
    {
      /* Produce a list of new paths to add, and provide it to the
         mechanism used to acquire a log message. */
      svn_client_commit_item3_t *item;
      const char *tmp_file;
      apr_array_header_t *commit_items
        = apr_array_make(pool, 2 * copy_pairs->nelts, sizeof(item));

      /* Add any intermediate directories to the message */
      if (make_parents)
        {
          for (i = 0; i < new_dirs->nelts; i++)
            {
              const char *relpath = APR_ARRAY_IDX(new_dirs, i, const char *);

              item = svn_client_commit_item3_create(pool);
              item->url = svn_path_url_add_component2(top_url, relpath, pool);
              item->kind = svn_node_dir;
              item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
              APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
            }
        }

      for (i = 0; i < path_infos->nelts; i++)
        {
          path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
                                                   path_driver_info_t *);

          item = svn_client_commit_item3_create(pool);
          item->url = svn_path_url_add_component2(top_url, info->dst_path,
                                                  pool);
          item->kind = info->src_kind;
          item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD
                              | SVN_CLIENT_COMMIT_ITEM_IS_COPY;
          item->copyfrom_url = info->src_url;
          item->copyfrom_rev = info->src_revnum;
          APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;

          if (is_move && (! info->resurrection))
            {
              item = svn_client_commit_item3_create(pool);
              item->url = svn_path_url_add_component2(top_url, info->src_path,
                                                      pool);
              item->kind = info->src_kind;
              item->state_flags = SVN_CLIENT_COMMIT_ITEM_DELETE;
              APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
            }
        }

      SVN_ERR(svn_client__get_log_msg(&message, &tmp_file, commit_items,
                                      ctx, pool));
      if (! message)
        return SVN_NO_ERROR;
    }
  else
    message = "";

  /* Setup our PATHS for the path-based editor drive. */
  /* First any intermediate directories. */
  if (make_parents)
    {
      for (i = 0; i < new_dirs->nelts; i++)
        {
          const char *relpath = APR_ARRAY_IDX(new_dirs, i, const char *);
          path_driver_info_t *info = apr_pcalloc(pool, sizeof(*info));

          info->dst_path = relpath;
          info->dir_add = TRUE;

          APR_ARRAY_PUSH(paths, const char *) = relpath;
          svn_hash_sets(action_hash, relpath, info);
        }
    }

  /* Then our copy destinations and move sources (if any). */
  for (i = 0; i < path_infos->nelts; i++)
    {
      path_driver_info_t *info = APR_ARRAY_IDX(path_infos, i,
                                               path_driver_info_t *);

      APR_ARRAY_PUSH(paths, const char *) = info->dst_path;
      if (is_move && (! info->resurrection))
        APR_ARRAY_PUSH(paths, const char *) = info->src_path;
    }

  /* Add any items which only need their externals pinned. */
  if (pin_externals_only_infos)
    {
      for (i = 0; i < pin_externals_only_infos->nelts; i++)
        {
          path_driver_info_t *info;

          info = APR_ARRAY_IDX(pin_externals_only_infos, i, path_driver_info_t *);
          APR_ARRAY_PUSH(paths, const char *) = info->dst_path;
          svn_hash_sets(action_hash, info->dst_path, info);
        }
    }

  SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
                                           message, ctx, pool));

  /* Fetch RA commit editor. */
  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
                        svn_client__get_shim_callbacks(ctx->wc_ctx,
                                                       NULL, pool)));
  SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
                                    commit_revprops,
                                    commit_callback,
                                    commit_baton,
                                    NULL, TRUE, /* No lock tokens */
                                    pool));

  /* Setup the callback baton. */
  cb_baton.action_hash = action_hash;
  cb_baton.is_move = is_move;

  /* Call the path-based editor driver. */
  err = svn_delta_path_driver3(editor, edit_baton, paths, TRUE,
                               path_driver_cb_func, &cb_baton, pool);
  if (err)
    {
      /* At least try to abort the edit (and fs txn) before throwing err. */
      return svn_error_compose_create(
                    err,
                    editor->abort_edit(edit_baton, pool));
    }

  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify;
      notify = svn_wc_create_notify_url(top_url,
                                        svn_wc_notify_commit_finalizing,
                                        pool);
      ctx->notify_func2(ctx->notify_baton2, notify, pool);
    }

  /* Close the edit. */
  return svn_error_trace(editor->close_edit(edit_baton, pool));
}

/* Baton for check_url_kind */
struct check_url_kind_baton
{
  svn_ra_session_t *session;
  const char *repos_root_url;
  svn_boolean_t should_reparent;
};

/* Implements svn_client__check_url_kind_t for wc_to_repos_copy */
static svn_error_t *
check_url_kind(void *baton,
               svn_node_kind_t *kind,
               const char *url,
               svn_revnum_t revision,
               apr_pool_t *scratch_pool)
{
  struct check_url_kind_baton *cukb = baton;

  /* If we don't have a session or can't use the session, get one */
  if (!svn_uri__is_ancestor(cukb->repos_root_url, url))
    *kind = svn_node_none;
  else
    {
      cukb->should_reparent = TRUE;

      SVN_ERR(svn_ra_reparent(cukb->session, url, scratch_pool));

      SVN_ERR(svn_ra_check_path(cukb->session, "", revision,
                                kind, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Queue a property change on a copy of LOCAL_ABSPATH to COMMIT_URL
 * in the COMMIT_ITEMS list.
 * If the list does not already have a commit item for COMMIT_URL
 * add a new commit item for the property change.
 * Allocate results in RESULT_POOL.
 * Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
queue_prop_change_commit_items(const char *local_abspath,
                               const char *commit_url,
                               apr_array_header_t *commit_items,
                               const char *propname,
                               svn_string_t *propval,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
{
  svn_client_commit_item3_t *item = NULL;
  svn_prop_t *prop;
  int i;

  for (i = 0; i < commit_items->nelts; i++)
    {
      svn_client_commit_item3_t *existing_item;

      existing_item = APR_ARRAY_IDX(commit_items, i,
                                    svn_client_commit_item3_t *);
      if (strcmp(existing_item->url, commit_url) == 0)
        {
          item = existing_item;
          break;
        }
    }

  if (item == NULL)
    {
      item = svn_client_commit_item3_create(result_pool);
      item->path = local_abspath;
      item->url = commit_url;
      item->kind = svn_node_dir;
      item->state_flags = SVN_CLIENT_COMMIT_ITEM_PROP_MODS;

      item->incoming_prop_changes = apr_array_make(result_pool, 1,
                                                   sizeof(svn_prop_t *));
      APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
    }
  else
    item->state_flags |= SVN_CLIENT_COMMIT_ITEM_PROP_MODS;

  if (item->outgoing_prop_changes == NULL)
    item->outgoing_prop_changes = apr_array_make(result_pool, 1,
                                                 sizeof(svn_prop_t *));

  prop = apr_palloc(result_pool, sizeof(*prop));
  prop->name = propname;
  prop->value = propval;
  APR_ARRAY_PUSH(item->outgoing_prop_changes, svn_prop_t *) = prop;

  return SVN_NO_ERROR;
}

/* ### Copy ...
 * COMMIT_INFO_P is ...
 * COPY_PAIRS is ... such that each 'src_abspath_or_url' is a local abspath
 * and each 'dst_abspath_or_url' is a URL.
 * MAKE_PARENTS is ...
 * REVPROP_TABLE is ...
 * CTX is ... */
static svn_error_t *
wc_to_repos_copy(const apr_array_header_t *copy_pairs,
                 svn_boolean_t make_parents,
                 const apr_hash_t *revprop_table,
                 svn_commit_callback2_t commit_callback,
                 void *commit_baton,
                 svn_boolean_t pin_externals,
                 const apr_hash_t *externals_to_pin,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *scratch_pool)
{
  const char *message;
  const char *top_src_path, *top_dst_url;
  struct check_url_kind_baton cukb;
  const char *top_src_abspath;
  svn_ra_session_t *ra_session;
  const svn_delta_editor_t *editor;
#ifdef ENABLE_EV2_SHIMS
  apr_hash_t *relpath_map = NULL;
#endif
  void *edit_baton;
  svn_client__committables_t *committables;
  apr_array_header_t *commit_items;
  apr_pool_t *iterpool;
  apr_array_header_t *new_dirs = NULL;
  apr_hash_t *commit_revprops;
  svn_client__copy_pair_t *first_pair;
  apr_pool_t *session_pool = svn_pool_create(scratch_pool);
  apr_array_header_t *commit_items_for_dav;
  int i;

  /* Find the common root of all the source paths */
  SVN_ERR(get_copy_pair_ancestors(copy_pairs, &top_src_path, NULL, NULL,
                                  scratch_pool));

  /* Do we need to lock the working copy?  1.6 didn't take a write
     lock, but what happens if the working copy changes during the copy
     operation? */

  iterpool = svn_pool_create(scratch_pool);

  /* Determine the longest common ancestor for the destinations, and open an RA
     session to that location. */
  /* ### But why start by getting the _parent_ of the first one? */
  /* --- That works because multiple destinations always point to the same
   *     directory. I'm rather wondering why we need to find a common
   *     destination parent here at all, instead of simply getting
   *     top_dst_url from get_copy_pair_ancestors() above?
   *     It looks like the entire block of code hanging off this comment
   *     is redundant. */
  first_pair = APR_ARRAY_IDX(copy_pairs, 0, svn_client__copy_pair_t *);
  top_dst_url = svn_uri_dirname(first_pair->dst_abspath_or_url, scratch_pool);
  for (i = 1; i < copy_pairs->nelts; i++)
    {
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      top_dst_url = svn_uri_get_longest_ancestor(top_dst_url,
                                                 pair->dst_abspath_or_url,
                                                 scratch_pool);
    }

  SVN_ERR(svn_dirent_get_absolute(&top_src_abspath, top_src_path, scratch_pool));

  commit_items_for_dav = apr_array_make(session_pool, 0,
                                        sizeof(svn_client_commit_item3_t*));

  /* Open a session to help while determining the exact targets */
  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, top_dst_url,
                                               top_src_abspath,
                                               commit_items_for_dav,
                                               FALSE /* write_dav_props */,
                                               TRUE /* read_dav_props */,
                                               ctx,
                                               session_pool, session_pool));

  /* If requested, determine the nearest existing parent of the destination,
     and reparent the ra session there. */
  if (make_parents)
    {
      new_dirs = apr_array_make(scratch_pool, 0, sizeof(const char *));
      SVN_ERR(find_absent_parents2(ra_session, &top_dst_url, new_dirs,
                                   scratch_pool));
    }

  /* Figure out the basename that will result from each copy and check to make
     sure it doesn't exist already. */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      svn_node_kind_t dst_kind;
      const char *dst_rel;
      svn_client__copy_pair_t *pair =
        APR_ARRAY_IDX(copy_pairs, i, svn_client__copy_pair_t *);

      svn_pool_clear(iterpool);
      dst_rel = svn_uri_skip_ancestor(top_dst_url, pair->dst_abspath_or_url,
                                      iterpool);
      SVN_ERR(svn_ra_check_path(ra_session, dst_rel, SVN_INVALID_REVNUM,
                                &dst_kind, iterpool));
      if (dst_kind != svn_node_none)
        {
          return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
                                   _("Path '%s' already exists"),
                                   pair->dst_abspath_or_url);
        }
    }

  cukb.session = ra_session;
  SVN_ERR(svn_ra_get_repos_root2(ra_session, &cukb.repos_root_url, session_pool));
  cukb.should_reparent = FALSE;

  /* Crawl the working copy for commit items. */
  /* ### TODO: Pass check_url_func for issue #3314 handling */
  SVN_ERR(svn_client__get_copy_committables(&committables,
                                            copy_pairs,
                                            check_url_kind, &cukb,
                                            ctx, scratch_pool, iterpool));

  /* The committables are keyed by the repository root */
  commit_items = svn_hash_gets(committables->by_repository,
                               cukb.repos_root_url);
  SVN_ERR_ASSERT(commit_items != NULL);

  if (cukb.should_reparent)
    SVN_ERR(svn_ra_reparent(ra_session, top_dst_url, session_pool));

  /* If we are creating intermediate directories, tack them onto the list
     of committables. */
  if (make_parents)
    {
      for (i = 0; i < new_dirs->nelts; i++)
        {
          const char *url = APR_ARRAY_IDX(new_dirs, i, const char *);
          svn_client_commit_item3_t *item;

          item = svn_client_commit_item3_create(scratch_pool);
          item->url = url;
          item->kind = svn_node_dir;
          item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;
          item->incoming_prop_changes = apr_array_make(scratch_pool, 1,
                                                       sizeof(svn_prop_t *));
          APR_ARRAY_PUSH(commit_items, svn_client_commit_item3_t *) = item;
        }
    }

  /* ### TODO: This extra loop would be unnecessary if this code lived
     ### in svn_client__get_copy_committables(), which is incidentally
     ### only used above (so should really be in this source file). */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      apr_hash_t *mergeinfo, *wc_mergeinfo;
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      svn_client_commit_item3_t *item =
        APR_ARRAY_IDX(commit_items, i, svn_client_commit_item3_t *);
      svn_client__pathrev_t *src_origin;

      svn_pool_clear(iterpool);

      SVN_ERR(svn_client__wc_node_get_origin(&src_origin,
                                             pair->src_abspath_or_url,
                                             ctx, iterpool, iterpool));

      /* Set the mergeinfo for the destination to the combined merge
         info known to the WC and the repository. */
      /* Repository mergeinfo (or NULL if it's locally added)... */
      if (src_origin)
        SVN_ERR(svn_client__get_repos_mergeinfo(
                  &mergeinfo, ra_session, src_origin->url, src_origin->rev,
                  svn_mergeinfo_inherited, TRUE /*sqelch_inc.*/, iterpool));
      else
        mergeinfo = NULL;
      /* ... and WC mergeinfo. */
      SVN_ERR(svn_client__parse_mergeinfo(&wc_mergeinfo, ctx->wc_ctx,
                                          pair->src_abspath_or_url,
                                          iterpool, iterpool));
      if (wc_mergeinfo && mergeinfo)
        SVN_ERR(svn_mergeinfo_merge2(mergeinfo, wc_mergeinfo, iterpool,
                                     iterpool));
      else if (! mergeinfo)
        mergeinfo = wc_mergeinfo;

      if (mergeinfo)
        {
          /* Push a mergeinfo prop representing MERGEINFO onto the
           * OUTGOING_PROP_CHANGES array. */

          svn_prop_t *mergeinfo_prop
                            = apr_palloc(scratch_pool, sizeof(*mergeinfo_prop));
          svn_string_t *prop_value;

          SVN_ERR(svn_mergeinfo_to_string(&prop_value, mergeinfo,
                                          scratch_pool));

          if (!item->outgoing_prop_changes)
            {
              item->outgoing_prop_changes = apr_array_make(scratch_pool, 1,
                                                           sizeof(svn_prop_t *));
            }

          mergeinfo_prop->name = SVN_PROP_MERGEINFO;
          mergeinfo_prop->value = prop_value;
          APR_ARRAY_PUSH(item->outgoing_prop_changes, svn_prop_t *)
            = mergeinfo_prop;
        }

      if (pin_externals)
        {
          apr_hash_t *pinned_externals;
          apr_hash_index_t *hi;

          SVN_ERR(resolve_pinned_externals(&pinned_externals,
                                           externals_to_pin, pair,
                                           ra_session, cukb.repos_root_url,
                                           ctx, scratch_pool, iterpool));
          for (hi = apr_hash_first(scratch_pool, pinned_externals);
               hi;
               hi = apr_hash_next(hi))
            {
              const char *dst_relpath = apr_hash_this_key(hi);
              svn_string_t *externals_propval = apr_hash_this_val(hi);
              const char *dst_url;
              const char *commit_url;
              const char *src_abspath;

              if (svn_path_is_url(pair->dst_abspath_or_url))
                dst_url = pair->dst_abspath_or_url;
              else
                SVN_ERR(svn_wc__node_get_url(&dst_url, ctx->wc_ctx,
                                             pair->dst_abspath_or_url,
                                             scratch_pool, iterpool));
              commit_url = svn_path_url_add_component2(dst_url, dst_relpath,
                                                       scratch_pool);
              src_abspath = svn_dirent_join(pair->src_abspath_or_url,
                                            dst_relpath, iterpool);
              SVN_ERR(queue_prop_change_commit_items(src_abspath,
                                                     commit_url, commit_items,
                                                     SVN_PROP_EXTERNALS,
                                                     externals_propval,
                                                     scratch_pool, iterpool));
            }
        }
    }

  if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
    {
      const char *tmp_file;

      SVN_ERR(svn_client__get_log_msg(&message, &tmp_file, commit_items,
                                      ctx, scratch_pool));
      if (! message)
        {
          svn_pool_destroy(iterpool);
          svn_pool_destroy(session_pool);
          return SVN_NO_ERROR;
        }
    }
  else
    message = "";

  /* Sort and condense our COMMIT_ITEMS. */
  SVN_ERR(svn_client__condense_commit_items(&top_dst_url,
                                            commit_items, scratch_pool));

  /* Add the commit items to the DAV commit item list to provide access
     to dav properties (for pre http-v2 DAV) */
  apr_array_cat(commit_items_for_dav, commit_items);

#ifdef ENABLE_EV2_SHIMS
  if (commit_items)
    {
      relpath_map = apr_hash_make(scratch_pool);
      for (i = 0; i < commit_items->nelts; i++)
        {
          svn_client_commit_item3_t *item = APR_ARRAY_IDX(commit_items, i,
                                                  svn_client_commit_item3_t *);
          const char *relpath;

          if (!item->path)
            continue;

          svn_pool_clear(iterpool);
          SVN_ERR(svn_wc__node_get_origin(NULL, NULL, &relpath, NULL, NULL,
                                          NULL, NULL,
                                          ctx->wc_ctx, item->path, FALSE,
                                          scratch_pool, iterpool));
          if (relpath)
            svn_hash_sets(relpath_map, relpath, item->path);
        }
    }
#endif

  SVN_ERR(svn_ra_reparent(ra_session, top_dst_url, session_pool));

  SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
                                           message, ctx, session_pool));

  /* Fetch RA commit editor. */
#ifdef ENABLE_EV2_SHIMS
  SVN_ERR(svn_ra__register_editor_shim_callbacks(ra_session,
                        svn_client__get_shim_callbacks(ctx->wc_ctx, relpath_map,
                                                       session_pool)));
#endif
  SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
                                    commit_revprops,
                                    commit_callback,
                                    commit_baton, NULL,
                                    TRUE, /* No lock tokens */
                                    session_pool));

  /* Perform the commit. */
  SVN_ERR_W(svn_client__do_commit(top_dst_url, commit_items,
                                  editor, edit_baton,
                                  NULL /* notify_path_prefix */,
                                  NULL, ctx, session_pool, session_pool),
            _("Commit failed (details follow):"));

  svn_pool_destroy(iterpool);
  svn_pool_destroy(session_pool);

  return SVN_NO_ERROR;
}

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

/* A svn_wc_notify_func2_t function that wraps BATON->inner_func (whose
 * baton is BATON->inner_baton) to turn the result of a 'checkout' into
 * what we want to see for a 'copy to WC' operation.
 *
 *  - Adjust the notification paths that start with BATON->checkout_abspath
 *    to start instead with BATON->final_abspath.
 *  - Change start-of-update notification into a plain WC 'add' for the root.
 *  - Change checkout 'add' notifications into a plain WC 'add'.
 *  - Discard 'update_completed' notifications.
 */
static void
notification_adjust_func(void *baton,
                         const svn_wc_notify_t *notify,
                         apr_pool_t *pool)
{
  struct notification_adjust_baton *nb = baton;
  svn_wc_notify_t *inner_notify = svn_wc_dup_notify(notify, pool);
  const char *relpath;

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

  /* Convert 'update' notifications to plain 'add' notifications; discard
     notifications about checkout/update starting/finishing. */
  if (notify->action == svn_wc_notify_update_started  /* root */
      || notify->action == svn_wc_notify_update_add)  /* non-root */
    {
      inner_notify->action = svn_wc_notify_add;
    }
  else if (notify->action == svn_wc_notify_update_update
           || notify->action == svn_wc_notify_update_completed)
    {
      /* update_update happens only for a prop mod on root; the root was
         already notified so discard this */
      return;
    }

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

/** Copy a directory tree from a remote repository.
 *
 * Copy from RA_SESSION:LOCATION to WC_CTX:DST_ABSPATH.
 *
 * Create the directory DST_ABSPATH, if not present. Its parent should be
 * already under version control in the WC and in a suitable state for
 * scheduling the addition of a child.
 *
 * Ignore any incoming non-regular properties (entry-props, DAV/WC-props).
 * Remove any incoming 'svn:mergeinfo' properties.
 */
static svn_error_t *
copy_foreign_dir(svn_ra_session_t *ra_session,
                 const svn_client__pathrev_t *location,
                 const char *dst_abspath,
                 svn_wc_notify_func2_t notify_func,
                 void *notify_baton,
                 svn_cancel_func_t cancel_func,
                 void *cancel_baton,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *scratch_pool)
{
  const svn_delta_editor_t *editor;
  void *eb;
  const svn_delta_editor_t *wrapped_editor;
  void *wrapped_baton;
  const svn_ra_reporter3_t *reporter;
  void *reporter_baton;

  /* Get a WC editor. It does not need an RA session because we will not
     be sending it any 'copy from' requests, only 'add' requests. */
  SVN_ERR(svn_client__wc_editor_internal(&editor, &eb,
                                         dst_abspath,
                                         TRUE /*root_dir_add*/,
                                         TRUE /*ignore_mergeinfo_changes*/,
                                         FALSE /*manage_wc_write_lock*/,
                                         notify_func, notify_baton,
                                         NULL /*ra_session*/,
                                         ctx, scratch_pool));

  SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton,
                                            editor, eb,
                                            &wrapped_editor, &wrapped_baton,
                                            scratch_pool));

  SVN_ERR(svn_ra_do_update3(ra_session, &reporter, &reporter_baton,
                            location->rev, "", svn_depth_infinity,
                            FALSE, FALSE, wrapped_editor, wrapped_baton,
                            scratch_pool, scratch_pool));

  SVN_ERR(reporter->set_path(reporter_baton, "", location->rev,
                             svn_depth_infinity /* irrelevant */,
                             TRUE /*start_empty*/,
                             NULL, scratch_pool));

  SVN_ERR(reporter->finish_report(reporter_baton, scratch_pool));

  return SVN_NO_ERROR;
}

/* Implementation of svn_client__repos_to_wc_copy() for a dir.
 */
static svn_error_t *
svn_client__repos_to_wc_copy_dir(svn_boolean_t *timestamp_sleep,
                                 const char *src_url,
                                 svn_revnum_t src_revnum,
                                 const char *dst_abspath,
                                 svn_boolean_t same_repositories,
                                 svn_ra_session_t *ra_session,
                                 svn_client_ctx_t *ctx,
                                 apr_pool_t *scratch_pool)
{
  const char *tmpdir_abspath, *tmp_abspath;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));

  if (!same_repositories)
    {
      svn_client__pathrev_t *location;

      *timestamp_sleep = TRUE;

      /* ### Reparenting "ra_session" can't be right, can it? As this is
             a foreign repo, surely we need a new RA session? */
      SVN_ERR(svn_client__pathrev_create_with_session(&location, ra_session,
                                                      src_revnum, src_url,
                                                      scratch_pool));
      SVN_ERR(svn_ra_reparent(ra_session, src_url, scratch_pool));
      SVN_ERR(copy_foreign_dir(ra_session, location,
                               dst_abspath,
                               ctx->notify_func2, ctx->notify_baton2,
                               ctx->cancel_func, ctx->cancel_baton,
                               ctx, scratch_pool));

      return SVN_NO_ERROR;
    }

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

  /* Get a temporary path. The crude way we do this is to create a
     temporary file, remember its name, and let it be deleted immediately. */
  SVN_ERR(svn_io_open_unique_file3(NULL, &tmp_abspath, tmpdir_abspath,
                                   svn_io_file_del_on_close,
                                   scratch_pool, scratch_pool));

  /* Make a new checkout of the requested source. While doing so,
   * resolve copy_src_revnum to an actual revision number in case it
   * was until now 'invalid' meaning 'head'.  Ask this function not to
   * sleep for timestamps, by passing a sleep_needed output param.
   * Send notifications for all nodes except the root node, and adjust
   * them to refer to the destination rather than this temporary path. */
  {
    svn_wc_notify_func2_t old_notify_func2 = ctx->notify_func2;
    void *old_notify_baton2 = ctx->notify_baton2;
    struct notification_adjust_baton nb;
    svn_error_t *err;
    svn_opt_revision_t copy_src_revision;

    copy_src_revision.kind = svn_opt_revision_number;
    copy_src_revision.value.number = src_revnum;

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

    err = svn_client__checkout_internal(NULL /*result_rev*/, timestamp_sleep,
                                        src_url,
                                        tmp_abspath,
                                        &copy_src_revision,
                                        &copy_src_revision,
                                        svn_depth_infinity,
                                        TRUE /*ignore_externals*/,
                                        FALSE, /* we don't allow obstructions */
                                        ra_session, ctx, scratch_pool);

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

    SVN_ERR(err);
  }

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

  /* Move the temporary disk tree into place. */
  SVN_ERR(svn_io_file_rename2(tmp_abspath, dst_abspath, FALSE, scratch_pool));

  return SVN_NO_ERROR;
}

/* Implementation of svn_client__repos_to_wc_copy() for a file.
 *
 * This has no 'ignore_externals' parameter because we don't support the
 * 'svn:externals' property being set on a file.
 */
static svn_error_t *
svn_client__repos_to_wc_copy_file(svn_boolean_t *timestamp_sleep,
                                  const char *src_url,
                                  svn_revnum_t src_rev,
                                  const char *dst_abspath,
                                  svn_boolean_t same_repositories,
                                  svn_ra_session_t *ra_session,
                                  svn_client_ctx_t *ctx,
                                  apr_pool_t *scratch_pool)
{
  const char *src_rel;
  apr_hash_t *new_props;
  svn_stream_t *new_base_contents = svn_stream_buffered(scratch_pool);

  SVN_ERR(svn_ra_get_path_relative_to_session(ra_session, &src_rel, src_url,
                                              scratch_pool));
  /* Fetch the file content. */
  SVN_ERR(svn_ra_get_file(ra_session, src_rel, src_rev,
                          new_base_contents, NULL, &new_props,
                          scratch_pool));
  if (!same_repositories)
    svn_hash_sets(new_props, SVN_PROP_MERGEINFO, NULL);

  *timestamp_sleep = TRUE;
  SVN_ERR(svn_wc_add_repos_file4(
            ctx->wc_ctx, dst_abspath,
            new_base_contents, NULL, new_props, NULL,
            same_repositories ? src_url : NULL,
            same_repositories ? src_rev : SVN_INVALID_REVNUM,
            ctx->cancel_func, ctx->cancel_baton,
            scratch_pool));
  /* Do our own notification for the root node, even if we could possibly
     have delegated it.  See also issue #2198. */
  if (ctx->notify_func2)
    {
      svn_wc_notify_t *notify
        = svn_wc_create_notify(dst_abspath, svn_wc_notify_add, scratch_pool);

      notify->kind = svn_node_file;
      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
    }
  return SVN_NO_ERROR;
}

/* Are RA_SESSION and the versioned *parent* dir of WC_TARGET_ABSPATH in
 * the same repository?
 */
static svn_error_t *
is_same_repository(svn_boolean_t *same_repository,
                   svn_ra_session_t *ra_session,
                   const char *wc_target_abspath,
                   svn_client_ctx_t *ctx,
                   apr_pool_t *scratch_pool)
{
  const char *src_uuid, *dst_uuid;

  /* Get the repository UUIDs of copy source URL and WC parent path */
  SVN_ERR(svn_ra_get_uuid2(ra_session, &src_uuid, scratch_pool));
  SVN_ERR(svn_client_get_repos_root(NULL /*root_url*/, &dst_uuid,
                                    svn_dirent_dirname(wc_target_abspath,
                                                       scratch_pool),
                                    ctx, scratch_pool, scratch_pool));
  *same_repository = (strcmp(src_uuid, dst_uuid) == 0);
  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__repos_to_wc_copy_internal(svn_boolean_t *timestamp_sleep,
                             svn_node_kind_t kind,
                             const char *src_url,
                             svn_revnum_t src_rev,
                             const char *dst_abspath,
                             svn_ra_session_t *ra_session,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *scratch_pool)
{
  const char *old_session_url;
  svn_boolean_t timestamp_sleep_ignored;
  svn_boolean_t same_repositories;

  SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ra_session,
                                            src_url, scratch_pool));

  SVN_ERR(is_same_repository(&same_repositories,
                             ra_session, dst_abspath, ctx, scratch_pool));

  if (!timestamp_sleep)
    timestamp_sleep = &timestamp_sleep_ignored;

  if (kind == svn_node_dir)
    {
      SVN_ERR(svn_client__repos_to_wc_copy_dir(timestamp_sleep,
                                               src_url, src_rev,
                                               dst_abspath,
                                               same_repositories,
                                               ra_session,
                                               ctx, scratch_pool));
    }
  else if (kind == svn_node_file)
    {
      SVN_ERR(svn_client__repos_to_wc_copy_file(timestamp_sleep,
                                                src_url, src_rev,
                                                dst_abspath,
                                                same_repositories,
                                                ra_session,
                                                ctx, scratch_pool));
    }

  /* Reparent the session back to the original URL. */
  SVN_ERR(svn_ra_reparent(ra_session, old_session_url, scratch_pool));
  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__repos_to_wc_copy_by_editor(svn_boolean_t *timestamp_sleep,
                svn_node_kind_t kind,
                const char *src_url,
                svn_revnum_t src_rev,
                const char *dst_abspath,
                svn_ra_session_t *ra_session,
                svn_client_ctx_t *ctx,
                apr_pool_t *scratch_pool)
{
  const svn_delta_editor_t *editor;
  void *eb;
  const char *src_anchor = svn_uri_dirname(src_url, scratch_pool);
  const char *dst_target = svn_dirent_basename(dst_abspath, scratch_pool);
  void *rb, *db;

  SVN_ERR(svn_ra_reparent(ra_session, src_anchor, scratch_pool));

  SVN_ERR(svn_client__wc_editor_internal(
            &editor, &eb,
            svn_dirent_dirname(dst_abspath, scratch_pool),
            FALSE /*root_dir_add*/,
            FALSE /*ignore_mergeinfo_changes*/,
            FALSE /*manage_wc_write_lock*/,
            ctx->notify_func2, ctx->notify_baton2,
            ra_session,
            ctx, scratch_pool));

  SVN_ERR(editor->open_root(eb, SVN_INVALID_REVNUM, scratch_pool, &rb));
  if (kind == svn_node_dir)
    {
      SVN_ERR(editor->add_directory(dst_target, rb,
                                    src_url, src_rev,
                                    scratch_pool,
                                    &db));
      SVN_ERR(editor->close_directory(db, scratch_pool));
    }
  else
    {
      SVN_ERR(editor->add_file(dst_target, rb,
                               src_url, src_rev,
                               scratch_pool,
                               &db));
      SVN_ERR(editor->close_file(db, NULL, scratch_pool));
    }
  SVN_ERR(editor->close_edit(eb, scratch_pool));

  if (timestamp_sleep)
    *timestamp_sleep = TRUE;
  return SVN_NO_ERROR;
}

/* Peform each individual copy operation for a repos -> wc copy.  A
   helper for repos_to_wc_copy().

   PAIR->src_revnum PAIR->src_abspath_or_url should already have been
   resolved to the operative revision number and operative URL.
 */
static svn_error_t *
repos_to_wc_copy_single(svn_boolean_t *timestamp_sleep,
                        const svn_client__copy_pair_t *pair,
                        svn_boolean_t ignore_externals,
                        svn_boolean_t pin_externals,
                        const apr_hash_t *externals_to_pin,
                        svn_ra_session_t *ra_session,
                        svn_client_ctx_t *ctx,
                        apr_pool_t *pool)
{
  apr_hash_t *src_mergeinfo;
  const char *dst_abspath = pair->dst_abspath_or_url;
  svn_boolean_t same_repositories;

  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(pair->src_revnum));
  SVN_ERR_ASSERT(svn_path_is_url(pair->src_abspath_or_url));
  SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));

  SVN_ERR(is_same_repository(&same_repositories,
                             ra_session, dst_abspath, ctx, pool));
  if (!same_repositories && ctx->notify_func2)
    {
      svn_wc_notify_t *notify;
      notify = svn_wc_create_notify_url(
                            pair->src_abspath_or_url,
                            svn_wc_notify_foreign_copy_begin,
                            pool);
      notify->kind = pair->src_kind;
      ctx->notify_func2(ctx->notify_baton2, notify, pool);

      /* Allow a theoretical cancel to get through. */
      if (ctx->cancel_func)
        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
    }

  SVN_ERR(svn_client__repos_to_wc_copy_by_editor(
            timestamp_sleep,
            pair->src_kind,
            pair->src_abspath_or_url,
            pair->src_revnum,
            dst_abspath,
            ra_session, ctx, pool));

  /* Fetch externals, pinning them if requested */
  if (!ignore_externals && pair->src_kind == svn_node_dir)
    {
      if (same_repositories)
        {
          const char *repos_root_url;
          apr_hash_t *new_externals;
          apr_hash_t *new_depths;

          SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url, pool));

          if (pin_externals)
            {
              apr_hash_t *pinned_externals;
              apr_hash_index_t *hi;
              apr_pool_t *iterpool;

              SVN_ERR(resolve_pinned_externals(&pinned_externals,
                                               externals_to_pin, pair,
                                               ra_session, repos_root_url,
                                               ctx, pool, pool));

              iterpool = svn_pool_create(pool);
              for (hi = apr_hash_first(pool, pinned_externals);
                   hi;
                   hi = apr_hash_next(hi))
                {
                  const char *dst_relpath = apr_hash_this_key(hi);
                  svn_string_t *externals_propval = apr_hash_this_val(hi);
                  const char *local_abspath;

                  svn_pool_clear(iterpool);

                  local_abspath = svn_dirent_join(pair->dst_abspath_or_url,
                                                  dst_relpath, iterpool);
                  /* ### use a work queue? */
                  SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, local_abspath,
                                           SVN_PROP_EXTERNALS, externals_propval,
                                           svn_depth_empty, TRUE /* skip_checks */,
                                           NULL  /* changelist_filter */,
                                           ctx->cancel_func, ctx->cancel_baton,
                                           NULL, NULL, /* no extra notification */
                                           iterpool));
                }
              svn_pool_destroy(iterpool);
            }

          /* Now update all externals in the newly created copy. */
          SVN_ERR(svn_wc__externals_gather_definitions(&new_externals,
                                                       &new_depths,
                                                       ctx->wc_ctx,
                                                       dst_abspath,
                                                       svn_depth_infinity,
                                                       pool, pool));
          SVN_ERR(svn_client__handle_externals(new_externals,
                                               new_depths,
                                               repos_root_url, dst_abspath,
                                               svn_depth_infinity,
                                               timestamp_sleep,
                                               ra_session,
                                               ctx, pool));
        }
    }

  if (same_repositories)
    {
      /* Record the implied mergeinfo. */
      SVN_ERR(svn_client__get_repos_mergeinfo(&src_mergeinfo, ra_session,
                                              pair->src_abspath_or_url,
                                              pair->src_revnum,
                                              svn_mergeinfo_inherited,
                                              TRUE /*squelch_incapable*/,
                                              pool));
      SVN_ERR(extend_wc_mergeinfo(dst_abspath, src_mergeinfo, ctx, pool));

      /* ### Maybe the notification should mention this mergeinfo change. */
      /* ### Maybe we should do this during rather than after the copy. */
    }

  return SVN_NO_ERROR;
}

static svn_error_t *
repos_to_wc_copy_locked(svn_boolean_t *timestamp_sleep,
                        const apr_array_header_t *copy_pairs,
                        const char *top_dst_abspath,
                        svn_boolean_t ignore_externals,
                        svn_boolean_t pin_externals,
                        const apr_hash_t *externals_to_pin,
                        svn_ra_session_t *ra_session,
                        svn_client_ctx_t *ctx,
                        apr_pool_t *scratch_pool)
{
  int i;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);

  /* Perform the move for each of the copy_pairs. */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      /* Check for cancellation */
      if (ctx->cancel_func)
        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));

      svn_pool_clear(iterpool);

      SVN_ERR(repos_to_wc_copy_single(timestamp_sleep,
                                      APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *),
                                      ignore_externals,
                                      pin_externals, externals_to_pin,
                                      ra_session, ctx, iterpool));
    }
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

static svn_error_t *
repos_to_wc_copy(svn_boolean_t *timestamp_sleep,
                 const apr_array_header_t *copy_pairs,
                 svn_boolean_t ignore_externals,
                 svn_boolean_t pin_externals,
                 const apr_hash_t *externals_to_pin,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *pool)
{
  svn_ra_session_t *ra_session;
  const char *top_src_url, *top_dst_abspath;
  apr_pool_t *iterpool = svn_pool_create(pool);
  const char *lock_abspath;
  int i;

  /* Get the real path for the source, based upon its peg revision. */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      const char *src;

      svn_pool_clear(iterpool);

      SVN_ERR(svn_client__repos_locations(&src, &pair->src_revnum, NULL, NULL,
                                          NULL,
                                          pair->src_abspath_or_url,
                                          &pair->src_peg_revision,
                                          &pair->src_op_revision, NULL,
                                          ctx, iterpool));

      pair->src_original = pair->src_abspath_or_url;
      pair->src_abspath_or_url = apr_pstrdup(pool, src);
    }

  SVN_ERR(get_copy_pair_ancestors(copy_pairs, &top_src_url, &top_dst_abspath,
                                  NULL, pool));
  lock_abspath = top_dst_abspath;
  if (copy_pairs->nelts == 1)
    {
      top_src_url = svn_uri_dirname(top_src_url, pool);
      lock_abspath = svn_dirent_dirname(top_dst_abspath, pool);
    }

  /* Open a repository session to the longest common src ancestor.  We do not
     (yet) have a working copy, so we don't have a corresponding path and
     tempfiles cannot go into the admin area. */
  SVN_ERR(svn_client_open_ra_session2(&ra_session, top_src_url, lock_abspath,
                                      ctx, pool, pool));

  /* Get the correct src path for the peg revision used, and verify that we
     aren't overwriting an existing path. */
  for (i = 0; i < copy_pairs->nelts; i++)
    {
      svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);
      const char *src_rel;

      svn_pool_clear(iterpool);

      /* Next, make sure that the path exists in the repository. */
      SVN_ERR(svn_ra_get_path_relative_to_session(ra_session, &src_rel,
                                                  pair->src_abspath_or_url,
                                                  iterpool));
      SVN_ERR(svn_ra_check_path(ra_session, src_rel, pair->src_revnum,
                                &pair->src_kind, pool));
      if (pair->src_kind == svn_node_none)
        {
          if (SVN_IS_VALID_REVNUM(pair->src_revnum))
            return svn_error_createf
              (SVN_ERR_FS_NOT_FOUND, NULL,
               _("Path '%s' not found in revision %ld"),
               pair->src_abspath_or_url, pair->src_revnum);
          else
            return svn_error_createf
              (SVN_ERR_FS_NOT_FOUND, NULL,
               _("Path '%s' not found in head revision"),
               pair->src_abspath_or_url);
        }
    }
  svn_pool_destroy(iterpool);

  SVN_WC__CALL_WITH_WRITE_LOCK(
    repos_to_wc_copy_locked(timestamp_sleep,
                            copy_pairs, top_dst_abspath, ignore_externals,
                            pin_externals, externals_to_pin,
                            ra_session, ctx, pool),
    ctx->wc_ctx, lock_abspath, FALSE, pool);
  return SVN_NO_ERROR;
}

#define NEED_REPOS_REVNUM(revision) \
        ((revision.kind != svn_opt_revision_unspecified) \
          && (revision.kind != svn_opt_revision_working))

/* ...
 *
 * Set *TIMESTAMP_SLEEP to TRUE if a sleep is required; otherwise do not
 * change *TIMESTAMP_SLEEP.  This output will be valid even if the
 * function returns an error.
 *
 * Perform all allocations in POOL.
 */
static svn_error_t *
try_copy(svn_boolean_t *timestamp_sleep,
         const apr_array_header_t *sources,
         const char *dst_path_in,
         svn_boolean_t is_move,
         svn_boolean_t allow_mixed_revisions,
         svn_boolean_t metadata_only,
         svn_boolean_t make_parents,
         svn_boolean_t ignore_externals,
         svn_boolean_t pin_externals,
         const apr_hash_t *externals_to_pin,
         const apr_hash_t *revprop_table,
         svn_commit_callback2_t commit_callback,
         void *commit_baton,
         svn_client_ctx_t *ctx,
         apr_pool_t *pool)
{
  apr_array_header_t *copy_pairs =
                        apr_array_make(pool, sources->nelts,
                                       sizeof(svn_client__copy_pair_t *));
  svn_boolean_t srcs_are_urls, dst_is_url;
  int i;

  /* Assert instead of crashing if the sources list is empty. */
  SVN_ERR_ASSERT(sources->nelts > 0);

  /* Are either of our paths URLs?  Just check the first src_path.  If
     there are more than one, we'll check for homogeneity among them
     down below. */
  srcs_are_urls = svn_path_is_url(APR_ARRAY_IDX(sources, 0,
                                  svn_client_copy_source_t *)->path);
  dst_is_url = svn_path_is_url(dst_path_in);
  if (!dst_is_url)
    SVN_ERR(svn_dirent_get_absolute(&dst_path_in, dst_path_in, pool));

  /* If we have multiple source paths, it implies the dst_path is a
     directory we are moving or copying into.  Populate the COPY_PAIRS
     array to contain a destination path for each of the source paths. */
  if (sources->nelts > 1)
    {
      apr_pool_t *iterpool = svn_pool_create(pool);

      for (i = 0; i < sources->nelts; i++)
        {
          svn_client_copy_source_t *source = APR_ARRAY_IDX(sources, i,
                                               svn_client_copy_source_t *);
          svn_client__copy_pair_t *pair = apr_pcalloc(pool, sizeof(*pair));
          const char *src_basename;
          svn_boolean_t src_is_url = svn_path_is_url(source->path);

          svn_pool_clear(iterpool);

          if (src_is_url)
            {
              pair->src_abspath_or_url = apr_pstrdup(pool, source->path);
              src_basename = svn_uri_basename(pair->src_abspath_or_url,
                                              iterpool);
            }
          else
            {
              SVN_ERR(svn_dirent_get_absolute(&pair->src_abspath_or_url,
                                              source->path, pool));
              src_basename = svn_dirent_basename(pair->src_abspath_or_url,
                                                 iterpool);
            }

          pair->src_op_revision = *source->revision;
          pair->src_peg_revision = *source->peg_revision;
          pair->src_kind = svn_node_unknown;

          SVN_ERR(svn_opt_resolve_revisions(&pair->src_peg_revision,
                                            &pair->src_op_revision,
                                            src_is_url,
                                            TRUE,
                                            iterpool));

          /* Check to see if all the sources are urls or all working copy
           * paths. */
          if (src_is_url != srcs_are_urls)
            return svn_error_create
              (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
               _("Cannot mix repository and working copy sources"));

          if (dst_is_url)
            pair->dst_abspath_or_url =
              svn_path_url_add_component2(dst_path_in, src_basename, pool);
          else
            pair->dst_abspath_or_url = svn_dirent_join(dst_path_in,
                                                       src_basename, pool);
          APR_ARRAY_PUSH(copy_pairs, svn_client__copy_pair_t *) = pair;
        }

      svn_pool_destroy(iterpool);
    }
  else
    {
      /* Only one source path. */
      svn_client__copy_pair_t *pair = apr_pcalloc(pool, sizeof(*pair));
      svn_client_copy_source_t *source =
        APR_ARRAY_IDX(sources, 0, svn_client_copy_source_t *);
      svn_boolean_t src_is_url = svn_path_is_url(source->path);

      if (src_is_url)
        pair->src_abspath_or_url = apr_pstrdup(pool, source->path);
      else
        SVN_ERR(svn_dirent_get_absolute(&pair->src_abspath_or_url,
                                        source->path, pool));
      pair->src_op_revision = *source->revision;
      pair->src_peg_revision = *source->peg_revision;
      pair->src_kind = svn_node_unknown;

      SVN_ERR(svn_opt_resolve_revisions(&pair->src_peg_revision,
                                        &pair->src_op_revision,
                                        src_is_url, TRUE, pool));

      pair->dst_abspath_or_url = dst_path_in;
      APR_ARRAY_PUSH(copy_pairs, svn_client__copy_pair_t *) = pair;
    }

  if (!srcs_are_urls && !dst_is_url)
    {
      apr_pool_t *iterpool = svn_pool_create(pool);

      for (i = 0; i < copy_pairs->nelts; i++)
        {
          svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                            svn_client__copy_pair_t *);

          svn_pool_clear(iterpool);

          if (svn_dirent_is_child(pair->src_abspath_or_url,
                                  pair->dst_abspath_or_url, iterpool))
            return svn_error_createf
              (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
               _("Cannot copy path '%s' into its own child '%s'"),
               svn_dirent_local_style(pair->src_abspath_or_url, pool),
               svn_dirent_local_style(pair->dst_abspath_or_url, pool));
        }

      svn_pool_destroy(iterpool);
    }

  /* A file external should not be moved since the file external is
     implemented as a switched file and it would delete the file the
     file external is switched to, which is not the behavior the user
     would probably want. */
  if (is_move && !srcs_are_urls)
    {
      apr_pool_t *iterpool = svn_pool_create(pool);

      for (i = 0; i < copy_pairs->nelts; i++)
        {
          svn_client__copy_pair_t *pair =
            APR_ARRAY_IDX(copy_pairs, i, svn_client__copy_pair_t *);
          svn_node_kind_t external_kind;
          const char *defining_abspath;

          svn_pool_clear(iterpool);

          SVN_ERR_ASSERT(svn_dirent_is_absolute(pair->src_abspath_or_url));
          SVN_ERR(svn_wc__read_external_info(&external_kind, &defining_abspath,
                                             NULL, NULL, NULL, ctx->wc_ctx,
                                             pair->src_abspath_or_url,
                                             pair->src_abspath_or_url, TRUE,
                                             iterpool, iterpool));

          if (external_kind != svn_node_none)
            return svn_error_createf(
                     SVN_ERR_WC_CANNOT_MOVE_FILE_EXTERNAL,
                     NULL,
                     _("Cannot move the external at '%s'; please "
                       "edit the svn:externals property on '%s'."),
                     svn_dirent_local_style(pair->src_abspath_or_url, pool),
                     svn_dirent_local_style(defining_abspath, pool));
        }
      svn_pool_destroy(iterpool);
    }

  if (is_move)
    {
      /* Disallow moves between the working copy and the repository. */
      if (srcs_are_urls != dst_is_url)
        {
          return svn_error_create
            (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
             _("Moves between the working copy and the repository are not "
               "supported"));
        }

      /* Disallow moving any path/URL onto or into itself. */
      for (i = 0; i < copy_pairs->nelts; i++)
        {
          svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                            svn_client__copy_pair_t *);

          if (strcmp(pair->src_abspath_or_url,
                     pair->dst_abspath_or_url) == 0)
            return svn_error_createf(
              SVN_ERR_UNSUPPORTED_FEATURE, NULL,
              srcs_are_urls ?
                _("Cannot move URL '%s' into itself") :
                _("Cannot move path '%s' into itself"),
              srcs_are_urls ?
                pair->src_abspath_or_url :
                svn_dirent_local_style(pair->src_abspath_or_url, pool));
        }
    }
  else
    {
      if (!srcs_are_urls)
        {
          /* If we are doing a wc->* copy, but with an operational revision
             other than the working copy revision, we are really doing a
             repo->* copy, because we're going to need to get the rev from the
             repo. */

          svn_boolean_t need_repos_op_rev = FALSE;
          svn_boolean_t need_repos_peg_rev = FALSE;

          /* Check to see if any revision is something other than
             svn_opt_revision_unspecified or svn_opt_revision_working. */
          for (i = 0; i < copy_pairs->nelts; i++)
            {
              svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                svn_client__copy_pair_t *);

              if (NEED_REPOS_REVNUM(pair->src_op_revision))
                need_repos_op_rev = TRUE;

              if (NEED_REPOS_REVNUM(pair->src_peg_revision))
                need_repos_peg_rev = TRUE;

              if (need_repos_op_rev || need_repos_peg_rev)
                break;
            }

          if (need_repos_op_rev || need_repos_peg_rev)
            {
              apr_pool_t *iterpool = svn_pool_create(pool);

              for (i = 0; i < copy_pairs->nelts; i++)
                {
                  const char *copyfrom_repos_root_url;
                  const char *copyfrom_repos_relpath;
                  const char *url;
                  svn_revnum_t copyfrom_rev;
                  svn_client__copy_pair_t *pair = APR_ARRAY_IDX(copy_pairs, i,
                                                    svn_client__copy_pair_t *);

                  svn_pool_clear(iterpool);

                  SVN_ERR_ASSERT(svn_dirent_is_absolute(pair->src_abspath_or_url));

                  SVN_ERR(svn_wc__node_get_origin(NULL, &copyfrom_rev,
                                                  &copyfrom_repos_relpath,
                                                  &copyfrom_repos_root_url,
                                                  NULL, NULL, NULL,
                                                  ctx->wc_ctx,
                                                  pair->src_abspath_or_url,
                                                  TRUE, iterpool, iterpool));

                  if (copyfrom_repos_relpath)
                    url = svn_path_url_add_component2(copyfrom_repos_root_url,
                                                      copyfrom_repos_relpath,
                                                      pool);
                  else
                    return svn_error_createf
                      (SVN_ERR_ENTRY_MISSING_URL, NULL,
                       _("'%s' does not have a URL associated with it"),
                       svn_dirent_local_style(pair->src_abspath_or_url, pool));

                  pair->src_abspath_or_url = url;

                  if (!need_repos_peg_rev
                      || pair->src_peg_revision.kind == svn_opt_revision_base)
                    {
                      /* Default the peg revision to that of the WC entry. */
                      pair->src_peg_revision.kind = svn_opt_revision_number;
                      pair->src_peg_revision.value.number = copyfrom_rev;
                    }

                  if (pair->src_op_revision.kind == svn_opt_revision_base)
                    {
                      /* Use the entry's revision as the operational rev. */
                      pair->src_op_revision.kind = svn_opt_revision_number;
                      pair->src_op_revision.value.number = copyfrom_rev;
                    }
                }

              svn_pool_destroy(iterpool);
              srcs_are_urls = TRUE;
            }
        }
    }

  /* Now, call the right handler for the operation. */
  if ((! srcs_are_urls) && (! dst_is_url))
    {
      SVN_ERR(verify_wc_srcs(copy_pairs, ctx, pool));
      SVN_ERR(verify_wc_dsts(copy_pairs, make_parents, is_move, metadata_only,
                             ctx, pool, pool));

      /* Copy or move all targets. */
      if (is_move)
        return svn_error_trace(do_wc_to_wc_moves(timestamp_sleep,
                                                 copy_pairs, dst_path_in,
                                                 allow_mixed_revisions,
                                                 metadata_only,
                                                 ctx, pool));
      else
        {
          /* We ignore these values, so assert the default value */
          SVN_ERR_ASSERT(allow_mixed_revisions);
          return svn_error_trace(do_wc_to_wc_copies(timestamp_sleep,
                                                    copy_pairs,
                                                    metadata_only,
                                                    pin_externals,
                                                    externals_to_pin,
                                                    ctx, pool));
        }
    }
  else if ((! srcs_are_urls) && (dst_is_url))
    {
      return svn_error_trace(
        wc_to_repos_copy(copy_pairs, make_parents, revprop_table,
                         commit_callback, commit_baton,
                         pin_externals, externals_to_pin, ctx, pool));
    }
  else if ((srcs_are_urls) && (! dst_is_url))
    {
      SVN_ERR(verify_wc_dsts(copy_pairs, make_parents,
                             FALSE, FALSE /* metadata_only */,
                             ctx, pool, pool));

      return svn_error_trace(
        repos_to_wc_copy(timestamp_sleep,
                         copy_pairs, ignore_externals,
                         pin_externals, externals_to_pin, ctx, pool));
    }
  else
    {
      return svn_error_trace(
        repos_to_repos_copy(copy_pairs, make_parents, revprop_table,
                            commit_callback, commit_baton, ctx, is_move,
                            pin_externals, externals_to_pin, pool));
    }
}



/* Public Interfaces */
svn_error_t *
svn_client_copy7(const apr_array_header_t *sources,
                 const char *dst_path,
                 svn_boolean_t copy_as_child,
                 svn_boolean_t make_parents,
                 svn_boolean_t ignore_externals,
                 svn_boolean_t metadata_only,
                 svn_boolean_t pin_externals,
                 const apr_hash_t *externals_to_pin,
                 const apr_hash_t *revprop_table,
                 svn_commit_callback2_t commit_callback,
                 void *commit_baton,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *pool)
{
  svn_error_t *err;
  svn_boolean_t timestamp_sleep = FALSE;
  apr_pool_t *subpool = svn_pool_create(pool);

  if (sources->nelts > 1 && !copy_as_child)
    return svn_error_create(SVN_ERR_CLIENT_MULTIPLE_SOURCES_DISALLOWED,
                            NULL, NULL);

  err = try_copy(&timestamp_sleep,
                 sources, dst_path,
                 FALSE /* is_move */,
                 TRUE /* allow_mixed_revisions */,
                 metadata_only,
                 make_parents,
                 ignore_externals,
                 pin_externals,
                 externals_to_pin,
                 revprop_table,
                 commit_callback, commit_baton,
                 ctx,
                 subpool);

  /* If the destination exists, try to copy the sources as children of the
     destination. */
  if (copy_as_child && err && (sources->nelts == 1)
        && (err->apr_err == SVN_ERR_ENTRY_EXISTS
            || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
    {
      const char *src_path = APR_ARRAY_IDX(sources, 0,
                                           svn_client_copy_source_t *)->path;
      const char *src_basename;
      svn_boolean_t src_is_url = svn_path_is_url(src_path);
      svn_boolean_t dst_is_url = svn_path_is_url(dst_path);

      svn_error_clear(err);
      svn_pool_clear(subpool);

      src_basename = src_is_url ? svn_uri_basename(src_path, subpool)
                                : svn_dirent_basename(src_path, subpool);
      dst_path
        = dst_is_url ? svn_path_url_add_component2(dst_path, src_basename,
                                                   subpool)
                     : svn_dirent_join(dst_path, src_basename, subpool);

      err = try_copy(&timestamp_sleep,
                     sources, dst_path,
                     FALSE /* is_move */,
                     TRUE /* allow_mixed_revisions */,
                     metadata_only,
                     make_parents,
                     ignore_externals,
                     pin_externals,
                     externals_to_pin,
                     revprop_table,
                     commit_callback, commit_baton,
                     ctx,
                     subpool);
    }

  /* Sleep if required.  DST_PATH is not a URL in these cases. */
  if (timestamp_sleep)
    svn_io_sleep_for_timestamps(dst_path, subpool);

  svn_pool_destroy(subpool);
  return svn_error_trace(err);
}


svn_error_t *
svn_client_move7(const apr_array_header_t *src_paths,
                 const char *dst_path,
                 svn_boolean_t move_as_child,
                 svn_boolean_t make_parents,
                 svn_boolean_t allow_mixed_revisions,
                 svn_boolean_t metadata_only,
                 const apr_hash_t *revprop_table,
                 svn_commit_callback2_t commit_callback,
                 void *commit_baton,
                 svn_client_ctx_t *ctx,
                 apr_pool_t *pool)
{
  const svn_opt_revision_t head_revision
    = { svn_opt_revision_head, { 0 } };
  svn_error_t *err;
  svn_boolean_t timestamp_sleep = FALSE;
  int i;
  apr_pool_t *subpool = svn_pool_create(pool);
  apr_array_header_t *sources = apr_array_make(pool, src_paths->nelts,
                                  sizeof(const svn_client_copy_source_t *));

  if (src_paths->nelts > 1 && !move_as_child)
    return svn_error_create(SVN_ERR_CLIENT_MULTIPLE_SOURCES_DISALLOWED,
                            NULL, NULL);

  for (i = 0; i < src_paths->nelts; i++)
    {
      const char *src_path = APR_ARRAY_IDX(src_paths, i, const char *);
      svn_client_copy_source_t *copy_source = apr_palloc(pool,
                                                         sizeof(*copy_source));

      copy_source->path = src_path;
      copy_source->revision = &head_revision;
      copy_source->peg_revision = &head_revision;

      APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = copy_source;
    }

  err = try_copy(&timestamp_sleep,
                 sources, dst_path,
                 TRUE /* is_move */,
                 allow_mixed_revisions,
                 metadata_only,
                 make_parents,
                 FALSE /* ignore_externals */,
                 FALSE /* pin_externals */,
                 NULL /* externals_to_pin */,
                 revprop_table,
                 commit_callback, commit_baton,
                 ctx,
                 subpool);

  /* If the destination exists, try to move the sources as children of the
     destination. */
  if (move_as_child && err && (src_paths->nelts == 1)
        && (err->apr_err == SVN_ERR_ENTRY_EXISTS
            || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS))
    {
      const char *src_path = APR_ARRAY_IDX(src_paths, 0, const char *);
      const char *src_basename;
      svn_boolean_t src_is_url = svn_path_is_url(src_path);
      svn_boolean_t dst_is_url = svn_path_is_url(dst_path);

      svn_error_clear(err);
      svn_pool_clear(subpool);

      src_basename = src_is_url ? svn_uri_basename(src_path, pool)
                                : svn_dirent_basename(src_path, pool);
      dst_path
        = dst_is_url ? svn_path_url_add_component2(dst_path, src_basename,
                                                   subpool)
                     : svn_dirent_join(dst_path, src_basename, subpool);

      err = try_copy(&timestamp_sleep,
                     sources, dst_path,
                     TRUE /* is_move */,
                     allow_mixed_revisions,
                     metadata_only,
                     make_parents,
                     FALSE /* ignore_externals */,
                     FALSE /* pin_externals */,
                     NULL /* externals_to_pin */,
                     revprop_table,
                     commit_callback, commit_baton,
                     ctx,
                     subpool);
    }

  /* Sleep if required.  DST_PATH is not a URL in these cases. */
  if (timestamp_sleep)
    svn_io_sleep_for_timestamps(dst_path, subpool);

  svn_pool_destroy(subpool);
  return svn_error_trace(err);
}
