/*
 * update_editor.c :  main editor for checkouts and updates
 *
 * ====================================================================
 *    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 <stdlib.h>
#include <string.h>

#include <apr_pools.h>
#include <apr_hash.h>
#include <apr_md5.h>
#include <apr_tables.h>
#include <apr_strings.h>

#include "svn_types.h"
#include "svn_pools.h"
#include "svn_hash.h"
#include "svn_string.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_error.h"
#include "svn_io.h"
#include "svn_private_config.h"
#include "svn_time.h"

#include "wc.h"
#include "adm_files.h"
#include "conflicts.h"
#include "translate.h"
#include "workqueue.h"

#include "private/svn_subr_private.h"
#include "private/svn_wc_private.h"
#include "private/svn_editor.h"

/* Checks whether a svn_wc__db_status_t indicates whether a node is
   present in a working copy. Used by the editor implementation */
#define IS_NODE_PRESENT(status)                             \
           ((status) != svn_wc__db_status_server_excluded &&\
            (status) != svn_wc__db_status_excluded &&       \
            (status) != svn_wc__db_status_not_present)

static svn_error_t *
path_join_under_root(const char **result_path,
                     const char *base_path,
                     const char *add_path,
                     apr_pool_t *result_pool);


/*
 * This code handles "checkout" and "update" and "switch".
 * A checkout is similar to an update that is only adding new items.
 *
 * The intended behaviour of "update" and "switch", focusing on the checks
 * to be made before applying a change, is:
 *
 *   For each incoming change:
 *     if target is already in conflict or obstructed:
 *       skip this change
 *     else
 *     if this action will cause a tree conflict:
 *       record the tree conflict
 *       skip this change
 *     else:
 *       make this change
 *
 * In more detail:
 *
 *   For each incoming change:
 *
 *   1.   if  # Incoming change is inside an item already in conflict:
 *    a.    tree/text/prop change to node beneath tree-conflicted dir
 *        then  # Skip all changes in this conflicted subtree [*1]:
 *          do not update the Base nor the Working
 *          notify "skipped because already in conflict" just once
 *            for the whole conflicted subtree
 *
 *        if  # Incoming change affects an item already in conflict:
 *    b.    tree/text/prop change to tree-conflicted dir/file, or
 *    c.    tree change to a text/prop-conflicted file/dir, or
 *    d.    text/prop change to a text/prop-conflicted file/dir [*2], or
 *    e.    tree change to a dir tree containing any conflicts,
 *        then  # Skip this change [*1]:
 *          do not update the Base nor the Working
 *          notify "skipped because already in conflict"
 *
 *   2.   if  # Incoming change affects an item that's "obstructed":
 *    a.    on-disk node kind doesn't match recorded Working node kind
 *            (including an absence/presence mis-match),
 *        then  # Skip this change [*1]:
 *          do not update the Base nor the Working
 *          notify "skipped because obstructed"
 *
 *   3.   if  # Incoming change raises a tree conflict:
 *    a.    tree/text/prop change to node beneath sched-delete dir, or
 *    b.    tree/text/prop change to sched-delete dir/file, or
 *    c.    text/prop change to tree-scheduled dir/file,
 *        then  # Skip this change:
 *          do not update the Base nor the Working [*3]
 *          notify "tree conflict"
 *
 *   4.   Apply the change:
 *          update the Base
 *          update the Working, possibly raising text/prop conflicts
 *          notify
 *
 * Notes:
 *
 *      "Tree change" here refers to an add or delete of the target node,
 *      including the add or delete part of a copy or move or rename.
 *
 * [*1] We should skip changes to an entire node, as the base revision number
 *      applies to the entire node. Not sure how this affects attempts to
 *      handle text and prop changes separately.
 *
 * [*2] Details of which combinations of property and text changes conflict
 *      are not specified here.
 *
 * [*3] For now, we skip the update, and require the user to:
 *        - Modify the WC to be compatible with the incoming change;
 *        - Mark the conflict as resolved;
 *        - Repeat the update.
 *      Ideally, it would be possible to resolve any conflict without
 *      repeating the update. To achieve this, we would have to store the
 *      necessary data at conflict detection time, and delay the update of
 *      the Base until the time of resolving.
 */


/*** batons ***/

struct edit_baton
{
  /* For updates, the "destination" of the edit is ANCHOR_ABSPATH, the
     directory containing TARGET_ABSPATH. If ANCHOR_ABSPATH itself is the
     target, the values are identical.

     TARGET_BASENAME is the name of TARGET_ABSPATH in ANCHOR_ABSPATH, or "" if
     ANCHOR_ABSPATH is the target */
  const char *target_basename;

  /* Absolute variants of ANCHOR and TARGET */
  const char *anchor_abspath;
  const char *target_abspath;

  /* The DB handle for managing the working copy state.  */
  svn_wc__db_t *db;

  /* Array of file extension patterns to preserve as extensions in
     generated conflict files. */
  const apr_array_header_t *ext_patterns;

  /* Hash mapping const char * absolute working copy paths to depth-first
     ordered arrays of svn_prop_inherited_item_t * structures representing
     the properties inherited by the base node at that working copy path.
     May be NULL. */
  apr_hash_t *wcroot_iprops;

  /* The revision we're targeting...or something like that.  This
     starts off as a pointer to the revision to which we are updating,
     or SVN_INVALID_REVNUM, but by the end of the edit, should be
     pointing to the final revision. */
  svn_revnum_t *target_revision;

  /* The requested depth of this edit. */
  svn_depth_t requested_depth;

  /* Is the requested depth merely an operational limitation, or is
     also the new sticky ambient depth of the update target? */
  svn_boolean_t depth_is_sticky;

  /* Need to know if the user wants us to overwrite the 'now' times on
     edited/added files with the last-commit-time. */
  svn_boolean_t use_commit_times;

  /* Was the root actually opened (was this a non-empty edit)? */
  svn_boolean_t root_opened;

  /* Was the update-target deleted?  This is a special situation. */
  svn_boolean_t target_deleted;

  /* Allow unversioned obstructions when adding a path. */
  svn_boolean_t allow_unver_obstructions;

  /* Handle local additions as modifications of new nodes */
  svn_boolean_t adds_as_modification;

  /* If set, we check out into an empty directory. This allows for a number
     of conflict checks to be omitted. */
  svn_boolean_t clean_checkout;

  /* If this is a 'switch' operation, the new relpath of target_abspath,
     else NULL. */
  const char *switch_repos_relpath;

  /* The URL to the root of the repository. */
  const char *repos_root;

  /* The UUID of the repos, or NULL. */
  const char *repos_uuid;

  /* External diff3 to use for merges (can be null, in which case
     internal merge code is used). */
  const char *diff3_cmd;

  /* Externals handler */
  svn_wc_external_update_t external_func;
  void *external_baton;

  /* This editor sends back notifications as it edits. */
  svn_wc_notify_func2_t notify_func;
  void *notify_baton;

  /* This editor is normally wrapped in a cancellation editor anyway,
     so it doesn't bother to check for cancellation itself.  However,
     it needs a cancel_func and cancel_baton available to pass to
     long-running functions. */
  svn_cancel_func_t cancel_func;
  void *cancel_baton;

  /* This editor will invoke a interactive conflict-resolution
     callback, if available. */
  svn_wc_conflict_resolver_func2_t conflict_func;
  void *conflict_baton;

  /* Subtrees that were skipped during the edit, and therefore shouldn't
     have their revision/url info updated at the end.  If a path is a
     directory, its descendants will also be skipped.  The keys are paths
     relative to the working copy root and the values unspecified. */
  apr_hash_t *skipped_trees;

  /* A mapping from const char * repos_relpaths to the apr_hash_t * instances
     returned from fetch_dirents_func for that repos_relpath. These
     are used to avoid issue #3569 in specific update scenarios where a
     restricted depth is used. */
  apr_hash_t *dir_dirents;

  /* Absolute path of the working copy root or NULL if not initialized yet */
  const char *wcroot_abspath;

  /* After closing the root directory a copy of its edited value */
  svn_boolean_t edited;

  apr_pool_t *pool;
};


/* Record in the edit baton EB that LOCAL_ABSPATH's base version is not being
 * updated.
 *
 * Add to EB->skipped_trees a copy (allocated in EB->pool) of the string
 * LOCAL_ABSPATH.
 */
static svn_error_t *
remember_skipped_tree(struct edit_baton *eb,
                      const char *local_abspath,
                      apr_pool_t *scratch_pool)
{
  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));

  svn_hash_sets(eb->skipped_trees,
                apr_pstrdup(eb->pool,
                            svn_dirent_skip_ancestor(eb->wcroot_abspath,
                                                     local_abspath)),
                (void *)1);

  return SVN_NO_ERROR;
}

/* Per directory baton. Lives in its own subpool of the parent directory
   or of the edit baton if there is no parent directory */
struct dir_baton
{
  /* Basename of this directory. */
  const char *name;

  /* Absolute path of this directory */
  const char *local_abspath;

  /* The repository relative path this directory will correspond to. */
  const char *new_repos_relpath;

  /* The revision of the directory before updating */
  svn_revnum_t old_revision;

  /* The repos_relpath before updating/switching */
  const char *old_repos_relpath;

  /* The global edit baton. */
  struct edit_baton *edit_baton;

  /* Baton for this directory's parent, or NULL if this is the root
     directory. */
  struct dir_baton *parent_baton;

  /* Set if updates to this directory are skipped */
  svn_boolean_t skip_this;

  /* Set if there was a previous notification for this directory */
  svn_boolean_t already_notified;

  /* Set if this directory is being added during this editor drive. */
  svn_boolean_t adding_dir;

  /* Set on a node and its descendants are not present in the working copy
     but should still be updated (not skipped). These nodes should all be
     marked as deleted. */
  svn_boolean_t shadowed;

  /* Set on a node when the existing node is obstructed, and the edit operation
     continues as semi-shadowed update */
  svn_boolean_t edit_obstructed;

  /* The (new) changed_* information, cached to avoid retrieving it later */
  svn_revnum_t changed_rev;
  apr_time_t changed_date;
  const char *changed_author;

  /* If not NULL, contains a mapping of const char* basenames of children that
     have been deleted to their svn_skel_t* tree conflicts.
     We store this hash to allow replacements to continue under a just
     installed tree conflict.

     The add after the delete will then update the tree conflicts information
     and reinstall it. */
  apr_hash_t *deletion_conflicts;

  /* A hash of file names (only the hash key matters) seen by add_file and
     add_directory and not yet added to the database, mapping to a const
     char * node kind (via svn_node_kind_to_word(). */
  apr_hash_t *not_present_nodes;

  /* Set if an unversioned dir of the same name already existed in
     this directory. */
  svn_boolean_t obstruction_found;

  /* Set if a dir of the same name already exists and is
     scheduled for addition without history. */
  svn_boolean_t add_existed;

  /* An array of svn_prop_t structures, representing all the property
     changes to be applied to this directory. */
  apr_array_header_t *propchanges;

  /* A boolean indicating whether this node or one of its children has
     received any 'real' changes. Used to avoid tree conflicts for simple
     entryprop changes, like lock management */
  svn_boolean_t edited;

  /* The tree conflict to install once the node is really edited */
  svn_skel_t *edit_conflict;

  /* The bump information for this directory. */
  struct bump_dir_info *bump_info;

  /* The depth of the directory in the wc (or inferred if added).  Not
     used for filtering; we have a separate wrapping editor for that. */
  svn_depth_t ambient_depth;

  /* Was the directory marked as incomplete before the update?
     (In other words, are we resuming an interrupted update?)

     If WAS_INCOMPLETE is set to TRUE we expect to receive all child nodes
     and properties for/of the directory. If WAS_INCOMPLETE is FALSE then
     we only receive the changes in/for children and properties.*/
  svn_boolean_t was_incomplete;

  /* The pool in which this baton itself is allocated. */
  apr_pool_t *pool;

  /* how many nodes are referring to baton? */
  int ref_count;

};


struct handler_baton
{
  svn_txdelta_window_handler_t apply_handler;
  void *apply_baton;
  apr_pool_t *pool;
  struct file_baton *fb;

  /* Where we are assembling the new file. */
  svn_wc__db_install_data_t *install_data;

    /* The expected source checksum of the text source or NULL if no base
     checksum is available (MD5 if the server provides a checksum, SHA1 if
     the server doesn't) */
  svn_checksum_t *expected_source_checksum;

  /* Why two checksums?
     The editor currently provides an md5 which we use to detect corruption
     during transmission.  We use the sha1 inside libsvn_wc both for pristine
     handling and corruption detection.  In the future, the editor will also
     provide a sha1, so we may not have to calculate both, but for the time
     being, that's the way it is. */

  /* The calculated checksum of the text source or NULL if the actual
     checksum is not being calculated. The checksum kind is identical to the
     kind of expected_source_checksum. */
  svn_checksum_t *actual_source_checksum;

  /* The stream used to calculate the source checksums */
  svn_stream_t *source_checksum_stream;

  /* A calculated MD5 digest of NEW_TEXT_BASE_TMP_ABSPATH.
     This is initialized to all zeroes when the baton is created, then
     populated with the MD5 digest of the resultant fulltext after the
     last window is handled by the handler returned from
     apply_textdelta(). */
  unsigned char new_text_base_md5_digest[APR_MD5_DIGESTSIZE];

  /* A calculated SHA-1 of NEW_TEXT_BASE_TMP_ABSPATH, which we'll use for
     eventually writing the pristine. */
  svn_checksum_t * new_text_base_sha1_checksum;
};


/* Get an empty file in the temporary area for WRI_ABSPATH.  The file will
   not be set for automatic deletion, and the name will be returned in
   TMP_FILENAME.

   This implementation creates a new empty file with a unique name.

   ### This is inefficient for callers that just want an empty file to read
   ### from.  There could be (and there used to be) a permanent, shared
   ### empty file for this purpose.

   ### This is inefficient for callers that just want to reserve a unique
   ### file name to create later.  A better way may not be readily available.
 */
static svn_error_t *
get_empty_tmp_file(const char **tmp_filename,
                   svn_wc__db_t *db,
                   const char *wri_abspath,
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
{
  const char *temp_dir_abspath;

  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, db, wri_abspath,
                                         scratch_pool, scratch_pool));
  SVN_ERR(svn_io_open_unique_file3(NULL, tmp_filename, temp_dir_abspath,
                                   svn_io_file_del_none,
                                   scratch_pool, scratch_pool));

  return SVN_NO_ERROR;
}

/* An APR pool cleanup handler.  This runs the working queue for an
   editor baton. */
static apr_status_t
cleanup_edit_baton(void *edit_baton)
{
  struct edit_baton *eb = edit_baton;
  svn_error_t *err;
  apr_pool_t *pool = apr_pool_parent_get(eb->pool);

  err = svn_wc__wq_run(eb->db, eb->wcroot_abspath,
                       NULL /* cancel_func */, NULL /* cancel_baton */,
                       pool);

  if (err)
    {
      apr_status_t apr_err = err->apr_err;
      svn_error_clear(err);
      return apr_err;
    }
  return APR_SUCCESS;
}

/* Calculate the new repos_relpath for a directory or file */
static svn_error_t *
calculate_repos_relpath(const char **new_repos_relpath,
                        const char *local_abspath,
                        const char *old_repos_relpath,
                        struct edit_baton *eb,
                        struct dir_baton *pb,
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
{
  const char *name = svn_dirent_basename(local_abspath, NULL);

  /* Figure out the new_repos_relpath for this directory. */
  if (eb->switch_repos_relpath)
    {
      /* Handle switches... */

      if (pb == NULL)
        {
          if (*eb->target_basename == '\0')
            {
              /* No parent baton and target_basename=="" means that we are
                 the target of the switch. Thus, our new_repos_relpath will be
                 the switch_repos_relpath.  */
              *new_repos_relpath = eb->switch_repos_relpath;
            }
          else
            {
              /* This node is NOT the target of the switch (one of our
                 children is the target); therefore, it must already exist.
                 Get its old REPOS_RELPATH, as it won't be changing.  */
              *new_repos_relpath = apr_pstrdup(result_pool, old_repos_relpath);
            }
        }
      else
        {
          /* This directory is *not* the root (has a parent). If there is
             no grandparent, then we may have anchored at the parent,
             and self is the target. If we match the target, then set
             new_repos_relpath to the switch_repos_relpath.

             Otherwise, we simply extend new_repos_relpath from the parent.  */

          if (pb->parent_baton == NULL
              && strcmp(eb->target_basename, name) == 0)
            *new_repos_relpath = eb->switch_repos_relpath;
          else
            *new_repos_relpath = svn_relpath_join(pb->new_repos_relpath, name,
                                                  result_pool);
        }
    }
  else  /* must be an update */
    {
      /* If we are adding the node, then simply extend the parent's
         relpath for our own.  */
      if (old_repos_relpath == NULL)
        {
          SVN_ERR_ASSERT(pb != NULL);
          *new_repos_relpath = svn_relpath_join(pb->new_repos_relpath, name,
                                                result_pool);
        }
      else
        {
          *new_repos_relpath = apr_pstrdup(result_pool, old_repos_relpath);
        }
    }

  return SVN_NO_ERROR;
}

/* Make a new dir baton in a subpool of PB->pool. PB is the parent baton.
   If PATH and PB are NULL, this is the root directory of the edit; in this
   case, make the new dir baton in a subpool of EB->pool.
   ADDING should be TRUE if we are adding this directory.  */
static svn_error_t *
make_dir_baton(struct dir_baton **d_p,
               const char *path,
               struct edit_baton *eb,
               struct dir_baton *pb,
               svn_boolean_t adding,
               apr_pool_t *scratch_pool)
{
  apr_pool_t *dir_pool;
  struct dir_baton *d;

  if (pb != NULL)
    dir_pool = svn_pool_create(pb->pool);
  else
    dir_pool = svn_pool_create(eb->pool);

  SVN_ERR_ASSERT(path || (! pb));

  /* Okay, no easy out, so allocate and initialize a dir baton. */
  d = apr_pcalloc(dir_pool, sizeof(*d));

  /* Construct the PATH and baseNAME of this directory. */
  if (path)
    {
      d->name = svn_dirent_basename(path, dir_pool);
      SVN_ERR(path_join_under_root(&d->local_abspath,
                                   pb->local_abspath, d->name, dir_pool));
    }
  else
    {
      /* This is the root baton. */
      d->name = NULL;
      d->local_abspath = eb->anchor_abspath;
    }

  d->edit_baton   = eb;
  d->parent_baton = pb;
  d->pool         = dir_pool;
  d->propchanges  = apr_array_make(dir_pool, 1, sizeof(svn_prop_t));
  d->obstruction_found = FALSE;
  d->add_existed  = FALSE;
  d->ref_count = 1;
  d->old_revision = SVN_INVALID_REVNUM;
  d->adding_dir   = adding;
  d->changed_rev  = SVN_INVALID_REVNUM;
  d->not_present_nodes = apr_hash_make(dir_pool);

  /* Copy some flags from the parent baton */
  if (pb)
    {
      d->skip_this = pb->skip_this;
      d->shadowed = pb->shadowed || pb->edit_obstructed;

      /* the parent's bump info has one more referer */
      pb->ref_count++;
    }

  /* The caller of this function needs to fill these in. */
  d->ambient_depth = svn_depth_unknown;
  d->was_incomplete = FALSE;

  *d_p = d;
  return SVN_NO_ERROR;
}

/* Forward declarations. */
static svn_error_t *
already_in_a_tree_conflict(svn_boolean_t *conflicted,
                           svn_boolean_t *ignored,
                           svn_wc__db_t *db,
                           const char *local_abspath,
                           apr_pool_t *scratch_pool);


static void
do_notification(const struct edit_baton *eb,
                const char *local_abspath,
                svn_node_kind_t kind,
                svn_wc_notify_action_t action,
                apr_pool_t *scratch_pool)
{
  svn_wc_notify_t *notify;

  if (eb->notify_func == NULL)
    return;

  notify = svn_wc_create_notify(local_abspath, action, scratch_pool);
  notify->kind = kind;

  (*eb->notify_func)(eb->notify_baton, notify, scratch_pool);
}

/* Decrement the directory's reference count. If it hits zero,
   then this directory is "done". This means it is safe to clear its pool.

   In addition, when the directory is "done", we recurse to possible cleanup
   the parent directory.
*/
static svn_error_t *
maybe_release_dir_info(struct dir_baton *db)
{
  db->ref_count--;

  if (!db->ref_count)
    {
      struct dir_baton *pb = db->parent_baton;

      svn_pool_destroy(db->pool);

      if (pb)
        SVN_ERR(maybe_release_dir_info(pb));
    }

  return SVN_NO_ERROR;
}

/* Per file baton. Lives in its own subpool below the pool of the parent
   directory */
struct file_baton
{
  /* Pool specific to this file_baton. */
  apr_pool_t *pool;

  /* Name of this file (its entry in the directory). */
  const char *name;

  /* Absolute path to this file */
  const char *local_abspath;

  /* The repository relative path this file will correspond to. */
  const char *new_repos_relpath;

  /* The revision of the file before updating */
  svn_revnum_t old_revision;

  /* The repos_relpath before updating/switching */
  const char *old_repos_relpath;

  /* The global edit baton. */
  struct edit_baton *edit_baton;

  /* The parent directory of this file. */
  struct dir_baton *dir_baton;

  /* Set if updates to this directory are skipped */
  svn_boolean_t skip_this;

  /* Set if there was a previous notification  */
  svn_boolean_t already_notified;

  /* Set if this file is new. */
  svn_boolean_t adding_file;

  /* Set if an unversioned file of the same name already existed in
     this directory. */
  svn_boolean_t obstruction_found;

  /* Set if a file of the same name already exists and is
     scheduled for addition without history. */
  svn_boolean_t add_existed;

  /* Set if this file is being added in the BASE layer, but is not-present
     in the working copy (replaced, deleted, etc.). */
  svn_boolean_t shadowed;

  /* Set on a node when the existing node is obstructed, and the edit operation
     continues as semi-shadowed update */
  svn_boolean_t edit_obstructed;

  /* The (new) changed_* information, cached to avoid retrieving it later */
  svn_revnum_t changed_rev;
  apr_time_t changed_date;
  const char *changed_author;

  /* If there are file content changes, these are the checksums of the
     resulting new text base, which is in the pristine store, else NULL. */
  const svn_checksum_t *new_text_base_md5_checksum;
  const svn_checksum_t *new_text_base_sha1_checksum;

  /* The checksum of the file before the update */
  const svn_checksum_t *original_checksum;

  /* An array of svn_prop_t structures, representing all the property
     changes to be applied to this file.  Once a file baton is
     initialized, this is never NULL, but it may have zero elements.  */
  apr_array_header_t *propchanges;

  /* For existing files, whether there are local modifications. FALSE for added
     files */
  svn_boolean_t local_prop_mods;

  /* Bump information for the directory this file lives in */
  struct bump_dir_info *bump_info;

  /* A boolean indicating whether this node or one of its children has
     received any 'real' changes. Used to avoid tree conflicts for simple
     entryprop changes, like lock management */
  svn_boolean_t edited;

  /* The tree conflict to install once the node is really edited */
  svn_skel_t *edit_conflict;
};


/* Make a new file baton in a subpool of PB->pool. PB is the parent baton.
 * PATH is relative to the root of the edit. ADDING tells whether this file
 * is being added. */
static svn_error_t *
make_file_baton(struct file_baton **f_p,
                struct dir_baton *pb,
                const char *path,
                svn_boolean_t adding,
                apr_pool_t *scratch_pool)
{
  apr_pool_t *file_pool = svn_pool_create(pb->pool);
  struct file_baton *f = apr_pcalloc(file_pool, sizeof(*f));

  SVN_ERR_ASSERT(path);

  /* Make the file's on-disk name. */
  f->name = svn_dirent_basename(path, file_pool);
  f->old_revision = SVN_INVALID_REVNUM;
  SVN_ERR(path_join_under_root(&f->local_abspath,
                               pb->local_abspath, f->name, file_pool));

  f->pool              = file_pool;
  f->edit_baton        = pb->edit_baton;
  f->propchanges       = apr_array_make(file_pool, 1, sizeof(svn_prop_t));
  f->bump_info         = pb->bump_info;
  f->adding_file       = adding;
  f->obstruction_found = FALSE;
  f->add_existed       = FALSE;
  f->skip_this         = pb->skip_this;
  f->shadowed          = pb->shadowed || pb->edit_obstructed;
  f->dir_baton         = pb;
  f->changed_rev       = SVN_INVALID_REVNUM;

  /* the directory has one more referer now */
  pb->ref_count++;

  *f_p = f;
  return SVN_NO_ERROR;
}

/* Complete a conflict skel by describing the update.
 *
 * LOCAL_KIND is the node kind of the tree conflict victim in the
 * working copy.
 *
 * All temporary allocations are be made in SCRATCH_POOL, while allocations
 * needed for the returned conflict struct are made in RESULT_POOL.
 */
static svn_error_t *
complete_conflict(svn_skel_t *conflict,
                  const struct edit_baton *eb,
                  const char *local_abspath,
                  const char *old_repos_relpath,
                  svn_revnum_t old_revision,
                  const char *new_repos_relpath,
                  svn_node_kind_t local_kind,
                  svn_node_kind_t target_kind,
                  const svn_skel_t *delete_conflict,
                  apr_pool_t *result_pool,
                  apr_pool_t *scratch_pool)
{
  const svn_wc_conflict_version_t *original_version = NULL;
  svn_wc_conflict_version_t *target_version;
  svn_boolean_t is_complete;

  SVN_ERR_ASSERT(new_repos_relpath);

  if (!conflict)
    return SVN_NO_ERROR; /* Not conflicted */

  SVN_ERR(svn_wc__conflict_skel_is_complete(&is_complete, conflict));

  if (is_complete)
    return SVN_NO_ERROR; /* Already completed */

  if (old_repos_relpath)
    original_version = svn_wc_conflict_version_create2(eb->repos_root,
                                                       eb->repos_uuid,
                                                       old_repos_relpath,
                                                       old_revision,
                                                       local_kind,
                                                       result_pool);
  else if (delete_conflict)
    {
      const apr_array_header_t *locations;

      SVN_ERR(svn_wc__conflict_read_info(NULL, &locations, NULL, NULL, NULL,
                                         eb->db, local_abspath,
                                         delete_conflict,
                                         scratch_pool, scratch_pool));

      if (locations)
        {
          original_version = APR_ARRAY_IDX(locations, 0,
                                           const svn_wc_conflict_version_t *);
        }
    }

  target_version = svn_wc_conflict_version_create2(eb->repos_root,
                                                   eb->repos_uuid,
                                                   new_repos_relpath,
                                                   *eb->target_revision,
                                                   target_kind,
                                                   result_pool);

  if (eb->switch_repos_relpath)
    SVN_ERR(svn_wc__conflict_skel_set_op_switch(conflict,
                                                original_version,
                                                target_version,
                                                result_pool, scratch_pool));
  else
    SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict,
                                                original_version,
                                                target_version,
                                                result_pool, scratch_pool));

  return SVN_NO_ERROR;
}


/* Called when a directory is really edited, to avoid marking a
   tree conflict on a node for a no-change edit */
static svn_error_t *
mark_directory_edited(struct dir_baton *db, apr_pool_t *scratch_pool)
{
  if (db->edited)
    return SVN_NO_ERROR;

  if (db->parent_baton)
    SVN_ERR(mark_directory_edited(db->parent_baton, scratch_pool));

  db->edited = TRUE;

  if (db->edit_conflict)
    {
      /* We have a (delayed) tree conflict to install */

      SVN_ERR(complete_conflict(db->edit_conflict, db->edit_baton,
                                db->local_abspath,
                                db->old_repos_relpath, db->old_revision,
                                db->new_repos_relpath,
                                svn_node_dir, svn_node_dir,
                                NULL,
                                db->pool, scratch_pool));
      SVN_ERR(svn_wc__db_op_mark_conflict(db->edit_baton->db,
                                          db->local_abspath,
                                          db->edit_conflict, NULL,
                                          scratch_pool));

      do_notification(db->edit_baton, db->local_abspath, svn_node_dir,
                      svn_wc_notify_tree_conflict, scratch_pool);
      db->already_notified = TRUE;
    }

  return SVN_NO_ERROR;
}

/* Called when a file is really edited, to avoid marking a
   tree conflict on a node for a no-change edit */
static svn_error_t *
mark_file_edited(struct file_baton *fb, apr_pool_t *scratch_pool)
{
  if (fb->edited)
    return SVN_NO_ERROR;

  SVN_ERR(mark_directory_edited(fb->dir_baton, scratch_pool));

  fb->edited = TRUE;

  if (fb->edit_conflict)
    {
      /* We have a (delayed) tree conflict to install */

      SVN_ERR(complete_conflict(fb->edit_conflict, fb->edit_baton,
                                fb->local_abspath, fb->old_repos_relpath,
                                fb->old_revision, fb->new_repos_relpath,
                                svn_node_file, svn_node_file,
                                NULL,
                                fb->pool, scratch_pool));

      SVN_ERR(svn_wc__db_op_mark_conflict(fb->edit_baton->db,
                                          fb->local_abspath,
                                          fb->edit_conflict, NULL,
                                          scratch_pool));

      do_notification(fb->edit_baton, fb->local_abspath, svn_node_file,
                      svn_wc_notify_tree_conflict, scratch_pool);
      fb->already_notified = TRUE;
    }

  return SVN_NO_ERROR;
}


/* Handle the next delta window of the file described by BATON.  If it is
 * the end (WINDOW == NULL), then check the checksum, store the text in the
 * pristine store and write its details into BATON->fb->new_text_base_*. */
static svn_error_t *
window_handler(svn_txdelta_window_t *window, void *baton)
{
  struct handler_baton *hb = baton;
  struct file_baton *fb = hb->fb;
  svn_error_t *err;

  /* Apply this window.  We may be done at that point.  */
  err = hb->apply_handler(window, hb->apply_baton);
  if (window != NULL && !err)
    return SVN_NO_ERROR;

  if (hb->expected_source_checksum)
    {
      /* Close the stream to calculate HB->actual_source_md5_checksum. */
      svn_error_t *err2 = svn_stream_close(hb->source_checksum_stream);

      if (!err2)
        {
          SVN_ERR_ASSERT(hb->expected_source_checksum->kind ==
                        hb->actual_source_checksum->kind);

          if (!svn_checksum_match(hb->expected_source_checksum,
                                  hb->actual_source_checksum))
            {
              err = svn_error_createf(SVN_ERR_WC_CORRUPT_TEXT_BASE, err,
                        _("Checksum mismatch while updating '%s':\n"
                          "   expected:  %s\n"
                          "     actual:  %s\n"),
                        svn_dirent_local_style(fb->local_abspath, hb->pool),
                        svn_checksum_to_cstring(hb->expected_source_checksum,
                                                hb->pool),
                        svn_checksum_to_cstring(hb->actual_source_checksum,
                                                hb->pool));
            }
        }

      err = svn_error_compose_create(err, err2);
    }

  if (err)
    {
      /* We failed to apply the delta; clean up the temporary file if it
         already created by lazy_open_target(). */
      if (hb->install_data)
        {
          svn_error_clear(svn_wc__db_pristine_install_abort(hb->install_data,
                                                            hb->pool));
        }
    }
  else
    {
      /* Tell the file baton about the new text base's checksums. */
      fb->new_text_base_md5_checksum =
        svn_checksum__from_digest_md5(hb->new_text_base_md5_digest, fb->pool);
      fb->new_text_base_sha1_checksum =
        svn_checksum_dup(hb->new_text_base_sha1_checksum, fb->pool);

      /* Store the new pristine text in the pristine store now.  Later, in a
         single transaction we will update the BASE_NODE to include a
         reference to this pristine text's checksum. */
      SVN_ERR(svn_wc__db_pristine_install(hb->install_data,
                                          fb->new_text_base_sha1_checksum,
                                          fb->new_text_base_md5_checksum,
                                          hb->pool));
    }

  svn_pool_destroy(hb->pool);

  return err;
}


/* Find the last-change info within ENTRY_PROPS, and return then in the
   CHANGED_* parameters. Each parameter will be initialized to its "none"
   value, and will contain the relavent info if found.

   CHANGED_AUTHOR will be allocated in RESULT_POOL. SCRATCH_POOL will be
   used for some temporary allocations.
*/
static svn_error_t *
accumulate_last_change(svn_revnum_t *changed_rev,
                       apr_time_t *changed_date,
                       const char **changed_author,
                       const apr_array_header_t *entry_props,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  int i;

  *changed_rev = SVN_INVALID_REVNUM;
  *changed_date = 0;
  *changed_author = NULL;

  for (i = 0; i < entry_props->nelts; ++i)
    {
      const svn_prop_t *prop = &APR_ARRAY_IDX(entry_props, i, svn_prop_t);

      /* A prop value of NULL means the information was not
         available.  We don't remove this field from the entries
         file; we have convention just leave it empty.  So let's
         just skip those entry props that have no values. */
      if (! prop->value)
        continue;

      if (! strcmp(prop->name, SVN_PROP_ENTRY_LAST_AUTHOR))
        *changed_author = apr_pstrdup(result_pool, prop->value->data);
      else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_REV))
        {
          apr_int64_t rev;
          SVN_ERR(svn_cstring_atoi64(&rev, prop->value->data));
          *changed_rev = (svn_revnum_t)rev;
        }
      else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_DATE))
        SVN_ERR(svn_time_from_cstring(changed_date, prop->value->data,
                                      scratch_pool));

      /* Starting with Subversion 1.7 we ignore the SVN_PROP_ENTRY_UUID
         property here. */
    }

  return SVN_NO_ERROR;
}


/* Join ADD_PATH to BASE_PATH.  If ADD_PATH is absolute, or if any ".."
 * component of it resolves to a path above BASE_PATH, then return
 * SVN_ERR_WC_OBSTRUCTED_UPDATE.
 *
 * This is to prevent the situation where the repository contains,
 * say, "..\nastyfile".  Although that's perfectly legal on some
 * systems, when checked out onto Win32 it would cause "nastyfile" to
 * be created in the parent of the current edit directory.
 *
 * (http://cve.mitre.org/cgi-bin/cvename.cgi?name=2007-3846)
 */
static svn_error_t *
path_join_under_root(const char **result_path,
                     const char *base_path,
                     const char *add_path,
                     apr_pool_t *pool)
{
  svn_boolean_t under_root;

  SVN_ERR(svn_dirent_is_under_root(&under_root,
                                   result_path, base_path, add_path, pool));

  if (! under_root)
    {
      return svn_error_createf(
          SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
          _("Path '%s' is not in the working copy"),
          svn_dirent_local_style(svn_dirent_join(base_path, add_path, pool),
                                 pool));
    }

  /* This catches issue #3288 */
  if (strcmp(add_path, svn_dirent_basename(*result_path, NULL)) != 0)
    {
      return svn_error_createf(
          SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
          _("'%s' is not valid as filename in directory '%s'"),
          svn_dirent_local_style(add_path, pool),
          svn_dirent_local_style(base_path, pool));
    }

  return SVN_NO_ERROR;
}


/*** The callbacks we'll plug into an svn_delta_editor_t structure. ***/

/* An svn_delta_editor_t function. */
static svn_error_t *
set_target_revision(void *edit_baton,
                    svn_revnum_t target_revision,
                    apr_pool_t *pool)
{
  struct edit_baton *eb = edit_baton;

  *(eb->target_revision) = target_revision;
  return SVN_NO_ERROR;
}

/* An svn_delta_editor_t function. */
static svn_error_t *
open_root(void *edit_baton,
          svn_revnum_t base_revision, /* This is ignored in co */
          apr_pool_t *pool,
          void **dir_baton)
{
  struct edit_baton *eb = edit_baton;
  struct dir_baton *db;
  svn_boolean_t already_conflicted, conflict_ignored;
  svn_error_t *err;
  svn_wc__db_status_t status;
  svn_wc__db_status_t base_status;
  svn_node_kind_t kind;
  svn_boolean_t have_work;

  /* Note that something interesting is actually happening in this
     edit run. */
  eb->root_opened = TRUE;

  SVN_ERR(make_dir_baton(&db, NULL, eb, NULL, FALSE, pool));
  *dir_baton = db;

  err = already_in_a_tree_conflict(&already_conflicted, &conflict_ignored,
                                   eb->db, db->local_abspath, pool);

  if (err)
    {
      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
        return svn_error_trace(err);

      svn_error_clear(err);
      already_conflicted = conflict_ignored = FALSE;
    }
  else if (already_conflicted)
    {
      /* Record a skip of both the anchor and target in the skipped tree
         as the anchor itself might not be updated */
      SVN_ERR(remember_skipped_tree(eb, db->local_abspath, pool));
      SVN_ERR(remember_skipped_tree(eb, eb->target_abspath, pool));

      db->skip_this = TRUE;
      db->already_notified = TRUE;

      /* Notify that we skipped the target, while we actually skipped
         the anchor */
      do_notification(eb, eb->target_abspath, svn_node_unknown,
                      svn_wc_notify_skip_conflicted, pool);

      return SVN_NO_ERROR;
    }


  SVN_ERR(svn_wc__db_read_info(&status, &kind, &db->old_revision,
                               &db->old_repos_relpath, NULL, NULL,
                               &db->changed_rev, &db->changed_date,
                               &db->changed_author, &db->ambient_depth,
                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               NULL, NULL, &have_work,
                               eb->db, db->local_abspath,
                               db->pool, pool));

  if (have_work)
    {
      SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL,
                                       &db->old_revision,
                                       &db->old_repos_relpath, NULL, NULL,
                                       &db->changed_rev, &db->changed_date,
                                       &db->changed_author,
                                       &db->ambient_depth,
                                       NULL, NULL, NULL, NULL, NULL, NULL,
                                       eb->db, db->local_abspath,
                                       db->pool, pool));
    }
  else
    base_status = status;

  SVN_ERR(calculate_repos_relpath(&db->new_repos_relpath, db->local_abspath,
                                  db->old_repos_relpath, eb, NULL,
                                  db->pool, pool));

  if (conflict_ignored)
    db->shadowed = TRUE;
  else if (have_work)
    {
      const char *move_src_root_abspath;

      SVN_ERR(svn_wc__db_base_moved_to(NULL, NULL, &move_src_root_abspath,
                                       NULL, eb->db, db->local_abspath,
                                       pool, pool));

      if (move_src_root_abspath)
        {
          /* This is an update anchored inside a move. We need to
             raise a move-edit tree-conflict on the move root to
             update the move destination. */
          svn_skel_t *tree_conflict = svn_wc__conflict_skel_create(pool);

          SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
                    tree_conflict, eb->db, move_src_root_abspath,
                    svn_wc_conflict_reason_moved_away,
                    svn_wc_conflict_action_edit,
                    move_src_root_abspath, pool, pool));

          if (strcmp(db->local_abspath, move_src_root_abspath))
            {
              /* We are raising the tree-conflict on some parent of
                 the edit root, we won't be handling that path again
                 so raise the conflict now. */
              SVN_ERR(complete_conflict(tree_conflict, eb,
                                        move_src_root_abspath,
                                        db->old_repos_relpath,
                                        db->old_revision,
                                        db->new_repos_relpath,
                                        svn_node_dir, svn_node_dir,
                                        NULL, pool, pool));
              SVN_ERR(svn_wc__db_op_mark_conflict(eb->db,
                                                  move_src_root_abspath,
                                                  tree_conflict,
                                                  NULL, pool));
              do_notification(eb, move_src_root_abspath, svn_node_dir,
                              svn_wc_notify_tree_conflict, pool);
            }
          else
            db->edit_conflict = tree_conflict;
        }

      db->shadowed = TRUE; /* Needed for the close_directory() on the root, to
                              make sure it doesn't use the ACTUAL tree */
    }

  if (*eb->target_basename == '\0')
    {
      /* For an update with a NULL target, this is equivalent to open_dir(): */

      db->was_incomplete = (base_status == svn_wc__db_status_incomplete);

      /* ### TODO: Add some tree conflict and obstruction detection, etc. like
                   open_directory() does.
                   (or find a way to reuse that code here)

         ### BH 2013: I don't think we need all of the detection here, as the
                      user explicitly asked to update this node. So we don't
                      have to tell that it is a local replacement/delete.
       */

      SVN_ERR(svn_wc__db_temp_op_start_directory_update(eb->db,
                                                        db->local_abspath,
                                                        db->new_repos_relpath,
                                                        *eb->target_revision,
                                                        pool));
    }

  return SVN_NO_ERROR;
}


/* ===================================================================== */
/* Checking for local modifications. */

/* Indicates an unset svn_wc_conflict_reason_t. */
#define SVN_WC_CONFLICT_REASON_NONE (svn_wc_conflict_reason_t)(-1)

/* Check whether the incoming change ACTION on FULL_PATH would conflict with
 * LOCAL_ABSPATH's scheduled change. If so, then raise a tree conflict with
 * LOCAL_ABSPATH as the victim.
 *
 * The edit baton EB gives information including whether the operation is
 * an update or a switch.
 *
 * WORKING_STATUS is the current node status of LOCAL_ABSPATH
 * and EXISTS_IN_REPOS specifies whether a BASE_NODE representation for exists
 * for this node. In that case the on disk type is compared to EXPECTED_KIND.
 *
 * If a tree conflict reason was found for the incoming action, the resulting
 * tree conflict info is returned in *PCONFLICT. PCONFLICT must be non-NULL,
 * while *PCONFLICT is always overwritten.
 *
 * The tree conflict is allocated in RESULT_POOL. Temporary allocations use
 * SCRATCH_POOL.
 */
static svn_error_t *
check_tree_conflict(svn_skel_t **pconflict,
                    struct edit_baton *eb,
                    const char *local_abspath,
                    svn_wc__db_status_t working_status,
                    svn_boolean_t exists_in_repos,
                    svn_node_kind_t expected_kind,
                    svn_wc_conflict_action_t action,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
{
  svn_wc_conflict_reason_t reason = SVN_WC_CONFLICT_REASON_NONE;
  svn_boolean_t modified = FALSE;
  const char *move_src_op_root_abspath = NULL;

  *pconflict = NULL;

  /* Find out if there are any local changes to this node that may
   * be the "reason" of a tree-conflict with the incoming "action". */
  switch (working_status)
    {
      case svn_wc__db_status_added:
      case svn_wc__db_status_moved_here:
      case svn_wc__db_status_copied:
        if (!exists_in_repos)
          {
            /* The node is locally added, and it did not exist before.  This
             * is an 'update', so the local add can only conflict with an
             * incoming 'add'.  In fact, if we receive anything else than an
             * svn_wc_conflict_action_add (which includes 'added',
             * 'copied-here' and 'moved-here') during update on a node that
             * did not exist before, then something is very wrong.
             * Note that if there was no action on the node, this code
             * would not have been called in the first place. */
            SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);

            /* Scan the addition in case our caller didn't. */
            if (working_status == svn_wc__db_status_added)
              SVN_ERR(svn_wc__db_scan_addition(&working_status, NULL, NULL,
                                               NULL, NULL, NULL, NULL,
                                               NULL, NULL,
                                               eb->db, local_abspath,
                                               scratch_pool, scratch_pool));

            if (working_status == svn_wc__db_status_moved_here)
              reason = svn_wc_conflict_reason_moved_here;
            else
              reason = svn_wc_conflict_reason_added;
          }
        else
          {
            /* The node is locally replaced but could also be moved-away,
               but we can't report that it is moved away and replaced.

               And we wouldn't be able to store that each of a dozen
               descendants was moved to other locations...

               Replaced is what actually happened... */

            reason = svn_wc_conflict_reason_replaced;
          }
        break;


      case svn_wc__db_status_deleted:
        {
          SVN_ERR(svn_wc__db_base_moved_to(NULL, NULL, NULL,
                                           &move_src_op_root_abspath,
                                           eb->db, local_abspath,
                                           scratch_pool, scratch_pool));
          if (move_src_op_root_abspath)
            reason = svn_wc_conflict_reason_moved_away;
          else
            reason = svn_wc_conflict_reason_deleted;
        }
        break;

      case svn_wc__db_status_incomplete:
        /* We used svn_wc__db_read_info(), so 'incomplete' means
         * - there is no node in the WORKING tree
         * - a BASE node is known to exist
         * So the node exists and is essentially 'normal'. We still need to
         * check prop and text mods, and those checks will retrieve the
         * missing information (hopefully). */
      case svn_wc__db_status_normal:
        if (action == svn_wc_conflict_action_edit)
          {
            /* An edit onto a local edit or onto *no* local changes is no
             * tree-conflict. (It's possibly a text- or prop-conflict,
             * but we don't handle those here.)
             *
             * Except when there is a local obstruction
             */
            if (exists_in_repos)
              {
                svn_node_kind_t disk_kind;

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

                if (disk_kind != expected_kind && disk_kind != svn_node_none)
                  {
                    reason = svn_wc_conflict_reason_obstructed;
                    break;
                  }

              }
            return SVN_NO_ERROR;
          }

        /* Replace is handled as delete and then specifically in
           add_directory() and add_file(), so we only expect deletes here */
        SVN_ERR_ASSERT(action == svn_wc_conflict_action_delete);

        /* Check if the update wants to delete or replace a locally
         * modified node. */


        /* Do a deep tree detection of local changes. The update editor will
         * not visit the subdirectories of a directory that it wants to delete.
         * Therefore, we need to start a separate crawl here. */

        SVN_ERR(svn_wc__node_has_local_mods(&modified, NULL,
                                            eb->db, local_abspath, FALSE,
                                            eb->cancel_func, eb->cancel_baton,
                                            scratch_pool));

        if (modified)
          {
            if (working_status == svn_wc__db_status_deleted)
              reason = svn_wc_conflict_reason_deleted;
            else
              reason = svn_wc_conflict_reason_edited;
          }
        break;

      case svn_wc__db_status_server_excluded:
        /* Not allowed to view the node. Not allowed to report tree
         * conflicts. */
      case svn_wc__db_status_excluded:
        /* Locally marked as excluded. No conflicts wanted. */
      case svn_wc__db_status_not_present:
        /* A committed delete (but parent not updated). The delete is
           committed, so no conflict possible during update. */
        return SVN_NO_ERROR;

      case svn_wc__db_status_base_deleted:
        /* An internal status. Should never show up here. */
        SVN_ERR_MALFUNCTION();
        break;

    }

  if (reason == SVN_WC_CONFLICT_REASON_NONE)
    /* No conflict with the current action. */
    return SVN_NO_ERROR;


  /* Sanity checks. Note that if there was no action on the node, this function
   * would not have been called in the first place.*/
  if (reason == svn_wc_conflict_reason_edited
      || reason == svn_wc_conflict_reason_obstructed
      || reason == svn_wc_conflict_reason_deleted
      || reason == svn_wc_conflict_reason_moved_away
      || reason == svn_wc_conflict_reason_replaced)
    {
      /* When the node existed before (it was locally deleted, replaced or
       * edited), then 'update' cannot add it "again". So it can only send
       * _action_edit, _delete or _replace. */
    if (action != svn_wc_conflict_action_edit
        && action != svn_wc_conflict_action_delete
        && action != svn_wc_conflict_action_replace)
      return svn_error_createf(SVN_ERR_WC_FOUND_CONFLICT, NULL,
               _("Unexpected attempt to add a node at path '%s'"),
               svn_dirent_local_style(local_abspath, scratch_pool));
    }
  else if (reason == svn_wc_conflict_reason_added ||
           reason == svn_wc_conflict_reason_moved_here)
    {
      /* When the node did not exist before (it was locally added),
       * then 'update' cannot want to modify it in any way.
       * It can only send _action_add. */
      if (action != svn_wc_conflict_action_add)
        return svn_error_createf(SVN_ERR_WC_FOUND_CONFLICT, NULL,
                 _("Unexpected attempt to edit, delete, or replace "
                   "a node at path '%s'"),
                 svn_dirent_local_style(local_abspath, scratch_pool));

    }


  /* A conflict was detected. Create a conflict skel to record it. */
  *pconflict = svn_wc__conflict_skel_create(result_pool);

  SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(*pconflict,
                                                  eb->db, local_abspath,
                                                  reason,
                                                  action,
                                                  move_src_op_root_abspath,
                                                  result_pool, scratch_pool));

  return SVN_NO_ERROR;
}


/* If LOCAL_ABSPATH is inside a conflicted tree and the conflict is
 * not a moved-away-edit conflict, set *CONFLICTED to TRUE.  Otherwise
 * set *CONFLICTED to FALSE.
 */
static svn_error_t *
already_in_a_tree_conflict(svn_boolean_t *conflicted,
                           svn_boolean_t *ignored,
                           svn_wc__db_t *db,
                           const char *local_abspath,
                           apr_pool_t *scratch_pool)
{
  const char *ancestor_abspath = local_abspath;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);

  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));

  *conflicted = *ignored = FALSE;

  while (TRUE)
    {
      svn_boolean_t is_wc_root;

      svn_pool_clear(iterpool);

      SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, ignored, db,
                                              ancestor_abspath, TRUE,
                                              scratch_pool));
      if (*conflicted || *ignored)
        break;

      SVN_ERR(svn_wc__db_is_wcroot(&is_wc_root, db, ancestor_abspath,
                                   iterpool));
      if (is_wc_root)
        break;

      ancestor_abspath = svn_dirent_dirname(ancestor_abspath, scratch_pool);
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* Temporary helper until the new conflict handling is in place */
static svn_error_t *
node_already_conflicted(svn_boolean_t *conflicted,
                        svn_boolean_t *conflict_ignored,
                        svn_wc__db_t *db,
                        const char *local_abspath,
                        apr_pool_t *scratch_pool)
{
  SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, conflict_ignored, db,
                                          local_abspath, FALSE,
                                          scratch_pool));

  return SVN_NO_ERROR;
}


/* An svn_delta_editor_t function. */
static svn_error_t *
delete_entry(const char *path,
             svn_revnum_t revision,
             void *parent_baton,
             apr_pool_t *pool)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  const char *base = svn_relpath_basename(path, NULL);
  const char *local_abspath;
  const char *repos_relpath;
  const char *deleted_repos_relpath;
  svn_node_kind_t kind;
  svn_revnum_t old_revision;
  svn_boolean_t conflicted;
  svn_boolean_t have_work;
  svn_skel_t *tree_conflict = NULL;
  svn_wc__db_status_t status;
  svn_wc__db_status_t base_status;
  apr_pool_t *scratch_pool;
  svn_boolean_t deleting_target;
  svn_boolean_t deleting_switched;

  if (pb->skip_this)
    return SVN_NO_ERROR;

  scratch_pool = svn_pool_create(pb->pool);

  SVN_ERR(mark_directory_edited(pb, scratch_pool));

  SVN_ERR(path_join_under_root(&local_abspath, pb->local_abspath, base,
                               scratch_pool));

  deleting_target =  (strcmp(local_abspath, eb->target_abspath) == 0);

  /* Detect obstructing working copies */
  {
    svn_boolean_t is_root;


    SVN_ERR(svn_wc__db_is_wcroot(&is_root, eb->db, local_abspath,
                                 scratch_pool));

    if (is_root)
      {
        /* Just skip this node; a future update will handle it */
        SVN_ERR(remember_skipped_tree(eb, local_abspath, pool));
        do_notification(eb, local_abspath, svn_node_unknown,
                        svn_wc_notify_update_skip_obstruction, scratch_pool);

        svn_pool_destroy(scratch_pool);

        return SVN_NO_ERROR;
      }
  }

  SVN_ERR(svn_wc__db_read_info(&status, &kind, &old_revision, &repos_relpath,
                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               &conflicted, NULL, NULL, NULL,
                               NULL, NULL, &have_work,
                               eb->db, local_abspath,
                               scratch_pool, scratch_pool));

  if (!have_work)
    {
      base_status = status;
    }
  else
    SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, &old_revision,
                                     &repos_relpath,
                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL,
                                     eb->db, local_abspath,
                                     scratch_pool, scratch_pool));

  if (pb->old_repos_relpath && repos_relpath)
    {
      const char *expected_name;

      expected_name = svn_relpath_skip_ancestor(pb->old_repos_relpath,
                                                repos_relpath);

      deleting_switched = (!expected_name || strcmp(expected_name, base) != 0);
    }
  else
    deleting_switched = FALSE;

  /* Is this path a conflict victim? */
  if (pb->shadowed)
    conflicted = FALSE; /* Conflict applies to WORKING */
  else if (conflicted)
    SVN_ERR(node_already_conflicted(&conflicted, NULL,
                                    eb->db, local_abspath, scratch_pool));
  if (conflicted)
    {
      SVN_ERR(remember_skipped_tree(eb, local_abspath, scratch_pool));

      do_notification(eb, local_abspath, svn_node_unknown,
                      svn_wc_notify_skip_conflicted,
                      scratch_pool);

      svn_pool_destroy(scratch_pool);

      return SVN_NO_ERROR;
    }


  /* Receive the remote removal of excluded/server-excluded/not present node.
     Do not notify, but perform the change even when the node is shadowed */
  if (base_status == svn_wc__db_status_not_present
      || base_status == svn_wc__db_status_excluded
      || base_status == svn_wc__db_status_server_excluded)
    {
      SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath, TRUE,
                                     deleting_target, FALSE,
                                     *eb->target_revision,
                                     NULL, NULL,
                                     scratch_pool));

      if (deleting_target)
        eb->target_deleted = TRUE;

      svn_pool_destroy(scratch_pool);

      return SVN_NO_ERROR;
    }

  /* Is this path the victim of a newly-discovered tree conflict?  If so,
   * remember it and notify the client. Then (if it was existing and
   * modified), re-schedule the node to be added back again, as a (modified)
   * copy of the previous base version.  */

  /* Check for conflicts only when we haven't already recorded
   * a tree-conflict on a parent node. */
  if (!pb->shadowed && !pb->edit_obstructed)
    {
      SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
                                  status, TRUE,
                                  kind,
                                  svn_wc_conflict_action_delete,
                                  pb->pool, scratch_pool));
    }

  if (tree_conflict != NULL)
    {
      /* When we raise a tree conflict on a node, we don't want to mark the
       * node as skipped, to allow a replacement to continue doing at least
       * a bit of its work (possibly adding a not present node, for the
       * next update) */
      if (!pb->deletion_conflicts)
        pb->deletion_conflicts = apr_hash_make(pb->pool);

      svn_hash_sets(pb->deletion_conflicts, apr_pstrdup(pb->pool, base),
                    tree_conflict);

      /* Whatever the kind of conflict, we can just clear BASE
         by turning whatever is there into a copy */
    }

  /* Calculate the repository-relative path of the entry which was
   * deleted. For updates it's the same as REPOS_RELPATH but for
   * switches it is within the switch target. */
  SVN_ERR(calculate_repos_relpath(&deleted_repos_relpath, local_abspath,
                                  repos_relpath, eb, pb, scratch_pool,
                                  scratch_pool));
  SVN_ERR(complete_conflict(tree_conflict, eb, local_abspath, repos_relpath,
                            old_revision, deleted_repos_relpath,
                            kind, svn_node_none, NULL,
                            pb->pool, scratch_pool));

  /* Issue a wq operation to delete the BASE_NODE data and to delete actual
     nodes based on that from disk, but leave any WORKING_NODEs on disk.

     Local modifications are already turned into copies at this point.

     If the thing being deleted is the *target* of this update, then
     we need to recreate a 'deleted' entry, so that the parent can give
     accurate reports about itself in the future. */
  if (! deleting_target && ! deleting_switched)
    {
      /* Delete, and do not leave a not-present node.  */
      SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath,
                                     (tree_conflict != NULL),
                                     FALSE, FALSE,
                                     SVN_INVALID_REVNUM /* not_present_rev */,
                                     tree_conflict, NULL,
                                     scratch_pool));
    }
  else
    {
      /* Delete, leaving a not-present node.  */
      SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath,
                                     (tree_conflict != NULL),
                                     TRUE, FALSE,
                                     *eb->target_revision,
                                     tree_conflict, NULL,
                                     scratch_pool));
      if (deleting_target)
        eb->target_deleted = TRUE;
      else
        {
          /* Don't remove the not-present marker at the final bump */
          SVN_ERR(remember_skipped_tree(eb, local_abspath, pool));
        }
    }

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

  /* Notify. */
  if (tree_conflict)
    {
      if (eb->conflict_func)
        SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, local_abspath,
                                                 kind,
                                                 tree_conflict,
                                                 NULL /* merge_options */,
                                                 eb->conflict_func,
                                                 eb->conflict_baton,
                                                 eb->cancel_func,
                                                 eb->cancel_baton,
                                                 scratch_pool));
      do_notification(eb, local_abspath, kind,
                      svn_wc_notify_tree_conflict, scratch_pool);
    }
  else
    {
      svn_wc_notify_action_t action = svn_wc_notify_update_delete;

      if (pb->shadowed || pb->edit_obstructed)
        action = svn_wc_notify_update_shadowed_delete;

      do_notification(eb, local_abspath, kind, action, scratch_pool);
    }

  svn_pool_destroy(scratch_pool);

  return SVN_NO_ERROR;
}

/* An svn_delta_editor_t function. */
static svn_error_t *
add_directory(const char *path,
              void *parent_baton,
              const char *copyfrom_path,
              svn_revnum_t copyfrom_rev,
              apr_pool_t *pool,
              void **child_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct dir_baton *db;
  apr_pool_t *scratch_pool = svn_pool_create(pool);
  svn_node_kind_t kind;
  svn_wc__db_status_t status;
  svn_node_kind_t wc_kind;
  svn_boolean_t conflicted;
  svn_boolean_t conflict_ignored = FALSE;
  svn_boolean_t versioned_locally_and_present;
  svn_skel_t *tree_conflict = NULL;
  svn_error_t *err;

  SVN_ERR_ASSERT(! (copyfrom_path || SVN_IS_VALID_REVNUM(copyfrom_rev)));

  SVN_ERR(make_dir_baton(&db, path, eb, pb, TRUE, pool));
  SVN_ERR(calculate_repos_relpath(&db->new_repos_relpath, db->local_abspath,
                                  NULL, eb, pb, db->pool, scratch_pool));
  *child_baton = db;

  if (db->skip_this)
    return SVN_NO_ERROR;

  SVN_ERR(mark_directory_edited(db, pool));

  if (strcmp(eb->target_abspath, db->local_abspath) == 0)
    {
      /* The target of the edit is being added, give it the requested
         depth of the edit (but convert svn_depth_unknown to
         svn_depth_infinity). */
      db->ambient_depth = (eb->requested_depth == svn_depth_unknown)
        ? svn_depth_infinity : eb->requested_depth;
    }
  else if (eb->requested_depth == svn_depth_immediates
           || (eb->requested_depth == svn_depth_unknown
               && pb->ambient_depth == svn_depth_immediates))
    {
      db->ambient_depth = svn_depth_empty;
    }
  else
    {
      db->ambient_depth = svn_depth_infinity;
    }

  /* It may not be named the same as the administrative directory. */
  if (svn_wc_is_adm_dir(db->name, pool))
    return svn_error_createf(
       SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
       _("Failed to add directory '%s': object of the same name as the "
         "administrative directory"),
       svn_dirent_local_style(db->local_abspath, pool));

  if (!eb->clean_checkout)
    {
      SVN_ERR(svn_io_check_path(db->local_abspath, &kind, db->pool));

      err = svn_wc__db_read_info(&status, &wc_kind, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL,
                                &conflicted, NULL, NULL, NULL, NULL, NULL, NULL,
                                eb->db, db->local_abspath,
                                scratch_pool, scratch_pool);
    }
  else
    {
      kind = svn_node_none;
      status = svn_wc__db_status_not_present;
      wc_kind = svn_node_unknown;
      conflicted = FALSE;
      err = NULL;
    }

  if (err)
    {
      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
        return svn_error_trace(err);

      svn_error_clear(err);
      wc_kind = svn_node_unknown;
      status = svn_wc__db_status_normal;
      conflicted = FALSE;

      versioned_locally_and_present = FALSE;
    }
  else if (status == svn_wc__db_status_normal && wc_kind == svn_node_unknown)
    {
      SVN_ERR_ASSERT(conflicted);
      versioned_locally_and_present = FALSE; /* Tree conflict ACTUAL-only node */
    }
  else if (status == svn_wc__db_status_normal
           || status == svn_wc__db_status_incomplete)
    {
      svn_boolean_t root;

      SVN_ERR(svn_wc__db_is_wcroot(&root, eb->db, db->local_abspath,
                                   scratch_pool));

      if (root)
        {
          /* !! We found the root of a working copy obstructing the wc !!

             If the directory would be part of our own working copy then
             we wouldn't have been called as an add_directory().

             The only thing we can do is add a not-present node, to allow
             a future update to bring in the new files when the problem is
             resolved.  Note that svn_wc__db_base_add_not_present_node()
             explicitly adds the node into the parent's node database. */

          svn_hash_sets(pb->not_present_nodes,
                        apr_pstrdup(pb->pool, db->name),
                        svn_node_kind_to_word(svn_node_dir));
        }
      else if (wc_kind == svn_node_dir)
        {
          /* We have an editor violation. Github sometimes does this
             in its subversion compatibility code, when changing the
             depth of a working copy, or on updates from incomplete */
        }
      else
        {
          /* We found a file external occupating the place we need in BASE.

            We can't add a not-present node in this case as that would overwrite
            the file external. Luckily the file external itself stops us from
            forgetting a child of this parent directory like an obstructing
            working copy would.

            The reason we get here is that the adm crawler doesn't report
            file externals.
          */
          SVN_ERR_ASSERT(wc_kind == svn_node_file
                         || wc_kind == svn_node_symlink);
        }

      SVN_ERR(remember_skipped_tree(eb, db->local_abspath, scratch_pool));
      db->skip_this = TRUE;
      db->already_notified = TRUE;

      do_notification(eb, db->local_abspath, wc_kind,
                      svn_wc_notify_update_skip_obstruction, scratch_pool);

      svn_pool_destroy(scratch_pool);

      return SVN_NO_ERROR;
    }
  else
    versioned_locally_and_present = IS_NODE_PRESENT(status);

  /* Is this path a conflict victim? */
  if (conflicted)
    {
      if (pb->deletion_conflicts)
        tree_conflict = svn_hash_gets(pb->deletion_conflicts, db->name);

      if (tree_conflict)
        {
          svn_wc_conflict_reason_t reason;
          const char *move_src_op_root_abspath;
          /* So this deletion wasn't just a deletion, it is actually a
             replacement. Let's install a better tree conflict. */

          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
                                                      &move_src_op_root_abspath,
                                                      eb->db,
                                                      db->local_abspath,
                                                      tree_conflict,
                                                      db->pool, scratch_pool));

          tree_conflict = svn_wc__conflict_skel_create(db->pool);

          SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
                                        tree_conflict,
                                        eb->db, db->local_abspath,
                                        reason, svn_wc_conflict_action_replace,
                                        move_src_op_root_abspath,
                                        db->pool, scratch_pool));

          /* And now stop checking for conflicts here and just perform
             a shadowed update */
          db->edit_conflict = tree_conflict; /* Cache for close_directory */
          tree_conflict = NULL; /* No direct notification */
          db->shadowed = TRUE; /* Just continue */
          conflicted = FALSE; /* No skip */
        }
      else
        SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
                                        eb->db, db->local_abspath,
                                        scratch_pool));
    }

  /* Now the "usual" behaviour if already conflicted. Skip it. */
  if (conflicted)
    {
      /* Record this conflict so that its descendants are skipped silently. */
      SVN_ERR(remember_skipped_tree(eb, db->local_abspath, pool));

      db->skip_this = TRUE;
      db->already_notified = TRUE;

      /* We skip this node, but once the update completes the parent node will
         be updated to the new revision. So a future recursive update of the
         parent will not bring in this new node as the revision of the parent
         describes to the repository that all children are available.

         To resolve this problem, we add a not-present node to allow bringing
         the node in once this conflict is resolved.

         Note that we can safely assume that no present base node exists,
         because then we would not have received an add_directory.
       */
      svn_hash_sets(pb->not_present_nodes, apr_pstrdup(pb->pool, db->name),
                    svn_node_kind_to_word(svn_node_dir));

      do_notification(eb, db->local_abspath, svn_node_dir,
                      svn_wc_notify_skip_conflicted, scratch_pool);

      svn_pool_destroy(scratch_pool);
      return SVN_NO_ERROR;
    }
  else if (conflict_ignored)
    {
      db->shadowed = TRUE;
    }

  if (db->shadowed)
    {
      /* Nothing to check; does not and will not exist in working copy */
    }
  else if (versioned_locally_and_present)
    {
      /* What to do with a versioned or schedule-add dir:

         A dir already added without history is OK.  Set add_existed
         so that user notification is delayed until after any prop
         conflicts have been found.

         An existing versioned dir is an error.  In the future we may
         relax this restriction and simply update such dirs.

         A dir added with history is a tree conflict. */

      svn_boolean_t local_is_non_dir;
      svn_wc__db_status_t add_status = svn_wc__db_status_normal;

      /* Is the local add a copy? */
      if (status == svn_wc__db_status_added)
        SVN_ERR(svn_wc__db_scan_addition(&add_status, NULL, NULL, NULL, NULL,
                                         NULL, NULL, NULL, NULL,
                                         eb->db, db->local_abspath,
                                         scratch_pool, scratch_pool));


      /* Is there *something* that is not a dir? */
      local_is_non_dir = (wc_kind != svn_node_dir
                          && status != svn_wc__db_status_deleted);

      /* Do tree conflict checking if
       *  - if there is a local copy.
       *  - if this is a switch operation
       *  - the node kinds mismatch
       *
       * During switch, local adds at the same path as incoming adds get
       * "lost" in that switching back to the original will no longer have the
       * local add. So switch always alerts the user with a tree conflict. */
      if (!eb->adds_as_modification
          || local_is_non_dir
          || add_status != svn_wc__db_status_added)
        {
          SVN_ERR(check_tree_conflict(&tree_conflict, eb,
                                      db->local_abspath,
                                      status, FALSE, svn_node_none,
                                      svn_wc_conflict_action_add,
                                      db->pool, scratch_pool));
        }

      if (tree_conflict == NULL)
        db->add_existed = TRUE; /* Take over WORKING */
      else
        db->shadowed = TRUE; /* Only update BASE */
    }
  else if (kind != svn_node_none)
    {
      /* There's an unversioned node at this path. */
      db->obstruction_found = TRUE;

      /* Unversioned, obstructing dirs are handled by prop merge/conflict,
       * if unversioned obstructions are allowed. */
      if (! (kind == svn_node_dir && eb->allow_unver_obstructions))
        {
          /* Bring in the node as deleted */ /* ### Obstructed Conflict */
          db->shadowed = TRUE;

          /* Mark a conflict */
          tree_conflict = svn_wc__conflict_skel_create(db->pool);

          SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
                                        tree_conflict,
                                        eb->db, db->local_abspath,
                                        svn_wc_conflict_reason_unversioned,
                                        svn_wc_conflict_action_add, NULL,
                                        db->pool, scratch_pool));
          db->edit_conflict = tree_conflict;
        }
    }

  if (tree_conflict)
    SVN_ERR(complete_conflict(tree_conflict, eb, db->local_abspath,
                              db->old_repos_relpath, db->old_revision,
                              db->new_repos_relpath,
                              wc_kind, svn_node_dir,
                              pb->deletion_conflicts
                                ? svn_hash_gets(pb->deletion_conflicts,
                                                db->name)
                                : NULL,
                              db->pool, scratch_pool));

  SVN_ERR(svn_wc__db_base_add_incomplete_directory(
                                     eb->db, db->local_abspath,
                                     db->new_repos_relpath,
                                     eb->repos_root,
                                     eb->repos_uuid,
                                     *eb->target_revision,
                                     db->ambient_depth,
                                     (db->shadowed && db->obstruction_found),
                                     (! db->shadowed
                                      && status == svn_wc__db_status_added),
                                     tree_conflict, NULL,
                                     scratch_pool));

  /* Make sure there is a real directory at LOCAL_ABSPATH, unless we are just
     updating the DB */
  if (!db->shadowed)
    SVN_ERR(svn_wc__ensure_directory(db->local_abspath, scratch_pool));

  if (tree_conflict != NULL)
    {
      db->edit_conflict = tree_conflict;

      db->already_notified = TRUE;
      do_notification(eb, db->local_abspath, svn_node_dir,
                      svn_wc_notify_tree_conflict, scratch_pool);
    }


  /* If this add was obstructed by dir scheduled for addition without
     history let close_directory() handle the notification because there
     might be properties to deal with.  If PATH was added inside a locally
     deleted tree, then suppress notification, a tree conflict was already
     issued. */
  if (eb->notify_func && !db->already_notified && !db->add_existed)
    {
      svn_wc_notify_action_t action;

      if (db->shadowed)
        action = svn_wc_notify_update_shadowed_add;
      else if (db->obstruction_found || db->add_existed)
        action = svn_wc_notify_exists;
      else
        action = svn_wc_notify_update_add;

      db->already_notified = TRUE;

      do_notification(eb, db->local_abspath, svn_node_dir, action,
                      scratch_pool);
    }

  svn_pool_destroy(scratch_pool);

  return SVN_NO_ERROR;
}

/* An svn_delta_editor_t function. */
static svn_error_t *
open_directory(const char *path,
               void *parent_baton,
               svn_revnum_t base_revision,
               apr_pool_t *pool,
               void **child_baton)
{
  struct dir_baton *db, *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  svn_boolean_t have_work;
  svn_boolean_t conflicted;
  svn_boolean_t conflict_ignored = FALSE;
  svn_skel_t *tree_conflict = NULL;
  svn_wc__db_status_t status, base_status;
  svn_node_kind_t wc_kind;

  SVN_ERR(make_dir_baton(&db, path, eb, pb, FALSE, pool));
  *child_baton = db;

  if (db->skip_this)
    return SVN_NO_ERROR;

  /* Detect obstructing working copies */
  {
    svn_boolean_t is_root;

    SVN_ERR(svn_wc__db_is_wcroot(&is_root, eb->db, db->local_abspath,
                                 pool));

    if (is_root)
      {
        /* Just skip this node; a future update will handle it */
        SVN_ERR(remember_skipped_tree(eb, db->local_abspath, pool));
        db->skip_this = TRUE;
        db->already_notified = TRUE;

        do_notification(eb, db->local_abspath, svn_node_dir,
                        svn_wc_notify_update_skip_obstruction, pool);

        return SVN_NO_ERROR;
      }
  }

  /* We should have a write lock on every directory touched.  */
  SVN_ERR(svn_wc__write_check(eb->db, db->local_abspath, pool));

  SVN_ERR(svn_wc__db_read_info(&status, &wc_kind, &db->old_revision,
                               &db->old_repos_relpath, NULL, NULL,
                               &db->changed_rev, &db->changed_date,
                               &db->changed_author, &db->ambient_depth,
                               NULL, NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL, NULL, NULL,
                               &conflicted, NULL, NULL, NULL,
                               NULL, NULL, &have_work,
                               eb->db, db->local_abspath,
                               db->pool, pool));

  if (!have_work)
    base_status = status;
  else
    SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, &db->old_revision,
                                     &db->old_repos_relpath, NULL, NULL,
                                     &db->changed_rev, &db->changed_date,
                                     &db->changed_author, &db->ambient_depth,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     eb->db, db->local_abspath,
                                     db->pool, pool));

  db->was_incomplete = (base_status == svn_wc__db_status_incomplete);

  SVN_ERR(calculate_repos_relpath(&db->new_repos_relpath, db->local_abspath,
                                  db->old_repos_relpath, eb, pb,
                                  db->pool, pool));

  /* Is this path a conflict victim? */
  if (db->shadowed)
    conflicted = FALSE; /* Conflict applies to WORKING */
  else if (conflicted)
    SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
                                    eb->db, db->local_abspath, pool));
  if (conflicted)
    {
      SVN_ERR(remember_skipped_tree(eb, db->local_abspath, pool));

      db->skip_this = TRUE;
      db->already_notified = TRUE;

      do_notification(eb, db->local_abspath, svn_node_unknown,
                      svn_wc_notify_skip_conflicted, pool);

      return SVN_NO_ERROR;
    }
  else if (conflict_ignored)
    {
      db->shadowed = TRUE;
    }

  /* Is this path a fresh tree conflict victim?  If so, skip the tree
     with one notification. */

  /* Check for conflicts only when we haven't already recorded
   * a tree-conflict on a parent node. */
  if (!db->shadowed)
    SVN_ERR(check_tree_conflict(&tree_conflict, eb, db->local_abspath,
                                status, TRUE, svn_node_dir,
                                svn_wc_conflict_action_edit,
                                db->pool, pool));

  /* Remember the roots of any locally deleted trees. */
  if (tree_conflict != NULL)
    {
      svn_wc_conflict_reason_t reason;
      db->edit_conflict = tree_conflict;
      /* Other modifications wouldn't be a tree conflict */

      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                  eb->db, db->local_abspath,
                                                  tree_conflict,
                                                  db->pool, db->pool));
      SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_deleted
                     || reason == svn_wc_conflict_reason_moved_away
                     || reason == svn_wc_conflict_reason_replaced
                     || reason == svn_wc_conflict_reason_obstructed);

      /* Continue updating BASE */
      if (reason == svn_wc_conflict_reason_obstructed)
        db->edit_obstructed = TRUE;
      else
        db->shadowed = TRUE;
    }

  /* Mark directory as being at target_revision and URL, but incomplete. */
  SVN_ERR(svn_wc__db_temp_op_start_directory_update(eb->db, db->local_abspath,
                                                    db->new_repos_relpath,
                                                    *eb->target_revision,
                                                    pool));

  return SVN_NO_ERROR;
}


/* An svn_delta_editor_t function. */
static svn_error_t *
change_dir_prop(void *dir_baton,
                const char *name,
                const svn_string_t *value,
                apr_pool_t *pool)
{
  svn_prop_t *propchange;
  struct dir_baton *db = dir_baton;

  if (db->skip_this)
    return SVN_NO_ERROR;

  propchange = apr_array_push(db->propchanges);
  propchange->name = apr_pstrdup(db->pool, name);
  propchange->value = svn_string_dup(value, db->pool);

  if (!db->edited && svn_property_kind2(name) == svn_prop_regular_kind)
    SVN_ERR(mark_directory_edited(db, pool));

  return SVN_NO_ERROR;
}

/* If any of the svn_prop_t objects in PROPCHANGES represents a change
   to the SVN_PROP_EXTERNALS property, return that change, else return
   null.  If PROPCHANGES contains more than one such change, return
   the first. */
static const svn_prop_t *
externals_prop_changed(const apr_array_header_t *propchanges)
{
  int i;

  for (i = 0; i < propchanges->nelts; i++)
    {
      const svn_prop_t *p = &(APR_ARRAY_IDX(propchanges, i, svn_prop_t));
      if (strcmp(p->name, SVN_PROP_EXTERNALS) == 0)
        return p;
    }

  return NULL;
}



/* An svn_delta_editor_t function. */
static svn_error_t *
close_directory(void *dir_baton,
                apr_pool_t *pool)
{
  struct dir_baton *db = dir_baton;
  struct edit_baton *eb = db->edit_baton;
  svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
  apr_array_header_t *entry_prop_changes;
  apr_array_header_t *dav_prop_changes;
  apr_array_header_t *regular_prop_changes;
  apr_hash_t *base_props;
  apr_hash_t *actual_props;
  apr_hash_t *new_base_props = NULL;
  apr_hash_t *new_actual_props = NULL;
  svn_revnum_t new_changed_rev = SVN_INVALID_REVNUM;
  apr_time_t new_changed_date = 0;
  const char *new_changed_author = NULL;
  apr_pool_t *scratch_pool = db->pool;
  svn_skel_t *all_work_items = NULL;
  svn_skel_t *conflict_skel = NULL;

  /* Skip if we're in a conflicted tree. */
  if (db->skip_this)
    {
      /* Allow the parent to complete its update. */
      SVN_ERR(maybe_release_dir_info(db));

      return SVN_NO_ERROR;
    }

  if (db->edited)
    conflict_skel = db->edit_conflict;

  SVN_ERR(svn_categorize_props(db->propchanges, &entry_prop_changes,
                               &dav_prop_changes, &regular_prop_changes, pool));

  /* Fetch the existing properties.  */
  if ((!db->adding_dir || db->add_existed)
      && !db->shadowed)
    {
      SVN_ERR(svn_wc__get_actual_props(&actual_props,
                                       eb->db, db->local_abspath,
                                       scratch_pool, scratch_pool));
    }
  else
    actual_props = apr_hash_make(pool);

  if (db->add_existed)
    {
      /* This node already exists. Grab the current pristine properties. */
      SVN_ERR(svn_wc__db_read_pristine_props(&base_props,
                                             eb->db, db->local_abspath,
                                             scratch_pool, scratch_pool));
    }
  else if (!db->adding_dir)
    {
      /* Get the BASE properties for proper merging. */
      SVN_ERR(svn_wc__db_base_get_props(&base_props,
                                        eb->db, db->local_abspath,
                                        scratch_pool, scratch_pool));
    }
  else
    base_props = apr_hash_make(pool);

  /* An incomplete directory might have props which were supposed to be
     deleted but weren't.  Because the server sent us all the props we're
     supposed to have, any previous base props not in this list must be
     deleted (issue #1672). */
  if (db->was_incomplete)
    {
      int i;
      apr_hash_t *props_to_delete;
      apr_hash_index_t *hi;

      /* In a copy of the BASE props, remove every property that we see an
         incoming change for. The remaining unmentioned properties are those
         which need to be deleted.  */
      props_to_delete = apr_hash_copy(pool, base_props);
      for (i = 0; i < regular_prop_changes->nelts; i++)
        {
          const svn_prop_t *prop;
          prop = &APR_ARRAY_IDX(regular_prop_changes, i, svn_prop_t);
          svn_hash_sets(props_to_delete, prop->name, NULL);
        }

      /* Add these props to the incoming propchanges (in
       * regular_prop_changes).  */
      for (hi = apr_hash_first(pool, props_to_delete);
           hi != NULL;
           hi = apr_hash_next(hi))
        {
          const char *propname = apr_hash_this_key(hi);
          svn_prop_t *prop = apr_array_push(regular_prop_changes);

          /* Record a deletion for PROPNAME.  */
          prop->name = propname;
          prop->value = NULL;
        }
    }

  /* If this directory has property changes stored up, now is the time
     to deal with them. */
  if (regular_prop_changes->nelts)
    {
      /* If recording traversal info, then see if the
         SVN_PROP_EXTERNALS property on this directory changed,
         and record before and after for the change. */
      if (eb->external_func)
        {
          const svn_prop_t *change
            = externals_prop_changed(regular_prop_changes);

          if (change)
            {
              const svn_string_t *new_val_s = change->value;
              const svn_string_t *old_val_s;

              old_val_s = svn_hash_gets(base_props, SVN_PROP_EXTERNALS);

              if ((new_val_s == NULL) && (old_val_s == NULL))
                ; /* No value before, no value after... so do nothing. */
              else if (new_val_s && old_val_s
                       && (svn_string_compare(old_val_s, new_val_s)))
                ; /* Value did not change... so do nothing. */
              else if (old_val_s || new_val_s)
                /* something changed, record the change */
                {
                  SVN_ERR((eb->external_func)(
                                       eb->external_baton,
                                       db->local_abspath,
                                       old_val_s,
                                       new_val_s,
                                       db->ambient_depth,
                                       db->pool));
                }
            }
        }

      if (db->shadowed)
        {
          /* We don't have a relevant actual row, but we need actual properties
             to allow property merging without conflicts. */
          if (db->adding_dir)
            actual_props = apr_hash_make(scratch_pool);
          else
            actual_props = base_props;
        }

      /* Merge pending properties. */
      new_base_props = svn_prop__patch(base_props, regular_prop_changes,
                                       db->pool);
      SVN_ERR_W(svn_wc__merge_props(&conflict_skel,
                                    &prop_state,
                                    &new_actual_props,
                                    eb->db,
                                    db->local_abspath,
                                    NULL /* use baseprops */,
                                    base_props,
                                    actual_props,
                                    regular_prop_changes,
                                    db->pool,
                                    scratch_pool),
                _("Couldn't do property merge"));
      /* After a (not-dry-run) merge, we ALWAYS have props to save.  */
      SVN_ERR_ASSERT(new_base_props != NULL && new_actual_props != NULL);
    }

  SVN_ERR(accumulate_last_change(&new_changed_rev, &new_changed_date,
                                 &new_changed_author, entry_prop_changes,
                                 scratch_pool, scratch_pool));

  /* Check if we should add some not-present markers before marking the
     directory complete (Issue #3569) */
  {
    apr_hash_t *new_children = svn_hash_gets(eb->dir_dirents,
                                             db->new_repos_relpath);

    if (new_children != NULL)
      {
        apr_hash_index_t *hi;
        apr_pool_t *iterpool = svn_pool_create(scratch_pool);

        for (hi = apr_hash_first(scratch_pool, new_children);
             hi;
             hi = apr_hash_next(hi))
          {
            const char *child_name;
            const char *child_abspath;
            const char *child_relpath;
            const svn_dirent_t *dirent;
            svn_wc__db_status_t status;
            svn_node_kind_t child_kind;
            svn_error_t *err;

            svn_pool_clear(iterpool);

            child_name = apr_hash_this_key(hi);
            child_abspath = svn_dirent_join(db->local_abspath, child_name,
                                            iterpool);

            dirent = apr_hash_this_val(hi);
            child_kind = (dirent->kind == svn_node_dir)
                                        ? svn_node_dir
                                        : svn_node_file;

            if (db->ambient_depth < svn_depth_immediates
                && child_kind == svn_node_dir)
              continue; /* We don't need the subdirs */

            /* ### We just check if there is some node in BASE at this path */
            err = svn_wc__db_base_get_info(&status, NULL, NULL, NULL, NULL,
                                           NULL, NULL, NULL, NULL, NULL, NULL,
                                           NULL, NULL, NULL, NULL, NULL,
                                           eb->db, child_abspath,
                                           iterpool, iterpool);

            if (!err)
              {
                svn_boolean_t is_wcroot;
                SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, eb->db, child_abspath,
                                             iterpool));

                if (!is_wcroot)
                  continue; /* Everything ok... Nothing to do here */
                /* Fall through to allow recovering later */
              }
            else if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
              return svn_error_trace(err);

            svn_error_clear(err);

            child_relpath = svn_relpath_join(db->new_repos_relpath, child_name,
                                             iterpool);

            SVN_ERR(svn_wc__db_base_add_not_present_node(eb->db,
                                                         child_abspath,
                                                         child_relpath,
                                                         eb->repos_root,
                                                         eb->repos_uuid,
                                                         *eb->target_revision,
                                                         child_kind,
                                                         NULL, NULL,
                                                         iterpool));
          }

        svn_pool_destroy(iterpool);
      }
  }

  if (apr_hash_count(db->not_present_nodes))
    {
      apr_hash_index_t *hi;
      apr_pool_t *iterpool = svn_pool_create(scratch_pool);

      /* This should call some new function (which could also be used
         for new_children above) to add all the names in single
         transaction, but I can't even trigger it.  I've tried
         ra_local, ra_svn, ra_neon, ra_serf and they all call
         close_file before close_dir. */
      for (hi = apr_hash_first(scratch_pool, db->not_present_nodes);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *child = apr_hash_this_key(hi);
          const char *child_abspath, *child_relpath;
          svn_node_kind_t kind = svn_node_kind_from_word(apr_hash_this_val(hi));

          svn_pool_clear(iterpool);

          child_abspath = svn_dirent_join(db->local_abspath, child, iterpool);
          child_relpath = svn_dirent_join(db->new_repos_relpath, child, iterpool);

          SVN_ERR(svn_wc__db_base_add_not_present_node(eb->db,
                                                       child_abspath,
                                                       child_relpath,
                                                       eb->repos_root,
                                                       eb->repos_uuid,
                                                       *eb->target_revision,
                                                       kind,
                                                       NULL, NULL,
                                                       iterpool));
        }
      svn_pool_destroy(iterpool);
    }

  /* If this directory is merely an anchor for a targeted child, then we
     should not be updating the node at all.  */
  if (db->parent_baton == NULL
      && *eb->target_basename != '\0')
    {
      /* And we should not have received any changes!  */
      SVN_ERR_ASSERT(db->propchanges->nelts == 0);
      /* ... which also implies NEW_CHANGED_* are not set,
         and NEW_BASE_PROPS == NULL.  */
    }
  else
    {
      apr_hash_t *props;
      apr_array_header_t *iprops = NULL;

      /* ### we know a base node already exists. it was created in
         ### open_directory or add_directory.  let's just preserve the
         ### existing DEPTH value, and possibly CHANGED_*.  */
      /* If we received any changed_* values, then use them.  */
      if (SVN_IS_VALID_REVNUM(new_changed_rev))
        db->changed_rev = new_changed_rev;
      if (new_changed_date != 0)
        db->changed_date = new_changed_date;
      if (new_changed_author != NULL)
        db->changed_author = new_changed_author;

      /* If no depth is set yet, set to infinity. */
      if (db->ambient_depth == svn_depth_unknown)
        db->ambient_depth = svn_depth_infinity;

      if (eb->depth_is_sticky
          && db->ambient_depth != eb->requested_depth)
        {
          /* After a depth upgrade the entry must reflect the new depth.
             Upgrading to infinity changes the depth of *all* directories,
             upgrading to something else only changes the target. */

          if (eb->requested_depth == svn_depth_infinity
              || (strcmp(db->local_abspath, eb->target_abspath) == 0
                  && eb->requested_depth > db->ambient_depth))
            {
              db->ambient_depth = eb->requested_depth;
            }
        }

      /* Do we have new properties to install? Or shall we simply retain
         the prior set of properties? If we're installing new properties,
         then we also want to write them to an old-style props file.  */
      props = new_base_props;
      if (props == NULL)
        props = base_props;

      if (conflict_skel)
        {
          svn_skel_t *work_item;

          SVN_ERR(complete_conflict(conflict_skel,
                                    db->edit_baton,
                                    db->local_abspath,
                                    db->old_repos_relpath,
                                    db->old_revision,
                                    db->new_repos_relpath,
                                    svn_node_dir, svn_node_dir,
                                    (db->parent_baton
                                     && db->parent_baton->deletion_conflicts)
                                      ? svn_hash_gets(
                                            db->parent_baton->deletion_conflicts,
                                            db->name)
                                      : NULL,
                                    db->pool, scratch_pool));

          SVN_ERR(svn_wc__conflict_create_markers(&work_item,
                                                  eb->db, db->local_abspath,
                                                  conflict_skel,
                                                  scratch_pool, scratch_pool));

          all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                            scratch_pool);
        }

      /* Any inherited props to be set set for this base node? */
      if (eb->wcroot_iprops)
        {
          iprops = svn_hash_gets(eb->wcroot_iprops, db->local_abspath);

          /* close_edit may also update iprops for switched nodes, catching
             those for which close_directory is never called (e.g. a switch
             with no changes).  So as a minor optimization we remove any
             iprops from the hash so as not to set them again in
             close_edit. */
          if (iprops)
            svn_hash_sets(eb->wcroot_iprops, db->local_abspath, NULL);
        }

      /* Update the BASE data for the directory and mark the directory
         complete */
      SVN_ERR(svn_wc__db_base_add_directory(
                eb->db, db->local_abspath,
                eb->wcroot_abspath,
                db->new_repos_relpath,
                eb->repos_root, eb->repos_uuid,
                *eb->target_revision,
                props,
                db->changed_rev, db->changed_date, db->changed_author,
                NULL /* children */,
                db->ambient_depth,
                (dav_prop_changes->nelts > 0)
                    ? svn_prop_array_to_hash(dav_prop_changes, pool)
                    : NULL,
                (! db->shadowed) && new_base_props != NULL,
                new_actual_props, iprops,
                conflict_skel, all_work_items,
                scratch_pool));
    }

  /* Process all of the queued work items for this directory.  */
  SVN_ERR(svn_wc__wq_run(eb->db, db->local_abspath,
                         eb->cancel_func, eb->cancel_baton,
                         scratch_pool));

  if (db->parent_baton)
    svn_hash_sets(db->parent_baton->not_present_nodes, db->name, NULL);

  if (conflict_skel && eb->conflict_func)
    SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, db->local_abspath,
                                             svn_node_dir,
                                             conflict_skel,
                                             NULL /* merge_options */,
                                             eb->conflict_func,
                                             eb->conflict_baton,
                                             eb->cancel_func,
                                             eb->cancel_baton,
                                             scratch_pool));

  /* Notify of any prop changes on this directory -- but do nothing if
     it's an added or skipped directory, because notification has already
     happened in that case - unless the add was obstructed by a dir
     scheduled for addition without history, in which case we handle
     notification here). */
  if (!db->already_notified && eb->notify_func && db->edited)
    {
      svn_wc_notify_t *notify;
      svn_wc_notify_action_t action;

      if (db->shadowed || db->edit_obstructed)
        action = svn_wc_notify_update_shadowed_update;
      else if (db->obstruction_found || db->add_existed)
        action = svn_wc_notify_exists;
      else
        action = svn_wc_notify_update_update;

      notify = svn_wc_create_notify(db->local_abspath, action, pool);
      notify->kind = svn_node_dir;
      notify->prop_state = prop_state;
      notify->revision = *eb->target_revision;
      notify->old_revision = db->old_revision;

      eb->notify_func(eb->notify_baton, notify, scratch_pool);
    }

  if (db->edited)
    eb->edited = db->edited;

  /* We're done with this directory, so remove one reference from the
     bump information. */
  SVN_ERR(maybe_release_dir_info(db));

  return SVN_NO_ERROR;
}


/* Common code for 'absent_file' and 'absent_directory'. */
static svn_error_t *
absent_node(const char *path,
            svn_node_kind_t absent_kind,
            void *parent_baton,
            apr_pool_t *pool)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  apr_pool_t *scratch_pool = svn_pool_create(pool);
  const char *name = svn_dirent_basename(path, NULL);
  const char *local_abspath;
  svn_error_t *err;
  svn_wc__db_status_t status;
  svn_node_kind_t kind;
  svn_skel_t *tree_conflict = NULL;

  if (pb->skip_this)
    return SVN_NO_ERROR;

  SVN_ERR(mark_directory_edited(pb, scratch_pool));

  local_abspath = svn_dirent_join(pb->local_abspath, name, scratch_pool);

  /* If an item by this name is scheduled for addition that's a
     genuine tree-conflict.  */
  err = svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
                             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                             NULL, NULL, NULL, NULL,
                             eb->db, local_abspath,
                             scratch_pool, scratch_pool);

  if (err)
    {
      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
        return svn_error_trace(err);

      svn_error_clear(err);
      status = svn_wc__db_status_not_present;
      kind = svn_node_unknown;
    }

  if (status == svn_wc__db_status_normal)
    {
      svn_boolean_t wcroot;
      /* We found an obstructing working copy or a file external! */

      SVN_ERR(svn_wc__db_is_wcroot(&wcroot, eb->db, local_abspath,
                                   scratch_pool));

      if (wcroot)
        {
          /*
             We have an obstructing working copy; possibly a directory external

             We can do two things now:
             1) notify the user, record a skip, etc.
             2) Just record the absent node in BASE in the parent
                working copy.

             As option 2 happens to be exactly what we do anyway, fall through.
           */
        }
      else
        {
          /* The server asks us to replace a file external
             (Existing BASE node; not reported by the working copy crawler or
              there would have been a delete_entry() call.

             There is no way we can store this state in the working copy as
             the BASE layer is already filled.

             We could error out, but that is not helping anybody; the user is not
             even seeing with what the file external would be replaced, so let's
             report a skip and continue the update.
           */

          if (eb->notify_func)
            {
              svn_wc_notify_t *notify;
              notify = svn_wc_create_notify(
                                    local_abspath,
                                    svn_wc_notify_update_skip_obstruction,
                                    scratch_pool);

              eb->notify_func(eb->notify_baton, notify, scratch_pool);
            }

          svn_pool_destroy(scratch_pool);
          return SVN_NO_ERROR;
        }
    }
  else if (status == svn_wc__db_status_not_present
           || status == svn_wc__db_status_server_excluded
           || status == svn_wc__db_status_excluded)
    {
      /* The BASE node is not actually there, so we can safely turn it into
         an absent node */
    }
  else
    {
      /* We have a local addition. If this would be a BASE node it would have
         been deleted before we get here. (Which might have turned it into
         a copy). */
      SVN_ERR_ASSERT(status != svn_wc__db_status_normal);

      if (!pb->shadowed && !pb->edit_obstructed)
        SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
                                    status, FALSE, svn_node_unknown,
                                    svn_wc_conflict_action_add,
                                    scratch_pool, scratch_pool));

    }

  {
    const char *repos_relpath;
    repos_relpath = svn_relpath_join(pb->new_repos_relpath, name, scratch_pool);

    if (tree_conflict)
      SVN_ERR(complete_conflict(tree_conflict, eb, local_abspath,
                                NULL, SVN_INVALID_REVNUM, repos_relpath,
                                kind, svn_node_unknown, NULL,
                                scratch_pool, scratch_pool));

    /* Insert an excluded node below the parent node to note that this child
       is absent. (This puts it in the parent db if the child is obstructed) */
    SVN_ERR(svn_wc__db_base_add_excluded_node(eb->db, local_abspath,
                                              repos_relpath, eb->repos_root,
                                              eb->repos_uuid,
                                              *(eb->target_revision),
                                              absent_kind,
                                              svn_wc__db_status_server_excluded,
                                              tree_conflict, NULL,
                                              scratch_pool));

    if (tree_conflict)
      {
        if (eb->conflict_func)
          SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, local_abspath,
                                                   kind,
                                                   tree_conflict,
                                                   NULL /* merge_options */,
                                                   eb->conflict_func,
                                                   eb->conflict_baton,
                                                   eb->cancel_func,
                                                   eb->cancel_baton,
                                                   scratch_pool));
        do_notification(eb, local_abspath, kind, svn_wc_notify_tree_conflict,
                        scratch_pool);
      }
  }

  svn_pool_destroy(scratch_pool);

  return SVN_NO_ERROR;
}


/* An svn_delta_editor_t function. */
static svn_error_t *
absent_file(const char *path,
            void *parent_baton,
            apr_pool_t *pool)
{
  return absent_node(path, svn_node_file, parent_baton, pool);
}


/* An svn_delta_editor_t function. */
static svn_error_t *
absent_directory(const char *path,
                 void *parent_baton,
                 apr_pool_t *pool)
{
  return absent_node(path, svn_node_dir, parent_baton, pool);
}


/* An svn_delta_editor_t function. */
static svn_error_t *
add_file(const char *path,
         void *parent_baton,
         const char *copyfrom_path,
         svn_revnum_t copyfrom_rev,
         apr_pool_t *pool,
         void **file_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct file_baton *fb;
  svn_node_kind_t kind;
  svn_node_kind_t wc_kind;
  svn_wc__db_status_t status;
  apr_pool_t *scratch_pool;
  svn_boolean_t conflicted;
  svn_boolean_t conflict_ignored = FALSE;
  svn_boolean_t versioned_locally_and_present;
  svn_skel_t *tree_conflict = NULL;
  svn_error_t *err = SVN_NO_ERROR;

  SVN_ERR_ASSERT(! (copyfrom_path || SVN_IS_VALID_REVNUM(copyfrom_rev)));

  SVN_ERR(make_file_baton(&fb, pb, path, TRUE, pool));
  SVN_ERR(calculate_repos_relpath(&fb->new_repos_relpath, fb->local_abspath,
                                  NULL, eb, pb, fb->pool, pool));
  *file_baton = fb;

  if (fb->skip_this)
    return SVN_NO_ERROR;

  SVN_ERR(mark_file_edited(fb, pool));

  /* The file_pool can stick around for a *long* time, so we want to
     use a subpool for any temporary allocations. */
  scratch_pool = svn_pool_create(pool);


  /* It may not be named the same as the administrative directory. */
  if (svn_wc_is_adm_dir(fb->name, pool))
    return svn_error_createf(
       SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
       _("Failed to add file '%s': object of the same name as the "
         "administrative directory"),
       svn_dirent_local_style(fb->local_abspath, pool));

  if (!eb->clean_checkout)
    {
      SVN_ERR(svn_io_check_path(fb->local_abspath, &kind, scratch_pool));

      err = svn_wc__db_read_info(&status, &wc_kind, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL,
                                &conflicted, NULL, NULL, NULL, NULL, NULL, NULL,
                                eb->db, fb->local_abspath,
                                scratch_pool, scratch_pool);
    }
  else
    {
      kind =  svn_node_none;
      status = svn_wc__db_status_not_present;
      wc_kind = svn_node_unknown;
      conflicted = FALSE;
    }

  if (err)
    {
      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
        return svn_error_trace(err);

      svn_error_clear(err);
      wc_kind = svn_node_unknown;
      conflicted = FALSE;

      versioned_locally_and_present = FALSE;
    }
  else if (status == svn_wc__db_status_normal && wc_kind == svn_node_unknown)
    {
      SVN_ERR_ASSERT(conflicted);
      versioned_locally_and_present = FALSE; /* Tree conflict ACTUAL-only node */
    }
  else if (status == svn_wc__db_status_normal
           || status == svn_wc__db_status_incomplete)
    {
      svn_boolean_t root;

      SVN_ERR(svn_wc__db_is_wcroot(&root, eb->db, fb->local_abspath,
                                   scratch_pool));

      if (root)
        {
          /* !! We found the root of a working copy obstructing the wc !!

             If the directory would be part of our own working copy then
             we wouldn't have been called as an add_directory().

             The only thing we can do is add a not-present node, to allow
             a future update to bring in the new files when the problem is
             resolved.  Note that svn_wc__db_base_add_not_present_node()
             explicitly adds the node into the parent's node database. */

          svn_hash_sets(pb->not_present_nodes,
                        apr_pstrdup(pb->pool, fb->name),
                        svn_node_kind_to_word(svn_node_dir));
        }
      else if (wc_kind == svn_node_dir)
        {
          /* We have an editor violation. Github sometimes does this
             in its subversion compatibility code, when changing the
             depth of a working copy, or on updates from incomplete */
        }
      else
        {
          /* We found a file external occupating the place we need in BASE.

             We can't add a not-present node in this case as that would overwrite
             the file external. Luckily the file external itself stops us from
             forgetting a child of this parent directory like an obstructing
             working copy would.

             The reason we get here is that the adm crawler doesn't report
             file externals.
           */
          SVN_ERR_ASSERT(wc_kind == svn_node_file
                         || wc_kind == svn_node_symlink);
        }

      SVN_ERR(remember_skipped_tree(eb, fb->local_abspath, pool));
      fb->skip_this = TRUE;
      fb->already_notified = TRUE;

      do_notification(eb, fb->local_abspath, wc_kind,
                      svn_wc_notify_update_skip_obstruction, scratch_pool);

      svn_pool_destroy(scratch_pool);

      return SVN_NO_ERROR;
    }
  else
    versioned_locally_and_present = IS_NODE_PRESENT(status);


  /* Is this path a conflict victim? */
  if (fb->shadowed)
    conflicted = FALSE; /* Conflict applies to WORKING */
  else if (conflicted)
    {
      if (pb->deletion_conflicts)
        tree_conflict = svn_hash_gets(pb->deletion_conflicts, fb->name);

      if (tree_conflict)
        {
          svn_wc_conflict_reason_t reason;
          const char *move_src_op_root_abspath;
          /* So this deletion wasn't just a deletion, it is actually a
             replacement. Let's install a better tree conflict. */

          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
                                                      &move_src_op_root_abspath,
                                                      eb->db,
                                                      fb->local_abspath,
                                                      tree_conflict,
                                                      fb->pool, scratch_pool));

          tree_conflict = svn_wc__conflict_skel_create(fb->pool);

          SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
                                        tree_conflict,
                                        eb->db, fb->local_abspath,
                                        reason, svn_wc_conflict_action_replace,
                                        move_src_op_root_abspath,
                                        fb->pool, scratch_pool));

          /* And now stop checking for conflicts here and just perform
             a shadowed update */
          fb->edit_conflict = tree_conflict; /* Cache for close_file */
          tree_conflict = NULL; /* No direct notification */
          fb->shadowed = TRUE; /* Just continue */
          conflicted = FALSE; /* No skip */
        }
      else
        SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
                                        eb->db, fb->local_abspath, pool));
    }

  /* Now the usual conflict handling: skip. */
  if (conflicted)
    {
      SVN_ERR(remember_skipped_tree(eb, fb->local_abspath, pool));

      fb->skip_this = TRUE;
      fb->already_notified = TRUE;

      /* We skip this node, but once the update completes the parent node will
         be updated to the new revision. So a future recursive update of the
         parent will not bring in this new node as the revision of the parent
         describes to the repository that all children are available.

         To resolve this problem, we add a not-present node to allow bringing
         the node in once this conflict is resolved.

         Note that we can safely assume that no present base node exists,
         because then we would not have received an add_file.
       */
      svn_hash_sets(pb->not_present_nodes, apr_pstrdup(pb->pool, fb->name),
                    svn_node_kind_to_word(svn_node_file));

      do_notification(eb, fb->local_abspath, svn_node_file,
                      svn_wc_notify_skip_conflicted, scratch_pool);

      svn_pool_destroy(scratch_pool);

      return SVN_NO_ERROR;
    }
  else if (conflict_ignored)
    {
      fb->shadowed = TRUE;
    }

  if (fb->shadowed)
    {
      /* Nothing to check; does not and will not exist in working copy */
    }
  else if (versioned_locally_and_present)
    {
      /* What to do with a versioned or schedule-add file:

         If the UUID doesn't match the parent's, or the URL isn't a child of
         the parent dir's URL, it's an error.

         Set add_existed so that user notification is delayed until after any
         text or prop conflicts have been found.

         Whether the incoming add is a symlink or a file will only be known in
         close_file(), when the props are known. So with a locally added file
         or symlink, let close_file() check for a tree conflict.

         We will never see missing files here, because these would be
         re-added during the crawler phase. */
      svn_boolean_t local_is_file;

      /* Is the local node a copy or move */
      if (status == svn_wc__db_status_added)
        SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, NULL,
                                         NULL, NULL, NULL,
                                         eb->db, fb->local_abspath,
                                         scratch_pool, scratch_pool));

      /* Is there something that is a file? */
      local_is_file = (wc_kind == svn_node_file
                       || wc_kind == svn_node_symlink);

      /* Do tree conflict checking if
       *  - if there is a local copy.
       *  - if this is a switch operation
       *  - the node kinds mismatch
       *
       * During switch, local adds at the same path as incoming adds get
       * "lost" in that switching back to the original will no longer have the
       * local add. So switch always alerts the user with a tree conflict. */
      if (!eb->adds_as_modification
          || !local_is_file
          || status != svn_wc__db_status_added)
        {
          SVN_ERR(check_tree_conflict(&tree_conflict, eb,
                                      fb->local_abspath,
                                      status, FALSE, svn_node_none,
                                      svn_wc_conflict_action_add,
                                      fb->pool, scratch_pool));
        }

      if (tree_conflict == NULL)
        fb->add_existed = TRUE; /* Take over WORKING */
      else
        fb->shadowed = TRUE; /* Only update BASE */

    }
  else if (kind != svn_node_none)
    {
      /* There's an unversioned node at this path. */
      fb->obstruction_found = TRUE;

      /* Unversioned, obstructing files are handled by text merge/conflict,
       * if unversioned obstructions are allowed. */
      if (! (kind == svn_node_file && eb->allow_unver_obstructions))
        {
          /* Bring in the node as deleted */ /* ### Obstructed Conflict */
          fb->shadowed = TRUE;

          /* Mark a conflict */
          tree_conflict = svn_wc__conflict_skel_create(fb->pool);

          SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
                                        tree_conflict,
                                        eb->db, fb->local_abspath,
                                        svn_wc_conflict_reason_unversioned,
                                        svn_wc_conflict_action_add,
                                        NULL,
                                        fb->pool, scratch_pool));
        }
    }

  /* When this is not the update target add a not-present BASE node now,
     to allow marking the parent directory complete in its close_edit() call.
     This resolves issues when that occurs before the close_file(). */
  if (pb->parent_baton
      || *eb->target_basename == '\0'
      || (strcmp(fb->local_abspath, eb->target_abspath) != 0))
    {
      svn_hash_sets(pb->not_present_nodes, apr_pstrdup(pb->pool, fb->name),
                    svn_node_kind_to_word(svn_node_file));
    }

  if (tree_conflict != NULL)
    {
      SVN_ERR(complete_conflict(tree_conflict,
                                fb->edit_baton,
                                fb->local_abspath,
                                fb->old_repos_relpath,
                                fb->old_revision,
                                fb->new_repos_relpath,
                                wc_kind, svn_node_file,
                                pb->deletion_conflicts
                                  ? svn_hash_gets(pb->deletion_conflicts,
                                                  fb->name)
                                  : NULL,
                                fb->pool, scratch_pool));

      SVN_ERR(svn_wc__db_op_mark_conflict(eb->db,
                                          fb->local_abspath,
                                          tree_conflict, NULL,
                                          scratch_pool));

      fb->edit_conflict = tree_conflict;

      fb->already_notified = TRUE;
      do_notification(eb, fb->local_abspath, svn_node_file,
                      svn_wc_notify_tree_conflict, scratch_pool);
    }

  svn_pool_destroy(scratch_pool);

  return SVN_NO_ERROR;
}


/* An svn_delta_editor_t function. */
static svn_error_t *
open_file(const char *path,
          void *parent_baton,
          svn_revnum_t base_revision,
          apr_pool_t *pool,
          void **file_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct file_baton *fb;
  svn_boolean_t conflicted;
  svn_boolean_t conflict_ignored = FALSE;
  svn_boolean_t have_work;
  svn_wc__db_status_t status;
  svn_node_kind_t wc_kind;
  svn_skel_t *tree_conflict = NULL;

  /* the file_pool can stick around for a *long* time, so we want to use
     a subpool for any temporary allocations. */
  apr_pool_t *scratch_pool = svn_pool_create(pool);

  SVN_ERR(make_file_baton(&fb, pb, path, FALSE, pool));
  *file_baton = fb;

  if (fb->skip_this)
    return SVN_NO_ERROR;

  /* Detect obstructing working copies */
  {
    svn_boolean_t is_root;

    SVN_ERR(svn_wc__db_is_wcroot(&is_root, eb->db, fb->local_abspath,
                                 pool));

    if (is_root)
      {
        /* Just skip this node; a future update will handle it */
        SVN_ERR(remember_skipped_tree(eb, fb->local_abspath, pool));
        fb->skip_this = TRUE;
        fb->already_notified = TRUE;

        do_notification(eb, fb->local_abspath, svn_node_file,
                        svn_wc_notify_update_skip_obstruction, pool);

        return SVN_NO_ERROR;
      }
  }

  /* Sanity check. */

  SVN_ERR(svn_wc__db_read_info(&status, &wc_kind, &fb->old_revision,
                               &fb->old_repos_relpath, NULL, NULL,
                               &fb->changed_rev, &fb->changed_date,
                               &fb->changed_author, NULL,
                               &fb->original_checksum, NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL, NULL, NULL,
                               &conflicted, NULL, NULL, &fb->local_prop_mods,
                               NULL, NULL, &have_work,
                               eb->db, fb->local_abspath,
                               fb->pool, scratch_pool));

  if (have_work)
    SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &fb->old_revision,
                                     &fb->old_repos_relpath, NULL, NULL,
                                     &fb->changed_rev, &fb->changed_date,
                                     &fb->changed_author, NULL,
                                     &fb->original_checksum, NULL, NULL,
                                     NULL, NULL, NULL,
                                     eb->db, fb->local_abspath,
                                     fb->pool, scratch_pool));

  SVN_ERR(calculate_repos_relpath(&fb->new_repos_relpath, fb->local_abspath,
                                  fb->old_repos_relpath, eb, pb,
                                  fb->pool, scratch_pool));

  /* Is this path a conflict victim? */
  if (fb->shadowed)
    conflicted = FALSE; /* Conflict applies to WORKING */
  else if (conflicted)
    SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
                                    eb->db, fb->local_abspath, pool));
  if (conflicted)
    {
      SVN_ERR(remember_skipped_tree(eb, fb->local_abspath, pool));

      fb->skip_this = TRUE;
      fb->already_notified = TRUE;

      do_notification(eb, fb->local_abspath, svn_node_unknown,
                      svn_wc_notify_skip_conflicted, scratch_pool);

      svn_pool_destroy(scratch_pool);

      return SVN_NO_ERROR;
    }
  else if (conflict_ignored)
    {
      fb->shadowed = TRUE;
    }

  /* Check for conflicts only when we haven't already recorded
   * a tree-conflict on a parent node. */
  if (!fb->shadowed)
    SVN_ERR(check_tree_conflict(&tree_conflict, eb, fb->local_abspath,
                                status, TRUE, svn_node_file,
                                svn_wc_conflict_action_edit,
                                fb->pool, scratch_pool));

  /* Is this path the victim of a newly-discovered tree conflict? */
  if (tree_conflict != NULL)
    {
      svn_wc_conflict_reason_t reason;
      fb->edit_conflict = tree_conflict;
      /* Other modifications wouldn't be a tree conflict */

      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                  eb->db, fb->local_abspath,
                                                  tree_conflict,
                                                  scratch_pool, scratch_pool));
      SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_deleted
                     || reason == svn_wc_conflict_reason_moved_away
                     || reason == svn_wc_conflict_reason_replaced
                     || reason == svn_wc_conflict_reason_obstructed);

      /* Continue updating BASE */
      if (reason == svn_wc_conflict_reason_obstructed)
        fb->edit_obstructed = TRUE;
      else
        fb->shadowed = TRUE;
    }

  svn_pool_destroy(scratch_pool);

  return SVN_NO_ERROR;
}

/* Implements svn_stream_lazyopen_func_t. */
static svn_error_t *
lazy_open_source(svn_stream_t **stream,
                 void *baton,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
{
  struct file_baton *fb = baton;

  SVN_ERR(svn_wc__db_pristine_read(stream, NULL, fb->edit_baton->db,
                                   fb->local_abspath,
                                   fb->original_checksum,
                                   result_pool, scratch_pool));


  return SVN_NO_ERROR;
}

/* Implements svn_stream_lazyopen_func_t. */
static svn_error_t *
lazy_open_target(svn_stream_t **stream,
                 void *baton,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
{
  struct handler_baton *hb = baton;

  SVN_ERR(svn_wc__db_pristine_prepare_install(stream,
                                              &hb->install_data,
                                              &hb->new_text_base_sha1_checksum,
                                              NULL,
                                              hb->fb->edit_baton->db,
                                              hb->fb->dir_baton->local_abspath,
                                              result_pool, scratch_pool));

  return SVN_NO_ERROR;
}

/* An svn_delta_editor_t function. */
static svn_error_t *
apply_textdelta(void *file_baton,
                const char *expected_checksum,
                apr_pool_t *pool,
                svn_txdelta_window_handler_t *handler,
                void **handler_baton)
{
  struct file_baton *fb = file_baton;
  apr_pool_t *handler_pool = svn_pool_create(fb->pool);
  struct handler_baton *hb = apr_pcalloc(handler_pool, sizeof(*hb));
  struct edit_baton *eb = fb->edit_baton;
  const svn_checksum_t *recorded_base_checksum;
  svn_checksum_t *expected_base_checksum;
  svn_stream_t *source;
  svn_stream_t *target;

  if (fb->skip_this)
    {
      *handler = svn_delta_noop_window_handler;
      *handler_baton = NULL;
      return SVN_NO_ERROR;
    }

  SVN_ERR(mark_file_edited(fb, pool));

  /* Parse checksum or sets expected_base_checksum to NULL */
  SVN_ERR(svn_checksum_parse_hex(&expected_base_checksum, svn_checksum_md5,
                                 expected_checksum, pool));

  /* Before applying incoming svndiff data to text base, make sure
     text base hasn't been corrupted, and that its checksum
     matches the expected base checksum. */

  /* The incoming delta is targeted against EXPECTED_BASE_CHECKSUM. Find and
     check our RECORDED_BASE_CHECKSUM.  (In WC-1, we could not do this test
     for replaced nodes because we didn't store the checksum of the "revert
     base".  In WC-NG, we do and we can.) */
  recorded_base_checksum = fb->original_checksum;

  /* If we have a checksum that we want to compare to a MD5 checksum,
     ensure that it is a MD5 checksum */
  if (recorded_base_checksum
      && expected_base_checksum
      && recorded_base_checksum->kind != svn_checksum_md5)
    SVN_ERR(svn_wc__db_pristine_get_md5(&recorded_base_checksum,
                                        eb->db, eb->wcroot_abspath,
                                        recorded_base_checksum, pool, pool));


  if (!svn_checksum_match(expected_base_checksum, recorded_base_checksum))
      return svn_error_createf(SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,
                     _("Checksum mismatch for '%s':\n"
                       "   expected:  %s\n"
                       "   recorded:  %s\n"),
                     svn_dirent_local_style(fb->local_abspath, pool),
                     svn_checksum_to_cstring_display(expected_base_checksum,
                                                     pool),
                     svn_checksum_to_cstring_display(recorded_base_checksum,
                                                     pool));

  /* Open the text base for reading, unless this is an added file. */

  /*
     kff todo: what we really need to do here is:

     1. See if there's a file or dir by this name already here.
     2. See if it's under revision control.
     3. If both are true, open text-base.
     4. If only 1 is true, bail, because we can't go destroying user's
        files (or as an alternative to bailing, move it to some tmp
        name and somehow tell the user, but communicating with the
        user without erroring is a whole callback system we haven't
        finished inventing yet.)
  */

  if (! fb->adding_file)
    {
      SVN_ERR_ASSERT(!fb->original_checksum
                     || fb->original_checksum->kind == svn_checksum_sha1);

      source = svn_stream_lazyopen_create(lazy_open_source, fb, FALSE,
                                          handler_pool);
    }
  else
    {
      source = svn_stream_empty(handler_pool);
    }

  /* If we don't have a recorded checksum, use the ra provided checksum */
  if (!recorded_base_checksum)
    recorded_base_checksum = expected_base_checksum;

  /* Checksum the text base while applying deltas */
  if (recorded_base_checksum)
    {
      hb->expected_source_checksum = svn_checksum_dup(recorded_base_checksum,
                                                      handler_pool);

      /* Wrap stream and store reference to allow calculating the
         checksum. */
      source = svn_stream_checksummed2(source,
                                       &hb->actual_source_checksum,
                                       NULL, recorded_base_checksum->kind,
                                       TRUE, handler_pool);
      hb->source_checksum_stream = source;
    }

  target = svn_stream_lazyopen_create(lazy_open_target, hb, TRUE, handler_pool);

  /* Prepare to apply the delta.  */
  svn_txdelta_apply(source, target,
                    hb->new_text_base_md5_digest,
                    fb->local_abspath /* error_info */,
                    handler_pool,
                    &hb->apply_handler, &hb->apply_baton);

  hb->pool = handler_pool;
  hb->fb = fb;

  /* We're all set.  */
  *handler_baton = hb;
  *handler = window_handler;

  return SVN_NO_ERROR;
}


/* An svn_delta_editor_t function. */
static svn_error_t *
change_file_prop(void *file_baton,
                 const char *name,
                 const svn_string_t *value,
                 apr_pool_t *scratch_pool)
{
  struct file_baton *fb = file_baton;
  svn_prop_t *propchange;

  if (fb->skip_this)
    return SVN_NO_ERROR;

  /* Push a new propchange to the file baton's array of propchanges */
  propchange = apr_array_push(fb->propchanges);
  propchange->name = apr_pstrdup(fb->pool, name);
  propchange->value = svn_string_dup(value, fb->pool);

  if (!fb->edited && svn_property_kind2(name) == svn_prop_regular_kind)
    SVN_ERR(mark_file_edited(fb, scratch_pool));

  if (! fb->shadowed
      && strcmp(name, SVN_PROP_SPECIAL) == 0)
    {
      struct edit_baton *eb = fb->edit_baton;
      svn_boolean_t modified = FALSE;
      svn_boolean_t becomes_symlink;
      svn_boolean_t was_symlink;

      /* Let's see if we have a change as in some scenarios servers report
         non-changes of properties. */
      becomes_symlink = (value != NULL);

      if (fb->adding_file)
        was_symlink = becomes_symlink; /* No change */
      else
        {
          apr_hash_t *props;

          /* We read the server-props, not the ACTUAL props here as we just
             want to see if this is really an incoming prop change. */
          SVN_ERR(svn_wc__db_base_get_props(&props, eb->db,
                                            fb->local_abspath,
                                            scratch_pool, scratch_pool));

          was_symlink = ((props
                              && svn_hash_gets(props, SVN_PROP_SPECIAL) != NULL)
                              ? svn_tristate_true
                              : svn_tristate_false);
        }

      if (was_symlink != becomes_symlink)
        {
          /* If the local node was not modified, we continue as usual, if
             modified we want a tree conflict just like how we would handle
             it when receiving a delete + add (aka "replace") */
          if (fb->local_prop_mods)
            modified = TRUE;
          else
            SVN_ERR(svn_wc__internal_file_modified_p(&modified, eb->db,
                                                     fb->local_abspath,
                                                     FALSE, scratch_pool));
        }

      if (modified)
        {
          if (!fb->edit_conflict)
            fb->edit_conflict = svn_wc__conflict_skel_create(fb->pool);

          SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
                                     fb->edit_conflict,
                                     eb->db, fb->local_abspath,
                                     svn_wc_conflict_reason_edited,
                                     svn_wc_conflict_action_replace,
                                     NULL,
                                     fb->pool, scratch_pool));

          SVN_ERR(complete_conflict(fb->edit_conflict, fb->edit_baton,
                                    fb->local_abspath, fb->old_repos_relpath,
                                    fb->old_revision, fb->new_repos_relpath,
                                    svn_node_file, svn_node_file,
                                    NULL, fb->pool, scratch_pool));

          /* Create a copy of the existing (pre update) BASE node in WORKING,
             mark a tree conflict and handle the rest of the update as
             shadowed */
          SVN_ERR(svn_wc__db_op_make_copy(eb->db, fb->local_abspath,
                                          fb->edit_conflict, NULL,
                                          scratch_pool));

          do_notification(eb, fb->local_abspath, svn_node_file,
                          svn_wc_notify_tree_conflict, scratch_pool);

          /* Ok, we introduced a replacement, so we can now handle the rest
             as a normal shadowed update */
          fb->shadowed = TRUE;
          fb->add_existed = FALSE;
          fb->already_notified = TRUE;
      }
    }

  return SVN_NO_ERROR;
}

/* Perform the actual merge of file changes between an original file,
   identified by ORIGINAL_CHECKSUM (an empty file if NULL) to a new file
   identified by NEW_CHECKSUM.

   Merge the result into LOCAL_ABSPATH, which is part of the working copy
   identified by WRI_ABSPATH. Use OLD_REVISION and TARGET_REVISION for naming
   the intermediate files.

   The rest of the arguments are passed to svn_wc__internal_merge().
 */
svn_error_t *
svn_wc__perform_file_merge(svn_skel_t **work_items,
                           svn_skel_t **conflict_skel,
                           svn_boolean_t *found_conflict,
                           svn_wc__db_t *db,
                           const char *local_abspath,
                           const char *wri_abspath,
                           const svn_checksum_t *new_checksum,
                           const svn_checksum_t *original_checksum,
                           apr_hash_t *old_actual_props,
                           const apr_array_header_t *ext_patterns,
                           svn_revnum_t old_revision,
                           svn_revnum_t target_revision,
                           const apr_array_header_t *propchanges,
                           const char *diff3_cmd,
                           svn_cancel_func_t cancel_func,
                           void *cancel_baton,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
{
  /* Actual file exists and has local mods:
     Now we need to let loose svn_wc__internal_merge() to merge
     the textual changes into the working file. */
  const char *oldrev_str, *newrev_str, *mine_str;
  const char *merge_left;
  svn_boolean_t delete_left = FALSE;
  const char *path_ext = "";
  const char *new_pristine_abspath;
  enum svn_wc_merge_outcome_t merge_outcome = svn_wc_merge_unchanged;
  svn_skel_t *work_item;

  *work_items = NULL;

  SVN_ERR(svn_wc__db_pristine_get_path(&new_pristine_abspath,
                                       db, wri_abspath, new_checksum,
                                       scratch_pool, scratch_pool));

  /* If we have any file extensions we're supposed to
     preserve in generated conflict file names, then find
     this path's extension.  But then, if it isn't one of
     the ones we want to keep in conflict filenames,
     pretend it doesn't have an extension at all. */
  if (ext_patterns && ext_patterns->nelts)
    {
      svn_path_splitext(NULL, &path_ext, local_abspath, scratch_pool);
      if (! (*path_ext && svn_cstring_match_glob_list(path_ext, ext_patterns)))
        path_ext = "";
    }

  /* old_revision can be invalid when the conflict is against a
     local addition */
  if (!SVN_IS_VALID_REVNUM(old_revision))
    old_revision = 0;

  oldrev_str = apr_psprintf(scratch_pool, ".r%ld%s%s",
                            old_revision,
                            *path_ext ? "." : "",
                            *path_ext ? path_ext : "");

  newrev_str = apr_psprintf(scratch_pool, ".r%ld%s%s",
                            target_revision,
                            *path_ext ? "." : "",
                            *path_ext ? path_ext : "");
  mine_str = apr_psprintf(scratch_pool, ".mine%s%s",
                          *path_ext ? "." : "",
                          *path_ext ? path_ext : "");

  if (! original_checksum)
    {
      SVN_ERR(get_empty_tmp_file(&merge_left, db, wri_abspath,
                                 result_pool, scratch_pool));
      delete_left = TRUE;
    }
  else
    SVN_ERR(svn_wc__db_pristine_get_path(&merge_left, db, wri_abspath,
                                         original_checksum,
                                         result_pool, scratch_pool));

  /* Merge the changes from the old textbase to the new
     textbase into the file we're updating.
     Remember that this function wants full paths! */
  SVN_ERR(svn_wc__internal_merge(&work_item,
                                 conflict_skel,
                                 &merge_outcome,
                                 db,
                                 merge_left,
                                 new_pristine_abspath,
                                 local_abspath,
                                 wri_abspath,
                                 oldrev_str, newrev_str, mine_str,
                                 old_actual_props,
                                 FALSE /* dry_run */,
                                 diff3_cmd, NULL, propchanges,
                                 cancel_func, cancel_baton,
                                 result_pool, scratch_pool));

  *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
  *found_conflict = (merge_outcome == svn_wc_merge_conflict);

  /* If we created a temporary left merge file, get rid of it. */
  if (delete_left)
    {
      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db, wri_abspath,
                                           merge_left,
                                           result_pool, scratch_pool));
      *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
    }

  return SVN_NO_ERROR;
}

/* This is the small planet.  It has the complex responsibility of
 * "integrating" a new revision of a file into a working copy.
 *
 * Given a file_baton FB for a file either already under version control, or
 * prepared (see below) to join version control, fully install a
 * new revision of the file.
 *
 * ### transitional: installation of the working file will be handled
 * ### by the *INSTALL_PRISTINE flag.
 *
 * By "install", we mean: create a new text-base and prop-base, merge
 * any textual and property changes into the working file, and finally
 * update all metadata so that the working copy believes it has a new
 * working revision of the file.  All of this work includes being
 * sensitive to eol translation, keyword substitution, and performing
 * all actions accumulated the parent directory's work queue.
 *
 * Set *CONTENT_STATE to the state of the contents after the
 * installation.
 *
 * Return values are allocated in RESULT_POOL and temporary allocations
 * are performed in SCRATCH_POOL.
 */
static svn_error_t *
merge_file(svn_skel_t **work_items,
           svn_skel_t **conflict_skel,
           svn_boolean_t *install_pristine,
           const char **install_from,
           svn_wc_notify_state_t *content_state,
           struct file_baton *fb,
           apr_hash_t *actual_props,
           apr_time_t last_changed_date,
           apr_pool_t *result_pool,
           apr_pool_t *scratch_pool)
{
  struct edit_baton *eb = fb->edit_baton;
  struct dir_baton *pb = fb->dir_baton;
  svn_boolean_t is_locally_modified;
  svn_boolean_t found_text_conflict = FALSE;

  SVN_ERR_ASSERT(! fb->shadowed
                 && ! fb->obstruction_found
                 && ! fb->edit_obstructed);

  /*
     When this function is called on file F, we assume the following
     things are true:

         - The new pristine text of F is present in the pristine store
           iff FB->NEW_TEXT_BASE_SHA1_CHECKSUM is not NULL.

         - The WC metadata still reflects the old version of F.
           (We can still access the old pristine base text of F.)

     The goal is to update the local working copy of F to reflect
     the changes received from the repository, preserving any local
     modifications.
  */

  *work_items = NULL;
  *install_pristine = FALSE;
  *install_from = NULL;

  /* Start by splitting the file path, getting an access baton for the parent,
     and an entry for the file if any. */

  /* Has the user made local mods to the working file?
     Note that this compares to the current pristine file, which is
     different from fb->old_text_base_path if we have a replaced-with-history
     file.  However, in the case we had an obstruction, we check against the
     new text base.
   */
  if (fb->adding_file && !fb->add_existed)
    {
      is_locally_modified = FALSE; /* There is no file: Don't check */
    }
  else
    {
      /* The working file is not an obstruction.
         So: is the file modified, relative to its ORIGINAL pristine?

         This function sets is_locally_modified to FALSE for
         files that do not exist and for directories. */

      SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified,
                                               eb->db, fb->local_abspath,
                                               FALSE /* exact_comparison */,
                                               scratch_pool));
    }

  /* For 'textual' merging, we use the following system:

     When a file is modified and we have a new BASE:
      - For text files
          * svn_wc_merge uses diff3
          * possibly makes backups and marks files as conflicted.

      - For binary files
          * svn_wc_merge makes backups and marks files as conflicted.

     If a file is not modified and we have a new BASE:
       * Install from pristine.

     If we have property changes related to magic properties or if the
     svn:keywords property is set:
       * Retranslate from the working file.
   */
  if (! is_locally_modified
      && fb->new_text_base_sha1_checksum)
    {
          /* If there are no local mods, who cares whether it's a text
             or binary file!  Just write a log command to overwrite
             any working file with the new text-base.  If newline
             conversion or keyword substitution is activated, this
             will happen as well during the copy.
             For replaced files, though, we want to merge in the changes
             even if the file is not modified compared to the (non-revert)
             text-base. */

      *install_pristine = TRUE;
    }
  else if (fb->new_text_base_sha1_checksum)
    {
      /* Actual file exists and has local mods:
         Now we need to let loose svn_wc__merge_internal() to merge
         the textual changes into the working file. */
      SVN_ERR(svn_wc__perform_file_merge(work_items,
                                         conflict_skel,
                                         &found_text_conflict,
                                         eb->db,
                                         fb->local_abspath,
                                         pb->local_abspath,
                                         fb->new_text_base_sha1_checksum,
                                         fb->add_existed
                                                  ? NULL
                                                  : fb->original_checksum,
                                         actual_props,
                                         eb->ext_patterns,
                                         fb->old_revision,
                                         *eb->target_revision,
                                         fb->propchanges,
                                         eb->diff3_cmd,
                                         eb->cancel_func, eb->cancel_baton,
                                         result_pool, scratch_pool));
    } /* end: working file exists and has mods */
  else
    {
      /* There is no new text base, but let's see if the working file needs
         to be updated for any other reason. */

      apr_hash_t *keywords;

      /* Determine if any of the propchanges are the "magic" ones that
         might require changing the working file. */
      svn_boolean_t magic_props_changed;

      magic_props_changed = svn_wc__has_magic_property(fb->propchanges);

      SVN_ERR(svn_wc__get_translate_info(NULL, NULL,
                                         &keywords,
                                         NULL,
                                         eb->db, fb->local_abspath,
                                         actual_props, TRUE,
                                         scratch_pool, scratch_pool));
      if (magic_props_changed || keywords)
        {
          /* Special edge-case: it's possible that this file installation
             only involves propchanges, but that some of those props still
             require a retranslation of the working file.

             OR that the file doesn't involve propchanges which by themselves
             require retranslation, but receiving a change bumps the revision
             number which requires re-expansion of keywords... */

          if (is_locally_modified)
            {
              const char *tmptext;

              /* Copy and DEtranslate the working file to a temp text-base.
                 Note that detranslation is done according to the old props. */
              SVN_ERR(svn_wc__internal_translated_file(
                        &tmptext, fb->local_abspath, eb->db, fb->local_abspath,
                        SVN_WC_TRANSLATE_TO_NF
                          | SVN_WC_TRANSLATE_NO_OUTPUT_CLEANUP,
                        eb->cancel_func, eb->cancel_baton,
                        result_pool, scratch_pool));

              /* We always want to reinstall the working file if the magic
                 properties have changed, or there are any keywords present.
                 Note that TMPTEXT might actually refer to the working file
                 itself (the above function skips a detranslate when not
                 required). This is acceptable, as we will (re)translate
                 according to the new properties into a temporary file (from
                 the working file), and then rename the temp into place. Magic!
               */
              *install_pristine = TRUE;
              *install_from = tmptext;
            }
          else
            {
              /* Use our existing 'copy' from the pristine store instead
                 of making a new copy. This way we can use the standard code
                 to update the recorded size and modification time.
                 (Issue #3842) */
              *install_pristine = TRUE;
            }
        }
    }

  /* Set the returned content state. */

  if (found_text_conflict)
    *content_state = svn_wc_notify_state_conflicted;
  else if (fb->new_text_base_sha1_checksum)
    {
      if (is_locally_modified)
        *content_state = svn_wc_notify_state_merged;
      else
        *content_state = svn_wc_notify_state_changed;
    }
  else
    *content_state = svn_wc_notify_state_unchanged;

  return SVN_NO_ERROR;
}


/* An svn_delta_editor_t function. */
/* Mostly a wrapper around merge_file. */
static svn_error_t *
close_file(void *file_baton,
           const char *expected_md5_digest,
           apr_pool_t *pool)
{
  struct file_baton *fb = file_baton;
  struct dir_baton *pdb = fb->dir_baton;
  struct edit_baton *eb = fb->edit_baton;
  svn_wc_notify_state_t content_state, prop_state;
  svn_wc_notify_lock_state_t lock_state;
  svn_checksum_t *expected_md5_checksum = NULL;
  apr_hash_t *new_base_props = NULL;
  apr_hash_t *new_actual_props = NULL;
  apr_array_header_t *entry_prop_changes;
  apr_array_header_t *dav_prop_changes;
  apr_array_header_t *regular_prop_changes;
  apr_hash_t *current_base_props = NULL;
  apr_hash_t *current_actual_props = NULL;
  apr_hash_t *local_actual_props = NULL;
  svn_skel_t *all_work_items = NULL;
  svn_skel_t *conflict_skel = NULL;
  svn_skel_t *work_item;
  apr_pool_t *scratch_pool = fb->pool; /* Destroyed at function exit */
  svn_boolean_t keep_recorded_info = FALSE;
  const svn_checksum_t *new_checksum;
  apr_array_header_t *iprops = NULL;

  if (fb->skip_this)
    {
      svn_pool_destroy(fb->pool);
      SVN_ERR(maybe_release_dir_info(pdb));
      return SVN_NO_ERROR;
    }

  if (fb->edited)
    conflict_skel = fb->edit_conflict;

  if (expected_md5_digest)
    SVN_ERR(svn_checksum_parse_hex(&expected_md5_checksum, svn_checksum_md5,
                                   expected_md5_digest, scratch_pool));

  if (fb->new_text_base_md5_checksum && expected_md5_checksum
      && !svn_checksum_match(expected_md5_checksum,
                             fb->new_text_base_md5_checksum))
    return svn_error_trace(
                svn_checksum_mismatch_err(expected_md5_checksum,
                                          fb->new_text_base_md5_checksum,
                                          scratch_pool,
                                          _("Checksum mismatch for '%s'"),
                                          svn_dirent_local_style(
                                                fb->local_abspath, pool)));

  /* Gather the changes for each kind of property.  */
  SVN_ERR(svn_categorize_props(fb->propchanges, &entry_prop_changes,
                               &dav_prop_changes, &regular_prop_changes,
                               scratch_pool));

  /* Extract the changed_* and lock state information.  */
  {
    svn_revnum_t new_changed_rev;
    apr_time_t new_changed_date;
    const char *new_changed_author;

    SVN_ERR(accumulate_last_change(&new_changed_rev,
                                   &new_changed_date,
                                   &new_changed_author,
                                   entry_prop_changes,
                                   scratch_pool, scratch_pool));

    if (SVN_IS_VALID_REVNUM(new_changed_rev))
      fb->changed_rev = new_changed_rev;
    if (new_changed_date != 0)
      fb->changed_date = new_changed_date;
    if (new_changed_author != NULL)
      fb->changed_author = new_changed_author;
  }

  /* Determine whether the file has become unlocked.  */
  {
    int i;

    lock_state = svn_wc_notify_lock_state_unchanged;

    for (i = 0; i < entry_prop_changes->nelts; ++i)
      {
        const svn_prop_t *prop
          = &APR_ARRAY_IDX(entry_prop_changes, i, svn_prop_t);

        /* If we see a change to the LOCK_TOKEN entry prop, then the only
           possible change is its REMOVAL. Thus, the lock has been removed,
           and we should likewise remove our cached copy of it.  */
        if (! strcmp(prop->name, SVN_PROP_ENTRY_LOCK_TOKEN))
          {
            /* If we lose the lock, but not because we are switching to
               another url, remove the state lock from the wc */
            if (! eb->switch_repos_relpath
                || strcmp(fb->new_repos_relpath, fb->old_repos_relpath) == 0)
              {
                SVN_ERR_ASSERT(prop->value == NULL);
                SVN_ERR(svn_wc__db_lock_remove(eb->db, fb->local_abspath, NULL,
                                               scratch_pool));

                lock_state = svn_wc_notify_lock_state_unlocked;
              }
            break;
          }
      }
  }

  /* Install all kinds of properties.  It is important to do this before
     any file content merging, since that process might expand keywords, in
     which case we want the new entryprops to be in place. */

  /* Write log commands to merge REGULAR_PROPS into the existing
     properties of FB->LOCAL_ABSPATH.  Update *PROP_STATE to reflect
     the result of the regular prop merge.

     BASE_PROPS and WORKING_PROPS are hashes of the base and
     working props of the file; if NULL they are read from the wc.  */

  /* ### some of this feels like voodoo... */

  if ((!fb->adding_file || fb->add_existed)
      && !fb->shadowed)
    SVN_ERR(svn_wc__get_actual_props(&local_actual_props,
                                     eb->db, fb->local_abspath,
                                     scratch_pool, scratch_pool));
  if (local_actual_props == NULL)
    local_actual_props = apr_hash_make(scratch_pool);

  if (fb->add_existed)
    {
      /* This node already exists. Grab the current pristine properties. */
      SVN_ERR(svn_wc__db_read_pristine_props(&current_base_props,
                                             eb->db, fb->local_abspath,
                                             scratch_pool, scratch_pool));
      current_actual_props = local_actual_props;
    }
  else if (!fb->adding_file)
    {
      /* Get the BASE properties for proper merging. */
      SVN_ERR(svn_wc__db_base_get_props(&current_base_props,
                                        eb->db, fb->local_abspath,
                                        scratch_pool, scratch_pool));
      current_actual_props = local_actual_props;
    }

  /* Note: even if the node existed before, it may not have
     pristine props (e.g a local-add)  */
  if (current_base_props == NULL)
    current_base_props = apr_hash_make(scratch_pool);

  /* And new nodes need an empty set of ACTUAL props.  */
  if (current_actual_props == NULL)
    current_actual_props = apr_hash_make(scratch_pool);

  prop_state = svn_wc_notify_state_unknown;

  if (! fb->shadowed)
    {
      svn_boolean_t install_pristine;
      const char *install_from = NULL;

      /* Merge the 'regular' props into the existing working proplist. */
      /* This will merge the old and new props into a new prop db, and
         write <cp> commands to the logfile to install the merged
         props.  */
      new_base_props = svn_prop__patch(current_base_props, regular_prop_changes,
                                       scratch_pool);
      SVN_ERR(svn_wc__merge_props(&conflict_skel,
                                  &prop_state,
                                  &new_actual_props,
                                  eb->db,
                                  fb->local_abspath,
                                  NULL /* server_baseprops (update, not merge)  */,
                                  current_base_props,
                                  current_actual_props,
                                  regular_prop_changes, /* propchanges */
                                  scratch_pool,
                                  scratch_pool));
      /* We will ALWAYS have properties to save (after a not-dry-run merge). */
      SVN_ERR_ASSERT(new_base_props != NULL && new_actual_props != NULL);

      /* Merge the text. This will queue some additional work.  */
      if (!fb->obstruction_found && !fb->edit_obstructed)
        {
          svn_error_t *err;
          err = merge_file(&work_item, &conflict_skel,
                           &install_pristine, &install_from,
                           &content_state, fb, current_actual_props,
                           fb->changed_date, scratch_pool, scratch_pool);

          if (err && err->apr_err == SVN_ERR_WC_PATH_ACCESS_DENIED)
            {
              if (eb->notify_func)
                {
                  svn_wc_notify_t *notify =svn_wc_create_notify(
                                fb->local_abspath,
                                svn_wc_notify_update_skip_access_denied,
                                scratch_pool);

                  notify->kind = svn_node_file;
                  notify->err = err;

                  eb->notify_func(eb->notify_baton, notify, scratch_pool);
                }
              svn_error_clear(err);

              SVN_ERR(remember_skipped_tree(eb, fb->local_abspath,
                                            scratch_pool));
              fb->skip_this = TRUE;

              svn_pool_destroy(fb->pool);
              SVN_ERR(maybe_release_dir_info(pdb));
              return SVN_NO_ERROR;
            }
          else
            SVN_ERR(err);

          all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                            scratch_pool);
        }
      else
        {
          install_pristine = FALSE;
          if (fb->new_text_base_sha1_checksum)
            content_state = svn_wc_notify_state_changed;
          else
            content_state = svn_wc_notify_state_unchanged;
        }

      if (install_pristine)
        {
          svn_boolean_t record_fileinfo;

          /* If we are installing from the pristine contents, then go ahead and
             record the fileinfo. That will be the "proper" values. Installing
             from some random file means the fileinfo does NOT correspond to
             the pristine (in which case, the fileinfo will be cleared for
             safety's sake).  */
          record_fileinfo = (install_from == NULL);

          SVN_ERR(svn_wc__wq_build_file_install(&work_item,
                                                eb->db,
                                                fb->local_abspath,
                                                install_from,
                                                eb->use_commit_times,
                                                record_fileinfo,
                                                scratch_pool, scratch_pool));
          all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                            scratch_pool);
        }
      else if (lock_state == svn_wc_notify_lock_state_unlocked
               && !fb->obstruction_found)
        {
          /* If a lock was removed and we didn't update the text contents, we
             might need to set the file read-only.

             Note: this will also update the executable flag, but ... meh.  */
          SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, eb->db,
                                                   fb->local_abspath,
                                                   scratch_pool, scratch_pool));
          all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                            scratch_pool);
        }

      if (! install_pristine
          && (content_state == svn_wc_notify_state_unchanged))
        {
          /* It is safe to keep the current recorded timestamp and size */
          keep_recorded_info = TRUE;
        }

      /* Clean up any temporary files.  */

      /* Remove the INSTALL_FROM file, as long as it doesn't refer to the
         working file.  */
      if (install_from != NULL
          && strcmp(install_from, fb->local_abspath) != 0)
        {
          SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
                                               fb->local_abspath, install_from,
                                               scratch_pool, scratch_pool));
          all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                            scratch_pool);
        }
    }
  else
    {
      /* Adding or updating a BASE node under a locally added node. */
      apr_hash_t *fake_actual_props;

      if (fb->adding_file)
        fake_actual_props = apr_hash_make(scratch_pool);
      else
        fake_actual_props = current_base_props;

      /* Store the incoming props (sent as propchanges) in new_base_props
         and create a set of new actual props to use for notifications */
      new_base_props = svn_prop__patch(current_base_props, regular_prop_changes,
                                       scratch_pool);
      SVN_ERR(svn_wc__merge_props(&conflict_skel,
                                  &prop_state,
                                  &new_actual_props,
                                  eb->db,
                                  fb->local_abspath,
                                  NULL /* server_baseprops (not merging) */,
                                  current_base_props /* pristine_props */,
                                  fake_actual_props /* actual_props */,
                                  regular_prop_changes, /* propchanges */
                                  scratch_pool,
                                  scratch_pool));

      if (fb->new_text_base_sha1_checksum)
        content_state = svn_wc_notify_state_changed;
      else
        content_state = svn_wc_notify_state_unchanged;
    }

  /* Insert/replace the BASE node with all of the new metadata.  */

  /* Set the 'checksum' column of the file's BASE_NODE row to
   * NEW_TEXT_BASE_SHA1_CHECKSUM.  The pristine text identified by that
   * checksum is already in the pristine store. */
  new_checksum = fb->new_text_base_sha1_checksum;

  /* If we don't have a NEW checksum, then the base must not have changed.
     Just carry over the old checksum.  */
  if (new_checksum == NULL)
    new_checksum = fb->original_checksum;

  if (conflict_skel)
    {
      SVN_ERR(complete_conflict(conflict_skel,
                                fb->edit_baton,
                                fb->local_abspath,
                                fb->old_repos_relpath,
                                fb->old_revision,
                                fb->new_repos_relpath,
                                svn_node_file, svn_node_file,
                                fb->dir_baton->deletion_conflicts
                                  ? svn_hash_gets(
                                        fb->dir_baton->deletion_conflicts,
                                        fb->name)
                                  : NULL,
                                fb->pool, scratch_pool));

      SVN_ERR(svn_wc__conflict_create_markers(&work_item,
                                              eb->db, fb->local_abspath,
                                              conflict_skel,
                                              scratch_pool, scratch_pool));

      all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                        scratch_pool);
    }

  /* Any inherited props to be set set for this base node? */
  if (eb->wcroot_iprops)
    {
      iprops = svn_hash_gets(eb->wcroot_iprops, fb->local_abspath);

      /* close_edit may also update iprops for switched nodes, catching
         those for which close_directory is never called (e.g. a switch
         with no changes).  So as a minor optimization we remove any
         iprops from the hash so as not to set them again in
         close_edit. */
      if (iprops)
        svn_hash_sets(eb->wcroot_iprops, fb->local_abspath, NULL);
    }

  SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath,
                                   eb->wcroot_abspath,
                                   fb->new_repos_relpath,
                                   eb->repos_root, eb->repos_uuid,
                                   *eb->target_revision,
                                   new_base_props,
                                   fb->changed_rev,
                                   fb->changed_date,
                                   fb->changed_author,
                                   new_checksum,
                                   (dav_prop_changes->nelts > 0)
                                     ? svn_prop_array_to_hash(
                                                      dav_prop_changes,
                                                      scratch_pool)
                                     : NULL,
                                   (fb->add_existed && fb->adding_file),
                                   (! fb->shadowed) && new_base_props,
                                   new_actual_props,
                                   iprops,
                                   keep_recorded_info,
                                   (fb->shadowed && fb->obstruction_found),
                                   conflict_skel,
                                   all_work_items,
                                   scratch_pool));

  if (conflict_skel && eb->conflict_func)
    SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, fb->local_abspath,
                                             svn_node_file,
                                             conflict_skel,
                                             NULL /* merge_options */,
                                             eb->conflict_func,
                                             eb->conflict_baton,
                                             eb->cancel_func,
                                             eb->cancel_baton,
                                             scratch_pool));

  /* Deal with the WORKING tree, based on updates to the BASE tree.  */

  svn_hash_sets(fb->dir_baton->not_present_nodes, fb->name, NULL);

  /* Send a notification to the callback function.  (Skip notifications
     about files which were already notified for another reason.) */
  if (eb->notify_func && !fb->already_notified
      && (fb->edited || lock_state == svn_wc_notify_lock_state_unlocked))
    {
      svn_wc_notify_t *notify;
      svn_wc_notify_action_t action = svn_wc_notify_update_update;

      if (fb->edited)
        {
          if (fb->shadowed || fb->edit_obstructed)
            action = fb->adding_file
                            ? svn_wc_notify_update_shadowed_add
                            : svn_wc_notify_update_shadowed_update;
          else if (fb->obstruction_found || fb->add_existed)
            {
              if (content_state != svn_wc_notify_state_conflicted)
                action = svn_wc_notify_exists;
            }
          else if (fb->adding_file)
            {
              action = svn_wc_notify_update_add;
            }
        }
      else
        {
          SVN_ERR_ASSERT(lock_state == svn_wc_notify_lock_state_unlocked);
          action = svn_wc_notify_update_broken_lock;
        }

      /* If the file was moved-away, notify for the moved-away node.
       * The original location only had its BASE info changed and
       * we don't usually notify about such changes. */
      notify = svn_wc_create_notify(fb->local_abspath, action, scratch_pool);
      notify->kind = svn_node_file;
      notify->content_state = content_state;
      notify->prop_state = prop_state;
      notify->lock_state = lock_state;
      notify->revision = *eb->target_revision;
      notify->old_revision = fb->old_revision;

      /* Fetch the mimetype from the actual properties */
      notify->mime_type = svn_prop_get_value(new_actual_props,
                                             SVN_PROP_MIME_TYPE);

      eb->notify_func(eb->notify_baton, notify, scratch_pool);
    }

  svn_pool_destroy(fb->pool); /* Destroy scratch_pool */

  /* We have one less referrer to the directory */
  SVN_ERR(maybe_release_dir_info(pdb));

  return SVN_NO_ERROR;
}


/* Implements svn_wc__proplist_receiver_t.
 * Check for the presence of an svn:keywords property and queues an install_file
 * work queue item if present. Thus, when the work queue is run to complete the
 * switch operation, all files with keywords will go through the translation
 * process so URLs etc are updated. */
static svn_error_t *
update_keywords_after_switch_cb(void *baton,
                                const char *local_abspath,
                                apr_hash_t *props,
                                apr_pool_t *scratch_pool)
{
  struct edit_baton *eb = baton;
  svn_string_t *propval;
  svn_boolean_t modified;
  svn_boolean_t record_fileinfo;
  svn_skel_t *work_items;
  const char *install_from;

  propval = svn_hash_gets(props, SVN_PROP_KEYWORDS);
  if (!propval)
    return SVN_NO_ERROR;

  SVN_ERR(svn_wc__internal_file_modified_p(&modified, eb->db,
                                           local_abspath, FALSE,
                                           scratch_pool));
  if (modified)
    {
      const char *temp_dir_abspath;
      svn_stream_t *working_stream;
      svn_stream_t *install_from_stream;

      SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, eb->db,
                                             local_abspath, scratch_pool,
                                             scratch_pool));
      SVN_ERR(svn_stream_open_readonly(&working_stream, local_abspath,
                                       scratch_pool, scratch_pool));
      SVN_ERR(svn_stream_open_unique(&install_from_stream, &install_from,
                                     temp_dir_abspath, svn_io_file_del_none,
                                     scratch_pool, scratch_pool));
      SVN_ERR(svn_stream_copy3(working_stream, install_from_stream,
                               eb->cancel_func, eb->cancel_baton,
                               scratch_pool));
      record_fileinfo = FALSE;
    }
  else
    {
      install_from = NULL;
      record_fileinfo = TRUE;
    }

  SVN_ERR(svn_wc__wq_build_file_install(&work_items, eb->db, local_abspath,
                                        install_from,
                                        eb->use_commit_times,
                                        record_fileinfo,
                                        scratch_pool, scratch_pool));
  if (install_from)
    {
      svn_skel_t *work_item;

      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
                                           local_abspath, install_from,
                                           scratch_pool, scratch_pool));
      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
    }

  SVN_ERR(svn_wc__db_wq_add(eb->db, local_abspath, work_items,
                            scratch_pool));

  return SVN_NO_ERROR;
}


/* An svn_delta_editor_t function. */
static svn_error_t *
close_edit(void *edit_baton,
           apr_pool_t *pool)
{
  struct edit_baton *eb = edit_baton;
  apr_pool_t *scratch_pool = eb->pool;

  /* The editor didn't even open the root; we have to take care of
     some cleanup stuffs. */
  if (! eb->root_opened
      && *eb->target_basename == '\0')
    {
      /* We need to "un-incomplete" the root directory. */
      SVN_ERR(svn_wc__db_temp_op_end_directory_update(eb->db,
                                                      eb->anchor_abspath,
                                                      scratch_pool));
    }

  /* By definition, anybody "driving" this editor for update or switch
     purposes at a *minimum* must have called set_target_revision() at
     the outset, and close_edit() at the end -- even if it turned out
     that no changes ever had to be made, and open_root() was never
     called.  That's fine.  But regardless, when the edit is over,
     this editor needs to make sure that *all* paths have had their
     revisions bumped to the new target revision. */

  /* Make sure our update target now has the new working revision.
     Also, if this was an 'svn switch', then rewrite the target's
     url.  All of this tweaking might happen recursively!  Note
     that if eb->target is NULL, that's okay (albeit "sneaky",
     some might say).  */

  /* Extra check: if the update did nothing but make its target
     'deleted', then do *not* run cleanup on the target, as it
     will only remove the deleted entry!  */
  if (! eb->target_deleted)
    {
      SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db,
                                                       eb->target_abspath,
                                                       eb->requested_depth,
                                                       eb->switch_repos_relpath,
                                                       eb->repos_root,
                                                       eb->repos_uuid,
                                                       *(eb->target_revision),
                                                       eb->skipped_trees,
                                                       eb->wcroot_iprops,
                                                       ! eb->edited,
                                                       eb->notify_func,
                                                       eb->notify_baton,
                                                       eb->pool));

      if (*eb->target_basename != '\0')
        {
          svn_wc__db_status_t status;
          svn_error_t *err;

          /* Note: we are fetching information about the *target*, not anchor.
             There is no guarantee that the target has a BASE node.
             For example:

               The node was not present in BASE, but locally-added, and the
               update did not create a new BASE node "under" the local-add.

             If there is no BASE node for the target, then we certainly don't
             have to worry about removing it. */
          err = svn_wc__db_base_get_info(&status, NULL, NULL, NULL, NULL, NULL,
                                         NULL, NULL, NULL, NULL, NULL, NULL,
                                         NULL, NULL, NULL, NULL,
                                         eb->db, eb->target_abspath,
                                         scratch_pool, scratch_pool);
          if (err)
            {
              if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
                return svn_error_trace(err);

              svn_error_clear(err);
            }
          else if (status == svn_wc__db_status_excluded)
            {
              /* There is a small chance that the explicit target of an update/
                 switch is gone in the repository, in that specific case the
                 node hasn't been re-added to the BASE tree by this update.

                 If so, we should get rid of this excluded node now. */

              SVN_ERR(svn_wc__db_base_remove(eb->db, eb->target_abspath,
                                             TRUE, FALSE, FALSE,
                                             SVN_INVALID_REVNUM,
                                             NULL, NULL, scratch_pool));
            }
        }
    }

  /* Update keywords in switched files.
     GOTO #1975 (the year of the Altair 8800). */
  if (eb->switch_repos_relpath)
    {
      svn_depth_t depth;

      if (eb->requested_depth > svn_depth_empty)
        depth = eb->requested_depth;
      else
        depth = svn_depth_infinity;

      SVN_ERR(svn_wc__db_read_props_streamily(eb->db,
                                              eb->target_abspath,
                                              depth,
                                              FALSE, /* pristine */
                                              NULL, /* changelists */
                                              update_keywords_after_switch_cb,
                                              eb,
                                              eb->cancel_func,
                                              eb->cancel_baton,
                                              scratch_pool));
    }

  /* The edit is over: run the wq with proper cancel support,
     but first kill the handler that would run it on the pool
     cleanup at the end of this function. */
  apr_pool_cleanup_kill(eb->pool, eb, cleanup_edit_baton);

  SVN_ERR(svn_wc__wq_run(eb->db, eb->wcroot_abspath,
                         eb->cancel_func, eb->cancel_baton,
                         eb->pool));

  /* The edit is over, free its pool.
     ### No, this is wrong.  Who says this editor/baton won't be used
     again?  But the change is not merely to remove this call.  We
     should also make eb->pool not be a subpool (see make_editor),
     and change callers of svn_client_{checkout,update,switch} to do
     better pool management. ### */

  svn_pool_destroy(eb->pool);

  return SVN_NO_ERROR;
}


/*** Returning editors. ***/

/* Helper for the three public editor-supplying functions. */
static svn_error_t *
make_editor(svn_revnum_t *target_revision,
            svn_wc__db_t *db,
            const char *anchor_abspath,
            const char *target_basename,
            apr_hash_t *wcroot_iprops,
            svn_boolean_t use_commit_times,
            const char *switch_url,
            svn_depth_t depth,
            svn_boolean_t depth_is_sticky,
            svn_boolean_t allow_unver_obstructions,
            svn_boolean_t adds_as_modification,
            svn_boolean_t server_performs_filtering,
            svn_boolean_t clean_checkout,
            svn_wc_notify_func2_t notify_func,
            void *notify_baton,
            svn_cancel_func_t cancel_func,
            void *cancel_baton,
            svn_wc_dirents_func_t fetch_dirents_func,
            void *fetch_dirents_baton,
            svn_wc_conflict_resolver_func2_t conflict_func,
            void *conflict_baton,
            svn_wc_external_update_t external_func,
            void *external_baton,
            const char *diff3_cmd,
            const apr_array_header_t *preserved_exts,
            const svn_delta_editor_t **editor,
            void **edit_baton,
            apr_pool_t *result_pool,
            apr_pool_t *scratch_pool)
{
  struct edit_baton *eb;
  void *inner_baton;
  apr_pool_t *edit_pool = svn_pool_create(result_pool);
  svn_delta_editor_t *tree_editor = svn_delta_default_editor(edit_pool);
  const svn_delta_editor_t *inner_editor;
  const char *repos_root, *repos_uuid;
  struct svn_wc__shim_fetch_baton_t *sfb;
  svn_delta_shim_callbacks_t *shim_callbacks =
                                svn_delta_shim_callbacks_default(edit_pool);

  /* An unknown depth can't be sticky. */
  if (depth == svn_depth_unknown)
    depth_is_sticky = FALSE;

  /* Get the anchor's repository root and uuid. The anchor must already exist
     in BASE. */
  SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, &repos_root,
                                   &repos_uuid, NULL, NULL, NULL, NULL,
                                   NULL, NULL, NULL, NULL, NULL, NULL,
                                   db, anchor_abspath,
                                   result_pool, scratch_pool));

  /* With WC-NG we need a valid repository root */
  SVN_ERR_ASSERT(repos_root != NULL && repos_uuid != NULL);

  /* Disallow a switch operation to change the repository root of the target,
     if that is known. */
  if (switch_url && !svn_uri__is_ancestor(repos_root, switch_url))
    return svn_error_createf(SVN_ERR_WC_INVALID_SWITCH, NULL,
                             _("'%s'\nis not the same repository as\n'%s'"),
                             switch_url, repos_root);

  /* Construct an edit baton. */
  eb = apr_pcalloc(edit_pool, sizeof(*eb));
  eb->pool                     = edit_pool;
  eb->use_commit_times         = use_commit_times;
  eb->target_revision          = target_revision;
  eb->repos_root               = repos_root;
  eb->repos_uuid               = repos_uuid;
  eb->db                       = db;
  eb->target_basename          = target_basename;
  eb->anchor_abspath           = anchor_abspath;
  eb->wcroot_iprops            = wcroot_iprops;

  SVN_ERR(svn_wc__db_get_wcroot(&eb->wcroot_abspath, db, anchor_abspath,
                                edit_pool, scratch_pool));

  if (switch_url)
    eb->switch_repos_relpath =
      svn_uri_skip_ancestor(repos_root, switch_url, scratch_pool);
  else
    eb->switch_repos_relpath = NULL;

  if (svn_path_is_empty(target_basename))
    eb->target_abspath = eb->anchor_abspath;
  else
    eb->target_abspath = svn_dirent_join(eb->anchor_abspath, target_basename,
                                         edit_pool);

  eb->requested_depth          = depth;
  eb->depth_is_sticky          = depth_is_sticky;
  eb->notify_func              = notify_func;
  eb->notify_baton             = notify_baton;
  eb->external_func            = external_func;
  eb->external_baton           = external_baton;
  eb->diff3_cmd                = diff3_cmd;
  eb->cancel_func              = cancel_func;
  eb->cancel_baton             = cancel_baton;
  eb->conflict_func            = conflict_func;
  eb->conflict_baton           = conflict_baton;
  eb->allow_unver_obstructions = allow_unver_obstructions;
  eb->adds_as_modification     = adds_as_modification;
  eb->clean_checkout           = clean_checkout;
  eb->skipped_trees            = apr_hash_make(edit_pool);
  eb->dir_dirents              = apr_hash_make(edit_pool);
  eb->ext_patterns             = preserved_exts;

  apr_pool_cleanup_register(edit_pool, eb, cleanup_edit_baton,
                            apr_pool_cleanup_null);

  /* Construct an editor. */
  tree_editor->set_target_revision = set_target_revision;
  tree_editor->open_root = open_root;
  tree_editor->delete_entry = delete_entry;
  tree_editor->add_directory = add_directory;
  tree_editor->open_directory = open_directory;
  tree_editor->change_dir_prop = change_dir_prop;
  tree_editor->close_directory = close_directory;
  tree_editor->absent_directory = absent_directory;
  tree_editor->add_file = add_file;
  tree_editor->open_file = open_file;
  tree_editor->apply_textdelta = apply_textdelta;
  tree_editor->change_file_prop = change_file_prop;
  tree_editor->close_file = close_file;
  tree_editor->absent_file = absent_file;
  tree_editor->close_edit = close_edit;

  /* Fiddle with the type system. */
  inner_editor = tree_editor;
  inner_baton = eb;

  if (!depth_is_sticky
      && depth != svn_depth_unknown
      && svn_depth_empty <= depth && depth < svn_depth_infinity
      && fetch_dirents_func)
    {
      /* We are asked to perform an update at a depth less than the ambient
         depth. In this case the update won't describe additions that would
         have been reported if we updated at the ambient depth. */
      svn_error_t *err;
      svn_node_kind_t dir_kind;
      svn_wc__db_status_t dir_status;
      const char *dir_repos_relpath;
      svn_depth_t dir_depth;

      /* we have to do this on the target of the update, not the anchor */
      err = svn_wc__db_base_get_info(&dir_status, &dir_kind, NULL,
                                     &dir_repos_relpath, NULL, NULL, NULL,
                                     NULL, NULL, &dir_depth, NULL, NULL, NULL,
                                     NULL, NULL, NULL,
                                     db, eb->target_abspath,
                                     scratch_pool, scratch_pool);

      if (!err
          && dir_kind == svn_node_dir
          && dir_status == svn_wc__db_status_normal)
        {
          if (dir_depth > depth)
            {
              apr_hash_t *dirents;

              /* If we switch, we should look at the new relpath */
              if (eb->switch_repos_relpath)
                dir_repos_relpath = eb->switch_repos_relpath;

              SVN_ERR(fetch_dirents_func(fetch_dirents_baton, &dirents,
                                         repos_root, dir_repos_relpath,
                                         edit_pool, scratch_pool));

              if (dirents != NULL && apr_hash_count(dirents))
                svn_hash_sets(eb->dir_dirents,
                              apr_pstrdup(edit_pool, dir_repos_relpath),
                              dirents);
            }

          if (depth == svn_depth_immediates)
            {
              /* Worst case scenario of issue #3569 fix: We have to do the
                 same for all existing subdirs, but then we check for
                 svn_depth_empty. */
              const apr_array_header_t *children;
              apr_pool_t *iterpool = svn_pool_create(scratch_pool);
              int i;
              SVN_ERR(svn_wc__db_base_get_children(&children, db,
                                                   eb->target_abspath,
                                                   scratch_pool,
                                                   iterpool));

              for (i = 0; i < children->nelts; i++)
                {
                  const char *child_abspath;
                  const char *child_name;

                  svn_pool_clear(iterpool);

                  child_name = APR_ARRAY_IDX(children, i, const char *);

                  child_abspath = svn_dirent_join(eb->target_abspath,
                                                  child_name, iterpool);

                  SVN_ERR(svn_wc__db_base_get_info(&dir_status, &dir_kind,
                                                   NULL, &dir_repos_relpath,
                                                   NULL, NULL, NULL, NULL,
                                                   NULL, &dir_depth, NULL,
                                                   NULL, NULL, NULL, NULL,
                                                   NULL,
                                                   db, child_abspath,
                                                   iterpool, iterpool));

                  if (dir_kind == svn_node_dir
                      && dir_status == svn_wc__db_status_normal
                      && dir_depth > svn_depth_empty)
                    {
                      apr_hash_t *dirents;

                      /* If we switch, we should look at the new relpath */
                      if (eb->switch_repos_relpath)
                        dir_repos_relpath = svn_relpath_join(
                                                eb->switch_repos_relpath,
                                                child_name, iterpool);

                      SVN_ERR(fetch_dirents_func(fetch_dirents_baton, &dirents,
                                                 repos_root, dir_repos_relpath,
                                                 edit_pool, iterpool));

                      if (dirents != NULL && apr_hash_count(dirents))
                        svn_hash_sets(eb->dir_dirents,
                                      apr_pstrdup(edit_pool,
                                                  dir_repos_relpath),
                                      dirents);
                    }
                }
            }
        }
      else if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
        svn_error_clear(err);
      else
        SVN_ERR(err);
    }

  /* We need to limit the scope of our operation to the ambient depths
     present in the working copy already, but only if the requested
     depth is not sticky. If a depth was explicitly requested,
     libsvn_delta/depth_filter_editor.c will ensure that we never see
     editor calls that extend beyond the scope of the requested depth.
     But even what we do so might extend beyond the scope of our
     ambient depth.  So we use another filtering editor to avoid
     modifying the ambient working copy depth when not asked to do so.
     (This can also be skipped if the server understands depth.) */
  if (!server_performs_filtering
      && !depth_is_sticky)
    SVN_ERR(svn_wc__ambient_depth_filter_editor(&inner_editor,
                                                &inner_baton,
                                                db,
                                                anchor_abspath,
                                                target_basename,
                                                inner_editor,
                                                inner_baton,
                                                result_pool));

  SVN_ERR(svn_delta_get_cancellation_editor(cancel_func,
                                            cancel_baton,
                                            inner_editor,
                                            inner_baton,
                                            editor,
                                            edit_baton,
                                            result_pool));

  sfb = apr_palloc(result_pool, sizeof(*sfb));
  sfb->db = db;
  sfb->base_abspath = eb->anchor_abspath;
  sfb->fetch_base = TRUE;

  shim_callbacks->fetch_kind_func = svn_wc__fetch_kind_func;
  shim_callbacks->fetch_props_func = svn_wc__fetch_props_func;
  shim_callbacks->fetch_base_func = svn_wc__fetch_base_func;
  shim_callbacks->fetch_baton = sfb;

  SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
                                   NULL, NULL, shim_callbacks,
                                   result_pool, scratch_pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc__get_update_editor(const svn_delta_editor_t **editor,
                          void **edit_baton,
                          svn_revnum_t *target_revision,
                          svn_wc_context_t *wc_ctx,
                          const char *anchor_abspath,
                          const char *target_basename,
                          apr_hash_t *wcroot_iprops,
                          svn_boolean_t use_commit_times,
                          svn_depth_t depth,
                          svn_boolean_t depth_is_sticky,
                          svn_boolean_t allow_unver_obstructions,
                          svn_boolean_t adds_as_modification,
                          svn_boolean_t server_performs_filtering,
                          svn_boolean_t clean_checkout,
                          const char *diff3_cmd,
                          const apr_array_header_t *preserved_exts,
                          svn_wc_dirents_func_t fetch_dirents_func,
                          void *fetch_dirents_baton,
                          svn_wc_conflict_resolver_func2_t conflict_func,
                          void *conflict_baton,
                          svn_wc_external_update_t external_func,
                          void *external_baton,
                          svn_cancel_func_t cancel_func,
                          void *cancel_baton,
                          svn_wc_notify_func2_t notify_func,
                          void *notify_baton,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
{
  return make_editor(target_revision, wc_ctx->db, anchor_abspath,
                     target_basename, wcroot_iprops, use_commit_times,
                     NULL, depth, depth_is_sticky, allow_unver_obstructions,
                     adds_as_modification, server_performs_filtering,
                     clean_checkout,
                     notify_func, notify_baton,
                     cancel_func, cancel_baton,
                     fetch_dirents_func, fetch_dirents_baton,
                     conflict_func, conflict_baton,
                     external_func, external_baton,
                     diff3_cmd, preserved_exts, editor, edit_baton,
                     result_pool, scratch_pool);
}

svn_error_t *
svn_wc__get_switch_editor(const svn_delta_editor_t **editor,
                          void **edit_baton,
                          svn_revnum_t *target_revision,
                          svn_wc_context_t *wc_ctx,
                          const char *anchor_abspath,
                          const char *target_basename,
                          const char *switch_url,
                          apr_hash_t *wcroot_iprops,
                          svn_boolean_t use_commit_times,
                          svn_depth_t depth,
                          svn_boolean_t depth_is_sticky,
                          svn_boolean_t allow_unver_obstructions,
                          svn_boolean_t server_performs_filtering,
                          const char *diff3_cmd,
                          const apr_array_header_t *preserved_exts,
                          svn_wc_dirents_func_t fetch_dirents_func,
                          void *fetch_dirents_baton,
                          svn_wc_conflict_resolver_func2_t conflict_func,
                          void *conflict_baton,
                          svn_wc_external_update_t external_func,
                          void *external_baton,
                          svn_cancel_func_t cancel_func,
                          void *cancel_baton,
                          svn_wc_notify_func2_t notify_func,
                          void *notify_baton,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
{
  SVN_ERR_ASSERT(switch_url && svn_uri_is_canonical(switch_url, scratch_pool));

  return make_editor(target_revision, wc_ctx->db, anchor_abspath,
                     target_basename, wcroot_iprops, use_commit_times,
                     switch_url,
                     depth, depth_is_sticky, allow_unver_obstructions,
                     FALSE /* adds_as_modification */,
                     server_performs_filtering,
                     FALSE /* clean_checkout */,
                     notify_func, notify_baton,
                     cancel_func, cancel_baton,
                     fetch_dirents_func, fetch_dirents_baton,
                     conflict_func, conflict_baton,
                     external_func, external_baton,
                     diff3_cmd, preserved_exts,
                     editor, edit_baton,
                     result_pool, scratch_pool);
}



/* ### Note that this function is completely different from the rest of the
       update editor in what it updates. The update editor changes only BASE
       and ACTUAL and this function just changes WORKING and ACTUAL.

       In the entries world this function shared a lot of code with the
       update editor but in the wonderful new WC-NG world it will probably
       do more and more by itself and would be more logically grouped with
       the add/copy functionality in adm_ops.c and copy.c. */
svn_error_t *
svn_wc_add_repos_file4(svn_wc_context_t *wc_ctx,
                       const char *local_abspath,
                       svn_stream_t *new_base_contents,
                       svn_stream_t *new_contents,
                       apr_hash_t *new_base_props,
                       apr_hash_t *new_props,
                       const char *copyfrom_url,
                       svn_revnum_t copyfrom_rev,
                       svn_cancel_func_t cancel_func,
                       void *cancel_baton,
                       apr_pool_t *scratch_pool)
{
  svn_wc__db_t *db = wc_ctx->db;
  const char *dir_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
  svn_wc__db_status_t status;
  svn_node_kind_t kind;
  const char *tmp_text_base_abspath;
  svn_checksum_t *new_text_base_md5_checksum;
  svn_checksum_t *new_text_base_sha1_checksum;
  const char *source_abspath = NULL;
  svn_skel_t *all_work_items = NULL;
  svn_skel_t *work_item;
  const char *repos_root_url;
  const char *repos_uuid;
  const char *original_repos_relpath;
  svn_revnum_t changed_rev;
  apr_time_t changed_date;
  const char *changed_author;
  svn_stream_t *tmp_base_contents;
  svn_wc__db_install_data_t *install_data;
  svn_error_t *err;
  apr_pool_t *pool = scratch_pool;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
  SVN_ERR_ASSERT(new_base_contents != NULL);
  SVN_ERR_ASSERT(new_base_props != NULL);

  /* We should have a write lock on this file's parent directory.  */
  SVN_ERR(svn_wc__write_check(db, dir_abspath, pool));

  err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                             NULL, NULL, NULL,
                             db, local_abspath, scratch_pool, scratch_pool);

  if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
    return svn_error_trace(err);
  else if(err)
    svn_error_clear(err);
  else
    switch (status)
      {
        case svn_wc__db_status_not_present:
        case svn_wc__db_status_deleted:
          break;
        default:
          return svn_error_createf(SVN_ERR_ENTRY_EXISTS, NULL,
                                   _("Node '%s' exists."),
                                   svn_dirent_local_style(local_abspath,
                                                          scratch_pool));
      }

  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, &repos_root_url,
                               &repos_uuid, NULL, NULL, NULL, NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               db, dir_abspath, scratch_pool, scratch_pool));

  switch (status)
    {
      case svn_wc__db_status_normal:
      case svn_wc__db_status_added:
        break;
      case svn_wc__db_status_deleted:
        return
          svn_error_createf(SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
                            _("Can't add '%s' to a parent directory"
                              " scheduled for deletion"),
                            svn_dirent_local_style(local_abspath,
                                                   scratch_pool));
      default:
        return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, err,
                                 _("Can't find parent directory's node while"
                                   " trying to add '%s'"),
                                 svn_dirent_local_style(local_abspath,
                                                        scratch_pool));
    }
  if (kind != svn_node_dir)
    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                             _("Can't schedule an addition of '%s'"
                               " below a not-directory node"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  /* Fabricate the anticipated new URL of the target and check the
     copyfrom URL to be in the same repository. */
  if (copyfrom_url != NULL)
    {
      /* Find the repository_root via the parent directory, which
         is always versioned before this function is called */

      if (!repos_root_url)
        {
          /* The parent is an addition, scan upwards to find the right info */
          SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
                                           &repos_root_url, &repos_uuid,
                                           NULL, NULL, NULL, NULL,
                                           wc_ctx->db, dir_abspath,
                                           scratch_pool, scratch_pool));
        }
      SVN_ERR_ASSERT(repos_root_url);

      original_repos_relpath =
          svn_uri_skip_ancestor(repos_root_url, copyfrom_url, scratch_pool);

      if (!original_repos_relpath)
        return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                                 _("Copyfrom-url '%s' has different repository"
                                   " root than '%s'"),
                                 copyfrom_url, repos_root_url);
    }
  else
    {
      original_repos_relpath = NULL;
      copyfrom_rev = SVN_INVALID_REVNUM;  /* Just to be sure.  */
    }

  /* Set CHANGED_* to reflect the entry props in NEW_BASE_PROPS, and
     filter NEW_BASE_PROPS so it contains only regular props. */
  {
    apr_array_header_t *regular_props;
    apr_array_header_t *entry_props;

    SVN_ERR(svn_categorize_props(svn_prop_hash_to_array(new_base_props, pool),
                                 &entry_props, NULL, &regular_props,
                                 pool));

    /* Put regular props back into a hash table. */
    new_base_props = svn_prop_array_to_hash(regular_props, pool);

    /* Get the change_* info from the entry props.  */
    SVN_ERR(accumulate_last_change(&changed_rev,
                                   &changed_date,
                                   &changed_author,
                                   entry_props, pool, pool));
  }

  /* Copy NEW_BASE_CONTENTS into a temporary file so our log can refer to
     it, and set TMP_TEXT_BASE_ABSPATH to its path.  Compute its
     NEW_TEXT_BASE_MD5_CHECKSUM and NEW_TEXT_BASE_SHA1_CHECKSUM as we copy. */
  if (copyfrom_url)
    {
      SVN_ERR(svn_wc__db_pristine_prepare_install(&tmp_base_contents,
                                                  &install_data,
                                                  &new_text_base_sha1_checksum,
                                                  &new_text_base_md5_checksum,
                                                  wc_ctx->db, local_abspath,
                                                  scratch_pool, scratch_pool));
    }
  else
    {
      const char *tmp_dir_abspath;

      /* We are not installing a PRISTINE file, but we use the same code to
         create whatever we want to install */

      SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmp_dir_abspath,
                                             db, dir_abspath,
                                             scratch_pool, scratch_pool));

      SVN_ERR(svn_stream_open_unique(&tmp_base_contents, &tmp_text_base_abspath,
                                     tmp_dir_abspath, svn_io_file_del_none,
                                     scratch_pool, scratch_pool));

      new_text_base_sha1_checksum = NULL;
      new_text_base_md5_checksum = NULL;
    }
  SVN_ERR(svn_stream_copy3(new_base_contents, tmp_base_contents,
                           cancel_func, cancel_baton, pool));

  /* If the caller gave us a new working file, copy it to a safe (temporary)
     location and set SOURCE_ABSPATH to that path. We'll then translate/copy
     that into place after the node's state has been created.  */
  if (new_contents)
    {
      const char *temp_dir_abspath;
      svn_stream_t *tmp_contents;

      SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, db,
                                             local_abspath, pool, pool));
      SVN_ERR(svn_stream_open_unique(&tmp_contents, &source_abspath,
                                     temp_dir_abspath, svn_io_file_del_none,
                                     pool, pool));
      SVN_ERR(svn_stream_copy3(new_contents, tmp_contents,
                               cancel_func, cancel_baton, pool));
    }

  /* Install new text base for copied files. Added files do NOT have a
     text base.  */
  if (copyfrom_url != NULL)
    {
      SVN_ERR(svn_wc__db_pristine_install(install_data,
                                          new_text_base_sha1_checksum,
                                          new_text_base_md5_checksum, pool));
    }
  else
    {
      /* ### There's something wrong around here.  Sometimes (merge from a
         foreign repository, at least) we are called with copyfrom_url =
         NULL and an empty new_base_contents (and an empty set of
         new_base_props).  Why an empty "new base"?

         That happens in merge_tests.py 54,87,88,89,143.

         In that case, having been given this supposed "new base" file, we
         copy it and calculate its checksum but do not install it.  Why?
         That must be wrong.

         To crudely work around one issue with this, that we shouldn't
         record a checksum in the database if we haven't installed the
         corresponding pristine text, for now we'll just set the checksum
         to NULL.

         The proper solution is probably more like: the caller should pass
         NULL for the missing information, and this function should learn to
         handle that. */

      new_text_base_sha1_checksum = NULL;
      new_text_base_md5_checksum = NULL;
    }

  /* For added files without NEW_CONTENTS, then generate the working file
     from the provided "pristine" contents.  */
  if (new_contents == NULL && copyfrom_url == NULL)
    source_abspath = tmp_text_base_abspath;

  {
    svn_boolean_t record_fileinfo;

    /* If new contents were provided, then we do NOT want to record the
       file information. We assume the new contents do not match the
       "proper" values for RECORDED_SIZE and RECORDED_TIME.  */
    record_fileinfo = (new_contents == NULL);

    /* Install the working copy file (with appropriate translation) from
       the appropriate source. SOURCE_ABSPATH will be NULL, indicating an
       installation from the pristine (available for copied/moved files),
       or it will specify a temporary file where we placed a "pristine"
       (for an added file) or a detranslated local-mods file.  */
    SVN_ERR(svn_wc__wq_build_file_install(&work_item,
                                          db, local_abspath,
                                          source_abspath,
                                          FALSE /* use_commit_times */,
                                          record_fileinfo,
                                          pool, pool));
    all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);

    /* If we installed from somewhere besides the official pristine, then
       it is a temporary file, which needs to be removed.  */
    if (source_abspath != NULL)
      {
        SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db, local_abspath,
                                             source_abspath,
                                             pool, pool));
        all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
      }
  }

  SVN_ERR(svn_wc__db_op_copy_file(db, local_abspath,
                                  new_base_props,
                                  changed_rev,
                                  changed_date,
                                  changed_author,
                                  original_repos_relpath,
                                  original_repos_relpath ? repos_root_url
                                                         : NULL,
                                  original_repos_relpath ? repos_uuid : NULL,
                                  copyfrom_rev,
                                  new_text_base_sha1_checksum,
                                  TRUE,
                                  new_props,
                                  FALSE /* is_move */,
                                  NULL /* conflict */,
                                  all_work_items,
                                  pool));

  return svn_error_trace(svn_wc__wq_run(db, dir_abspath,
                                        cancel_func, cancel_baton,
                                        pool));
}

svn_error_t *
svn_wc__complete_directory_add(svn_wc_context_t *wc_ctx,
                               const char *local_abspath,
                               apr_hash_t *new_original_props,
                               const char *copyfrom_url,
                               svn_revnum_t copyfrom_rev,
                               apr_pool_t *scratch_pool)
{
  svn_wc__db_status_t status;
  svn_node_kind_t kind;
  const char *original_repos_relpath;
  const char *original_root_url;
  const char *original_uuid;
  svn_boolean_t had_props;
  svn_boolean_t props_mod;

  svn_revnum_t original_revision;
  svn_revnum_t changed_rev;
  apr_time_t changed_date;
  const char *changed_author;

  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL, NULL,
                               &original_repos_relpath, &original_root_url,
                               &original_uuid, &original_revision, NULL, NULL,
                               NULL, NULL, NULL, NULL, &had_props, &props_mod,
                               NULL, NULL, NULL,
                               wc_ctx->db, local_abspath,
                               scratch_pool, scratch_pool));

  if (status != svn_wc__db_status_added
      || kind != svn_node_dir
      || had_props
      || props_mod
      || !original_repos_relpath)
    {
      return svn_error_createf(
                    SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
                    _("'%s' is not an unmodified copied directory"),
                    svn_dirent_local_style(local_abspath, scratch_pool));
    }
  if (original_revision != copyfrom_rev
      || strcmp(copyfrom_url,
                 svn_path_url_add_component2(original_root_url,
                                             original_repos_relpath,
                                             scratch_pool)))
    {
      return svn_error_createf(
                    SVN_ERR_WC_COPYFROM_PATH_NOT_FOUND, NULL,
                    _("Copyfrom '%s' doesn't match original location of '%s'"),
                    copyfrom_url,
                    svn_dirent_local_style(local_abspath, scratch_pool));
    }

  {
    apr_array_header_t *regular_props;
    apr_array_header_t *entry_props;

    SVN_ERR(svn_categorize_props(svn_prop_hash_to_array(new_original_props,
                                                        scratch_pool),
                                 &entry_props, NULL, &regular_props,
                                 scratch_pool));

    /* Put regular props back into a hash table. */
    new_original_props = svn_prop_array_to_hash(regular_props, scratch_pool);

    /* Get the change_* info from the entry props.  */
    SVN_ERR(accumulate_last_change(&changed_rev,
                                   &changed_date,
                                   &changed_author,
                                   entry_props, scratch_pool, scratch_pool));
  }

  return svn_error_trace(
            svn_wc__db_op_copy_dir(wc_ctx->db, local_abspath,
                                   new_original_props,
                                   changed_rev, changed_date, changed_author,
                                   original_repos_relpath, original_root_url,
                                   original_uuid, original_revision,
                                   NULL /* children */,
                                   svn_depth_infinity,
                                   FALSE /* is_move */,
                                   NULL /* conflict */,
                                   NULL /* work_items */,
                                   scratch_pool));
}
