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

#include "svn_types.h"
#include "svn_error.h"
#include "svn_delta.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_hash.h"
#include "svn_iter.h"
#include "svn_props.h"
#include "svn_pools.h"

#include "private/svn_branch_impl.h"
#include "private/svn_branch_repos.h"
#include "private/svn_branch_nested.h"
#include "private/svn_delta_private.h"
#include "private/svn_branch_compat.h"

#include "svn_private_config.h"


/* Verify EXPR is true; raise an error if not. */
#define VERIFY(expr) SVN_ERR_ASSERT(expr)


/*
 * ===================================================================
 * Minor data types
 * ===================================================================
 */

/** A location in a committed revision.
 *
 * @a rev shall not be #SVN_INVALID_REVNUM unless the interface using this
 * type specifically allows it and defines its meaning. */
typedef struct svn_pathrev_t
{
  svn_revnum_t rev;
  const char *relpath;
} svn_pathrev_t;

/* Return true iff PEG_PATH1 and PEG_PATH2 are both the same location.
 */
static svn_boolean_t
pathrev_equal(const svn_pathrev_t *p1,
              const svn_pathrev_t *p2)
{
  if (p1->rev != p2->rev)
    return FALSE;
  if (strcmp(p1->relpath, p2->relpath) != 0)
    return FALSE;

  return TRUE;
}

#if 0
/* Return a human-readable string representation of LOC. */
static const char *
pathrev_str(const svn_pathrev_t *loc,
            apr_pool_t *result_pool)
{
  if (! loc)
    return "<nil>";
  return apr_psprintf(result_pool, "%s@%ld",
                      loc->relpath, loc->rev);
}

/* Return a string representation of the (string) keys of HASH. */
static const char *
hash_keys_str(apr_hash_t *hash)
{
  const char *str = NULL;
  apr_pool_t *pool;
  apr_hash_index_t *hi;

  if (! hash)
    return "<nil>";

  pool = apr_hash_pool_get(hash);
  for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
    {
      const char *key = apr_hash_this_key(hi);

      if (!str)
        str = key;
      else
        str = apr_psprintf(pool, "%s, %s", str, key);
    }
  return apr_psprintf(pool, "{%s}", str);
}
#endif

/**
 * Merge two hash tables into one new hash table. The values of the overlay
 * hash override the values of the base if both have the same key.
 *
 * Unlike apr_hash_overlay(), this doesn't care whether the input hashes use
 * the same hash function, nor about the relationship between the three pools.
 *
 * @param p The pool to use for the new hash table
 * @param overlay The table to add to the initial table
 * @param base The table that represents the initial values of the new table
 * @return A new hash table containing all of the data from the two passed in
 * @remark Makes a shallow copy: keys and values are not copied
 */
static apr_hash_t *
hash_overlay(apr_hash_t *overlay,
             apr_hash_t *base)
{
  apr_pool_t *pool = apr_hash_pool_get(base);
  apr_hash_t *result = apr_hash_copy(pool, base);
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(pool, overlay); hi; hi = apr_hash_next(hi))
    {
      svn_hash_sets(result, apr_hash_this_key(hi), apr_hash_this_val(hi));
    }
  return result;
}


/*
 * ========================================================================
 * Configuration Options
 * ========================================================================
 */

/* Features that are not wanted for this commit editor shim but may be
 * wanted in a similar but different shim such as for an update editor. */
/* #define SHIM_WITH_ADD_ABSENT */
/* #define SHIM_WITH_UNLOCK */

/* Whether to support switching from relative to absolute paths in the
 * Ev1 methods. */
/* #define SHIM_WITH_ABS_PATHS */


/*
 * ========================================================================
 * Shim Connector
 * ========================================================================
 *
 * The shim connector enables a more exact round-trip conversion from an
 * Ev1 drive to Ev3 and back to Ev1.
 */
struct svn_branch__compat_shim_connector_t
{
  /* Set to true if and when an Ev1 receiving shim receives an absolute
   * path (prefixed with '/') from the delta edit, and causes the Ev1
   * sending shim to send absolute paths.
   * ### NOT IMPLEMENTED
   */
#ifdef SHIM_WITH_ABS_PATHS
  svn_boolean_t *ev1_absolute_paths;
#endif

  /* The Ev1 set_target_revision and start_edit methods, respectively, will
   * call the TARGET_REVISION_FUNC and START_EDIT_FUNC callbacks, if non-null.
   * Otherwise, default calls will be used.
   *
   * (Possibly more useful for update editors than for commit editors?) */
  svn_branch__compat_set_target_revision_func_t target_revision_func;

  /* If not null, a callback that the Ev3 driver may call to
   * provide the "base revision" of the root directory, even if it is not
   * going to modify that directory. (If it does modify it, then it will
   * pass in the appropriate base revision at that time.) If null
   * or if the driver does not call it, then the Ev1
   * open_root() method will be called with SVN_INVALID_REVNUM as the base
   * revision parameter.
   */
  svn_delta__start_edit_func_t start_edit_func;

#ifdef SHIM_WITH_UNLOCK
  /* A callback which will be called when an unlocking action is received.
     (For update editors?) */
  svn_delta__unlock_func_t unlock_func;
#endif

  void *baton;
};

svn_error_t *
svn_branch__compat_insert_shims(
                        const svn_delta_editor_t **new_deditor,
                        void **new_dedit_baton,
                        const svn_delta_editor_t *old_deditor,
                        void *old_dedit_baton,
                        const char *repos_root,
                        const char *base_relpath,
                        svn_branch__compat_fetch_func_t fetch_func,
                        void *fetch_baton,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
#if 0
  svn_branch__txn_t *edit_txn;
  svn_branch__compat_shim_connector_t *shim_connector;

#ifdef SVN_DEBUG
  /*SVN_ERR(svn_delta__get_debug_editor(&old_deditor, &old_dedit_baton,
                                      old_deditor, old_dedit_baton,
                                      "[OUT] ", result_pool));*/
#endif
  SVN_ERR(svn_branch__compat_txn_from_delta_for_commit(
                        &edit_txn,
                        &shim_connector,
                        old_deditor, old_dedit_baton,
                        branching_txn,
                        repos_root,
                        fetch_func, fetch_baton,
                        NULL, NULL /*cancel*/,
                        result_pool, scratch_pool));
  SVN_ERR(svn_branch__compat_delta_from_txn_for_commit(
                        new_deditor, new_dedit_baton,
                        edit_txn,
                        repos_root, base_relpath,
                        fetch_func, fetch_baton,
                        shim_connector,
                        result_pool, scratch_pool));
#ifdef SVN_DEBUG
  /*SVN_ERR(svn_delta__get_debug_editor(new_deditor, new_dedit_baton,
                                      *new_deditor, *new_dedit_baton,
                                      "[IN]  ", result_pool));*/
#endif
#else
  *new_deditor = old_deditor;
  *new_dedit_baton = old_dedit_baton;
#endif
  return SVN_NO_ERROR;
}


/*
 * ========================================================================
 * Buffering the Delta Editor Changes
 * ========================================================================
 */

/* The kind of Ev1 restructuring operation on a particular path. For each
 * visited path we use exactly one restructuring action. */
enum restructure_action_t
{
  RESTRUCTURE_NONE = 0,
  RESTRUCTURE_ADD,         /* add the node, maybe replacing. maybe copy  */
#ifdef SHIM_WITH_ADD_ABSENT
  RESTRUCTURE_ADD_ABSENT,  /* add an absent node, possibly replacing  */
#endif
  RESTRUCTURE_DELETE       /* delete this node  */
};

/* Records everything about how this node is to be changed, from an Ev1
 * point of view.  */
typedef struct change_node_t
{
  /* what kind of (tree) restructure is occurring at this node?  */
  enum restructure_action_t action;

  svn_node_kind_t kind;  /* the NEW kind of this node  */

  /* We may need to specify the revision we are altering or the revision
     to delete or replace. These are mutually exclusive, but are separate
     for clarity. */
  /* CHANGING_REV is the base revision of the change if ACTION is 'none',
     else is SVN_INVALID_REVNUM. (If ACTION is 'add' and COPYFROM_PATH
     is non-null, then COPYFROM_REV serves the equivalent purpose for the
     copied node.) */
  /* ### Can also be SVN_INVALID_REVNUM for a pre-existing file/dir,
         meaning the base is the youngest revision. This is probably not
         a good idea -- it is at least confusing -- and we should instead
         resolve to a real revnum when Ev1 passes in SVN_INVALID_REVNUM
         in such cases. */
  svn_revnum_t changing_rev;
  /* If ACTION is 'delete' or if ACTION is 'add' and it is a replacement,
     DELETING is TRUE and DELETING_REV is the revision to delete. */
  /* ### Can also be SVN_INVALID_REVNUM for a pre-existing file/dir,
         meaning the base is the youngest revision. This is probably not
         a good idea -- it is at least confusing -- and we should instead
         resolve to a real revnum when Ev1 passes in SVN_INVALID_REVNUM
         in such cases. */
  svn_boolean_t deleting;
  svn_revnum_t deleting_rev;

  /* new/final set of props to apply; null => no *change*, not no props */
  apr_hash_t *props;

  /* new fulltext; null => no change */
  svn_boolean_t contents_changed;
  svn_stringbuf_t *contents_text;

  /* If COPYFROM_PATH is not NULL, then copy PATH@REV to this node.
     RESTRUCTURE must be RESTRUCTURE_ADD.  */
  const char *copyfrom_path;
  svn_revnum_t copyfrom_rev;

#ifdef SHIM_WITH_UNLOCK
  /* Record whether an incoming propchange unlocked this node.  */
  svn_boolean_t unlock;
#endif
} change_node_t;

#if 0
/* Return a string representation of CHANGE. */
static const char *
change_node_str(change_node_t *change,
                apr_pool_t *result_pool)
{
  const char *copyfrom = "<nil>";
  const char *str;

  if (change->copyfrom_path)
    copyfrom = apr_psprintf(result_pool, "'%s'@%ld",
                            change->copyfrom_path, change->copyfrom_rev);
  str = apr_psprintf(result_pool,
                     "action=%d, kind=%s, changing_rev=%ld, "
                     "deleting=%d, deleting_rev=%ld, ..., "
                     "copyfrom=%s",
                     change->action,
                     svn_node_kind_to_word(change->kind),
                     change->changing_rev,
                     change->deleting, change->deleting_rev,
                     copyfrom);
  return str;
}
#endif

/* Check whether RELPATH is known to exist, known to not exist, or unknown. */
static svn_tristate_t
check_existence(apr_hash_t *changes,
                const char *relpath)
{
  apr_pool_t *changes_pool = apr_hash_pool_get(changes);
  apr_pool_t *scratch_pool = changes_pool;
  change_node_t *change = svn_hash_gets(changes, relpath);
  svn_tristate_t exists = svn_tristate_unknown;

  if (change && change->action != RESTRUCTURE_DELETE)
    exists = svn_tristate_true;
  else if (change && change->action == RESTRUCTURE_DELETE)
    exists = svn_tristate_false;
  else
    {
      const char *parent_path = relpath;

      /* Find the nearest parent change. If that's a delete or a simple
         (non-recursive) add, this path cannot exist, else we don't know. */
      while ((parent_path = svn_relpath_dirname(parent_path, scratch_pool)),
             *parent_path)
        {
          change = svn_hash_gets(changes, parent_path);
          if (change)
            {
              if ((change->action == RESTRUCTURE_ADD && !change->copyfrom_path)
                  || change->action == RESTRUCTURE_DELETE)
                exists = svn_tristate_false;
              break;
            }
        }
    }

  return exists;
}

/* Insert a new Ev1-style change for RELPATH, or return an existing one.
 *
 * Verify Ev3 rules. Primary differences from Ev1 rules are ...
 *
 * If ACTION is 'delete', elide any previous explicit deletes inside
 * that subtree. (Other changes inside that subtree are not allowed.) We
 * do not store multiple change records per path even with nested moves
 * -- the most complex change is delete + copy which all fits in one
 * record with action='add'.
 */
static svn_error_t *
insert_change(change_node_t **change_p, apr_hash_t *changes,
              const char *relpath,
              enum restructure_action_t action)
{
  apr_pool_t *changes_pool = apr_hash_pool_get(changes);
  change_node_t *change = svn_hash_gets(changes, relpath);

  /* Check whether this op is allowed. */
  switch (action)
    {
    case RESTRUCTURE_NONE:
      if (change)
        {
          /* A no-restructure change is allowed after add, but not allowed
           * (in Ev3) after another no-restructure change, nor a delete. */
          VERIFY(change->action == RESTRUCTURE_ADD);
        }
      break;

    case RESTRUCTURE_ADD:
      if (change)
        {
          /* Add or copy is allowed after delete (and replaces the delete),
           * but not allowed after an add or a no-restructure change. */
          VERIFY(change->action == RESTRUCTURE_DELETE);
          change->action = action;
        }
      break;

#ifdef SHIM_WITH_ADD_ABSENT
    case RESTRUCTURE_ADD_ABSENT:
      /* ### */
      break;
#endif

    case RESTRUCTURE_DELETE:
      SVN_ERR_MALFUNCTION();
    }

  if (change)
    {
      if (action != RESTRUCTURE_NONE)
        {
          change->action = action;
        }
    }
  else
    {
      /* Create a new change. Callers will set the other fields as needed. */
      change = apr_pcalloc(changes_pool, sizeof(*change));
      change->action = action;
      change->changing_rev = SVN_INVALID_REVNUM;

      svn_hash_sets(changes, apr_pstrdup(changes_pool, relpath), change);
    }

  *change_p = change;
  return SVN_NO_ERROR;
}

/* Modify CHANGES so as to delete the subtree at RELPATH.
 *
 * Insert a new Ev1-style change record for RELPATH (or perhaps remove
 * the existing record if this would have the same effect), and remove
 * any change records for sub-paths under RELPATH.
 *
 * Follow Ev3 rules, although without knowing whether this delete is
 * part of a move. Ev3 (incremental) "rm" operation says each node to
 * be removed "MAY be a child of a copy but otherwise SHOULD NOT have
 * been created or modified in this edit". "mv" operation says ...
 */
static svn_error_t *
delete_subtree(apr_hash_t *changes,
               const char *relpath,
               svn_revnum_t deleting_rev)
{
  apr_pool_t *changes_pool = apr_hash_pool_get(changes);
  apr_pool_t *scratch_pool = changes_pool;
  change_node_t *change = svn_hash_gets(changes, relpath);

  if (change)
    {
      /* If this previous change was a non-replacing addition, there
         is no longer any change to be made at this path. If it was
         a replacement or a modification, it now becomes a delete.
         (If it was a delete, this attempt to delete is an error.) */
       VERIFY(change->action != RESTRUCTURE_DELETE);
       if (change->action == RESTRUCTURE_ADD && !change->deleting)
         {
           svn_hash_sets(changes, relpath, NULL);
           change = NULL;
         }
       else
         {
           change->action = RESTRUCTURE_DELETE;
         }
    }
  else
    {
      /* There was no change recorded at this path. Record a delete. */
      change = apr_pcalloc(changes_pool, sizeof(*change));
      change->action = RESTRUCTURE_DELETE;
      change->changing_rev = SVN_INVALID_REVNUM;
      change->deleting = TRUE;
      change->deleting_rev = deleting_rev;

      svn_hash_sets(changes, apr_pstrdup(changes_pool, relpath), change);
    }

  /* Elide all child ops. */
  {
    apr_hash_index_t *hi;

    for (hi = apr_hash_first(scratch_pool, changes);
         hi; hi = apr_hash_next(hi))
      {
        const char *this_relpath = apr_hash_this_key(hi);
        const char *r = svn_relpath_skip_ancestor(relpath, this_relpath);

        if (r && r[0])
          {
            svn_hash_sets(changes, this_relpath, NULL);
          }
      }
  }

  return SVN_NO_ERROR;
}


/*
 * ===================================================================
 * Commit Editor converter to join a v1 driver to a v3 consumer
 * ===================================================================
 *
 * ...
 */

svn_error_t *
svn_branch__compat_delta_from_txn_for_commit(
                        const svn_delta_editor_t **deditor,
                        void **dedit_baton,
                        svn_branch__txn_t *edit_txn,
                        const char *repos_root_url,
                        const char *base_relpath,
                        svn_branch__compat_fetch_func_t fetch_func,
                        void *fetch_baton,
                        const svn_branch__compat_shim_connector_t *shim_connector,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  /* ### ... */

  return SVN_NO_ERROR;
}

svn_error_t *
svn_branch__compat_delta_from_txn_for_update(
                        const svn_delta_editor_t **deditor,
                        void **dedit_baton,
                        svn_branch__compat_update_editor3_t *update_editor,
                        const char *repos_root_url,
                        const char *base_repos_relpath,
                        svn_branch__compat_fetch_func_t fetch_func,
                        void *fetch_baton,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  svn_branch__compat_shim_connector_t *shim_connector
    = apr_pcalloc(result_pool, sizeof(*shim_connector));

  shim_connector->target_revision_func = update_editor->set_target_revision_func;
  shim_connector->baton = update_editor->set_target_revision_baton;
#ifdef SHIM_WITH_ABS_PATHS
  shim_connector->ev1_absolute_paths /*...*/;
#endif

  SVN_ERR(svn_branch__compat_delta_from_txn_for_commit(
                        deditor, dedit_baton,
                        update_editor->edit_txn,
                        repos_root_url, base_repos_relpath,
                        fetch_func, fetch_baton,
                        shim_connector,
                        result_pool, scratch_pool));
  /*SVN_ERR(svn_delta__get_debug_editor(deditor, dedit_baton,
                                      *deditor, *dedit_baton,
                                      "[UP>1] ", result_pool));*/

  return SVN_NO_ERROR;
}


/*
 * ===================================================================
 * Commit Editor converter to join a v3 driver to a v1 consumer
 * ===================================================================
 *
 * This editor buffers all the changes before driving the Ev1 at the end,
 * since it needs to do a single depth-first traversal of the path space
 * and this cannot be started until all moves are known.
 *
 * Moves are converted to copy-and-delete, with the copy being from
 * the source peg rev. (### Should it request copy-from revision "-1"?)
 *
 * It works like this:
 *
 *                +------+--------+
 *                | path | change |
 *      Ev3  -->  +------+--------+  -->  Ev1
 *                | ...  | ...    |
 *                | ...  | ...    |
 *
 *   1. Ev3 changes are accumulated in a per-path table, EB->changes.
 *
 *   2. On Ev3 close-edit, walk through the table in a depth-first order,
 *      sending the equivalent Ev1 action for each change.
 *
 * TODO
 *
 * ### For changes inside a copied subtree, the calls to the "open dir"
 *     and "open file" Ev1 methods may be passing the wrong revision
 *     number: see comment in apply_change().
 *
 * ### Have we got our rel-paths in order? Ev1, Ev3 and callbacks may
 *     all expect different paths. Are they relative to repos root or to
 *     some base path? Leading slash (unimplemented 'send_abs_paths'
 *     feature), etc.
 *
 * ### May be tidier for OPEN_ROOT_FUNC callback (see open_root_ev3())
 *     not to actually open the root in advance, but instead just to
 *     remember the base revision that the driver wants us to specify
 *     when we do open it.
 */



/*
 * ========================================================================
 * Driving the Delta Editor
 * ========================================================================
 */

/* Information needed for driving the delta editor. */
struct svn_branch__txn_priv_t
{
  /* The Ev1 "delta editor" */
  const svn_delta_editor_t *deditor;
  void *dedit_baton;

  /* Callbacks */
  svn_branch__compat_fetch_func_t fetch_func;
  void *fetch_baton;

  /* The Ev1 root directory baton if we have opened the root, else null. */
  void *ev1_root_dir_baton;

#ifdef SHIM_WITH_ABS_PATHS
  const svn_boolean_t *make_abs_paths;
#endif

  /* Repository root URL
     ### Some code allows this to be null -- but is that valid? */
  const char *repos_root_url;

  /* Ev1 changes recorded so far: REPOS_RELPATH -> change_node_ev3_t */
  apr_hash_t *changes;

  /* The branching state on which the per-element API is working */
  svn_branch__txn_t *txn;

  apr_pool_t *edit_pool;
};

/* Get all the (Ev1) paths that have changes.
 */
static const apr_array_header_t *
get_unsorted_paths(apr_hash_t *changes,
                   apr_pool_t *scratch_pool)
{
  apr_array_header_t *paths = apr_array_make(scratch_pool, 0, sizeof(void *));
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(scratch_pool, changes); hi; hi = apr_hash_next(hi))
    {
      const char *this_path = apr_hash_this_key(hi);
      APR_ARRAY_PUSH(paths, const char *) = this_path;
    }

  return paths;
}

#if 0 /* needed only for shim connector */
/*  */
static svn_error_t *
set_target_revision_ev3(void *edit_baton,
                        svn_revnum_t target_revision,
                        apr_pool_t *scratch_pool)
{
  svn_branch__txn_priv_t *eb = edit_baton;

  SVN_ERR(eb->deditor->set_target_revision(eb->dedit_baton, target_revision,
                                           scratch_pool));

  return SVN_NO_ERROR;
}
#endif

/*  */
static svn_error_t *
open_root_ev3(void *baton,
              svn_revnum_t base_revision)
{
  svn_branch__txn_priv_t *eb = baton;

  SVN_ERR(eb->deditor->open_root(eb->dedit_baton, base_revision,
                                 eb->edit_pool, &eb->ev1_root_dir_baton));
  return SVN_NO_ERROR;
}

/* If RELPATH is a child of a copy, return the path of the copy root,
 * else return NULL.
 */
static const char *
find_enclosing_copy(apr_hash_t *changes,
                    const char *relpath,
                    apr_pool_t *result_pool)
{
  while (*relpath)
    {
      const change_node_t *change = svn_hash_gets(changes, relpath);

      if (change)
        {
          if (change->copyfrom_path)
            return relpath;
          if (change->action != RESTRUCTURE_NONE)
            return NULL;
        }
      relpath = svn_relpath_dirname(relpath, result_pool);
    }

  return NULL;
}

/* Set *BASE_PROPS to the 'base' properties, against which any changes
 * will be described, for the changed path described in CHANGES at
 * REPOS_RELPATH.
 *
 * For a copied path, including a copy child path, fetch from the copy
 * source path. For a plain add, return an empty set. For a delete,
 * return NULL.
 */
static svn_error_t *
fetch_base_props(apr_hash_t **base_props,
                 apr_hash_t *changes,
                 const char *repos_relpath,
                 svn_branch__compat_fetch_func_t fetch_func,
                 void *fetch_baton,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
{
  const change_node_t *change = svn_hash_gets(changes, repos_relpath);
  const char *source_path = NULL;
  svn_revnum_t source_rev;

  if (change->action == RESTRUCTURE_DELETE)
    {
      *base_props = NULL;
    }

  else if (change->action == RESTRUCTURE_ADD && ! change->copyfrom_path)
    {
      *base_props = apr_hash_make(result_pool);
    }
  else if (change->copyfrom_path)
    {
      source_path = change->copyfrom_path;
      source_rev = change->copyfrom_rev;
    }
  else /* RESTRUCTURE_NONE */
    {
      /* It's an edit, but possibly to a copy child. Discover if it's a
         copy child, & find the copy-from source. */

      const char *copy_path
        = find_enclosing_copy(changes, repos_relpath, scratch_pool);

      if (copy_path)
        {
          const change_node_t *enclosing_copy
            = svn_hash_gets(changes, copy_path);
          const char *remainder
            = svn_relpath_skip_ancestor(copy_path, repos_relpath);

          source_path = svn_relpath_join(enclosing_copy->copyfrom_path,
                                         remainder, scratch_pool);
          source_rev = enclosing_copy->copyfrom_rev;
        }
      else
        {
          /* It's a plain edit (not a copy child path). */
          source_path = repos_relpath;
          source_rev = change->changing_rev;
        }
    }

  if (source_path)
    {
      SVN_ERR(fetch_func(NULL, base_props, NULL, NULL,
                         fetch_baton, source_path, source_rev,
                         result_pool, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Send property changes to Ev1 for the CHANGE at REPOS_RELPATH.
 *
 * Ev1 requires exactly one prop-change call for each prop whose value
 * has changed. Therefore we *have* to fetch the original props from the
 * repository, provide them as OLD_PROPS, and calculate the changes.
 */
static svn_error_t *
drive_ev1_props(const char *repos_relpath,
                const change_node_t *change,
                apr_hash_t *old_props,
                const svn_delta_editor_t *deditor,
                void *node_baton,
                apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_array_header_t *propdiffs;
  int i;

  SVN_ERR_ASSERT(change->action != RESTRUCTURE_DELETE);

  /* If there are no property changes, then just exit. */
  if (change->props == NULL)
    return SVN_NO_ERROR;

  SVN_ERR(svn_prop_diffs(&propdiffs, change->props, old_props, scratch_pool));

  /* Apply property changes. These should be changes against the empty set
     for a new node, or changes against the source node for a copied node. */
  for (i = 0; i < propdiffs->nelts; i++)
    {
      const svn_prop_t *prop = &APR_ARRAY_IDX(propdiffs, i, svn_prop_t);

      svn_pool_clear(iterpool);

      if (change->kind == svn_node_dir)
        SVN_ERR(deditor->change_dir_prop(node_baton,
                                         prop->name, prop->value,
                                         iterpool));
      else
        SVN_ERR(deditor->change_file_prop(node_baton,
                                          prop->name, prop->value,
                                          iterpool));
    }

#ifdef SHIM_WITH_UNLOCK
  /* Handle the funky unlock protocol. Note: only possibly on files.  */
  if (change->unlock)
    {
      SVN_ERR_ASSERT(change->kind == svn_node_file);
      SVN_ERR(deditor->change_file_prop(node_baton,
                                            SVN_PROP_ENTRY_LOCK_TOKEN, NULL,
                                            iterpool));
    }
#endif

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Drive the Ev1 editor with the change recorded in EB->changes for the
 * path EV1_RELPATH.
 *
 * Conforms to svn_delta_path_driver_cb_func_t.
 */
static svn_error_t *
apply_change(void **dir_baton,
             const svn_delta_editor_t *editor,
             void *edit_baton,
             void *parent_baton,
             void *callback_baton,
             const char *ev1_relpath,
             apr_pool_t *result_pool)
{
  apr_pool_t *scratch_pool = result_pool;
  const svn_branch__txn_priv_t *eb = callback_baton;
  const change_node_t *change = svn_hash_gets(eb->changes, ev1_relpath);
  void *file_baton = NULL;
  apr_hash_t *base_props;

  /* The callback should only be called for paths in CHANGES.  */
  SVN_ERR_ASSERT(change != NULL);

  /* Typically, we are not creating new directory batons.  */
  *dir_baton = NULL;

  SVN_ERR(fetch_base_props(&base_props, eb->changes, ev1_relpath,
                           eb->fetch_func, eb->fetch_baton,
                           scratch_pool, scratch_pool));

  /* Are we editing the root of the tree?  */
  if (parent_baton == NULL)
    {
      /* The root dir was already opened. */
      *dir_baton = eb->ev1_root_dir_baton;

      /* Only property edits are allowed on the root.  */
      SVN_ERR_ASSERT(change->action == RESTRUCTURE_NONE);
      SVN_ERR(drive_ev1_props(ev1_relpath, change, base_props,
                              editor, *dir_baton, scratch_pool));

      /* No further action possible for the root.  */
      return SVN_NO_ERROR;
    }

  if (change->action == RESTRUCTURE_DELETE)
    {
      SVN_ERR(editor->delete_entry(ev1_relpath, change->deleting_rev,
                                   parent_baton, scratch_pool));

      /* No further action possible for this node.  */
      return SVN_NO_ERROR;
    }

  /* If we're not deleting this node, then we should know its kind.  */
  SVN_ERR_ASSERT(change->kind != svn_node_unknown);

#ifdef SHIM_WITH_ADD_ABSENT
  if (change->action == RESTRUCTURE_ADD_ABSENT)
    {
      if (change->kind == svn_node_dir)
        SVN_ERR(editor->absent_directory(ev1_relpath, parent_baton,
                                         scratch_pool));
      else if (change->kind == svn_node_file)
        SVN_ERR(editor->absent_file(ev1_relpath, parent_baton,
                                    scratch_pool));
      else
        SVN_ERR_MALFUNCTION();

      /* No further action possible for this node.  */
      return SVN_NO_ERROR;
    }
#endif
  /* RESTRUCTURE_NONE or RESTRUCTURE_ADD  */

  if (change->action == RESTRUCTURE_ADD)
    {
      const char *copyfrom_url = NULL;
      svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;

      /* Do we have an old node to delete first? If so, delete it. */
      if (change->deleting)
        SVN_ERR(editor->delete_entry(ev1_relpath, change->deleting_rev,
                                     parent_baton, scratch_pool));

      /* If it's a copy, determine the copy source location. */
      if (change->copyfrom_path)
        {
          /* ### What's this about URL vs. fspath? REPOS_ROOT_URL isn't
             optional, is it, at least in a commit editor? */
          if (eb->repos_root_url)
            copyfrom_url = svn_path_url_add_component2(eb->repos_root_url,
                                                       change->copyfrom_path,
                                                       scratch_pool);
          else
            {
              copyfrom_url = change->copyfrom_path;

              /* Make this an FS path by prepending "/" */
              if (copyfrom_url[0] != '/')
                copyfrom_url = apr_pstrcat(scratch_pool, "/",
                                           copyfrom_url, SVN_VA_NULL);
            }

          copyfrom_rev = change->copyfrom_rev;
        }

      if (change->kind == svn_node_dir)
        SVN_ERR(editor->add_directory(ev1_relpath, parent_baton,
                                      copyfrom_url, copyfrom_rev,
                                      result_pool, dir_baton));
      else if (change->kind == svn_node_file)
        SVN_ERR(editor->add_file(ev1_relpath, parent_baton,
                                 copyfrom_url, copyfrom_rev,
                                 result_pool, &file_baton));
      else
        SVN_ERR_MALFUNCTION();
    }
  else /* RESTRUCTURE_NONE */
    {
      /* ### The code that inserts a "plain edit" change record sets
         'changing_rev' to the peg rev of the pegged part of the path,
         even when the full path refers to a child of a copy. Should we
         instead be using the copy source rev here, in that case? (Like
         when we fetch the base properties.) */

      if (change->kind == svn_node_dir)
        SVN_ERR(editor->open_directory(ev1_relpath, parent_baton,
                                       change->changing_rev,
                                       result_pool, dir_baton));
      else if (change->kind == svn_node_file)
        SVN_ERR(editor->open_file(ev1_relpath, parent_baton,
                                  change->changing_rev,
                                  result_pool, &file_baton));
      else
        SVN_ERR_MALFUNCTION();
    }

  /* Apply any properties in CHANGE to the node.  */
  if (change->kind == svn_node_dir)
    SVN_ERR(drive_ev1_props(ev1_relpath, change, base_props,
                            editor, *dir_baton, scratch_pool));
  else
    SVN_ERR(drive_ev1_props(ev1_relpath, change, base_props,
                            editor, file_baton, scratch_pool));

  /* Send the text content delta, if new text content is provided. */
  if (change->contents_text)
    {
      svn_stream_t *read_stream;
      svn_txdelta_window_handler_t handler;
      void *handler_baton;

      read_stream = svn_stream_from_stringbuf(change->contents_text,
                                              scratch_pool);
      /* ### would be nice to have a BASE_CHECKSUM, but hey: this is the
         ### shim code...  */
      SVN_ERR(editor->apply_textdelta(file_baton, NULL, scratch_pool,
                                           &handler, &handler_baton));
      /* ### it would be nice to send a true txdelta here, but whatever.  */
      SVN_ERR(svn_txdelta_send_stream(read_stream, handler, handler_baton,
                                      NULL, scratch_pool));
      SVN_ERR(svn_stream_close(read_stream));
    }

  if (file_baton)
    {
      SVN_ERR(editor->close_file(file_baton, NULL, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/*
 * ========================================================================
 * Old-repository storage paths for branch elements
 * ========================================================================
 *
 * To support top-level branches, we map each top-level branch to its own
 * directory in the old repository, with each nested branch in a subdirectory:
 *
 *   B0  =>  ^/top0/...
 *           ^/top0/.../trunk/...  <= B0.12
 *   B1  =>  ^/top1/...
 *
 * It may be better to put each branch in its own directory:
 *
 *   B0     =>  ^/B0/...
 *   B0.12  =>  ^/B0.12/...
 *   B1     =>  ^/B1/...
 *
 * (A branch root is not necessarily a directory, it could be a file.)
 */

/* Get the old-repository path for the storage of the root element of BRANCH.
 *
 * Currently, this is the same as the nested-branching hierarchical path
 * (and thus assumes there is only one top-level branch).
 */
static const char *
branch_get_storage_root_rrpath(const svn_branch__state_t *branch,
                               apr_pool_t *result_pool)
{
  int top_branch_num = atoi(branch->bid + 1);
  const char *top_path = apr_psprintf(result_pool, "top%d", top_branch_num);
  const char *nested_path = svn_branch__get_root_rrpath(branch, result_pool);

  return svn_relpath_join(top_path, nested_path, result_pool);
}

/* Get the old-repository path for the storage of element EID of BRANCH.
 *
 * If the element EID doesn't exist in BRANCH, return NULL.
 */
static const char *
branch_get_storage_rrpath_by_eid(const svn_branch__state_t *branch,
                                 int eid,
                                 apr_pool_t *result_pool)
{
  const char *path = svn_branch__get_path_by_eid(branch, eid, result_pool);
  const char *rrpath = NULL;

  if (path)
    {
      rrpath = svn_relpath_join(branch_get_storage_root_rrpath(branch,
                                                               result_pool),
                                path, result_pool);
    }
  return rrpath;
}

/* Return, in *STORAGE_PATHREV_P, the storage-rrpath-rev for BRANCH_REF.
 */
static svn_error_t *
storage_pathrev_from_branch_ref(svn_pathrev_t *storage_pathrev_p,
                                svn_element__branch_ref_t branch_ref,
                                svn_branch__repos_t *repos,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
{
  svn_branch__el_rev_id_t *el_rev;

  SVN_ERR(svn_branch__repos_find_el_rev_by_id(&el_rev,
                                              repos,
                                              branch_ref.rev,
                                              branch_ref.branch_id,
                                              branch_ref.eid,
                                              scratch_pool, scratch_pool));

  storage_pathrev_p->rev = el_rev->rev;
  storage_pathrev_p->relpath
    = branch_get_storage_rrpath_by_eid(el_rev->branch, el_rev->eid,
                                       result_pool);

  return SVN_NO_ERROR;
}

/*
 * ========================================================================
 * Editor for Commit (independent per-element changes; element-id addressing)
 * ========================================================================
 */

/*  */
#define PAYLOAD_IS_ONLY_BY_REFERENCE(payload) \
    ((payload)->kind == svn_node_unknown)

/* Fetch a payload as *PAYLOAD_P from its storage-pathrev PATH_REV.
 * Fetch names of immediate children of PATH_REV as *CHILDREN_NAMES.
 * Either of the outputs may be null if not wanted.
 */
static svn_error_t *
payload_fetch(svn_element__payload_t **payload_p,
              apr_hash_t **children_names,
              svn_branch__txn_priv_t *eb,
              const svn_pathrev_t *path_rev,
              apr_pool_t *result_pool,
              apr_pool_t *scratch_pool)
{
  svn_element__payload_t *payload
    = apr_pcalloc(result_pool, sizeof (*payload));

  SVN_ERR(eb->fetch_func(&payload->kind,
                         &payload->props,
                         &payload->text,
                         children_names,
                         eb->fetch_baton,
                         path_rev->relpath, path_rev->rev,
                         result_pool, scratch_pool));

  SVN_ERR_ASSERT(svn_element__payload_invariants(payload));
  SVN_ERR_ASSERT(payload->kind == svn_node_dir
                 || payload->kind == svn_node_file);
  if (payload_p)
    *payload_p = payload;
  return SVN_NO_ERROR;
}

/* Return the storage-pathrev of PAYLOAD as *STORAGE_PATHREV_P.
 *
 * Find the storage-pathrev from PAYLOAD->branch_ref.
 */
static svn_error_t *
payload_get_storage_pathrev(svn_pathrev_t *storage_pathrev_p,
                            svn_element__payload_t *payload,
                            svn_branch__repos_t *repos,
                            apr_pool_t *result_pool)
{
  SVN_ERR_ASSERT(payload->branch_ref.branch_id /* && ... */);

  SVN_ERR(storage_pathrev_from_branch_ref(storage_pathrev_p,
                                          payload->branch_ref, repos,
                                          result_pool, result_pool));
  return SVN_NO_ERROR;
}

svn_error_t *
svn_branch__compat_fetch(svn_element__payload_t **payload_p,
                         svn_branch__txn_t *txn,
                         svn_element__branch_ref_t branch_ref,
                         svn_branch__compat_fetch_func_t fetch_func,
                         void *fetch_baton,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
{
  svn_branch__txn_priv_t eb;
  svn_pathrev_t storage_pathrev;

  /* Simulate the existence of /top0 in r0. */
  if (branch_ref.rev == 0 && branch_ref.eid == 0)
    {
      *payload_p = svn_element__payload_create_dir(apr_hash_make(result_pool),
                                                   result_pool);
      return SVN_NO_ERROR;
    }

  eb.txn = txn;
  eb.fetch_func = fetch_func;
  eb.fetch_baton = fetch_baton;

  SVN_ERR(storage_pathrev_from_branch_ref(&storage_pathrev,
                                          branch_ref, txn->repos,
                                          scratch_pool, scratch_pool));

  SVN_ERR(payload_fetch(payload_p, NULL,
                        &eb, &storage_pathrev, result_pool, scratch_pool));
  (*payload_p)->branch_ref = branch_ref;
  return SVN_NO_ERROR;
}

/* Fill in the actual payload, from its reference, if not already done.
 */
static svn_error_t *
payload_resolve(svn_element__payload_t *payload,
                svn_branch__txn_priv_t *eb,
                apr_pool_t *scratch_pool)
{
  svn_pathrev_t storage;

  SVN_ERR_ASSERT(svn_element__payload_invariants(payload));

  if (! PAYLOAD_IS_ONLY_BY_REFERENCE(payload))
    return SVN_NO_ERROR;

  SVN_ERR(payload_get_storage_pathrev(&storage, payload,
                                      eb->txn->repos,
                                      scratch_pool));

  SVN_ERR(eb->fetch_func(&payload->kind,
                         &payload->props,
                         &payload->text,
                         NULL,
                         eb->fetch_baton,
                         storage.relpath, storage.rev,
                         payload->pool, scratch_pool));

  SVN_ERR_ASSERT(svn_element__payload_invariants(payload));
  SVN_ERR_ASSERT(! PAYLOAD_IS_ONLY_BY_REFERENCE(payload));
  return SVN_NO_ERROR;
}

/* Update *PATHS, a hash of (storage_rrpath -> svn_branch__el_rev_id_t),
 * creating or filling in entries for all elements in BRANCH.
 */
static svn_error_t *
convert_branch_to_paths(apr_hash_t *paths,
                        svn_branch__state_t *branch,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;
  svn_element__tree_t *elements;

  /* assert(branch is at a sequence point); */

  SVN_ERR(svn_branch__state_get_elements(branch, &elements, scratch_pool));
  for (hi = apr_hash_first(scratch_pool, elements->e_map);
       hi; hi = apr_hash_next(hi))
    {
      int eid = svn_eid__hash_this_key(hi);
      svn_element__content_t *element = apr_hash_this_val(hi);
      const char *rrpath
        = branch_get_storage_rrpath_by_eid(branch, eid, result_pool);
      svn_branch__el_rev_id_t *ba;

      /* A subbranch-root element carries no payload; the corresponding
         inner branch root element will provide the payload for this path. */
      if (element->payload->is_subbranch_root)
        continue;

      /* No other element should exist at this path, given that we avoid
         storing anything for a subbranch-root element. */
      SVN_ERR_ASSERT(! svn_hash_gets(paths, rrpath));

      /* Fill in the details. */
      ba = svn_branch__el_rev_id_create(branch, eid, branch->txn->rev,
                                        result_pool);
      svn_hash_sets(paths, rrpath, ba);
      /*SVN_DBG(("branch-to-path[%d]: b%s e%d -> %s",
               i, svn_branch__get_id(branch, scratch_pool), eid, rrpath));*/
    }
  return SVN_NO_ERROR;
}

/* Produce a mapping from paths to element ids, covering all elements in
 * BRANCH and all its sub-branches, recursively.
 *
 * Update *PATHS_UNION, a hash of (storage_rrpath -> svn_branch__el_rev_id_t),
 * creating or filling in entries for all elements in all branches at and
 * under BRANCH, recursively.
 */
static svn_error_t *
convert_branch_to_paths_r(apr_hash_t *paths_union,
                          svn_branch__state_t *branch,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
{
  apr_array_header_t *subbranches;
  int i;

  /*SVN_DBG(("[%d] branch={b%s e%d at '%s'}", idx,
           svn_branch__get_id(branch, scratch_pool), branch->root_eid,
           svn_branch__get_root_rrpath(branch, scratch_pool)));*/
  SVN_ERR(convert_branch_to_paths(paths_union, branch,
                                  result_pool, scratch_pool));

  SVN_ERR(svn_branch__get_immediate_subbranches(branch, &subbranches,
                                               scratch_pool, scratch_pool));
  /* Rercurse into sub-branches */
  for (i = 0; i < subbranches->nelts; i++)
    {
      svn_branch__state_t *b = APR_ARRAY_IDX(subbranches, i, void *);

      SVN_ERR(convert_branch_to_paths_r(paths_union, b, result_pool,
                                        scratch_pool));
    }
  return SVN_NO_ERROR;
}

/* Return TRUE iff INITIAL_PAYLOAD and FINAL_PAYLOAD are both non-null
 * and have the same properties.
 */
static svn_boolean_t
props_equal(svn_element__payload_t *initial_payload,
            svn_element__payload_t *final_payload,
            apr_pool_t *scratch_pool)
{
  apr_array_header_t *prop_diffs;

  if (!initial_payload || !final_payload)
    return FALSE;

  svn_error_clear(svn_prop_diffs(&prop_diffs,
                                 initial_payload->props,
                                 final_payload->props,
                                 scratch_pool));
  return (prop_diffs->nelts == 0);
}

/* Return TRUE iff INITIAL_PAYLOAD and FINAL_PAYLOAD are both file payload
 * and have the same text.
 */
static svn_boolean_t
text_equal(svn_element__payload_t *initial_payload,
           svn_element__payload_t *final_payload)
{
  if (!initial_payload || !final_payload
      || initial_payload->kind != svn_node_file
      || final_payload->kind != svn_node_file)
    {
      return FALSE;
    }

  return svn_stringbuf_compare(initial_payload->text,
                               final_payload->text);
}

/* Return the copy-from location to be used if this is to be a copy;
 * otherwise return NULL.
 *
 * ### Currently this is indicated by payload-by-reference, which is
 *     an inadequate indication.
 */
static svn_error_t *
get_copy_from(svn_pathrev_t *copyfrom_pathrev_p,
              svn_element__payload_t *final_payload,
              svn_branch__txn_priv_t *eb,
              apr_pool_t *result_pool)
{
  if (final_payload->branch_ref.branch_id)
    {
      SVN_ERR(payload_get_storage_pathrev(copyfrom_pathrev_p, final_payload,
                                          eb->txn->repos,
                                          result_pool));
    }
  else
    {
      copyfrom_pathrev_p->relpath = NULL;
      copyfrom_pathrev_p->rev = SVN_INVALID_REVNUM;
    }

  return SVN_NO_ERROR;
}

/* Return a hash whose keys are the names of the immediate children of
 * RRPATH in PATHS.
 */
static apr_hash_t *
get_immediate_children_names(apr_hash_t *paths,
                             const char *parent_rrpath,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
{
  apr_hash_t *children = apr_hash_make(result_pool);
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(scratch_pool, paths); hi; hi = apr_hash_next(hi))
    {
      const char *this_rrpath = apr_hash_this_key(hi);

      if (this_rrpath[0]
          && strcmp(parent_rrpath, svn_relpath_dirname(this_rrpath,
                                                       scratch_pool)) == 0)
        {
          svn_hash_sets(children,
                        svn_relpath_basename(this_rrpath, result_pool), "");
        }
    }

  return children;
}

/* Generate Ev1 instructions to edit from a current state to a final state
 * at RRPATH, recursing for child paths of RRPATH.
 *
 * The current state at RRPATH might not be the initial state because,
 * although neither RRPATH nor any sub-paths have been explicitly visited
 * before, the current state at RRPATH and its sub-paths might be the
 * result of a copy.
 *
 * PRED_LOC is the predecessor location of the node currently at RRPATH in
 * the Ev1 transaction, or NULL if there is no node currently at RRPATH.
 * If the node is copied, including a child of a copy, this is its copy-from
 * location, otherwise this is its location in the txn base revision.
 * (The current node cannot be a plain added node on entry to this function,
 * as the function must be called only once for each path and there is no
 * recursive add operation.) PRED_LOC identifies the node content that the
 * that the Ev1 edit needs to delete, replace, update or leave unchanged.
 *
 * Process a single hierarchy of nested branches, rooted in the top-level
 * branch TOP_BRANCH_NUM.
 */
static svn_error_t *
drive_changes_r(const char *rrpath,
                svn_pathrev_t *pred_loc,
                apr_hash_t *paths_final,
                const char *top_branch_id,
                svn_branch__txn_priv_t *eb,
                apr_pool_t *scratch_pool)
{
  /* The el-rev-id of the element that will finally exist at RRPATH. */
  svn_branch__el_rev_id_t *final_el_rev = svn_hash_gets(paths_final, rrpath);
  svn_element__payload_t *final_payload;
  svn_pathrev_t final_copy_from;
  svn_boolean_t succession;

  /*SVN_DBG(("rrpath '%s' current=%s, final=e%d)",
           rrpath,
           pred_loc ? pathrev_str(*pred_loc, scratch_pool) : "<nil>",
           final_el_rev ? final_el_rev->eid : -1));*/

  SVN_ERR_ASSERT(!pred_loc
                 || (pred_loc->relpath && SVN_IS_VALID_REVNUM(pred_loc->rev)));

  if (final_el_rev)
    {
      svn_element__content_t *final_element;

      SVN_ERR(svn_branch__state_get_element(final_el_rev->branch, &final_element,
                                            final_el_rev->eid, scratch_pool));
      /* A non-null FINAL address means an element exists there. */
      SVN_ERR_ASSERT(final_element);

      final_payload = final_element->payload;

      /* Decide whether the state at this path should be a copy (incl. a
         copy-child) */
      SVN_ERR(get_copy_from(&final_copy_from, final_payload, eb, scratch_pool));
      /* It doesn't make sense to have a non-copy inside a copy */
      /*SVN_ERR_ASSERT(!(parent_is_copy && !final_copy_from));*/
   }
  else
    {
      final_payload = NULL;
      final_copy_from.relpath = NULL;
    }

  /* Succession means:
       for a copy (inc. child)  -- copy-from same place as natural predecessor
       otherwise                -- it's succession if it's the same element
                                   (which also implies the same kind) */
  if (pred_loc && final_copy_from.relpath)
    {
      succession = pathrev_equal(pred_loc, &final_copy_from);
    }
  else if (pred_loc && final_el_rev)
    {
      svn_branch__el_rev_id_t *pred_el_rev;

      SVN_ERR(svn_branch__repos_find_el_rev_by_path_rev(&pred_el_rev,
                                            eb->txn->repos,
                                            pred_loc->rev,
                                            top_branch_id,
                                            pred_loc->relpath,
                                            scratch_pool, scratch_pool));

      succession = (pred_el_rev->eid == final_el_rev->eid);
    }
  else
    {
      succession = FALSE;
    }

  /* If there's an initial node that isn't also going to be the final
     node at this path, then it's being deleted or replaced: delete it. */
  if (pred_loc && !succession)
    {
      /* Issue an Ev1 delete unless this path is inside a path at which
         we've already issued a delete. */
      if (check_existence(eb->changes, rrpath) != svn_tristate_false)
        {
          /*SVN_DBG(("ev1:del(%s)", rrpath));*/
          /* ### We don't need "delete_subtree", we only need to insert a
             single delete operation, as we know we haven't
             inserted any changes inside this subtree. */
          SVN_ERR(delete_subtree(eb->changes, rrpath, pred_loc->rev));
        }
      else
        {
          /*SVN_DBG(("ev1:del(%s): parent is already deleted", rrpath))*/
        }
    }

  /* If there's a final node, it's being added or modified.
     Or it's unchanged -- we do nothing in that case. */
  if (final_el_rev)
    {
      svn_element__payload_t *current_payload = NULL;
      apr_hash_t *current_children = NULL;
      change_node_t *change = NULL;

      /* Get the full payload of the final node. If we have
         only a reference to the payload, fetch it in full. */
      SVN_ERR_ASSERT(final_payload);
      SVN_ERR(payload_resolve(final_payload, eb, scratch_pool));

      /* If the final node was also the initial node, it's being
         modified, otherwise it's being added (perhaps a replacement). */
      if (succession)
        {
          /* Get full payload of the current node */
          SVN_ERR(payload_fetch(&current_payload, &current_children,
                                eb, pred_loc,
                                scratch_pool, scratch_pool));

          /* If no changes to make, then skip this path */
          if (svn_element__payload_equal(current_payload,
                                         final_payload, scratch_pool))
            {
              /*SVN_DBG(("ev1:no-op(%s)", rrpath));*/
            }
          else
            {
              /*SVN_DBG(("ev1:mod(%s)", rrpath));*/
              SVN_ERR(insert_change(&change, eb->changes, rrpath,
                                    RESTRUCTURE_NONE));
              change->changing_rev = pred_loc->rev;
            }
        }
      else /* add or copy/move */
        {
          /*SVN_DBG(("ev1:add(%s)", rrpath));*/
          SVN_ERR(insert_change(&change, eb->changes, rrpath,
                                RESTRUCTURE_ADD));

          /* If the node is to be copied (and possibly modified) ... */
          if (final_copy_from.relpath)
            {
              change->copyfrom_rev = final_copy_from.rev;
              change->copyfrom_path = final_copy_from.relpath;

              /* Get full payload of the copy source node */
              SVN_ERR(payload_fetch(&current_payload, &current_children,
                                    eb, &final_copy_from,
                                    scratch_pool, scratch_pool));
            }
        }

      if (change)
        {
          /* Copy the required content into the change record. Avoid no-op
             changes of props / text, not least to minimize clutter when
             debugging Ev1 operations. */
          SVN_ERR_ASSERT(final_payload->kind == svn_node_dir
                         || final_payload->kind == svn_node_file);
          change->kind = final_payload->kind;
          if (!props_equal(current_payload, final_payload, scratch_pool))
            {
              change->props = final_payload->props;
            }
          if (final_payload->kind == svn_node_file
              && !text_equal(current_payload, final_payload))
            {
              change->contents_text = final_payload->text;
            }
        }

      /* Recurse to process this directory's children */
      if (final_payload->kind == svn_node_dir)
        {
          apr_hash_t *final_children;
          apr_hash_t *union_children;
          apr_hash_index_t *hi;

          final_children = get_immediate_children_names(paths_final, rrpath,
                                                        scratch_pool,
                                                        scratch_pool);
          union_children = (current_children
                            ? hash_overlay(current_children, final_children)
                            : final_children);
          for (hi = apr_hash_first(scratch_pool, union_children);
               hi; hi = apr_hash_next(hi))
            {
              const char *name = apr_hash_this_key(hi);
              const char *this_rrpath = svn_relpath_join(rrpath, name,
                                                         scratch_pool);
              svn_boolean_t child_in_current
                = current_children && svn_hash_gets(current_children, name);
              svn_pathrev_t *child_pred = NULL;

              if (child_in_current)
                {
                 /* If the parent dir is copied, then this child has been
                    copied along with it: predecessor is parent's copy-from
                    location extended by the child's name. */
                  child_pred = apr_palloc(scratch_pool, sizeof(*child_pred));
                  if (final_copy_from.relpath)
                    {
                      child_pred->rev = final_copy_from.rev;
                      child_pred->relpath
                        = svn_relpath_join(final_copy_from.relpath, name,
                                           scratch_pool);
                    }
                  else
                    {
                      child_pred->rev = pred_loc->rev;
                      child_pred->relpath = this_rrpath;
                    }
               }

              SVN_ERR(drive_changes_r(this_rrpath,
                                      child_pred,
                                      paths_final, top_branch_id,
                                      eb, scratch_pool));
            }
        }
    }

  return SVN_NO_ERROR;
}

/*
 * Drive svn_delta_editor_t (actions: add/copy/delete/modify) from
 * a before-and-after element mapping.
 */
static svn_error_t *
drive_changes(svn_branch__txn_priv_t *eb,
              apr_pool_t *scratch_pool)
{
  apr_array_header_t *branches;
  int i;
  const apr_array_header_t *paths;

  /* Convert the element mappings to an svn_delta_editor_t traversal.

        1. find union of paths in initial and final states, across all branches.
        2. traverse paths in depth-first order.
        3. modify/delete/add/replace as needed at each path.
   */

  /* Process one hierarchy of nested branches at a time. */
  branches = svn_branch__txn_get_branches(eb->txn, scratch_pool);
  for (i = 0; i < branches->nelts; i++)
    {
      svn_branch__state_t *root_branch = APR_ARRAY_IDX(branches, i, void *);
      apr_hash_t *paths_final;

      const char *top_path = branch_get_storage_root_rrpath(root_branch,
                                                            scratch_pool);
      svn_pathrev_t current;
      svn_branch__state_t *base_root_branch;
      svn_boolean_t branch_is_new;

      if (strchr(root_branch->bid, '.'))
        continue;  /* that's not a root branch */

      SVN_ERR(svn_branch__repos_get_branch_by_id(&base_root_branch,
                                                 eb->txn->repos,
                                                 eb->txn->base_rev,
                                                 root_branch->bid, scratch_pool));
      branch_is_new = !base_root_branch;

      paths_final = apr_hash_make(scratch_pool);
      SVN_ERR(convert_branch_to_paths_r(paths_final,
                                        root_branch,
                                        scratch_pool, scratch_pool));

      current.rev = eb->txn->base_rev;
      current.relpath = top_path;

      /* Create the top-level storage node if the branch is new, or if this is
         the first commit to branch B0 which was created in r0 but had no
         storage node there. */
      if (branch_is_new || current.rev == 0)
        {
          change_node_t *change;

          SVN_ERR(insert_change(&change, eb->changes, top_path, RESTRUCTURE_ADD));
          change->kind = svn_node_dir;
        }

      SVN_ERR(drive_changes_r(top_path, &current,
                              paths_final, svn_branch__get_id(root_branch,
                                                              scratch_pool),
                              eb, scratch_pool));
    }

  /* If the driver has not explicitly opened the root directory via the
     start_edit (aka open_root) callback, do so now. */
  if (eb->ev1_root_dir_baton == NULL)
    SVN_ERR(open_root_ev3(eb, SVN_INVALID_REVNUM));

  /* Make the path driver visit the root dir of the edit. Otherwise, it
     will attempt an open_root() instead, which we already did. */
  if (! svn_hash_gets(eb->changes, ""))
    {
      change_node_t *change;

      SVN_ERR(insert_change(&change, eb->changes, "", RESTRUCTURE_NONE));
      change->kind = svn_node_dir;
    }

  /* Apply the appropriate Ev1 change to each Ev1-relative path. */
  paths = get_unsorted_paths(eb->changes, scratch_pool);
  SVN_ERR(svn_delta_path_driver3(eb->deditor, eb->dedit_baton,
                                 paths, TRUE /*sort*/,
                                 apply_change, (void *)eb,
                                 scratch_pool));

  return SVN_NO_ERROR;
}

/* An #svn_branch__txn_t method. */
static apr_array_header_t *
compat_branch_txn_get_branches(const svn_branch__txn_t *txn,
                               apr_pool_t *result_pool)
{
  /* Just forwarding: nothing more is needed. */
  apr_array_header_t *branches
    = svn_branch__txn_get_branches(txn->priv->txn,
                                   result_pool);

  return branches;
}

/* An #svn_branch__txn_t method. */
static svn_error_t *
compat_branch_txn_delete_branch(svn_branch__txn_t *txn,
                                const char *bid,
                                apr_pool_t *scratch_pool)
{
  /* Just forwarding: nothing more is needed. */
  SVN_ERR(svn_branch__txn_delete_branch(txn->priv->txn,
                                        bid,
                                        scratch_pool));
  return SVN_NO_ERROR;
}

/* An #svn_branch__txn_t method. */
static svn_error_t *
compat_branch_txn_get_num_new_eids(const svn_branch__txn_t *txn,
                                   int *num_new_eids_p,
                                   apr_pool_t *scratch_pool)
{
  /* Just forwarding: nothing more is needed. */
  SVN_ERR(svn_branch__txn_get_num_new_eids(txn->priv->txn,
                                           num_new_eids_p,
                                           scratch_pool));
  return SVN_NO_ERROR;
}

/* An #svn_branch__txn_t method. */
static svn_error_t *
compat_branch_txn_new_eid(svn_branch__txn_t *txn,
                          svn_branch__eid_t *eid_p,
                          apr_pool_t *scratch_pool)
{
  /* Just forwarding: nothing more is needed. */
  SVN_ERR(svn_branch__txn_new_eid(txn->priv->txn,
                                  eid_p,
                                  scratch_pool));
  return SVN_NO_ERROR;
}

/* An #svn_branch__txn_t method. */
static svn_error_t *
compat_branch_txn_finalize_eids(svn_branch__txn_t *txn,
                                apr_pool_t *scratch_pool)
{
  /* Just forwarding: nothing more is needed. */
  SVN_ERR(svn_branch__txn_finalize_eids(txn->priv->txn,
                                        scratch_pool));
  return SVN_NO_ERROR;
}

/* An #svn_branch__txn_t method. */
static svn_error_t *
compat_branch_txn_open_branch(svn_branch__txn_t *txn,
                              svn_branch__state_t **new_branch_p,
                              const char *new_branch_id,
                              int root_eid,
                              svn_branch__rev_bid_eid_t *tree_ref,
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool)
{
  /* Just forwarding: nothing more is needed. */
  SVN_ERR(svn_branch__txn_open_branch(txn->priv->txn,
                                      new_branch_p,
                                      new_branch_id, root_eid, tree_ref,
                                      result_pool,
                                      scratch_pool));
  return SVN_NO_ERROR;
}

/* An #svn_branch__txn_t method. */
static svn_error_t *
compat_branch_txn_serialize(svn_branch__txn_t *txn,
                            svn_stream_t *stream,
                            apr_pool_t *scratch_pool)
{
  /* Just forwarding: nothing more is needed. */
  SVN_ERR(svn_branch__txn_serialize(txn->priv->txn,
                                    stream,
                                    scratch_pool));
  return SVN_NO_ERROR;
}

/* An #svn_branch__txn_t method. */
static svn_error_t *
compat_branch_txn_sequence_point(svn_branch__txn_t *txn,
                                 apr_pool_t *scratch_pool)
{
  /* Just forwarding: nothing more is needed. */
  SVN_ERR(svn_branch__txn_sequence_point(txn->priv->txn,
                                         scratch_pool));
  return SVN_NO_ERROR;
}

/* An #svn_branch__txn_t method. */
static svn_error_t *
compat_branch_txn_complete(svn_branch__txn_t *txn,
                           apr_pool_t *scratch_pool)
{
  svn_branch__txn_priv_t *eb = txn->priv;
  svn_error_t *err;

  /* Convert the transaction to a revision */
  SVN_ERR(svn_branch__txn_sequence_point(txn->priv->txn, scratch_pool));
  SVN_ERR(svn_branch__txn_finalize_eids(txn->priv->txn, scratch_pool));

  err = drive_changes(eb, scratch_pool);

  if (!err)
     {
       err = svn_error_compose_create(err, eb->deditor->close_edit(
                                                            eb->dedit_baton,
                                                            scratch_pool));
     }

  if (err)
    svn_error_clear(eb->deditor->abort_edit(eb->dedit_baton, scratch_pool));

  SVN_ERR(svn_branch__txn_complete(txn->priv->txn, scratch_pool));

  return err;
}

/* An #svn_branch__txn_t method. */
static svn_error_t *
compat_branch_txn_abort(svn_branch__txn_t *txn,
                        apr_pool_t *scratch_pool)
{
  svn_branch__txn_priv_t *eb = txn->priv;

  SVN_ERR(eb->deditor->abort_edit(eb->dedit_baton, scratch_pool));

  SVN_ERR(svn_branch__txn_abort(txn->priv->txn,
                                scratch_pool));
  return SVN_NO_ERROR;
}

/* Baton for wrap_fetch_func. */
typedef struct wrap_fetch_baton_t
{
  /* Wrapped fetcher */
  svn_branch__compat_fetch_func_t fetch_func;
  void *fetch_baton;
} wrap_fetch_baton_t;

/* The purpose of this fetcher-wrapper is to make it appear that B0
 * was created (as an empty dir) in r0.
 */
static svn_error_t *
wrap_fetch_func(svn_node_kind_t *kind,
                apr_hash_t **props,
                svn_stringbuf_t **file_text,
                apr_hash_t **children_names,
                void *baton,
                const char *repos_relpath,
                svn_revnum_t revision,
                apr_pool_t *result_pool,
                apr_pool_t *scratch_pool)
{
  wrap_fetch_baton_t *b = baton;

  if (revision == 0 && strcmp(repos_relpath, "top0") == 0)
    {
      if (kind)
        *kind = svn_node_dir;
      if (props)
        *props = apr_hash_make(result_pool);
      if (file_text)
        *file_text = NULL;
      if (children_names)
        *children_names = apr_hash_make(result_pool);
    }
  else
    {
      SVN_ERR(b->fetch_func(kind, props, file_text, children_names,
                            b->fetch_baton,
                            repos_relpath, revision,
                            result_pool, scratch_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_branch__compat_txn_from_delta_for_commit(
                        svn_branch__txn_t **txn_p,
                        svn_branch__compat_shim_connector_t **shim_connector,
                        const svn_delta_editor_t *deditor,
                        void *dedit_baton,
                        svn_branch__txn_t *branching_txn,
                        const char *repos_root_url,
                        svn_branch__compat_fetch_func_t fetch_func,
                        void *fetch_baton,
                        svn_cancel_func_t cancel_func,
                        void *cancel_baton,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  static const svn_branch__txn_vtable_t vtable = {
    {0},
    compat_branch_txn_get_branches,
    compat_branch_txn_delete_branch,
    compat_branch_txn_get_num_new_eids,
    compat_branch_txn_new_eid,
    compat_branch_txn_open_branch,
    compat_branch_txn_finalize_eids,
    compat_branch_txn_serialize,
    compat_branch_txn_sequence_point,
    compat_branch_txn_complete,
    compat_branch_txn_abort
  };
  svn_branch__txn_t *txn;
  svn_branch__txn_priv_t *eb = apr_pcalloc(result_pool, sizeof(*eb));
  wrap_fetch_baton_t *wb = apr_pcalloc(result_pool, sizeof(*wb));

  eb->deditor = deditor;
  eb->dedit_baton = dedit_baton;

  eb->repos_root_url = apr_pstrdup(result_pool, repos_root_url);

  eb->changes = apr_hash_make(result_pool);

  wb->fetch_func = fetch_func;
  wb->fetch_baton = fetch_baton;
  eb->fetch_func = wrap_fetch_func;
  eb->fetch_baton = wb;

  eb->edit_pool = result_pool;

  branching_txn = svn_branch__nested_txn_create(branching_txn, result_pool);

  eb->txn = branching_txn;

  txn = svn_branch__txn_create(&vtable, NULL, NULL, result_pool);
  txn->priv = eb;
  txn->repos = branching_txn->repos;
  txn->rev = branching_txn->rev;
  txn->base_rev = branching_txn->base_rev;
  *txn_p = txn;

  if (shim_connector)
    {
#if 0
      *shim_connector = apr_palloc(result_pool, sizeof(**shim_connector));
#ifdef SHIM_WITH_ABS_PATHS
      (*shim_connector)->ev1_absolute_paths
        = apr_palloc(result_pool, sizeof(svn_boolean_t));
      eb->make_abs_paths = (*shim_connector)->ev1_absolute_paths;
#endif
      (*shim_connector)->target_revision_func = set_target_revision_ev3;
      (*shim_connector)->start_edit_func = open_root_ev3;
#ifdef SHIM_WITH_UNLOCK
      (*shim_connector)->unlock_func = do_unlock;
#endif
      (*shim_connector)->baton = eb;
#endif
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_branch__compat_txn_from_delta_for_update(
                        svn_branch__compat_update_editor3_t **update_editor_p,
                        const svn_delta_editor_t *deditor,
                        void *dedit_baton,
                        svn_branch__txn_t *branching_txn,
                        const char *repos_root_url,
                        const char *base_repos_relpath,
                        svn_branch__compat_fetch_func_t fetch_func,
                        void *fetch_baton,
                        svn_cancel_func_t cancel_func,
                        void *cancel_baton,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  svn_branch__compat_update_editor3_t *update_editor
    = apr_pcalloc(result_pool, sizeof(*update_editor));
  svn_branch__compat_shim_connector_t *shim_connector;

  /*(("svn_delta__ev3_from_delta_for_update(base='%s')...",
           base_repos_relpath));*/

  /*SVN_ERR(svn_delta__get_debug_editor(&deditor, &dedit_baton,
                                      deditor, dedit_baton,
                                      "[1>UP] ", result_pool));*/
  SVN_ERR(svn_branch__compat_txn_from_delta_for_commit(
                        &update_editor->edit_txn,
                        &shim_connector,
                        deditor, dedit_baton,
                        branching_txn, repos_root_url,
                        fetch_func, fetch_baton,
                        cancel_func, cancel_baton,
                        result_pool, scratch_pool));

  update_editor->set_target_revision_func = shim_connector->target_revision_func;
  update_editor->set_target_revision_baton = shim_connector->baton;
  /* shim_connector->start_edit_func = open_root_ev3; */
#ifdef SHIM_WITH_ABS_PATHS
  update_editor->ev1_absolute_paths /*...*/;
#endif
#ifdef SHIM_WITH_UNLOCK
  update_editor->unlock_func = do_unlock;
#endif

  *update_editor_p = update_editor;
  return SVN_NO_ERROR;
}
