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

#include <string.h>
#include <assert.h>

#include <apr_strings.h>

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

#include "wc.h"
#include "adm_files.h"
#include "conflicts.h"
#include "entries.h"
#include "lock.h"
#include "tree_conflicts.h"
#include "wc_db.h"
#include "wc-queries.h"  /* for STMT_*  */

#define SVN_WC__I_AM_WC_DB

#include "svn_private_config.h"
#include "private/svn_wc_private.h"
#include "private/svn_sqlite.h"
#include "token-map.h"

#include "wc_db_private.h"

#define MAYBE_ALLOC(x,p) ((x) ? (x) : apr_pcalloc((p), sizeof(*(x))))


/* Temporary structures which mirror the tables in wc-metadata.sql.
   For detailed descriptions of each field, see that file. */
typedef struct db_node_t {
  apr_int64_t wc_id;
  const char *local_relpath;
  int op_depth;
  apr_int64_t repos_id;
  const char *repos_relpath;
  const char *parent_relpath;
  svn_wc__db_status_t presence;
  svn_revnum_t revision;
  svn_node_kind_t kind;
  svn_checksum_t *checksum;
  svn_filesize_t recorded_size;
  svn_revnum_t changed_rev;
  apr_time_t changed_date;
  const char *changed_author;
  svn_depth_t depth;
  apr_time_t recorded_time;
  apr_hash_t *properties;
  svn_boolean_t file_external;
  apr_array_header_t *inherited_props;
} db_node_t;

typedef struct db_actual_node_t {
  apr_int64_t wc_id;
  const char *local_relpath;
  const char *parent_relpath;
  apr_hash_t *properties;
  const char *conflict_old;
  const char *conflict_new;
  const char *conflict_working;
  const char *prop_reject;
  const char *changelist;
  /* ### enum for text_mod */
  const char *tree_conflict_data;
} db_actual_node_t;



/*** reading and writing the entries file ***/


/* */
static svn_wc_entry_t *
alloc_entry(apr_pool_t *pool)
{
  svn_wc_entry_t *entry = apr_pcalloc(pool, sizeof(*entry));
  entry->revision = SVN_INVALID_REVNUM;
  entry->copyfrom_rev = SVN_INVALID_REVNUM;
  entry->cmt_rev = SVN_INVALID_REVNUM;
  entry->kind = svn_node_none;
  entry->working_size = SVN_WC_ENTRY_WORKING_SIZE_UNKNOWN;
  entry->depth = svn_depth_infinity;
  entry->file_external_peg_rev.kind = svn_opt_revision_unspecified;
  entry->file_external_rev.kind = svn_opt_revision_unspecified;
  return entry;
}


/* Is the entry in a 'hidden' state in the sense of the 'show_hidden'
 * switches on svn_wc_entries_read(), svn_wc_walk_entries*(), etc.? */
svn_error_t *
svn_wc__entry_is_hidden(svn_boolean_t *hidden, const svn_wc_entry_t *entry)
{
  /* In English, the condition is: "the entry is not present, and I haven't
     scheduled something over the top of it."  */
  if (entry->deleted
      || entry->absent
      || entry->depth == svn_depth_exclude)
    {
      /* These kinds of nodes cannot be marked for deletion (which also
         means no "replace" either).  */
      SVN_ERR_ASSERT(entry->schedule == svn_wc_schedule_add
                     || entry->schedule == svn_wc_schedule_normal);

      /* Hidden if something hasn't been added over it.

         ### is this even possible with absent or excluded nodes?  */
      *hidden = entry->schedule != svn_wc_schedule_add;
    }
  else
    *hidden = FALSE;

  return SVN_NO_ERROR;
}


/* Hit the database to check the file external information for the given
   entry.  The entry will be modified in place. */
static svn_error_t *
check_file_external(svn_wc_entry_t *entry,
                    svn_wc__db_t *db,
                    const char *local_abspath,
                    const char *wri_abspath,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
{
  svn_wc__db_status_t status;
  svn_node_kind_t kind;
  const char *repos_relpath;
  svn_revnum_t peg_revision;
  svn_revnum_t revision;
  svn_error_t *err;

  err = svn_wc__db_external_read(&status, &kind, NULL, NULL, NULL,
                                 &repos_relpath, &peg_revision, &revision,
                                 db, local_abspath, wri_abspath,
                                 result_pool, scratch_pool);

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

      svn_error_clear(err);
      return SVN_NO_ERROR;
    }

  if (status == svn_wc__db_status_normal
      && kind == svn_node_file)
    {
      entry->file_external_path = repos_relpath;
      if (SVN_IS_VALID_REVNUM(peg_revision))
        {
          entry->file_external_peg_rev.kind = svn_opt_revision_number;
          entry->file_external_peg_rev.value.number = peg_revision;
          entry->file_external_rev = entry->file_external_peg_rev;
        }
      if (SVN_IS_VALID_REVNUM(revision))
        {
          entry->file_external_rev.kind = svn_opt_revision_number;
          entry->file_external_rev.value.number = revision;
        }
    }

  return SVN_NO_ERROR;
}


/* Fill in the following fields of ENTRY:

     REVISION
     REPOS
     UUID
     CMT_REV
     CMT_DATE
     CMT_AUTHOR
     DEPTH
     DELETED

   Return: KIND, REPOS_RELPATH, CHECKSUM
*/
static svn_error_t *
get_info_for_deleted(svn_wc_entry_t *entry,
                     svn_node_kind_t *kind,
                     const char **repos_relpath,
                     const svn_checksum_t **checksum,
                     svn_wc__db_lock_t **lock,
                     svn_wc__db_t *db,
                     const char *entry_abspath,
                     svn_wc__db_wcroot_t *wcroot,
                     const char *entry_relpath,
                     const svn_wc_entry_t *parent_entry,
                     svn_boolean_t have_base,
                     svn_boolean_t have_more_work,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
{
  if (have_base && !have_more_work)
    {
      apr_int64_t repos_id;
      /* This is the delete of a BASE node */
      SVN_ERR(svn_wc__db_base_get_info_internal(
                                       NULL, kind,
                                       &entry->revision,
                                       repos_relpath,
                                       &repos_id,
                                       &entry->cmt_rev,
                                       &entry->cmt_date,
                                       &entry->cmt_author,
                                       &entry->depth,
                                       checksum,
                                       NULL,
                                       lock,
                                       &entry->has_props, NULL,
                                       NULL,
                                       wcroot, entry_relpath,
                                       result_pool,
                                       scratch_pool));
      SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid,
                                          wcroot, repos_id, result_pool));
    }
  else
    {
      const char *work_del_relpath;
      const char *parent_repos_relpath;
      const char *parent_relpath;
      apr_int64_t repos_id;

      /* This is a deleted child of a copy/move-here,
         so we need to scan up the WORKING tree to find the root of
         the deletion. Then examine its parent to discover its
         future location in the repository.  */
      SVN_ERR(svn_wc__db_read_pristine_info(NULL, kind,
                                            &entry->cmt_rev,
                                            &entry->cmt_date,
                                            &entry->cmt_author,
                                            &entry->depth,
                                            checksum,
                                            NULL,
                                            &entry->has_props, NULL,
                                            db,
                                            entry_abspath,
                                            result_pool,
                                            scratch_pool));
      /* working_size and text_time unavailable */

     SVN_ERR(svn_wc__db_scan_deletion_internal(
                                      NULL,
                                      NULL,
                                      &work_del_relpath, NULL,
                                      wcroot, entry_relpath,
                                      scratch_pool, scratch_pool));

      SVN_ERR_ASSERT(work_del_relpath != NULL);
      parent_relpath = svn_relpath_dirname(work_del_relpath, scratch_pool);

      /* The parent directory of the delete root must be added, so we
         can find the required information there */
      SVN_ERR(svn_wc__db_scan_addition_internal(
                                       NULL, NULL,
                                       &parent_repos_relpath,
                                       &repos_id,
                                       NULL, NULL, NULL,
                                       wcroot, parent_relpath,
                                       result_pool, scratch_pool));
      SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid,
                                          wcroot, repos_id, result_pool));

      /* Now glue it all together */
      *repos_relpath = svn_relpath_join(parent_repos_relpath,
                                        svn_relpath_skip_ancestor(
                                                            parent_relpath,
                                                            entry_relpath),
                                        result_pool);


      /* Even though this is the delete of a WORKING node, there might still
         be a BASE node somewhere below with an interesting revision */
      if (have_base)
        {
          svn_wc__db_status_t status;
          SVN_ERR(svn_wc__db_base_get_info_internal(
                                           &status, NULL, &entry->revision,
                                           NULL, NULL, NULL, NULL, NULL, NULL,
                                           NULL, NULL, lock, NULL, NULL,
                                           NULL,
                                           wcroot, entry_relpath,
                                           result_pool, scratch_pool));

          if (status == svn_wc__db_status_not_present)
            entry->deleted = TRUE;
        }
    }

  /* Do some extra work for the child nodes.  */
  if (!SVN_IS_VALID_REVNUM(entry->revision) && parent_entry != NULL)
    {
      /* For child nodes without a revision, pick up the parent's
         revision.  */
      entry->revision = parent_entry->revision;
    }

  return SVN_NO_ERROR;
}


/*
 * Encode tree conflict descriptions into a single string.
 *
 * Set *CONFLICT_DATA to a string, allocated in POOL, that encodes the tree
 * conflicts in CONFLICTS in a form suitable for storage in a single string
 * field in a WC entry. CONFLICTS is a hash of zero or more pointers to
 * svn_wc_conflict_description2_t objects, index by their basenames. All of the
 * conflict victim paths must be siblings.
 *
 * Do all allocations in POOL.
 *
 * @see svn_wc__read_tree_conflicts()
 */
static svn_error_t *
write_tree_conflicts(const char **conflict_data,
                     apr_hash_t *conflicts,
                     apr_pool_t *pool)
{
  svn_skel_t *skel = svn_skel__make_empty_list(pool);
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(pool, conflicts); hi; hi = apr_hash_next(hi))
    {
      svn_skel_t *c_skel;

      SVN_ERR(svn_wc__serialize_conflict(&c_skel, apr_hash_this_val(hi),
                                         pool, pool));
      svn_skel__prepend(c_skel, skel);
    }

  *conflict_data = svn_skel__unparse(skel, pool)->data;

  return SVN_NO_ERROR;
}


/* Read one entry from wc_db. It will be allocated in RESULT_POOL and
   returned in *NEW_ENTRY.

   DIR_ABSPATH is the name of the directory to read this entry from, and
   it will be named NAME (use "" for "this dir").

   DB specifies the wc_db database, and WC_ID specifies which working copy
   this information is being read from.

   If this node is "this dir", then PARENT_ENTRY should be NULL. Otherwise,
   it should refer to the entry for the child's parent directory.

   ### All database read operations should really use wcroot, dir_relpath,
       as that restores obstruction compatibility with <= 1.6.0
       but that has been the case since the introduction of WC-NG in 1.7.0

   Temporary allocations are made in SCRATCH_POOL.  */
static svn_error_t *
read_one_entry(const svn_wc_entry_t **new_entry,
               svn_wc__db_t *db,
               const char *dir_abspath,
               svn_wc__db_wcroot_t *wcroot,
               const char *dir_relpath,
               const char *name,
               const svn_wc_entry_t *parent_entry,
               apr_pool_t *result_pool,
               apr_pool_t *scratch_pool)
{
  svn_node_kind_t kind;
  svn_wc__db_status_t status;
  svn_wc__db_lock_t *lock;
  const char *repos_relpath;
  const svn_checksum_t *checksum;
  svn_filesize_t translated_size;
  svn_wc_entry_t *entry = alloc_entry(result_pool);
  const char *entry_relpath;
  const char *entry_abspath;
  apr_int64_t repos_id;
  apr_int64_t original_repos_id;
  const char *original_repos_relpath;
  const char *original_root_url;
  svn_boolean_t conflicted;
  svn_boolean_t have_base;
  svn_boolean_t have_more_work;
  svn_boolean_t op_root;

  entry->name = apr_pstrdup(result_pool, name);

  entry_relpath = svn_relpath_join(dir_relpath, entry->name, scratch_pool);
  entry_abspath = svn_dirent_join(dir_abspath, entry->name, scratch_pool);

  SVN_ERR(svn_wc__db_read_info_internal(
            &status,
            &kind,
            &entry->revision,
            &repos_relpath,
            &repos_id,
            &entry->cmt_rev,
            &entry->cmt_date,
            &entry->cmt_author,
            &entry->depth,
            &checksum,
            NULL,
            &original_repos_relpath,
            &original_repos_id,
            &entry->copyfrom_rev,
            &lock,
            &translated_size,
            &entry->text_time,
            &entry->changelist,
            &conflicted,
            &op_root,
            &entry->has_props /* have_props */,
            &entry->has_prop_mods /* props_mod */,
            &have_base,
            &have_more_work,
            NULL /* have_work */,
            wcroot, entry_relpath,
            result_pool, scratch_pool));

  SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid,
                                      wcroot, repos_id, result_pool));
  SVN_ERR(svn_wc__db_fetch_repos_info(&original_root_url, NULL,
                                      wcroot, original_repos_id,
                                      result_pool));

  if (entry->has_prop_mods)
    entry->has_props = TRUE;

  if (strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR) == 0)
    {
      /* get the tree conflict data. */
      apr_hash_t *tree_conflicts = NULL;
      const apr_array_header_t *conflict_victims;
      int k;

      SVN_ERR(svn_wc__db_read_conflict_victims(&conflict_victims, db,
                                               dir_abspath,
                                               scratch_pool,
                                               scratch_pool));

      for (k = 0; k < conflict_victims->nelts; k++)
        {
          int j;
          const apr_array_header_t *child_conflicts;
          const char *child_name;
          const char *child_abspath;

          child_name = APR_ARRAY_IDX(conflict_victims, k, const char *);
          child_abspath = svn_dirent_join(dir_abspath, child_name,
                                          scratch_pool);

          SVN_ERR(svn_wc__read_conflicts(&child_conflicts, NULL,
                                         db, child_abspath,
                                         FALSE /* create tempfiles */,
                                         TRUE /* tree_conflicts_only */,
                                         scratch_pool, scratch_pool));

          for (j = 0; j < child_conflicts->nelts; j++)
            {
              const svn_wc_conflict_description2_t *conflict =
                APR_ARRAY_IDX(child_conflicts, j,
                              svn_wc_conflict_description2_t *);

              if (conflict->kind == svn_wc_conflict_kind_tree)
                {
                  if (!tree_conflicts)
                    tree_conflicts = apr_hash_make(scratch_pool);
                  svn_hash_sets(tree_conflicts, child_name, conflict);
                }
            }
        }

      if (tree_conflicts)
        {
          SVN_ERR(write_tree_conflicts(&entry->tree_conflict_data,
                                       tree_conflicts, result_pool));
        }
    }

  if (status == svn_wc__db_status_normal
      || status == svn_wc__db_status_incomplete)
    {
      /* Plain old BASE node.  */
      entry->schedule = svn_wc_schedule_normal;

      /* Grab inherited repository information, if necessary. */
      if (repos_relpath == NULL)
        {
          SVN_ERR(svn_wc__db_base_get_info_internal(
                                           NULL, NULL, NULL, &repos_relpath,
                                           &repos_id, NULL, NULL, NULL,
                                           NULL, NULL, NULL, NULL, NULL, NULL,
                                           NULL,
                                           wcroot, entry_relpath,
                                           result_pool, scratch_pool));
          SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid,
                                              wcroot, repos_id, result_pool));
        }

      entry->incomplete = (status == svn_wc__db_status_incomplete);
    }
  else if (status == svn_wc__db_status_deleted)
    {
      svn_node_kind_t path_kind;

      /* ### we don't have to worry about moves, so this is a delete. */
      entry->schedule = svn_wc_schedule_delete;

      /* If there are multiple working layers or no BASE layer, then
         this is a WORKING delete or WORKING not-present. */
      if (have_more_work || !have_base)
        entry->copied = TRUE;
      else if (have_base && !have_more_work)
        entry->copied = FALSE;
      else
        {
          const char *work_del_relpath;
          SVN_ERR(svn_wc__db_scan_deletion_internal(
                                           NULL, NULL,
                                           &work_del_relpath, NULL,
                                           wcroot, entry_relpath,
                                           scratch_pool, scratch_pool));

          if (work_del_relpath)
            entry->copied = TRUE;
        }

      /* If there is still a directory on-disk we keep it, if not it is
         already deleted. Simple, isn't it?

         Before single-db we had to keep the administative area alive until
         after the commit really deletes it. Setting keep alive stopped the
         commit processing from deleting the directory. We don't delete it
         any more, so all we have to do is provide some 'sane' value.
       */
      SVN_ERR(svn_io_check_path(entry_abspath, &path_kind, scratch_pool));
      entry->keep_local = (path_kind == svn_node_dir);
    }
  else if (status == svn_wc__db_status_added)
    {
      svn_wc__db_status_t work_status;
      const char *op_root_abspath;
      const char *scanned_original_relpath;
      svn_revnum_t original_revision;

      /* For child nodes, pick up the parent's revision.  */
      if (*entry->name != '\0')
        {
          assert(parent_entry != NULL);
          assert(entry->revision == SVN_INVALID_REVNUM);

          entry->revision = parent_entry->revision;
        }

      if (have_base)
        {
          svn_wc__db_status_t base_status;

          /* ENTRY->REVISION is overloaded. When a node is schedule-add
             or -replace, then REVISION refers to the BASE node's revision
             that is being overwritten. We need to fetch it now.  */
          SVN_ERR(svn_wc__db_base_get_info_internal(
                                           &base_status, NULL,
                                           &entry->revision,
                                           NULL, NULL, NULL,
                                           NULL, NULL, NULL,
                                           NULL, NULL, NULL,
                                           NULL, NULL, NULL,
                                           wcroot, entry_relpath,
                                           scratch_pool,
                                           scratch_pool));

          if (base_status == svn_wc__db_status_not_present)
            {
              /* The underlying node is DELETED in this revision.  */
              entry->deleted = TRUE;

              /* This is an add since there isn't a node to replace.  */
              entry->schedule = svn_wc_schedule_add;
            }
          else
            entry->schedule = svn_wc_schedule_replace;
        }
      else
        {
          /* There is NO 'not-present' BASE_NODE for this node.
             Therefore, we are looking at some kind of add/copy
             rather than a replace.  */

          /* ### if this looks like a plain old add, then rev=0.  */
          if (!SVN_IS_VALID_REVNUM(entry->copyfrom_rev)
              && !SVN_IS_VALID_REVNUM(entry->cmt_rev))
            entry->revision = 0;

          entry->schedule = svn_wc_schedule_add;
        }

      /* If we don't have "real" data from the entry (obstruction),
         then we cannot begin a scan for data. The original node may
         have important data. Set up stuff to kill that idea off,
         and finish up this entry.  */
        {
          const char *op_root_relpath;
          SVN_ERR(svn_wc__db_scan_addition_internal(
                                           &work_status,
                                           &op_root_relpath,
                                           &repos_relpath,
                                           &repos_id,
                                           &scanned_original_relpath,
                                           NULL /* original_repos_id */,
                                           &original_revision,
                                           wcroot, entry_relpath,
                                           result_pool, scratch_pool));

          SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid,
                                      wcroot, repos_id, result_pool));

          if (!op_root_relpath)
            op_root_abspath = NULL;
          else
            op_root_abspath = svn_dirent_join(wcroot->abspath, op_root_relpath,
                                              scratch_pool);

          /* In wc.db we want to keep the valid revision of the not-present
             BASE_REV, but when we used entries we set the revision to 0
             when adding a new node over a not present base node. */
          if (work_status == svn_wc__db_status_added
              && entry->deleted)
            entry->revision = 0;
        }

      if (!SVN_IS_VALID_REVNUM(entry->cmt_rev)
          && scanned_original_relpath == NULL)
        {
          /* There is NOT a last-changed revision (last-changed date and
             author may be unknown, but we can always check the rev).
             The absence of a revision implies this node was added WITHOUT
             any history. Avoid the COPIED checks in the else block.  */
          /* ### scan_addition may need to be updated to avoid returning
             ### status_copied in this case.  */
        }
      /* For backwards-compatibility purposes we treat moves just like
       * regular copies. */
      else if (work_status == svn_wc__db_status_copied ||
               work_status == svn_wc__db_status_moved_here)
        {
          entry->copied = TRUE;

          /* If this is a child of a copied subtree, then it should be
             schedule_normal.  */
          if (original_repos_relpath == NULL)
            {
              /* ### what if there is a BASE node under there? */
              entry->schedule = svn_wc_schedule_normal;
            }

          /* Copied nodes need to mirror their copyfrom_rev, if they
             don't have a revision of their own already. */
          if (!SVN_IS_VALID_REVNUM(entry->revision)
              || entry->revision == 0 /* added */)
            entry->revision = original_revision;
        }

      /* Does this node have copyfrom_* information?  */
      if (scanned_original_relpath != NULL)
        {
          svn_boolean_t is_copied_child;
          svn_boolean_t is_mixed_rev = FALSE;

          SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied ||
                         work_status == svn_wc__db_status_moved_here);

          /* If this node inherits copyfrom information from an
             ancestor node, then it must be a copied child.  */
          is_copied_child = (original_repos_relpath == NULL);

          /* If this node has copyfrom information on it, then it may
             be an actual copy-root, or it could be participating in
             a mixed-revision copied tree. So if we don't already know
             this is a copied child, then we need to look for this
             mixed-revision situation.  */
          if (!is_copied_child)
            {
              const char *parent_relpath;
              svn_error_t *err;
              const char *parent_repos_relpath;
              const char *parent_root_url;
              apr_int64_t parent_repos_id;
              const char *op_root_relpath;

              /* When we insert entries into the database, we will
                 construct additional copyfrom records for mixed-revision
                 copies. The old entries would simply record the different
                 revision in the entry->revision field. That is not
                 available within wc-ng, so additional copies are made
                 (see the logic inside write_entry()). However, when
                 reading these back *out* of the database, the additional
                 copies look like new "Added" nodes rather than a simple
                 mixed-rev working copy.

                 That would be a behavior change if we did not compensate.
                 If there is copyfrom information for this node, then the
                 code below looks at the parent to detect if it *also* has
                 copyfrom information, and if the copyfrom_url would align
                 properly. If it *does*, then we omit storing copyfrom_url
                 and copyfrom_rev (ie. inherit the copyfrom info like a
                 normal child), and update entry->revision with the
                 copyfrom_rev in order to (re)create the mixed-rev copied
                 subtree that was originally presented for storage.  */

              /* Get the copyfrom information from our parent.

                 Note that the parent could be added/copied/moved-here.
                 There is no way for it to be deleted/moved-away and
                 have *this* node appear as copied.  */
              parent_relpath = svn_relpath_dirname(entry_relpath,
                                                   scratch_pool);
              err = svn_wc__db_scan_addition_internal(
                                             NULL,
                                             &op_root_relpath,
                                             NULL, NULL,
                                             &parent_repos_relpath,
                                             &parent_repos_id,
                                             NULL,
                                             wcroot, parent_relpath,
                                             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);
                  op_root_abspath = NULL;
                  parent_repos_relpath = NULL;
                  parent_root_url = NULL;
                }
              else
                {
                  SVN_ERR(svn_wc__db_fetch_repos_info(&parent_root_url, NULL,
                                                      wcroot, parent_repos_id,
                                                      scratch_pool));
                  op_root_abspath = svn_dirent_join(wcroot->abspath,
                                                    op_root_relpath,
                                                    scratch_pool);
                }

              if (parent_root_url != NULL
                       && strcmp(original_root_url, parent_root_url) == 0)
                {
                  
                  const char *relpath_to_entry = svn_dirent_is_child(
                    op_root_abspath, entry_abspath, NULL);
                  const char *entry_repos_relpath = svn_relpath_join(
                    parent_repos_relpath, relpath_to_entry, scratch_pool);

                  /* The copyfrom repos roots matched.

                     Now we look to see if the copyfrom path of the parent
                     would align with our own path. If so, then it means
                     this copyfrom was spontaneously created and inserted
                     for mixed-rev purposes and can be eliminated without
                     changing the semantics of a mixed-rev copied subtree.

                     See notes/api-errata/wc003.txt for some additional
                     detail, and potential issues.  */
                  if (strcmp(entry_repos_relpath,
                             original_repos_relpath) == 0)
                    {
                      is_copied_child = TRUE;
                      is_mixed_rev = TRUE;
                    }
                }
            }

          if (is_copied_child)
            {
              /* We won't be settig the  copyfrom_url, yet need to
                 clear out the copyfrom_rev. Thus, this node becomes a
                 child of a copied subtree (rather than its own root).  */
              entry->copyfrom_rev = SVN_INVALID_REVNUM;

              /* Children in a copied subtree are schedule normal
                 since we don't plan to actually *do* anything with
                 them. Their operation is implied by ancestors.  */
              entry->schedule = svn_wc_schedule_normal;

              /* And *finally* we turn this entry into the mixed
                 revision node that it was intended to be. This
                 node's revision is taken from the copyfrom record
                 that we spontaneously constructed.  */
              if (is_mixed_rev)
                entry->revision = original_revision;
            }
          else if (original_repos_relpath != NULL)
            {
              entry->copyfrom_url =
                svn_path_url_add_component2(original_root_url,
                                            original_repos_relpath,
                                            result_pool);
            }
          else
            {
              /* NOTE: if original_repos_relpath == NULL, then the
                 second call to scan_addition() will not have occurred.
                 Thus, this use of OP_ROOT_ABSPATH still contains the
                 original value where we fetched a value for
                 SCANNED_REPOS_RELPATH.  */
              const char *relpath_to_entry = svn_dirent_is_child(
                op_root_abspath, entry_abspath, NULL);
              const char *entry_repos_relpath = svn_relpath_join(
                scanned_original_relpath, relpath_to_entry, scratch_pool);

              entry->copyfrom_url =
                svn_path_url_add_component2(original_root_url,
                                            entry_repos_relpath,
                                            result_pool);
            }
        }
    }
  else if (status == svn_wc__db_status_not_present)
    {
      /* ### buh. 'deleted' nodes are actually supposed to be
         ### schedule "normal" since we aren't going to actually *do*
         ### anything to this node at commit time.  */
      entry->schedule = svn_wc_schedule_normal;
      entry->deleted = TRUE;
    }
  else if (status == svn_wc__db_status_server_excluded)
    {
      entry->absent = TRUE;
    }
  else if (status == svn_wc__db_status_excluded)
    {
      entry->schedule = svn_wc_schedule_normal;
      entry->depth = svn_depth_exclude;
    }
  else
    {
      /* ### we should have handled all possible status values.  */
      SVN_ERR_MALFUNCTION();
    }

  /* ### higher levels want repos information about deleted nodes, even
     ### tho they are not "part of" a repository any more.  */
  if (entry->schedule == svn_wc_schedule_delete)
    {
      SVN_ERR(get_info_for_deleted(entry,
                                   &kind,
                                   &repos_relpath,
                                   &checksum,
                                   &lock,
                                   db, entry_abspath,
                                   wcroot, entry_relpath,
                                   parent_entry,
                                   have_base, have_more_work,
                                   result_pool, scratch_pool));
    }

  /* ### default to the infinite depth if we don't know it. */
  if (entry->depth == svn_depth_unknown)
    entry->depth = svn_depth_infinity;

  if (kind == svn_node_dir)
    entry->kind = svn_node_dir;
  else if (kind == svn_node_file)
    entry->kind = svn_node_file;
  else if (kind == svn_node_symlink)
    entry->kind = svn_node_file;  /* ### no symlink kind */
  else
    entry->kind = svn_node_unknown;

  /* We should always have a REPOS_RELPATH, except for:
     - deleted nodes
     - certain obstructed nodes
     - not-present nodes
     - absent nodes
     - excluded nodes

     ### the last three should probably have an "implied" REPOS_RELPATH
  */
  SVN_ERR_ASSERT(repos_relpath != NULL
                 || entry->schedule == svn_wc_schedule_delete
                 || status == svn_wc__db_status_not_present
                 || status == svn_wc__db_status_server_excluded
                 || status == svn_wc__db_status_excluded);
  if (repos_relpath)
    entry->url = svn_path_url_add_component2(entry->repos,
                                             repos_relpath,
                                             result_pool);

  if (checksum)
    {
      /* We got a SHA-1, get the corresponding MD-5. */
      if (checksum->kind != svn_checksum_md5)
        SVN_ERR(svn_wc__db_pristine_get_md5(&checksum, db,
                                            dir_abspath, checksum,
                                            scratch_pool, scratch_pool));

      SVN_ERR_ASSERT(checksum->kind == svn_checksum_md5);
      entry->checksum = svn_checksum_to_cstring(checksum, result_pool);
    }

  if (conflicted)
    {
      svn_skel_t *conflict;
      svn_boolean_t text_conflicted;
      svn_boolean_t prop_conflicted;
      SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, NULL,
                                                wcroot, entry_relpath,
                                                scratch_pool, scratch_pool));

      SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, &text_conflicted,
                                         &prop_conflicted, NULL,
                                         db, dir_abspath, conflict,
                                         scratch_pool, scratch_pool));

      if (text_conflicted)
        {
          const char *my_abspath;
          const char *their_old_abspath;
          const char *their_abspath;
          SVN_ERR(svn_wc__conflict_read_text_conflict(&my_abspath,
                                                      &their_old_abspath,
                                                      &their_abspath,
                                                      db, dir_abspath,
                                                      conflict, scratch_pool,
                                                      scratch_pool));

          if (my_abspath)
            entry->conflict_wrk = svn_dirent_basename(my_abspath, result_pool);

          if (their_old_abspath)
            entry->conflict_old = svn_dirent_basename(their_old_abspath,
                                                      result_pool);

          if (their_abspath)
            entry->conflict_new = svn_dirent_basename(their_abspath,
                                                      result_pool);
        }

      if (prop_conflicted)
        {
          const char *prej_abspath;

          SVN_ERR(svn_wc__conflict_read_prop_conflict(&prej_abspath, NULL,
                                                      NULL, NULL, NULL,
                                                      db, dir_abspath,
                                                      conflict, scratch_pool,
                                                      scratch_pool));

          if (prej_abspath)
            entry->prejfile = svn_dirent_basename(prej_abspath, result_pool);
        }
    }

  if (lock)
    {
      entry->lock_token = lock->token;
      entry->lock_owner = lock->owner;
      entry->lock_comment = lock->comment;
      entry->lock_creation_date = lock->date;
    }

  /* Let's check for a file external.  ugh.  */
  if (status == svn_wc__db_status_normal
      && kind == svn_node_file)
    SVN_ERR(check_file_external(entry, db, entry_abspath, dir_abspath,
                                result_pool, scratch_pool));

  entry->working_size = translated_size;

  *new_entry = entry;

  return SVN_NO_ERROR;
}

/* Read entries for PATH/LOCAL_ABSPATH from DB. The entries
   will be allocated in RESULT_POOL, with temporary allocations in
   SCRATCH_POOL. The entries are returned in RESULT_ENTRIES.  */
static svn_error_t *
read_entries_new(apr_hash_t **result_entries,
                 svn_wc__db_t *db,
                 const char *dir_abspath,
                 svn_wc__db_wcroot_t *wcroot,
                 const char *dir_relpath,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
{
  apr_hash_t *entries;
  const apr_array_header_t *children;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  int i;
  const svn_wc_entry_t *parent_entry;

  entries = apr_hash_make(result_pool);

  SVN_ERR(read_one_entry(&parent_entry,
                         db, dir_abspath,
                         wcroot, dir_relpath,
                         "" /* name */,
                         NULL /* parent_entry */,
                         result_pool, iterpool));
  svn_hash_sets(entries, "", parent_entry);

  /* Use result_pool so that the child names (used by reference, rather
     than copied) appear in result_pool.  */
  SVN_ERR(svn_wc__db_read_children(&children, db,
                                   dir_abspath,
                                   scratch_pool, iterpool));
  for (i = children->nelts; i--; )
    {
      const char *name = APR_ARRAY_IDX(children, i, const char *);
      const svn_wc_entry_t *entry;

      svn_pool_clear(iterpool);

      SVN_ERR(read_one_entry(&entry,
                             db, dir_abspath, 
                             wcroot, dir_relpath,
                             name, parent_entry,
                             result_pool, iterpool));
      svn_hash_sets(entries, entry->name, entry);
    }

  svn_pool_destroy(iterpool);

  *result_entries = entries;

  return SVN_NO_ERROR;
}


static svn_error_t *
read_entry_pair_txn(const svn_wc_entry_t **parent_entry,
                    const svn_wc_entry_t **entry,
                    svn_wc__db_t *db,
                    const char *dir_abspath,
                    svn_wc__db_wcroot_t *wcroot,
                    const char *dir_relpath,
                    const char *name,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
{
  SVN_ERR(read_one_entry(parent_entry,
                         db, dir_abspath,
                         wcroot, dir_relpath,
                         "" /* name */,
                         NULL /* parent_entry */,
                         result_pool, scratch_pool));

  /* If we need the entry for "this dir", then return the parent_entry
     in both outputs. Otherwise, read the child node.  */
  if (*name == '\0')
    {
      /* If the retrieved node is a FILE, then we have a problem. We asked
         for a directory. This implies there is an obstructing, unversioned
         directory where a FILE should be. We navigated from the obstructing
         subdir up to the parent dir, then returned the FILE found there.

         Let's return WC_MISSING cuz the caller thought we had a dir, but
         that (versioned subdir) isn't there.  */
      if ((*parent_entry)->kind == svn_node_file)
        {
          *parent_entry = NULL;
          return svn_error_createf(SVN_ERR_WC_MISSING, NULL,
                                 _("'%s' is not a versioned working copy"),
                                 svn_dirent_local_style(dir_abspath,
                                                        scratch_pool));
        }

      *entry = *parent_entry;
    }
  else
    {
      const apr_array_header_t *children;
      int i;

      /* Default to not finding the child.  */
      *entry = NULL;

      /* Determine whether the parent KNOWS about this child. If it does
         not, then we should not attempt to look for it.

         For example: the parent doesn't "know" about the child, but the
         versioned directory *does* exist on disk. We don't want to look
         into that subdir.  */
      SVN_ERR(svn_wc__db_read_children(&children, db, dir_abspath,
                                       scratch_pool, scratch_pool));
      for (i = children->nelts; i--; )
        {
          const char *child = APR_ARRAY_IDX(children, i, const char *);

          if (strcmp(child, name) == 0)
            {
              svn_error_t *err;

              err = read_one_entry(entry,
                                   db, dir_abspath,
                                   wcroot, dir_relpath,
                                   name, *parent_entry,
                                   result_pool, scratch_pool);
              if (err)
                {
                  if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
                    return svn_error_trace(err);

                  /* No problem. Clear the error and leave the default value
                     of "missing".  */
                  svn_error_clear(err);
                }

              /* Found it. No need to keep searching.  */
              break;
            }
        }
      /* if the loop ends without finding a child, then we have the default
         ENTRY value of NULL.  */
    }

  return SVN_NO_ERROR;
}

/* Read a pair of entries from wc_db in the directory DIR_ABSPATH. Return
   the directory's entry in *PARENT_ENTRY and NAME's entry in *ENTRY. The
   two returned pointers will be the same if NAME=="" ("this dir").

   The parent entry must exist.

   The requested entry MAY exist. If it does not, then NULL will be returned.

   The resulting entries are allocated in RESULT_POOL, and all temporary
   allocations are made in SCRATCH_POOL.  */
static svn_error_t *
read_entry_pair(const svn_wc_entry_t **parent_entry,
                const svn_wc_entry_t **entry,
                svn_wc__db_t *db,
                const char *dir_abspath,
                const char *name,
                apr_pool_t *result_pool,
                apr_pool_t *scratch_pool)
{
  svn_wc__db_wcroot_t *wcroot;
  const char *dir_relpath;

  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath,
                                                db, dir_abspath,
                                                scratch_pool, scratch_pool));
  VERIFY_USABLE_WCROOT(wcroot);

  SVN_WC__DB_WITH_TXN(read_entry_pair_txn(parent_entry, entry,
                                          db, dir_abspath,
                                          wcroot, dir_relpath,
                                          name,
                                          result_pool, scratch_pool),
                      wcroot);

  return SVN_NO_ERROR;
}

/* */
static svn_error_t *
read_entries(apr_hash_t **entries,
             svn_wc__db_t *db,
             const char *dir_abspath,
             apr_pool_t *result_pool,
             apr_pool_t *scratch_pool)
{
  svn_wc__db_wcroot_t *wcroot;
  const char *dir_relpath;
  int wc_format;

  SVN_ERR(svn_wc__db_temp_get_format(&wc_format, db, dir_abspath,
                                     scratch_pool));

  if (wc_format < SVN_WC__WC_NG_VERSION)
    return svn_error_trace(svn_wc__read_entries_old(entries,
                                                    dir_abspath,
                                                    result_pool,
                                                    scratch_pool));

  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath,
                                                db, dir_abspath,
                                                scratch_pool, scratch_pool));
  VERIFY_USABLE_WCROOT(wcroot);

  SVN_WC__DB_WITH_TXN(read_entries_new(entries,
                                       db, dir_abspath,
                                       wcroot, dir_relpath,
                                       result_pool, scratch_pool),
                      wcroot);

  return SVN_NO_ERROR;
}


/* For a given LOCAL_ABSPATH, using DB, set *ADM_ABSPATH to the directory in
   which the entry information is located, and *ENTRY_NAME to the entry name
   to access that entry.

   KIND is as in svn_wc__get_entry().

   Return the results in RESULT_POOL and use SCRATCH_POOL for temporary
   allocations. */
static svn_error_t *
get_entry_access_info(const char **adm_abspath,
                      const char **entry_name,
                      svn_wc__db_t *db,
                      const char *local_abspath,
                      svn_node_kind_t kind,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
{
  svn_wc_adm_access_t *adm_access;
  svn_boolean_t read_from_subdir = FALSE;

  /* If the caller didn't know the node kind, then stat the path. Maybe
     it is really there, and we can speed up the steps below.  */
  if (kind == svn_node_unknown)
    {
      svn_node_kind_t on_disk;

      /* Do we already have an access baton for LOCAL_ABSPATH?  */
      adm_access = svn_wc__adm_retrieve_internal2(db, local_abspath,
                                                  scratch_pool);
      if (adm_access)
        {
          /* Sweet. The node is a directory.  */
          on_disk = svn_node_dir;
        }
      else
        {
          svn_boolean_t special;

          /* What's on disk?  */
          SVN_ERR(svn_io_check_special_path(local_abspath, &on_disk, &special,
                                            scratch_pool));
        }

      if (on_disk != svn_node_dir)
        {
          /* If this is *anything* besides a directory (FILE, NONE, or
             UNKNOWN), then we cannot treat it as a versioned directory
             containing entries to read. Leave READ_FROM_SUBDIR as FALSE,
             so that the parent will be examined.

             For NONE and UNKNOWN, it may be that metadata exists for the
             node, even though on-disk is unhelpful.

             If NEED_PARENT_STUB is TRUE, and the entry is not a DIRECTORY,
             then we'll error.

             If NEED_PARENT_STUB if FALSE, and we successfully read a stub,
             then this on-disk node is obstructing the read.  */
        }
      else
        {
          /* We found a directory for this UNKNOWN node. Determine whether
             we need to read inside it.  */
          read_from_subdir = TRUE;
        }
    }
  else if (kind == svn_node_dir)
    {
      read_from_subdir = TRUE;
    }

  if (read_from_subdir)
    {
      /* KIND must be a DIR or UNKNOWN (and we found a subdir). We want
         the "real" data, so treat LOCAL_ABSPATH as a versioned directory.  */
      *adm_abspath = apr_pstrdup(result_pool, local_abspath);
      *entry_name = "";
    }
  else
    {
      /* FILE node needs to read the parent directory. Or a DIR node
         needs to read from the parent to get at the stub entry. Or this
         is an UNKNOWN node, and we need to examine the parent.  */
      svn_dirent_split(adm_abspath, entry_name, local_abspath, result_pool);
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_wc__get_entry(const svn_wc_entry_t **entry,
                  svn_wc__db_t *db,
                  const char *local_abspath,
                  svn_boolean_t allow_unversioned,
                  svn_node_kind_t kind,
                  apr_pool_t *result_pool,
                  apr_pool_t *scratch_pool)
{
  const char *dir_abspath;
  const char *entry_name;

  SVN_ERR(get_entry_access_info(&dir_abspath, &entry_name, db, local_abspath,
                                kind, scratch_pool, scratch_pool));

    {
      const svn_wc_entry_t *parent_entry;
      svn_error_t *err;

      /* NOTE: if KIND is UNKNOWN and we decided to examine the *parent*
         directory, then it is possible we moved out of the working copy.
         If the on-disk node is a DIR, and we asked for a stub, then we
         obviously can't provide that (parent has no info). If the on-disk
         node is a FILE/NONE/UNKNOWN, then it is obstructing the real
         LOCAL_ABSPATH (or it was never a versioned item). In all these
         cases, the read_entries() will (properly) throw an error.

         NOTE: if KIND is a DIR and we asked for the real data, but it is
         obstructed on-disk by some other node kind (NONE, FILE, UNKNOWN),
         then this will throw an error.  */

      err = read_entry_pair(&parent_entry, entry,
                            db, dir_abspath, entry_name,
                            result_pool, scratch_pool);
      if (err)
        {
          if (err->apr_err != SVN_ERR_WC_MISSING || kind != svn_node_unknown
              || *entry_name != '\0')
            return svn_error_trace(err);
          svn_error_clear(err);

          /* The caller didn't know the node type, we saw a directory there,
             we attempted to read IN that directory, and then wc_db reports
             that it is NOT a working copy directory. It is possible that
             one of two things has happened:

             1) a directory is obstructing a file in the parent
             2) the (versioned) directory's contents have been removed

             Let's assume situation (1); if that is true, then we can just
             return the newly-found data.

             If we assumed (2), then a valid result still won't help us
             since the caller asked for the actual contents, not the stub
             (which is why we read *into* the directory). However, if we
             assume (1) and get back a stub, then we have verified a
             missing, versioned directory, and can return an error
             describing that.

             Redo the fetch, but "insist" we are trying to find a file.
             This will read from the parent directory of the "file".  */
          err = svn_wc__get_entry(entry, db, local_abspath, allow_unversioned,
                                  svn_node_file, result_pool, scratch_pool);
          if (err == SVN_NO_ERROR)
            return SVN_NO_ERROR;
          if (err->apr_err != SVN_ERR_NODE_UNEXPECTED_KIND)
            return svn_error_trace(err);
          svn_error_clear(err);

          /* We asked for a FILE, but the node found is a DIR. Thus, we
             are looking at a stub. Originally, we tried to read into the
             subdir because NEED_PARENT_STUB is FALSE. The stub we just
             read is not going to work for the caller, so inform them of
             the missing subdirectory.  */
          SVN_ERR_ASSERT(*entry != NULL && (*entry)->kind == svn_node_dir);
          return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                                 _("Admin area of '%s' is missing"),
                                 svn_dirent_local_style(local_abspath,
                                                        scratch_pool));
        }
    }

  if (*entry == NULL)
    {
      if (allow_unversioned)
        return SVN_NO_ERROR;
      return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                               _("'%s' is not under version control"),
                               svn_dirent_local_style(local_abspath,
                                                      scratch_pool));
    }

  /* The caller had the wrong information.  */
  if ((kind == svn_node_file && (*entry)->kind != svn_node_file)
      || (kind == svn_node_dir && (*entry)->kind != svn_node_dir))
    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                             _("'%s' is not of the right kind"),
                             svn_dirent_local_style(local_abspath,
                                                    scratch_pool));

  return SVN_NO_ERROR;
}

/* TODO ### Rewrite doc string to mention ENTRIES_ALL; not ADM_ACCESS.

   Prune the deleted entries from the cached entries in ADM_ACCESS, and
   return that collection in *ENTRIES_PRUNED.  SCRATCH_POOL is used for local,
   short term, memory allocation, RESULT_POOL for permanent stuff.  */
static svn_error_t *
prune_deleted(apr_hash_t **entries_pruned,
              apr_hash_t *entries_all,
              apr_pool_t *result_pool,
              apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;

  if (!entries_all)
    {
      *entries_pruned = NULL;
      return SVN_NO_ERROR;
    }

  /* I think it will be common for there to be no deleted entries, so
     it is worth checking for that case as we can optimise it. */
  for (hi = apr_hash_first(scratch_pool, entries_all);
       hi;
       hi = apr_hash_next(hi))
    {
      svn_boolean_t hidden;

      SVN_ERR(svn_wc__entry_is_hidden(&hidden,
                                      apr_hash_this_val(hi)));
      if (hidden)
        break;
    }

  if (! hi)
    {
      /* There are no deleted entries, so we can use the full hash */
      *entries_pruned = entries_all;
      return SVN_NO_ERROR;
    }

  /* Construct pruned hash without deleted entries */
  *entries_pruned = apr_hash_make(result_pool);
  for (hi = apr_hash_first(scratch_pool, entries_all);
       hi;
       hi = apr_hash_next(hi))
    {
      const void *key = apr_hash_this_key(hi);
      const svn_wc_entry_t *entry = apr_hash_this_val(hi);
      svn_boolean_t hidden;

      SVN_ERR(svn_wc__entry_is_hidden(&hidden, entry));
      if (!hidden)
        svn_hash_sets(*entries_pruned, key, entry);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__entries_read_internal(apr_hash_t **entries,
                              svn_wc_adm_access_t *adm_access,
                              svn_boolean_t show_hidden,
                              apr_pool_t *pool)
{
  apr_hash_t *new_entries;

  new_entries = svn_wc__adm_access_entries(adm_access);
  if (! new_entries)
    {
      svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
      const char *local_abspath = svn_wc__adm_access_abspath(adm_access);
      apr_pool_t *result_pool = svn_wc__adm_access_pool_internal(adm_access);

      SVN_ERR(read_entries(&new_entries, db, local_abspath,
                           result_pool, pool));

      svn_wc__adm_access_set_entries(adm_access, new_entries);
    }

  if (show_hidden)
    *entries = new_entries;
  else
    SVN_ERR(prune_deleted(entries, new_entries,
                          svn_wc__adm_access_pool_internal(adm_access),
                          pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc_entries_read(apr_hash_t **entries,
                    svn_wc_adm_access_t *adm_access,
                    svn_boolean_t show_hidden,
                    apr_pool_t *pool)
{
  return svn_error_trace(svn_wc__entries_read_internal(entries, adm_access,
                                                       show_hidden, pool));
}

/* No transaction required: called from write_entry which is itself
   transaction-wrapped. */
static svn_error_t *
insert_node(svn_sqlite__db_t *sdb,
            const db_node_t *node,
            apr_pool_t *scratch_pool)
{
  svn_sqlite__stmt_t *stmt;
  svn_boolean_t present = (node->presence == svn_wc__db_status_normal
                           || node->presence == svn_wc__db_status_incomplete);

  SVN_ERR_ASSERT(node->op_depth > 0 || node->repos_relpath);

  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
  SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnnnsn",
                            node->wc_id,
                            node->local_relpath,
                            node->op_depth,
                            node->parent_relpath,
                            /* Setting depth for files? */
                            (node->kind == svn_node_dir && present)
                              ? svn_depth_to_word(node->depth)
                              : NULL));

  if (present && node->repos_relpath)
    {
      SVN_ERR(svn_sqlite__bind_revnum(stmt, 11, node->changed_rev));
      SVN_ERR(svn_sqlite__bind_int64(stmt, 12, node->changed_date));
      SVN_ERR(svn_sqlite__bind_text(stmt, 13, node->changed_author));
    }

  if (node->repos_relpath
      && node->presence != svn_wc__db_status_base_deleted)
    {
      SVN_ERR(svn_sqlite__bind_int64(stmt, 5,
                                     node->repos_id));
      SVN_ERR(svn_sqlite__bind_text(stmt, 6,
                                    node->repos_relpath));
      SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, node->revision));
    }

  SVN_ERR(svn_sqlite__bind_token(stmt, 8, presence_map, node->presence));

  if (node->kind == svn_node_none)
    SVN_ERR(svn_sqlite__bind_text(stmt, 10, "unknown"));
  else
    SVN_ERR(svn_sqlite__bind_token(stmt, 10, kind_map, node->kind));

  if (node->kind == svn_node_file && present)
    {
      if (!node->checksum
          && node->op_depth == 0
          && node->presence != svn_wc__db_status_not_present
          && node->presence != svn_wc__db_status_excluded
          && node->presence != svn_wc__db_status_server_excluded)
        return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
                                 _("The file '%s' has no checksum"),
                                 svn_dirent_local_style(node->local_relpath,
                                                        scratch_pool));

      SVN_ERR(svn_sqlite__bind_checksum(stmt, 14, node->checksum,
                                        scratch_pool));

      if (node->repos_relpath)
        {
          if (node->recorded_size != SVN_INVALID_FILESIZE)
            SVN_ERR(svn_sqlite__bind_int64(stmt, 16, node->recorded_size));

          SVN_ERR(svn_sqlite__bind_int64(stmt, 17, node->recorded_time));
        }
    }

   /* ### Never set, props done later */
  if (node->properties && present && node->repos_relpath)
    SVN_ERR(svn_sqlite__bind_properties(stmt, 15, node->properties,
                                        scratch_pool));

  if (node->file_external)
    SVN_ERR(svn_sqlite__bind_int(stmt, 20, 1));

  if (node->inherited_props && present)
    SVN_ERR(svn_sqlite__bind_iprops(stmt, 23, node->inherited_props,
                                    scratch_pool));

  SVN_ERR(svn_sqlite__insert(NULL, stmt));

  return SVN_NO_ERROR;
}


/* */
static svn_error_t *
insert_actual_node(svn_sqlite__db_t *sdb,
                   svn_wc__db_t *db,
                   const char *wri_abspath,
                   const db_actual_node_t *actual_node,
                   apr_pool_t *scratch_pool)
{
  svn_sqlite__stmt_t *stmt;
  svn_skel_t *conflict_data = NULL;

  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL_NODE));

  SVN_ERR(svn_sqlite__bind_int64(stmt, 1, actual_node->wc_id));
  SVN_ERR(svn_sqlite__bind_text(stmt, 2, actual_node->local_relpath));
  SVN_ERR(svn_sqlite__bind_text(stmt, 3, actual_node->parent_relpath));

  if (actual_node->properties)
    SVN_ERR(svn_sqlite__bind_properties(stmt, 4, actual_node->properties,
                                        scratch_pool));

  if (actual_node->changelist)
    SVN_ERR(svn_sqlite__bind_text(stmt, 5, actual_node->changelist));

  SVN_ERR(svn_wc__upgrade_conflict_skel_from_raw(
                                &conflict_data,
                                db, wri_abspath,
                                actual_node->local_relpath,
                                actual_node->conflict_old,
                                actual_node->conflict_working,
                                actual_node->conflict_new,
                                actual_node->prop_reject,
                                actual_node->tree_conflict_data,
                                actual_node->tree_conflict_data
                                    ? strlen(actual_node->tree_conflict_data)
                                    : 0,
                                scratch_pool, scratch_pool));

  if (conflict_data)
    {
      svn_stringbuf_t *data = svn_skel__unparse(conflict_data, scratch_pool);

      SVN_ERR(svn_sqlite__bind_blob(stmt, 6, data->data, data->len));
    }

  /* Execute and reset the insert clause. */
  return svn_error_trace(svn_sqlite__insert(NULL, stmt));
}

static svn_boolean_t
is_switched(db_node_t *parent,
            db_node_t *child,
            apr_pool_t *scratch_pool)
{
  if (parent && child)
    {
      if (parent->repos_id != child->repos_id)
        return TRUE;

      if (parent->repos_relpath && child->repos_relpath)
        {
          const char *unswitched
            = svn_relpath_join(parent->repos_relpath,
                               svn_relpath_basename(child->local_relpath,
                                                    scratch_pool),
                               scratch_pool);
          if (strcmp(unswitched, child->repos_relpath))
            return TRUE;
        }
    }

  return FALSE;
}

struct write_baton {
  db_node_t *base;
  db_node_t *work;
  db_node_t *below_work;
  apr_hash_t *tree_conflicts;
};

#define WRITE_ENTRY_ASSERT(expr) \
  if (!(expr)) \
    return svn_error_createf(SVN_ERR_ASSERTION_FAIL, NULL,  \
                             _("Unable to upgrade '%s' at line %d"),    \
                             svn_dirent_local_style( \
                               svn_dirent_join(root_abspath, \
                                               local_relpath,           \
                                               scratch_pool),           \
                               scratch_pool), __LINE__)

/* Write the information for ENTRY to WC_DB.  The WC_ID, REPOS_ID and
   REPOS_ROOT will all be used for writing ENTRY.
   ### transitioning from straight sql to using the wc_db APIs.  For the
   ### time being, we'll need both parameters. */
static svn_error_t *
write_entry(struct write_baton **entry_node,
            const struct write_baton *parent_node,
            svn_wc__db_t *db,
            svn_sqlite__db_t *sdb,
            apr_int64_t wc_id,
            apr_int64_t repos_id,
            const svn_wc_entry_t *entry,
            const svn_wc__text_base_info_t *text_base_info,
            const char *local_relpath,
            const char *tmp_entry_abspath,
            const char *root_abspath,
            const svn_wc_entry_t *this_dir,
            svn_boolean_t create_locks,
            apr_pool_t *result_pool,
            apr_pool_t *scratch_pool)
{
  db_node_t *base_node = NULL;
  db_node_t *working_node = NULL, *below_working_node = NULL;
  db_actual_node_t *actual_node = NULL;
  const char *parent_relpath;
  apr_hash_t *tree_conflicts;

  if (*local_relpath == '\0')
    parent_relpath = NULL;
  else
    parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);

  /* This is how it should work, it doesn't work like this yet because
     we need proper op_depth to layer the working nodes.

     Using "svn add", "svn rm", "svn cp" only files can be replaced
     pre-wcng; directories can only be normal, deleted or added.
     Files cannot be replaced within a deleted directory, so replaced
     files can only exist in a normal directory, or a directory that
     is added+copied.  In a normal directory a replaced file needs a
     base node and a working node, in an added+copied directory a
     replaced file needs two working nodes at different op-depths.

     With just the above operations the conversion for files and
     directories is straightforward:

           pre-wcng                             wcng
     parent         child                 parent     child

     normal         normal                base       base
     add+copied     normal+copied         work       work
     normal+copied  normal+copied         work       work
     normal         delete                base       base+work
     delete         delete                base+work  base+work
     add+copied     delete                work       work
     normal         add                   base       work
     add            add                   work       work
     add+copied     add                   work       work
     normal         add+copied            base       work
     add            add+copied            work       work
     add+copied     add+copied            work       work
     normal         replace               base       base+work
     add+copied     replace               work       work+work
     normal         replace+copied        base       base+work
     add+copied     replace+copied        work       work+work

     However "svn merge" make this more complicated.  The pre-wcng
     "svn merge" is capable of replacing a directory, that is it can
     mark the whole tree deleted, and then copy another tree on top.
     The entries then represent the replacing tree overlayed on the
     deleted tree.

       original       replace          schedule in
       tree           tree             combined tree

       A              A                replace+copied
       A/f                             delete+copied
       A/g            A/g              replace+copied
                      A/h              add+copied
       A/B            A/B              replace+copied
       A/B/f                           delete+copied
       A/B/g          A/B/g            replace+copied
                      A/B/h            add+copied
       A/C                             delete+copied
       A/C/f                           delete+copied
                      A/D              add+copied
                      A/D/f            add+copied

     The original tree could be normal tree, or an add+copied tree.
     Committing such a merge generally worked, but making further tree
     modifications before commit sometimes failed.

     The root of the replace is handled like the file replace:

           pre-wcng                             wcng
     parent         child                 parent     child

     normal         replace+copied        base       base+work
     add+copied     replace+copied        work       work+work

     although obviously the node is a directory rather than a file.
     There are then more conversion states where the parent is
     replaced.

           pre-wcng                                wcng
     parent           child              parent            child

     replace+copied   add                [base|work]+work  work
     replace+copied   add+copied         [base|work]+work  work
     replace+copied   delete+copied      [base|work]+work  [base|work]+work
     delete+copied    delete+copied      [base|work]+work  [base|work]+work
     replace+copied   replace+copied     [base|work]+work  [base|work]+work
  */

  WRITE_ENTRY_ASSERT(parent_node || entry->schedule == svn_wc_schedule_normal);

  WRITE_ENTRY_ASSERT(!parent_node || parent_node->base
                     || parent_node->below_work || parent_node->work);

  switch (entry->schedule)
    {
      case svn_wc_schedule_normal:
        if (entry->copied ||
            (entry->depth == svn_depth_exclude
             && parent_node && !parent_node->base && parent_node->work))
          working_node = MAYBE_ALLOC(working_node, result_pool);
        else
          base_node = MAYBE_ALLOC(base_node, result_pool);
        break;

      case svn_wc_schedule_add:
        working_node = MAYBE_ALLOC(working_node, result_pool);
        if (entry->deleted)
          {
            if (parent_node->base)
              base_node = MAYBE_ALLOC(base_node, result_pool);
            else
              below_working_node = MAYBE_ALLOC(below_working_node, result_pool);
          }
        break;

      case svn_wc_schedule_delete:
        working_node = MAYBE_ALLOC(working_node, result_pool);
        if (parent_node->base)
          base_node = MAYBE_ALLOC(base_node, result_pool);
        if (parent_node->work)
          below_working_node = MAYBE_ALLOC(below_working_node, result_pool);
        break;

      case svn_wc_schedule_replace:
        working_node = MAYBE_ALLOC(working_node, result_pool);
        if (parent_node->base)
          base_node = MAYBE_ALLOC(base_node, result_pool);
        else
          below_working_node = MAYBE_ALLOC(below_working_node, result_pool);
        break;
    }

  /* Something deleted in this revision means there should always be a
     BASE node to indicate the not-present node.  */
  if (entry->deleted)
    {
      WRITE_ENTRY_ASSERT(base_node || below_working_node);
      WRITE_ENTRY_ASSERT(!entry->incomplete);
      if (base_node)
        base_node->presence = svn_wc__db_status_not_present;
      else
        below_working_node->presence = svn_wc__db_status_not_present;
    }
  else if (entry->absent)
    {
      WRITE_ENTRY_ASSERT(base_node && !working_node && !below_working_node);
      WRITE_ENTRY_ASSERT(!entry->incomplete);
      base_node->presence = svn_wc__db_status_server_excluded;
    }

  if (entry->copied)
    {
      db_node_t *work = parent_node->work
                              ? parent_node->work
                              : parent_node->below_work;

      if (entry->copyfrom_url)
        {
          working_node->repos_id = repos_id;
          working_node->repos_relpath = svn_uri_skip_ancestor(
                                          this_dir->repos, entry->copyfrom_url,
                                          result_pool);
          working_node->revision = entry->copyfrom_rev;
          working_node->op_depth
            = svn_wc__db_op_depth_for_upgrade(local_relpath);

          if (work && work->repos_relpath
              && work->repos_id == repos_id
              && work->revision == entry->copyfrom_rev)
            {
              const char *name;

              name = svn_relpath_skip_ancestor(work->repos_relpath,
                                               working_node->repos_relpath);

              if (name
                  && !strcmp(name, svn_relpath_basename(local_relpath, NULL)))
                {
                  working_node->op_depth = work->op_depth;
                }
            }
        }
      else if (work && work->repos_relpath)
        {
          working_node->repos_id = repos_id;
          working_node->repos_relpath
            = svn_relpath_join(work->repos_relpath,
                               svn_relpath_basename(local_relpath, NULL),
                               result_pool);
          working_node->revision = work->revision;
          working_node->op_depth = work->op_depth;
        }
      else if (parent_node->below_work
                && parent_node->below_work->repos_relpath)
        {
          /* Parent deleted, this not-present or similar */
          working_node->repos_id = repos_id;
          working_node->repos_relpath
            = svn_relpath_join(parent_node->below_work->repos_relpath,
                               svn_relpath_basename(local_relpath, NULL),
                               result_pool);
          working_node->revision = parent_node->below_work->revision;
          working_node->op_depth = parent_node->below_work->op_depth;
        }
      else
        return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
                                 _("No copyfrom URL for '%s'"),
                                 svn_dirent_local_style(local_relpath,
                                                        scratch_pool));

      if (work && work->op_depth != working_node->op_depth
          && work->repos_relpath
          && work->repos_id == working_node->repos_id
          && work->presence == svn_wc__db_status_normal
          && !below_working_node)
        {
          /* Introduce a not-present node! */
          below_working_node = MAYBE_ALLOC(below_working_node, scratch_pool);

          below_working_node->wc_id = wc_id;
          below_working_node->op_depth = work->op_depth;
          below_working_node->local_relpath = local_relpath;
          below_working_node->parent_relpath = parent_relpath;

          below_working_node->presence = svn_wc__db_status_not_present;
          below_working_node->repos_id = repos_id;
          below_working_node->repos_relpath = working_node->local_relpath;

          SVN_ERR(insert_node(sdb, below_working_node, scratch_pool));

          below_working_node = NULL; /* Don't write a present intermediate! */
        }
    }

  if (entry->conflict_old)
    {
      actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
      if (parent_relpath && entry->conflict_old)
        actual_node->conflict_old = svn_relpath_join(parent_relpath,
                                                     entry->conflict_old,
                                                     scratch_pool);
      else
        actual_node->conflict_old = entry->conflict_old;
      if (parent_relpath && entry->conflict_new)
        actual_node->conflict_new = svn_relpath_join(parent_relpath,
                                                     entry->conflict_new,
                                                     scratch_pool);
      else
        actual_node->conflict_new = entry->conflict_new;
      if (parent_relpath && entry->conflict_wrk)
        actual_node->conflict_working = svn_relpath_join(parent_relpath,
                                                         entry->conflict_wrk,
                                                         scratch_pool);
      else
        actual_node->conflict_working = entry->conflict_wrk;
    }

  if (entry->prejfile)
    {
      actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
      actual_node->prop_reject = svn_relpath_join((entry->kind == svn_node_dir
                                                   ? local_relpath
                                                   : parent_relpath),
                                                  entry->prejfile,
                                                  scratch_pool);
    }

  if (entry->changelist)
    {
      actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
      actual_node->changelist = entry->changelist;
    }

  /* ### set the text_mod value? */

  if (entry_node && entry->tree_conflict_data)
    {
      /* Issues #3840/#3916: 1.6 stores multiple tree conflicts on the
         parent node, 1.7 stores them directly on the conflited nodes.
         So "((skel1) (skel2))" becomes "(skel1)" and "(skel2)" */
      svn_skel_t *skel;

      skel = svn_skel__parse(entry->tree_conflict_data,
                             strlen(entry->tree_conflict_data),
                             scratch_pool);
      tree_conflicts = apr_hash_make(result_pool);
      skel = skel->children;
      while (skel)
        {
          svn_wc_conflict_description2_t *conflict;
          svn_skel_t *new_skel;
          const char *key;

          /* *CONFLICT is allocated so it is safe to use a non-const pointer */
          SVN_ERR(svn_wc__deserialize_conflict(
                             (const svn_wc_conflict_description2_t**)&conflict,
                                               skel,
                                               svn_dirent_join(root_abspath,
                                                               local_relpath,
                                                               scratch_pool),
                                               scratch_pool, scratch_pool));

          WRITE_ENTRY_ASSERT(conflict->kind == svn_wc_conflict_kind_tree);

          SVN_ERR(svn_wc__serialize_conflict(&new_skel, conflict,
                                             scratch_pool, scratch_pool));

          /* Store in hash to be retrieved when writing the child
             row. */
          key = svn_dirent_skip_ancestor(root_abspath, conflict->local_abspath);
          svn_hash_sets(tree_conflicts, apr_pstrdup(result_pool, key),
                        svn_skel__unparse(new_skel, result_pool)->data);
          skel = skel->next;
        }
    }
  else
    tree_conflicts = NULL;

  if (parent_node && parent_node->tree_conflicts)
    {
      const char *tree_conflict_data =
          svn_hash_gets(parent_node->tree_conflicts, local_relpath);
      if (tree_conflict_data)
        {
          actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
          actual_node->tree_conflict_data = tree_conflict_data;
        }

      /* Reset hash so that we don't write the row again when writing
         actual-only nodes */
      svn_hash_sets(parent_node->tree_conflicts, local_relpath, NULL);
    }

  if (entry->file_external_path != NULL)
    {
      base_node = MAYBE_ALLOC(base_node, result_pool);
    }


  /* Insert the base node. */
  if (base_node)
    {
      base_node->wc_id = wc_id;
      base_node->local_relpath = local_relpath;
      base_node->op_depth = 0;
      base_node->parent_relpath = parent_relpath;
      base_node->revision = entry->revision;
      base_node->recorded_time = entry->text_time;
      base_node->recorded_size = entry->working_size;

      if (entry->depth != svn_depth_exclude)
        base_node->depth = entry->depth;
      else
        {
          base_node->presence = svn_wc__db_status_excluded;
          base_node->depth = svn_depth_infinity;
        }

      if (entry->deleted)
        {
          WRITE_ENTRY_ASSERT(base_node->presence
                             == svn_wc__db_status_not_present);
          /* ### should be svn_node_unknown, but let's store what we have. */
          base_node->kind = entry->kind;
        }
      else if (entry->absent)
        {
          WRITE_ENTRY_ASSERT(base_node->presence
                             == svn_wc__db_status_server_excluded);
          /* ### should be svn_node_unknown, but let's store what we have. */
          base_node->kind = entry->kind;

          /* Store the most likely revision in the node to avoid
             base nodes without a valid revision. Of course
             we remember that the data is still incomplete. */
          if (!SVN_IS_VALID_REVNUM(base_node->revision) && parent_node->base)
            base_node->revision = parent_node->base->revision;
        }
      else
        {
          base_node->kind = entry->kind;

          if (base_node->presence != svn_wc__db_status_excluded)
            {
              /* All subdirs are initially incomplete, they stop being
                 incomplete when the entries file in the subdir is
                 upgraded and remain incomplete if that doesn't happen. */
              if (entry->kind == svn_node_dir
                  && strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR))
                {
                  base_node->presence = svn_wc__db_status_incomplete;

                  /* Store the most likely revision in the node to avoid
                     base nodes without a valid revision. Of course
                     we remember that the data is still incomplete. */
                  if (parent_node->base)
                    base_node->revision = parent_node->base->revision;
                }
              else if (entry->incomplete)
                {
                  /* ### nobody should have set the presence.  */
                  WRITE_ENTRY_ASSERT(base_node->presence
                                     == svn_wc__db_status_normal);
                  base_node->presence = svn_wc__db_status_incomplete;
                }
            }
        }

      if (entry->kind == svn_node_dir)
        base_node->checksum = NULL;
      else
        {
          if (text_base_info && text_base_info->revert_base.sha1_checksum)
            base_node->checksum = text_base_info->revert_base.sha1_checksum;
          else if (text_base_info && text_base_info->normal_base.sha1_checksum)
            base_node->checksum = text_base_info->normal_base.sha1_checksum;
          else
            base_node->checksum = NULL;

          /* The base MD5 checksum is available in the entry, unless there
           * is a copied WORKING node.  If possible, verify that the entry
           * checksum matches the base file that we found. */
          if (! (working_node && entry->copied))
            {
              svn_checksum_t *entry_md5_checksum, *found_md5_checksum;
              SVN_ERR(svn_checksum_parse_hex(&entry_md5_checksum,
                                             svn_checksum_md5,
                                             entry->checksum, scratch_pool));
              if (text_base_info && text_base_info->revert_base.md5_checksum)
                found_md5_checksum = text_base_info->revert_base.md5_checksum;
              else if (text_base_info
                       && text_base_info->normal_base.md5_checksum)
                found_md5_checksum = text_base_info->normal_base.md5_checksum;
              else
                found_md5_checksum = NULL;
              if (entry_md5_checksum && found_md5_checksum &&
                  !svn_checksum_match(entry_md5_checksum, found_md5_checksum))
                return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
                                         _("Bad base MD5 checksum for '%s'; "
                                           "expected: '%s'; found '%s'; "),
                                       svn_dirent_local_style(
                                         svn_dirent_join(root_abspath,
                                                         local_relpath,
                                                         scratch_pool),
                                         scratch_pool),
                                       svn_checksum_to_cstring_display(
                                         entry_md5_checksum, scratch_pool),
                                       svn_checksum_to_cstring_display(
                                         found_md5_checksum, scratch_pool));
              else
                {
                  /* ### Not sure what conditions this should cover. */
                  /* SVN_ERR_ASSERT(entry->deleted || ...); */
                }
            }
        }

      if (this_dir->repos)
        {
          base_node->repos_id = repos_id;

          if (entry->url != NULL)
            {
              base_node->repos_relpath = svn_uri_skip_ancestor(
                                           this_dir->repos, entry->url,
                                           result_pool);
            }
          else
            {
              const char *relpath = svn_uri_skip_ancestor(this_dir->repos,
                                                          this_dir->url,
                                                          scratch_pool);
              if (relpath == NULL || *relpath == '\0')
                base_node->repos_relpath = entry->name;
              else
                base_node->repos_relpath =
                  svn_dirent_join(relpath, entry->name, result_pool);
            }
        }

      /* TODO: These values should always be present, if they are missing
         during an upgrade, set a flag, and then ask the user to talk to the
         server.

         Note: cmt_rev is the distinguishing value. The others may be 0 or
         NULL if the corresponding revprop has been deleted.  */
      base_node->changed_rev = entry->cmt_rev;
      base_node->changed_date = entry->cmt_date;
      base_node->changed_author = entry->cmt_author;

      if (entry->file_external_path)
        base_node->file_external = TRUE;

      /* Switched nodes get an empty iprops cache. */
      if (parent_node
          && is_switched(parent_node->base, base_node, scratch_pool))
        base_node->inherited_props
          = apr_array_make(scratch_pool, 0, sizeof(svn_prop_inherited_item_t*));

      SVN_ERR(insert_node(sdb, base_node, scratch_pool));

      /* We have to insert the lock after the base node, because the node
         must exist to lookup various bits of repos related information for
         the abs path. */
      if (entry->lock_token && create_locks)
        {
          svn_wc__db_lock_t lock;

          lock.token = entry->lock_token;
          lock.owner = entry->lock_owner;
          lock.comment = entry->lock_comment;
          lock.date = entry->lock_creation_date;

          SVN_ERR(svn_wc__db_lock_add(db, tmp_entry_abspath, &lock,
                                      scratch_pool));
        }
    }

  if (below_working_node)
    {
      db_node_t *work
        = parent_node->below_work ? parent_node->below_work : parent_node->work;

      below_working_node->wc_id = wc_id;
      below_working_node->local_relpath = local_relpath;
      below_working_node->op_depth = work->op_depth;
      below_working_node->parent_relpath = parent_relpath;
      below_working_node->presence = svn_wc__db_status_normal;
      below_working_node->kind = entry->kind;
      below_working_node->repos_id = work->repos_id;
      below_working_node->revision = work->revision;

      /* This is just guessing. If the node below would have been switched
         or if it was updated to a different version, the guess would
         fail. But we don't have better information pre wc-ng :( */
      if (work->repos_relpath)
        below_working_node->repos_relpath
          = svn_relpath_join(work->repos_relpath,
                             svn_relpath_basename(local_relpath, NULL),
                             result_pool);
      else
        below_working_node->repos_relpath = NULL;

      /* The revert_base checksum isn't available in the entry structure,
         so the caller provides it. */

      /* text_base_info is NULL for files scheduled to be added. */
      below_working_node->checksum = NULL;
      if (text_base_info)
        {
          if (entry->schedule == svn_wc_schedule_delete)
            below_working_node->checksum =
              text_base_info->normal_base.sha1_checksum;
          else
            below_working_node->checksum =
              text_base_info->revert_base.sha1_checksum;
        }
      below_working_node->recorded_size = 0;
      below_working_node->changed_rev = SVN_INVALID_REVNUM;
      below_working_node->changed_date = 0;
      below_working_node->changed_author = NULL;
      below_working_node->depth = svn_depth_infinity;
      below_working_node->recorded_time = 0;
      below_working_node->properties = NULL;

      if (working_node
          && entry->schedule == svn_wc_schedule_delete
          && working_node->repos_relpath)
        {
          /* We are lucky, our guesses above are not necessary. The known
             correct information is in working. But our op_depth design
             expects more information here */
          below_working_node->repos_relpath = working_node->repos_relpath;
          below_working_node->repos_id = working_node->repos_id;
          below_working_node->revision = working_node->revision;

          /* Nice for 'svn status' */
          below_working_node->changed_rev = entry->cmt_rev;
          below_working_node->changed_date = entry->cmt_date;
          below_working_node->changed_author = entry->cmt_author;

          /* And now remove it from WORKING, because in wc-ng code
             should read it from the lower layer */
          working_node->repos_relpath = NULL;
          working_node->repos_id = 0;
          working_node->revision = SVN_INVALID_REVNUM;
        }

      SVN_ERR(insert_node(sdb, below_working_node, scratch_pool));
    }

  /* Insert the working node. */
  if (working_node)
    {
      working_node->wc_id = wc_id;
      working_node->local_relpath = local_relpath;
      working_node->parent_relpath = parent_relpath;
      working_node->changed_rev = SVN_INVALID_REVNUM;
      working_node->recorded_time = entry->text_time;
      working_node->recorded_size = entry->working_size;

      if (entry->depth != svn_depth_exclude)
        working_node->depth = entry->depth;
      else
        {
          working_node->presence = svn_wc__db_status_excluded;
          working_node->depth = svn_depth_infinity;
        }

      if (entry->kind == svn_node_dir)
        working_node->checksum = NULL;
      else
        {
          working_node->checksum = NULL;
          /* text_base_info is NULL for files scheduled to be added. */
          if (text_base_info)
            working_node->checksum = text_base_info->normal_base.sha1_checksum;


          /* If an MD5 checksum is present in the entry, we can verify that
           * it matches the MD5 of the base file we found earlier. */
#ifdef SVN_DEBUG
          if (entry->checksum && text_base_info)
          {
            svn_checksum_t *md5_checksum;
            SVN_ERR(svn_checksum_parse_hex(&md5_checksum, svn_checksum_md5,
                                           entry->checksum, result_pool));
            SVN_ERR_ASSERT(
              md5_checksum && text_base_info->normal_base.md5_checksum);
            SVN_ERR_ASSERT(svn_checksum_match(
              md5_checksum, text_base_info->normal_base.md5_checksum));
          }
#endif
        }

      working_node->kind = entry->kind;
      if (working_node->presence != svn_wc__db_status_excluded)
        {
          /* All subdirs start of incomplete, and stop being incomplete
             when the entries file in the subdir is upgraded. */
          if (entry->kind == svn_node_dir
              && strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR))
            {
              working_node->presence = svn_wc__db_status_incomplete;
              working_node->kind = svn_node_dir;
            }
          else if (entry->schedule == svn_wc_schedule_delete)
            {
              working_node->presence = svn_wc__db_status_base_deleted;
              working_node->kind = entry->kind;
            }
          else
            {
              /* presence == normal  */
              working_node->kind = entry->kind;

              if (entry->incomplete)
                {
                  /* We shouldn't be overwriting another status.  */
                  WRITE_ENTRY_ASSERT(working_node->presence
                                     == svn_wc__db_status_normal);
                  working_node->presence = svn_wc__db_status_incomplete;
                }
            }
        }

      /* These should generally be unset for added and deleted files,
         and contain whatever information we have for copied files. Let's
         just store whatever we have.

         Note: cmt_rev is the distinguishing value. The others may be 0 or
         NULL if the corresponding revprop has been deleted.  */
      if (working_node->presence != svn_wc__db_status_base_deleted)
        {
          working_node->changed_rev = entry->cmt_rev;
          working_node->changed_date = entry->cmt_date;
          working_node->changed_author = entry->cmt_author;
        }

      if (entry->schedule == svn_wc_schedule_delete
          && parent_node->work
          && parent_node->work->presence == svn_wc__db_status_base_deleted)
        {
          working_node->op_depth = parent_node->work->op_depth;
        }
      else if (working_node->presence == svn_wc__db_status_excluded
               && parent_node->work)
        {
          working_node->op_depth = parent_node->work->op_depth;
        }
      else if (!entry->copied)
        {
          working_node->op_depth
            = svn_wc__db_op_depth_for_upgrade(local_relpath);
        }

      SVN_ERR(insert_node(sdb, working_node, scratch_pool));
    }

  /* Insert the actual node. */
  if (actual_node)
    {
      actual_node = MAYBE_ALLOC(actual_node, scratch_pool);

      actual_node->wc_id = wc_id;
      actual_node->local_relpath = local_relpath;
      actual_node->parent_relpath = parent_relpath;

      SVN_ERR(insert_actual_node(sdb, db, tmp_entry_abspath,
                                 actual_node, scratch_pool));
    }

  if (entry_node)
    {
      *entry_node = apr_palloc(result_pool, sizeof(**entry_node));
      (*entry_node)->base = base_node;
      (*entry_node)->work = working_node;
      (*entry_node)->below_work = below_working_node;
      (*entry_node)->tree_conflicts = tree_conflicts;
    }

  if (entry->file_external_path)
    {
      /* TODO: Maybe add a file external registration inside EXTERNALS here,
               to allow removing file externals that aren't referenced from
               svn:externals.

         The svn:externals values are processed anyway after everything is
         upgraded */
    }

  return SVN_NO_ERROR;
}

static svn_error_t *
write_actual_only_entries(apr_hash_t *tree_conflicts,
                          svn_sqlite__db_t *sdb,
                          svn_wc__db_t *db,
                          const char *wri_abspath,
                          apr_int64_t wc_id,
                          const char *parent_relpath,
                          apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(scratch_pool, tree_conflicts);
       hi;
       hi = apr_hash_next(hi))
    {
      db_actual_node_t *actual_node = NULL;

      actual_node = MAYBE_ALLOC(actual_node, scratch_pool);
      actual_node->wc_id = wc_id;
      actual_node->local_relpath = apr_hash_this_key(hi);
      actual_node->parent_relpath = parent_relpath;
      actual_node->tree_conflict_data = apr_hash_this_val(hi);

      SVN_ERR(insert_actual_node(sdb, db, wri_abspath, actual_node,
                                 scratch_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__write_upgraded_entries(void **dir_baton,
                               void *parent_baton,
                               svn_wc__db_t *db,
                               svn_sqlite__db_t *sdb,
                               apr_int64_t repos_id,
                               apr_int64_t wc_id,
                               const char *dir_abspath,
                               const char *new_root_abspath,
                               apr_hash_t *entries,
                               apr_hash_t *text_bases_info,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
{
  const svn_wc_entry_t *this_dir;
  apr_hash_index_t *hi;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  const char *old_root_abspath, *dir_relpath;
  struct write_baton *parent_node = parent_baton;
  struct write_baton *dir_node;

  /* Get a copy of the "this dir" entry for comparison purposes. */
  this_dir = svn_hash_gets(entries, SVN_WC_ENTRY_THIS_DIR);

  /* If there is no "this dir" entry, something is wrong. */
  if (! this_dir)
    return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
                             _("No default entry in directory '%s'"),
                             svn_dirent_local_style(dir_abspath,
                                                    iterpool));
  old_root_abspath = svn_dirent_get_longest_ancestor(dir_abspath,
                                                     new_root_abspath,
                                                     scratch_pool);

  SVN_ERR_ASSERT(old_root_abspath[0]);

  dir_relpath = svn_dirent_skip_ancestor(old_root_abspath, dir_abspath);

  /* Write out "this dir" */
  SVN_ERR(write_entry(&dir_node, parent_node, db, sdb,
                      wc_id, repos_id, this_dir, NULL, dir_relpath,
                      svn_dirent_join(new_root_abspath, dir_relpath,
                                      iterpool),
                      old_root_abspath,
                      this_dir, FALSE, result_pool, iterpool));

  for (hi = apr_hash_first(scratch_pool, entries); hi;
       hi = apr_hash_next(hi))
    {
      const char *name = apr_hash_this_key(hi);
      const svn_wc_entry_t *this_entry = apr_hash_this_val(hi);
      const char *child_abspath, *child_relpath;
      svn_wc__text_base_info_t *text_base_info
        = svn_hash_gets(text_bases_info, name);

      svn_pool_clear(iterpool);

      /* Don't rewrite the "this dir" entry! */
      if (strcmp(name, SVN_WC_ENTRY_THIS_DIR) == 0)
        continue;

      /* Write the entry. Pass TRUE for create locks, because we still
         use this function for upgrading old working copies. */
      child_abspath = svn_dirent_join(dir_abspath, name, iterpool);
      child_relpath = svn_dirent_skip_ancestor(old_root_abspath, child_abspath);
      SVN_ERR(write_entry(NULL, dir_node, db, sdb,
                          wc_id, repos_id,
                          this_entry, text_base_info, child_relpath,
                          svn_dirent_join(new_root_abspath, child_relpath,
                                          iterpool),
                          old_root_abspath,
                          this_dir, TRUE, iterpool, iterpool));
    }

  if (dir_node->tree_conflicts)
    SVN_ERR(write_actual_only_entries(dir_node->tree_conflicts, sdb, db,
                                      new_root_abspath, wc_id, dir_relpath,
                                      iterpool));

  *dir_baton = dir_node;
  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}


svn_wc_entry_t *
svn_wc_entry_dup(const svn_wc_entry_t *entry, apr_pool_t *pool)
{
  svn_wc_entry_t *dupentry = apr_palloc(pool, sizeof(*dupentry));

  /* Perform a trivial copy ... */
  *dupentry = *entry;

  /* ...and then re-copy stuff that needs to be duped into our pool. */
  if (entry->name)
    dupentry->name = apr_pstrdup(pool, entry->name);
  if (entry->url)
    dupentry->url = apr_pstrdup(pool, entry->url);
  if (entry->repos)
    dupentry->repos = apr_pstrdup(pool, entry->repos);
  if (entry->uuid)
    dupentry->uuid = apr_pstrdup(pool, entry->uuid);
  if (entry->copyfrom_url)
    dupentry->copyfrom_url = apr_pstrdup(pool, entry->copyfrom_url);
  if (entry->conflict_old)
    dupentry->conflict_old = apr_pstrdup(pool, entry->conflict_old);
  if (entry->conflict_new)
    dupentry->conflict_new = apr_pstrdup(pool, entry->conflict_new);
  if (entry->conflict_wrk)
    dupentry->conflict_wrk = apr_pstrdup(pool, entry->conflict_wrk);
  if (entry->prejfile)
    dupentry->prejfile = apr_pstrdup(pool, entry->prejfile);
  if (entry->checksum)
    dupentry->checksum = apr_pstrdup(pool, entry->checksum);
  if (entry->cmt_author)
    dupentry->cmt_author = apr_pstrdup(pool, entry->cmt_author);
  if (entry->lock_token)
    dupentry->lock_token = apr_pstrdup(pool, entry->lock_token);
  if (entry->lock_owner)
    dupentry->lock_owner = apr_pstrdup(pool, entry->lock_owner);
  if (entry->lock_comment)
    dupentry->lock_comment = apr_pstrdup(pool, entry->lock_comment);
  if (entry->changelist)
    dupentry->changelist = apr_pstrdup(pool, entry->changelist);

  /* NOTE: we do not dup cachable_props or present_props since they
     are deprecated. Use "" to indicate "nothing cachable or cached". */
  dupentry->cachable_props = "";
  dupentry->present_props = "";

  if (entry->tree_conflict_data)
    dupentry->tree_conflict_data = apr_pstrdup(pool,
                                               entry->tree_conflict_data);
  if (entry->file_external_path)
    dupentry->file_external_path = apr_pstrdup(pool,
                                               entry->file_external_path);
  return dupentry;
}


/*** Generic Entry Walker */

/* A recursive entry-walker, helper for svn_wc_walk_entries3().
 *
 * For this directory (DIRPATH, ADM_ACCESS), call the "found_entry" callback
 * in WALK_CALLBACKS, passing WALK_BATON to it. Then, for each versioned
 * entry in this directory, call the "found entry" callback and then recurse
 * (if it is a directory and if DEPTH allows).
 *
 * If SHOW_HIDDEN is true, include entries that are in a 'deleted' or
 * 'absent' state (and not scheduled for re-addition), else skip them.
 *
 * Call CANCEL_FUNC with CANCEL_BATON to allow cancellation.
 */
static svn_error_t *
walker_helper(const char *dirpath,
              svn_wc_adm_access_t *adm_access,
              const svn_wc_entry_callbacks2_t *walk_callbacks,
              void *walk_baton,
              svn_depth_t depth,
              svn_boolean_t show_hidden,
              svn_cancel_func_t cancel_func,
              void *cancel_baton,
              apr_pool_t *pool)
{
  apr_pool_t *subpool = svn_pool_create(pool);
  apr_hash_t *entries;
  apr_hash_index_t *hi;
  svn_wc_entry_t *dot_entry;
  svn_error_t *err;
  svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);

  err = svn_wc__entries_read_internal(&entries, adm_access, show_hidden,
                                      pool);

  if (err)
    SVN_ERR(walk_callbacks->handle_error(dirpath, err, walk_baton, pool));

  /* As promised, always return the '.' entry first. */
  dot_entry = svn_hash_gets(entries, SVN_WC_ENTRY_THIS_DIR);
  if (! dot_entry)
    return walk_callbacks->handle_error
      (dirpath, svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
                                  _("Directory '%s' has no THIS_DIR entry"),
                                  svn_dirent_local_style(dirpath, pool)),
       walk_baton, pool);

  /* Call the "found entry" callback for this directory as a "this dir"
   * entry. Note that if this directory has been reached by recursion, this
   * is the second visit as it will already have been visited once as a
   * child entry of its parent. */

  err = walk_callbacks->found_entry(dirpath, dot_entry, walk_baton, subpool);


  if(err)
    SVN_ERR(walk_callbacks->handle_error(dirpath, err, walk_baton, pool));

  if (depth == svn_depth_empty)
    return SVN_NO_ERROR;

  /* Loop over each of the other entries. */
  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
    {
      const char *name = apr_hash_this_key(hi);
      const svn_wc_entry_t *current_entry = apr_hash_this_val(hi);
      const char *entrypath;
      const char *entry_abspath;
      svn_boolean_t hidden;

      svn_pool_clear(subpool);

      /* See if someone wants to cancel this operation. */
      if (cancel_func)
        SVN_ERR(cancel_func(cancel_baton));

      /* Skip the "this dir" entry. */
      if (strcmp(current_entry->name, SVN_WC_ENTRY_THIS_DIR) == 0)
        continue;

      entrypath = svn_dirent_join(dirpath, name, subpool);
      SVN_ERR(svn_wc__entry_is_hidden(&hidden, current_entry));
      SVN_ERR(svn_dirent_get_absolute(&entry_abspath, entrypath, subpool));

      /* Call the "found entry" callback for this entry. (For a directory,
       * this is the first visit: as a child.) */
      if (current_entry->kind == svn_node_file
          || depth >= svn_depth_immediates)
        {
          err = walk_callbacks->found_entry(entrypath, current_entry,
                                            walk_baton, subpool);

          if (err)
            SVN_ERR(walk_callbacks->handle_error(entrypath, err,
                                                 walk_baton, pool));
        }

      /* Recurse into this entry if appropriate. */
      if (current_entry->kind == svn_node_dir
          && !hidden
          && depth >= svn_depth_immediates)
        {
          svn_wc_adm_access_t *entry_access;
          svn_depth_t depth_below_here = depth;

          if (depth == svn_depth_immediates)
            depth_below_here = svn_depth_empty;

          entry_access = svn_wc__adm_retrieve_internal2(db, entry_abspath,
                                                        subpool);

          if (entry_access)
            SVN_ERR(walker_helper(entrypath, entry_access,
                                  walk_callbacks, walk_baton,
                                  depth_below_here, show_hidden,
                                  cancel_func, cancel_baton,
                                  subpool));
        }
    }

  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}

svn_error_t *
svn_wc__walker_default_error_handler(const char *path,
                                     svn_error_t *err,
                                     void *walk_baton,
                                     apr_pool_t *pool)
{
  /* Note: don't trace this. We don't want to insert a false "stack frame"
     onto an error generated elsewhere.  */
  return svn_error_trace(err);
}


/* The public API. */
svn_error_t *
svn_wc_walk_entries3(const char *path,
                     svn_wc_adm_access_t *adm_access,
                     const svn_wc_entry_callbacks2_t *walk_callbacks,
                     void *walk_baton,
                     svn_depth_t walk_depth,
                     svn_boolean_t show_hidden,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     apr_pool_t *pool)
{
  const char *local_abspath;
  svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
  svn_error_t *err;
  svn_node_kind_t kind;
  svn_wc__db_status_t status;

  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
  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,
                             db, local_abspath,
                             pool, pool);
  if (err)
    {
      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
        return svn_error_trace(err);
      /* Remap into SVN_ERR_UNVERSIONED_RESOURCE.  */
      svn_error_clear(err);
      return walk_callbacks->handle_error(
        path, svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                                _("'%s' is not under version control"),
                                svn_dirent_local_style(local_abspath, pool)),
        walk_baton, pool);
    }

  if (kind == svn_node_file
      || status == svn_wc__db_status_excluded
      || status == svn_wc__db_status_server_excluded)
    {
      const svn_wc_entry_t *entry;

      /* ### we should stop passing out entry structures.
         ###
         ### we should not call handle_error for an error the *callback*
         ###   gave us. let it deal with the problem before returning.  */

      if (!show_hidden
          && (status == svn_wc__db_status_not_present
              || status == svn_wc__db_status_excluded
              || status == svn_wc__db_status_server_excluded))
        {
          /* The fool asked to walk a "hidden" node. Report the node as
              unversioned.

              ### this is incorrect behavior. see depth_test 36. the walk
              ### API will be revamped to avoid entry structures. we should
              ### be able to solve the problem with the new API. (since we
              ### shouldn't return a hidden entry here)  */
          return walk_callbacks->handle_error(
                            path, svn_error_createf(
                              SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                              _("'%s' is not under version control"),
                              svn_dirent_local_style(local_abspath, pool)),
                            walk_baton, pool);
        }

      SVN_ERR(svn_wc__get_entry(&entry, db, local_abspath, FALSE,
                                svn_node_file, pool, pool));

      err = walk_callbacks->found_entry(path, entry, walk_baton, pool);
      if (err)
        return walk_callbacks->handle_error(path, err, walk_baton, pool);

      return SVN_NO_ERROR;
    }

  if (kind == svn_node_dir)
    return walker_helper(path, adm_access, walk_callbacks, walk_baton,
                         walk_depth, show_hidden, cancel_func, cancel_baton,
                         pool);

  return walk_callbacks->handle_error(
       path, svn_error_createf(SVN_ERR_NODE_UNKNOWN_KIND, NULL,
                               _("'%s' has an unrecognized node kind"),
                               svn_dirent_local_style(local_abspath, pool)),
       walk_baton, pool);
}
