/* dump.c --- writing filesystem contents into a portable 'dumpfile' format.
 *
 * ====================================================================
 *    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 <stdarg.h>

#include "svn_private_config.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_fs.h"
#include "svn_hash.h"
#include "svn_iter.h"
#include "svn_repos.h"
#include "svn_string.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_time.h"
#include "svn_checksum.h"
#include "svn_props.h"
#include "svn_sorts.h"

#include "private/svn_repos_private.h"
#include "private/svn_mergeinfo_private.h"
#include "private/svn_fs_private.h"
#include "private/svn_sorts_private.h"
#include "private/svn_utf_private.h"
#include "private/svn_cache.h"
#include "private/svn_fspath.h"

#define ARE_VALID_COPY_ARGS(p,r) ((p) && SVN_IS_VALID_REVNUM(r))

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

/* To be able to check whether a path exists in the current revision
   (as changes come in), we need to track the relevant tree changes.

   In particular, we remember deletions, additions and copies including
   their copy-from info.  Since the dump performs a pre-order tree walk,
   we only need to store the data for the stack of parent folders.

   The problem that we are trying to solve is that the dump receives
   transforming operations whose validity depends on previous operations
   in the same revision but cannot be checked against the final state
   as stored in the repository as that is the state *after* we applied
   the respective tree changes.

   Note that the tracker functions don't perform any sanity or validity
   checks.  Those higher-level tests have to be done in the calling code.
   However, there is no way to corrupt the data structure using the
   provided functions.
 */

/* Single entry in the path tracker.  Not all levels along the path
   hierarchy do need to have an instance of this struct but only those
   that got changed by a tree modification.

   Please note that the path info in this struct is stored in re-usable
   stringbuf objects such that we don't need to allocate more memory than
   the longest path we encounter.
 */
typedef struct path_tracker_entry_t
{
  /* path in the current tree */
  svn_stringbuf_t *path;

  /* copy-from path (must be empty if COPYFROM_REV is SVN_INVALID_REVNUM) */
  svn_stringbuf_t *copyfrom_path;

  /* copy-from revision (SVN_INVALID_REVNUM for additions / replacements
     that don't copy history, i.e. with no sub-tree) */
  svn_revnum_t copyfrom_rev;

  /* if FALSE, PATH has been deleted */
  svn_boolean_t exists;
} path_tracker_entry_t;

/* Tracks all tree modifications above the current path.
 */
typedef struct path_tracker_t
{
  /* Container for all relevant tree changes in depth order.
     May contain more entries than DEPTH to allow for reusing memory.
     Only entries 0 .. DEPTH-1 are valid.
   */
  apr_array_header_t *stack;

  /* Number of relevant entries in STACK.  May be 0 */
  int depth;

  /* Revision that we current track.  If DEPTH is 0, paths are exist in
     REVISION exactly when they exist in REVISION-1.  This applies only
     to the current state of our tree walk.
   */
  svn_revnum_t revision;

  /* Allocate container entries here. */
  apr_pool_t *pool;
} path_tracker_t;

/* Return a new path tracker object for REVISION, allocated in POOL.
 */
static path_tracker_t *
tracker_create(svn_revnum_t revision,
               apr_pool_t *pool)
{
  path_tracker_t *result = apr_pcalloc(pool, sizeof(*result));
  result->stack = apr_array_make(pool, 16, sizeof(path_tracker_entry_t));
  result->revision = revision;
  result->pool = pool;

  return result;
}

/* Remove all entries from TRACKER that are not relevant to PATH anymore.
 * If ALLOW_EXACT_MATCH is FALSE, keep only entries that pertain to
 * parent folders but not to PATH itself.
 *
 * This internal function implicitly updates the tracker state during the
 * tree by removing "past" entries.  Other functions will add entries when
 * we encounter a new tree change.
 */
static void
tracker_trim(path_tracker_t *tracker,
             const char *path,
             svn_boolean_t allow_exact_match)
{
  /* remove everything that is unrelated to PATH.
     Note that TRACKER->STACK is depth-ordered,
     i.e. stack[N] is a (maybe indirect) parent of stack[N+1]
     for N+1 < DEPTH.
   */
  for (; tracker->depth; --tracker->depth)
    {
      path_tracker_entry_t *parent = &APR_ARRAY_IDX(tracker->stack,
                                                    tracker->depth - 1,
                                                    path_tracker_entry_t);
      const char *rel_path
        = svn_dirent_skip_ancestor(parent->path->data, path);

      /* always keep parents.  Keep exact matches when allowed. */
      if (rel_path && (allow_exact_match || *rel_path != '\0'))
        break;
    }
}

/* Using TRACKER, check what path at what revision in the repository must
   be checked to decide that whether PATH exists.  Return the info in
   *ORIG_PATH and *ORIG_REV, respectively.

   If the path is known to not exist, *ORIG_PATH will be NULL and *ORIG_REV
   will be SVN_INVALID_REVNUM.  If *ORIG_REV is SVN_INVALID_REVNUM, PATH
   has just been added in the revision currently being tracked.

   Use POOL for allocations.  Note that *ORIG_PATH may be allocated in POOL,
   a reference to internal data with the same lifetime as TRACKER or just
   PATH.
 */
static void
tracker_lookup(const char **orig_path,
               svn_revnum_t *orig_rev,
               path_tracker_t *tracker,
               const char *path,
               apr_pool_t *pool)
{
  tracker_trim(tracker, path, TRUE);
  if (tracker->depth == 0)
    {
      /* no tree changes -> paths are the same as in the previous rev. */
      *orig_path = path;
      *orig_rev = tracker->revision - 1;
    }
  else
    {
      path_tracker_entry_t *parent = &APR_ARRAY_IDX(tracker->stack,
                                                    tracker->depth - 1,
                                                    path_tracker_entry_t);
      if (parent->exists)
        {
          const char *rel_path
            = svn_dirent_skip_ancestor(parent->path->data, path);

          if (parent->copyfrom_rev != SVN_INVALID_REVNUM)
            {
              /* parent is a copy with history. Translate path. */
              *orig_path = svn_dirent_join(parent->copyfrom_path->data,
                                           rel_path, pool);
              *orig_rev = parent->copyfrom_rev;
            }
          else if (*rel_path == '\0')
            {
              /* added in this revision with no history */
              *orig_path = path;
              *orig_rev = tracker->revision;
            }
          else
            {
              /* parent got added but not this path */
              *orig_path = NULL;
              *orig_rev = SVN_INVALID_REVNUM;
            }
        }
      else
        {
          /* (maybe parent) path has been deleted */
          *orig_path = NULL;
          *orig_rev = SVN_INVALID_REVNUM;
        }
    }
}

/* Return a reference to the stack entry in TRACKER for PATH.  If no
   suitable entry exists, add one.  Implicitly updates the tracked tree
   location.

   Only the PATH member of the result is being updated.  All other members
   will have undefined values.
 */
static path_tracker_entry_t *
tracker_add_entry(path_tracker_t *tracker,
                  const char *path)
{
  path_tracker_entry_t *entry;
  tracker_trim(tracker, path, FALSE);

  if (tracker->depth == tracker->stack->nelts)
    {
      entry = apr_array_push(tracker->stack);
      entry->path = svn_stringbuf_create_empty(tracker->pool);
      entry->copyfrom_path = svn_stringbuf_create_empty(tracker->pool);
    }
  else
    {
      entry = &APR_ARRAY_IDX(tracker->stack, tracker->depth,
                             path_tracker_entry_t);
    }

  svn_stringbuf_set(entry->path, path);
  ++tracker->depth;

  return entry;
}

/* Update the TRACKER with a copy from COPYFROM_PATH@COPYFROM_REV to
   PATH in the tracked revision.
 */
static void
tracker_path_copy(path_tracker_t *tracker,
                  const char *path,
                  const char *copyfrom_path,
                  svn_revnum_t copyfrom_rev)
{
  path_tracker_entry_t *entry = tracker_add_entry(tracker, path);

  svn_stringbuf_set(entry->copyfrom_path, copyfrom_path);
  entry->copyfrom_rev = copyfrom_rev;
  entry->exists = TRUE;
}

/* Update the TRACKER with a plain addition of PATH (without history).
 */
static void
tracker_path_add(path_tracker_t *tracker,
                 const char *path)
{
  path_tracker_entry_t *entry = tracker_add_entry(tracker, path);

  svn_stringbuf_setempty(entry->copyfrom_path);
  entry->copyfrom_rev = SVN_INVALID_REVNUM;
  entry->exists = TRUE;
}

/* Update the TRACKER with a replacement of PATH with a plain addition
   (without history).
 */
static void
tracker_path_replace(path_tracker_t *tracker,
                     const char *path)
{
  /* this will implicitly purge all previous sub-tree info from STACK.
     Thus, no need to tack the deletion explicitly. */
  tracker_path_add(tracker, path);
}

/* Update the TRACKER with a deletion of PATH.
 */
static void
tracker_path_delete(path_tracker_t *tracker,
                    const char *path)
{
  path_tracker_entry_t *entry = tracker_add_entry(tracker, path);

  svn_stringbuf_setempty(entry->copyfrom_path);
  entry->copyfrom_rev = SVN_INVALID_REVNUM;
  entry->exists = FALSE;
}


/* Compute the delta between OLDROOT/OLDPATH and NEWROOT/NEWPATH and
   store it into a new temporary file *TEMPFILE.  OLDROOT may be NULL,
   in which case the delta will be computed against an empty file, as
   per the svn_fs_get_file_delta_stream docstring.  Record the length
   of the temporary file in *LEN, and rewind the file before
   returning. */
static svn_error_t *
store_delta(apr_file_t **tempfile, svn_filesize_t *len,
            svn_fs_root_t *oldroot, const char *oldpath,
            svn_fs_root_t *newroot, const char *newpath, apr_pool_t *pool)
{
  svn_stream_t *temp_stream;
  apr_off_t offset;
  svn_txdelta_stream_t *delta_stream;
  svn_txdelta_window_handler_t wh;
  void *whb;

  /* Create a temporary file and open a stream to it. Note that we need
     the file handle in order to rewind it. */
  SVN_ERR(svn_io_open_unique_file3(tempfile, NULL, NULL,
                                   svn_io_file_del_on_pool_cleanup,
                                   pool, pool));
  temp_stream = svn_stream_from_aprfile2(*tempfile, TRUE, pool);

  /* Compute the delta and send it to the temporary file. */
  SVN_ERR(svn_fs_get_file_delta_stream(&delta_stream, oldroot, oldpath,
                                       newroot, newpath, pool));
  svn_txdelta_to_svndiff3(&wh, &whb, temp_stream, 0,
                          SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, pool);
  SVN_ERR(svn_txdelta_send_txstream(delta_stream, wh, whb, pool));

  /* Get the length of the temporary file and rewind it. */
  SVN_ERR(svn_io_file_get_offset(&offset, *tempfile, pool));
  *len = offset;
  offset = 0;
  return svn_io_file_seek(*tempfile, APR_SET, &offset, pool);
}


/* Send a notification of type #svn_repos_notify_warning, subtype WARNING,
   with message WARNING_FMT formatted with the remaining variable arguments.
   Send it by calling NOTIFY_FUNC (if not null) with NOTIFY_BATON.
 */
__attribute__((format(printf, 5, 6)))
static void
notify_warning(apr_pool_t *scratch_pool,
               svn_repos_notify_func_t notify_func,
               void *notify_baton,
               svn_repos_notify_warning_t warning,
               const char *warning_fmt,
               ...)
{
  va_list va;
  svn_repos_notify_t *notify;

  if (notify_func == NULL)
    return;

  notify = svn_repos_notify_create(svn_repos_notify_warning, scratch_pool);
  notify->warning = warning;
  va_start(va, warning_fmt);
  notify->warning_str = apr_pvsprintf(scratch_pool, warning_fmt, va);
  va_end(va);

  notify_func(notify_baton, notify, scratch_pool);
}


/*----------------------------------------------------------------------*/

/* Write to STREAM the header in HEADERS named KEY, if present.
 */
static svn_error_t *
write_header(svn_stream_t *stream,
             apr_hash_t *headers,
             const char *key,
             apr_pool_t *scratch_pool)
{
  const char *val = svn_hash_gets(headers, key);

  if (val)
    {
      SVN_ERR(svn_stream_printf(stream, scratch_pool,
                                "%s: %s\n", key, val));
    }
  return SVN_NO_ERROR;
}

/* Write headers, in arbitrary order.
 * ### TODO: use a stable order
 * ### Modifies HEADERS.
 */
static svn_error_t *
write_revision_headers(svn_stream_t *stream,
                       apr_hash_t *headers,
                       apr_pool_t *scratch_pool)
{
  const char **h;
  apr_hash_index_t *hi;

  static const char *revision_headers_order[] =
  {
    SVN_REPOS_DUMPFILE_REVISION_NUMBER,  /* must be first */
    NULL
  };

  /* Write some headers in a given order */
  for (h = revision_headers_order; *h; h++)
    {
      SVN_ERR(write_header(stream, headers, *h, scratch_pool));
      svn_hash_sets(headers, *h, NULL);
    }

  /* Write any and all remaining headers except Content-length.
   * ### TODO: use a stable order
   */
  for (hi = apr_hash_first(scratch_pool, headers); hi; hi = apr_hash_next(hi))
    {
      const char *key = apr_hash_this_key(hi);

      if (strcmp(key, SVN_REPOS_DUMPFILE_CONTENT_LENGTH) != 0)
        SVN_ERR(write_header(stream, headers, key, scratch_pool));
    }

  /* Content-length must be last */
  SVN_ERR(write_header(stream, headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
                       scratch_pool));

  return SVN_NO_ERROR;
}

/* A header entry: the element type of the apr_array_header_t which is
 * the real type of svn_repos__dumpfile_headers_t.
 */
typedef struct svn_repos__dumpfile_header_entry_t {
  const char *key, *val;
} svn_repos__dumpfile_header_entry_t;

svn_repos__dumpfile_headers_t *
svn_repos__dumpfile_headers_create(apr_pool_t *pool)
{
  svn_repos__dumpfile_headers_t *headers
    = apr_array_make(pool, 5, sizeof(svn_repos__dumpfile_header_entry_t));

  return headers;
}

void
svn_repos__dumpfile_header_push(svn_repos__dumpfile_headers_t *headers,
                                const char *key,
                                const char *val)
{
  svn_repos__dumpfile_header_entry_t *h
    = &APR_ARRAY_PUSH(headers, svn_repos__dumpfile_header_entry_t);

  h->key = apr_pstrdup(headers->pool, key);
  h->val = apr_pstrdup(headers->pool, val);
}

void
svn_repos__dumpfile_header_pushf(svn_repos__dumpfile_headers_t *headers,
                                 const char *key,
                                 const char *val_fmt,
                                 ...)
{
  va_list ap;
  svn_repos__dumpfile_header_entry_t *h
    = &APR_ARRAY_PUSH(headers, svn_repos__dumpfile_header_entry_t);

  h->key = apr_pstrdup(headers->pool, key);
  va_start(ap, val_fmt);
  h->val = apr_pvsprintf(headers->pool, val_fmt, ap);
  va_end(ap);
}

svn_error_t *
svn_repos__dump_headers(svn_stream_t *stream,
                        svn_repos__dumpfile_headers_t *headers,
                        apr_pool_t *scratch_pool)
{
  int i;

  for (i = 0; i < headers->nelts; i++)
    {
      svn_repos__dumpfile_header_entry_t *h
        = &APR_ARRAY_IDX(headers, i, svn_repos__dumpfile_header_entry_t);

      SVN_ERR(svn_stream_printf(stream, scratch_pool,
                                "%s: %s\n", h->key, h->val));
    }

  /* End of headers */
  SVN_ERR(svn_stream_puts(stream, "\n"));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_repos__dump_magic_header_record(svn_stream_t *dump_stream,
                                    int version,
                                    apr_pool_t *pool)
{
  SVN_ERR(svn_stream_printf(dump_stream, pool,
                            SVN_REPOS_DUMPFILE_MAGIC_HEADER ": %d\n\n",
                            version));
  return SVN_NO_ERROR;
}

svn_error_t *
svn_repos__dump_uuid_header_record(svn_stream_t *dump_stream,
                                   const char *uuid,
                                   apr_pool_t *pool)
{
  if (uuid)
    {
      SVN_ERR(svn_stream_printf(dump_stream, pool, SVN_REPOS_DUMPFILE_UUID
                                ": %s\n\n", uuid));
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_repos__dump_revision_record(svn_stream_t *dump_stream,
                                svn_revnum_t revision,
                                apr_hash_t *extra_headers,
                                apr_hash_t *revprops,
                                svn_boolean_t props_section_always,
                                apr_pool_t *scratch_pool)
{
  svn_stringbuf_t *propstring = NULL;
  apr_hash_t *headers;

  if (extra_headers)
    headers = apr_hash_copy(scratch_pool, extra_headers);
  else
    headers = apr_hash_make(scratch_pool);

  /* ### someday write a revision-content-checksum */

  svn_hash_sets(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER,
                apr_psprintf(scratch_pool, "%ld", revision));

  if (apr_hash_count(revprops) || props_section_always)
    {
      svn_stream_t *propstream;

      propstring = svn_stringbuf_create_empty(scratch_pool);
      propstream = svn_stream_from_stringbuf(propstring, scratch_pool);
      SVN_ERR(svn_hash_write2(revprops, propstream, "PROPS-END", scratch_pool));
      SVN_ERR(svn_stream_close(propstream));

      svn_hash_sets(headers, SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH,
                    apr_psprintf(scratch_pool,
                                 "%" APR_SIZE_T_FMT, propstring->len));
    }

  if (propstring)
    {
      /* Write out a regular Content-length header for the benefit of
         non-Subversion RFC-822 parsers. */
      svn_hash_sets(headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
                    apr_psprintf(scratch_pool,
                                 "%" APR_SIZE_T_FMT, propstring->len));
    }

  SVN_ERR(write_revision_headers(dump_stream, headers, scratch_pool));

  /* End of headers */
  SVN_ERR(svn_stream_puts(dump_stream, "\n"));

  /* Property data. */
  if (propstring)
    {
      SVN_ERR(svn_stream_write(dump_stream, propstring->data, &propstring->len));
    }

  /* put an end to revision */
  SVN_ERR(svn_stream_puts(dump_stream, "\n"));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_repos__dump_node_record(svn_stream_t *dump_stream,
                            svn_repos__dumpfile_headers_t *headers,
                            svn_stringbuf_t *props_str,
                            svn_boolean_t has_text,
                            svn_filesize_t text_content_length,
                            svn_boolean_t content_length_always,
                            apr_pool_t *scratch_pool)
{
  svn_filesize_t content_length = 0;

  /* add content-length headers */
  if (props_str)
    {
      svn_repos__dumpfile_header_pushf(
        headers, SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH,
        "%" APR_SIZE_T_FMT, props_str->len);
      content_length += props_str->len;
    }
  if (has_text)
    {
      svn_repos__dumpfile_header_pushf(
        headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH,
        "%" SVN_FILESIZE_T_FMT, text_content_length);
      content_length += text_content_length;
    }
  if (content_length_always || props_str || has_text)
    {
      svn_repos__dumpfile_header_pushf(
        headers, SVN_REPOS_DUMPFILE_CONTENT_LENGTH,
        "%" SVN_FILESIZE_T_FMT, content_length);
    }

  /* write the headers */
  SVN_ERR(svn_repos__dump_headers(dump_stream, headers, scratch_pool));

  /* write the props */
  if (props_str)
    {
      SVN_ERR(svn_stream_write(dump_stream, props_str->data, &props_str->len));
    }
  return SVN_NO_ERROR;
}

/*----------------------------------------------------------------------*/

/** An editor which dumps node-data in 'dumpfile format' to a file. **/

/* Look, mom!  No file batons! */

struct edit_baton
{
  /* The relpath which implicitly prepends all full paths coming into
     this editor.  This will almost always be "".  */
  const char *path;

  /* The stream to dump to. */
  svn_stream_t *stream;

  /* Send feedback here, if non-NULL */
  svn_repos_notify_func_t notify_func;
  void *notify_baton;

  /* The fs revision root, so we can read the contents of paths. */
  svn_fs_root_t *fs_root;
  svn_revnum_t current_rev;

  /* The fs, so we can grab historic information if needed. */
  svn_fs_t *fs;

  /* True if dumped nodes should output deltas instead of full text. */
  svn_boolean_t use_deltas;

  /* True if this "dump" is in fact a verify. */
  svn_boolean_t verify;

  /* True if checking UCS normalization during a verify. */
  svn_boolean_t check_normalization;

  /* The first revision dumped in this dumpstream. */
  svn_revnum_t oldest_dumped_rev;

  /* If not NULL, set to true if any references to revisions older than
     OLDEST_DUMPED_REV were found in the dumpstream. */
  svn_boolean_t *found_old_reference;

  /* If not NULL, set to true if any mergeinfo was dumped which contains
     revisions older than OLDEST_DUMPED_REV. */
  svn_boolean_t *found_old_mergeinfo;

  /* Structure allows us to verify the paths currently being dumped.
     If NULL, validity checks are being skipped. */
  path_tracker_t *path_tracker;
};

struct dir_baton
{
  struct edit_baton *edit_baton;

  /* has this directory been written to the output stream? */
  svn_boolean_t written_out;

  /* the repository relpath associated with this directory */
  const char *path;

  /* The comparison repository relpath and revision of this directory.
     If both of these are valid, use them as a source against which to
     compare the directory instead of the default comparison source of
     PATH in the previous revision. */
  const char *cmp_path;
  svn_revnum_t cmp_rev;

  /* hash of paths that need to be deleted, though some -might- be
     replaced.  maps const char * paths to this dir_baton.  (they're
     full paths, because that's what the editor driver gives us.  but
     really, they're all within this directory.) */
  apr_hash_t *deleted_entries;

  /* A flag indicating that new entries have been added to this
     directory in this revision. Used to optimize detection of UCS
     representation collisions; we will only check for that in
     revisions where new names appear in the directory. */
  svn_boolean_t check_name_collision;

  /* pool to be used for deleting the hash items */
  apr_pool_t *pool;
};


/* Make a directory baton to represent the directory was path
   (relative to EDIT_BATON's path) is PATH.

   CMP_PATH/CMP_REV are the path/revision against which this directory
   should be compared for changes.  If either is omitted (NULL for the
   path, SVN_INVALID_REVNUM for the rev), just compare this directory
   PATH against itself in the previous revision.

   PB is the directory baton of this directory's parent,
   or NULL if this is the top-level directory of the edit.

   Perform all allocations in POOL.  */
static struct svn_error_t *
make_dir_baton(struct dir_baton **dbp,
               const char *path,
               const char *cmp_path,
               svn_revnum_t cmp_rev,
               void *edit_baton,
               struct dir_baton *pb,
               apr_pool_t *pool)
{
  struct edit_baton *eb = edit_baton;
  struct dir_baton *new_db = apr_pcalloc(pool, sizeof(*new_db));
  const char *full_path, *canonicalized_path;

  /* A path relative to nothing?  I don't think so. */
  SVN_ERR_ASSERT(!path || pb);

  /* Construct the full path of this node. */
  if (pb)
    full_path = svn_relpath_join(eb->path, path, pool);
  else
    full_path = apr_pstrdup(pool, eb->path);

  /* Remove leading slashes from copyfrom paths. */
  if (cmp_path)
    {
      SVN_ERR(svn_relpath_canonicalize_safe(&canonicalized_path, NULL,
                                            cmp_path, pool, pool));
      cmp_path = canonicalized_path;
    }

  new_db->edit_baton = eb;
  new_db->path = full_path;
  new_db->cmp_path = cmp_path;
  new_db->cmp_rev = cmp_rev;
  new_db->written_out = FALSE;
  new_db->deleted_entries = apr_hash_make(pool);
  new_db->check_name_collision = FALSE;
  new_db->pool = pool;

  *dbp = new_db;
  return SVN_NO_ERROR;
}

static svn_error_t *
fetch_kind_func(svn_node_kind_t *kind,
                void *baton,
                const char *path,
                svn_revnum_t base_revision,
                apr_pool_t *scratch_pool);

/* Return an error when PATH in REVISION does not exist or is of a
   different kind than EXPECTED_KIND.  If the latter is svn_node_unknown,
   skip that check.  Use EB for context information.  If REVISION is the
   current revision, use EB's path tracker to follow renames, deletions,
   etc.

   Use SCRATCH_POOL for temporary allocations.
   No-op if EB's path tracker has not been initialized.
 */
static svn_error_t *
node_must_exist(struct edit_baton *eb,
                const char *path,
                svn_revnum_t revision,
                svn_node_kind_t expected_kind,
                apr_pool_t *scratch_pool)
{
  svn_node_kind_t kind = svn_node_none;

  /* in case the caller is trying something stupid ... */
  if (eb->path_tracker == NULL)
    return SVN_NO_ERROR;

  /* paths pertaining to the revision currently being processed must
     be translated / checked using our path tracker. */
  if (revision == eb->path_tracker->revision)
    tracker_lookup(&path, &revision, eb->path_tracker, path, scratch_pool);

  /* determine the node type (default: no such node) */
  if (path)
    SVN_ERR(fetch_kind_func(&kind, eb, path, revision, scratch_pool));

  /* check results */
  if (kind == svn_node_none)
    return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
                             _("Path '%s' not found in r%ld."),
                             path, revision);

  if (expected_kind != kind && expected_kind != svn_node_unknown)
    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                             _("Unexpected node kind %d for '%s' at r%ld. "
                               "Expected kind was %d."),
                             kind, path, revision, expected_kind);

  return SVN_NO_ERROR;
}

/* Return an error when PATH exists in REVISION.  Use EB for context
   information.  If REVISION is the current revision, use EB's path
   tracker to follow renames, deletions, etc.

   Use SCRATCH_POOL for temporary allocations.
   No-op if EB's path tracker has not been initialized.
 */
static svn_error_t *
node_must_not_exist(struct edit_baton *eb,
                    const char *path,
                    svn_revnum_t revision,
                    apr_pool_t *scratch_pool)
{
  svn_node_kind_t kind = svn_node_none;

  /* in case the caller is trying something stupid ... */
  if (eb->path_tracker == NULL)
    return SVN_NO_ERROR;

  /* paths pertaining to the revision currently being processed must
     be translated / checked using our path tracker. */
  if (revision == eb->path_tracker->revision)
    tracker_lookup(&path, &revision, eb->path_tracker, path, scratch_pool);

  /* determine the node type (default: no such node) */
  if (path)
    SVN_ERR(fetch_kind_func(&kind, eb, path, revision, scratch_pool));

  /* check results */
  if (kind != svn_node_none)
    return svn_error_createf(SVN_ERR_FS_ALREADY_EXISTS, NULL,
                             _("Path '%s' exists in r%ld."),
                             path, revision);

  return SVN_NO_ERROR;
}

/* If the mergeinfo in MERGEINFO_STR refers to any revisions older than
 * OLDEST_DUMPED_REV, issue a warning and set *FOUND_OLD_MERGEINFO to TRUE,
 * otherwise leave *FOUND_OLD_MERGEINFO unchanged.
 */
static svn_error_t *
verify_mergeinfo_revisions(svn_boolean_t *found_old_mergeinfo,
                           const char *mergeinfo_str,
                           svn_revnum_t oldest_dumped_rev,
                           svn_repos_notify_func_t notify_func,
                           void *notify_baton,
                           apr_pool_t *pool)
{
  svn_mergeinfo_t mergeinfo, old_mergeinfo;

  SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_str, pool));
  SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
            &old_mergeinfo, mergeinfo,
            oldest_dumped_rev - 1, 0,
            TRUE, pool, pool));

  if (apr_hash_count(old_mergeinfo))
    {
      notify_warning(pool, notify_func, notify_baton,
                     svn_repos_notify_warning_found_old_mergeinfo,
                     _("Mergeinfo referencing revision(s) prior "
                       "to the oldest dumped revision (r%ld). "
                       "Loading this dump may result in invalid "
                       "mergeinfo."),
                     oldest_dumped_rev);

      if (found_old_mergeinfo)
        *found_old_mergeinfo = TRUE;
    }

  return SVN_NO_ERROR;
}

/* Unique string pointers used by verify_mergeinfo_normalization()
   and check_name_collision() */
static const char normalized_unique[] = "normalized_unique";
static const char normalized_collision[] = "normalized_collision";


/* Baton for extract_mergeinfo_paths */
struct extract_mergeinfo_paths_baton
{
  apr_hash_t *result;
  svn_boolean_t normalize;
  svn_membuf_t buffer;
};

/* Hash iterator that uniquifies all keys into a single hash table,
   optionally normalizing them first. */
static svn_error_t *
extract_mergeinfo_paths(void *baton, const void *key, apr_ssize_t klen,
                         void *val, apr_pool_t *iterpool)
{
  struct extract_mergeinfo_paths_baton *const xb = baton;
  if (xb->normalize)
    {
      const char *normkey;
      SVN_ERR(svn_utf__normalize(&normkey, key, klen, &xb->buffer));
      svn_hash_sets(xb->result,
                    apr_pstrdup(xb->buffer.pool, normkey),
                    normalized_unique);
    }
  else
    apr_hash_set(xb->result,
                 apr_pmemdup(xb->buffer.pool, key, klen + 1), klen,
                 normalized_unique);
  return SVN_NO_ERROR;
}

/* Baton for filter_mergeinfo_paths */
struct filter_mergeinfo_paths_baton
{
  apr_hash_t *paths;
};

/* Compare two sets of denormalized paths from mergeinfo entries,
   removing duplicates. */
static svn_error_t *
filter_mergeinfo_paths(void *baton, const void *key, apr_ssize_t klen,
                       void *val, apr_pool_t *iterpool)
{
  struct filter_mergeinfo_paths_baton *const fb = baton;

  if (apr_hash_get(fb->paths, key, klen))
    apr_hash_set(fb->paths, key, klen, NULL);

  return SVN_NO_ERROR;
}

/* Baton used by the check_mergeinfo_normalization hash iterator. */
struct verify_mergeinfo_normalization_baton
{
  const char* path;
  apr_hash_t *normalized_paths;
  svn_membuf_t buffer;
  svn_repos_notify_func_t notify_func;
  void *notify_baton;
};

/* Hash iterator that verifies normalization and collision of paths in
   an svn:mergeinfo property. */
static svn_error_t *
verify_mergeinfo_normalization(void *baton, const void *key, apr_ssize_t klen,
                               void *val, apr_pool_t *iterpool)
{
  struct verify_mergeinfo_normalization_baton *const vb = baton;

  const char *const path = key;
  const char *normpath;
  const char *found;

  SVN_ERR(svn_utf__normalize(&normpath, path, klen, &vb->buffer));
  found = svn_hash_gets(vb->normalized_paths, normpath);
  if (!found)
      svn_hash_sets(vb->normalized_paths,
                    apr_pstrdup(vb->buffer.pool, normpath),
                    normalized_unique);
  else if (found == normalized_collision)
    /* Skip already reported collision */;
  else
    {
      /* Report path collision in mergeinfo */
      svn_hash_sets(vb->normalized_paths,
                    apr_pstrdup(vb->buffer.pool, normpath),
                    normalized_collision);

      notify_warning(iterpool, vb->notify_func, vb->notify_baton,
                     svn_repos_notify_warning_mergeinfo_collision,
                     _("Duplicate representation of path '%s'"
                       " in %s property of '%s'"),
                     normpath, SVN_PROP_MERGEINFO, vb->path);
    }
  return SVN_NO_ERROR;
}

/* Check UCS normalization of mergeinfo for PATH. NEW_MERGEINFO is the
   svn:mergeinfo property value being set; OLD_MERGEINFO is the
   previous property value, which may be NULL. Only the paths that
   were added in are checked, including collision checks. This
   minimizes the number of notifications we generate for a given
   mergeinfo property. */
static svn_error_t *
check_mergeinfo_normalization(const char *path,
                              const char *new_mergeinfo,
                              const char *old_mergeinfo,
                              svn_repos_notify_func_t notify_func,
                              void *notify_baton,
                              apr_pool_t *pool)
{
  svn_mergeinfo_t mergeinfo;
  apr_hash_t *normalized_paths;
  apr_hash_t *added_paths;
  struct extract_mergeinfo_paths_baton extract_baton;
  struct verify_mergeinfo_normalization_baton verify_baton;

  SVN_ERR(svn_mergeinfo_parse(&mergeinfo, new_mergeinfo, pool));

  extract_baton.result = apr_hash_make(pool);
  extract_baton.normalize = FALSE;
  svn_membuf__create(&extract_baton.buffer, 0, pool);
  SVN_ERR(svn_iter_apr_hash(NULL, mergeinfo,
                            extract_mergeinfo_paths,
                            &extract_baton, pool));
  added_paths = extract_baton.result;

  if (old_mergeinfo)
    {
      struct filter_mergeinfo_paths_baton filter_baton;
      svn_mergeinfo_t oldinfo;

      extract_baton.result = apr_hash_make(pool);
      extract_baton.normalize = TRUE;
      SVN_ERR(svn_mergeinfo_parse(&oldinfo, old_mergeinfo, pool));
      SVN_ERR(svn_iter_apr_hash(NULL, oldinfo,
                                extract_mergeinfo_paths,
                                &extract_baton, pool));
      normalized_paths = extract_baton.result;

      filter_baton.paths = added_paths;
      SVN_ERR(svn_iter_apr_hash(NULL, oldinfo,
                                filter_mergeinfo_paths,
                                &filter_baton, pool));
    }
  else
      normalized_paths = apr_hash_make(pool);

  verify_baton.path = path;
  verify_baton.normalized_paths = normalized_paths;
  verify_baton.buffer = extract_baton.buffer;
  verify_baton.notify_func = notify_func;
  verify_baton.notify_baton = notify_baton;
  SVN_ERR(svn_iter_apr_hash(NULL, added_paths,
                            verify_mergeinfo_normalization,
                            &verify_baton, pool));

  return SVN_NO_ERROR;
}


/* A special case of dump_node(), for a delete record.
 *
 * The only thing special about this version is it only writes one blank
 * line, not two, after the headers. Why? Historical precedent for the
 * case where a delete record is used as part of a (delete + add-with-history)
 * in implementing a replacement.
 *
 * Also it doesn't do a path-tracker check.
 */
static svn_error_t *
dump_node_delete(svn_stream_t *stream,
                 const char *node_relpath,
                 apr_pool_t *pool)
{
  svn_repos__dumpfile_headers_t *headers
    = svn_repos__dumpfile_headers_create(pool);

  /* Node-path: ... */
  svn_repos__dumpfile_header_push(
    headers, SVN_REPOS_DUMPFILE_NODE_PATH, node_relpath);

  /* Node-action: delete */
  svn_repos__dumpfile_header_push(
    headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");

  SVN_ERR(svn_repos__dump_headers(stream, headers, pool));
  return SVN_NO_ERROR;
}

/* This helper is the main "meat" of the editor -- it does all the
   work of writing a node record.

   Write out a node record for PATH of type KIND under EB->FS_ROOT.
   ACTION describes what is happening to the node (see enum svn_node_action).
   Write record to writable EB->STREAM.

   If the node was itself copied, IS_COPY is TRUE and the
   path/revision of the copy source are in CMP_PATH/CMP_REV.  If
   IS_COPY is FALSE, yet CMP_PATH/CMP_REV are valid, this node is part
   of a copied subtree.
  */
static svn_error_t *
dump_node(struct edit_baton *eb,
          const char *path,
          svn_node_kind_t kind,
          enum svn_node_action action,
          svn_boolean_t is_copy,
          const char *cmp_path,
          svn_revnum_t cmp_rev,
          apr_pool_t *pool)
{
  svn_stringbuf_t *propstring;
  apr_size_t len;
  svn_boolean_t must_dump_text = FALSE, must_dump_props = FALSE;
  const char *compare_path = path;
  svn_revnum_t compare_rev = eb->current_rev - 1;
  svn_fs_root_t *compare_root = NULL;
  apr_file_t *delta_file = NULL;
  svn_repos__dumpfile_headers_t *headers
    = svn_repos__dumpfile_headers_create(pool);
  svn_filesize_t textlen;

  /* Maybe validate the path. */
  if (eb->verify || eb->notify_func)
    {
      svn_error_t *err = svn_fs__path_valid(path, pool);

      if (err)
        {
          if (eb->notify_func)
            {
              char errbuf[512]; /* ### svn_strerror() magic number  */

              notify_warning(pool, eb->notify_func, eb->notify_baton,
                             svn_repos_notify_warning_invalid_fspath,
                             _("E%06d: While validating fspath '%s': %s"),
                             err->apr_err, path,
                             svn_err_best_message(err, errbuf, sizeof(errbuf)));
            }

          /* Return the error in addition to notifying about it. */
          if (eb->verify)
            return svn_error_trace(err);
          else
            svn_error_clear(err);
        }
    }

  /* Write out metadata headers for this file node. */
  svn_repos__dumpfile_header_push(
    headers, SVN_REPOS_DUMPFILE_NODE_PATH, path);
  if (kind == svn_node_file)
    svn_repos__dumpfile_header_push(
      headers, SVN_REPOS_DUMPFILE_NODE_KIND, "file");
  else if (kind == svn_node_dir)
    svn_repos__dumpfile_header_push(
      headers, SVN_REPOS_DUMPFILE_NODE_KIND, "dir");

  /* Remove leading slashes from copyfrom paths. */
  if (cmp_path)
    {
      const char *canonicalized_path;
      SVN_ERR(svn_relpath_canonicalize_safe(&canonicalized_path, NULL,
                                            cmp_path, pool, pool));
      cmp_path = canonicalized_path;
    }

  /* Validate the comparison path/rev. */
  if (ARE_VALID_COPY_ARGS(cmp_path, cmp_rev))
    {
      compare_path = cmp_path;
      compare_rev = cmp_rev;
    }

  switch (action)
    {
    case svn_node_action_change:
      if (eb->path_tracker)
        SVN_ERR_W(node_must_exist(eb, path, eb->current_rev, kind, pool),
                  apr_psprintf(pool, _("Change invalid path '%s' in r%ld"),
                               path, eb->current_rev));

      svn_repos__dumpfile_header_push(
        headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "change");

      /* either the text or props changed, or possibly both. */
      SVN_ERR(svn_fs_revision_root(&compare_root,
                                   svn_fs_root_fs(eb->fs_root),
                                   compare_rev, pool));

      SVN_ERR(svn_fs_props_changed(&must_dump_props,
                                   compare_root, compare_path,
                                   eb->fs_root, path, pool));
      if (kind == svn_node_file)
        SVN_ERR(svn_fs_contents_changed(&must_dump_text,
                                        compare_root, compare_path,
                                        eb->fs_root, path, pool));
      break;

    case svn_node_action_delete:
      if (eb->path_tracker)
        {
          SVN_ERR_W(node_must_exist(eb, path, eb->current_rev, kind, pool),
                    apr_psprintf(pool, _("Deleting invalid path '%s' in r%ld"),
                                 path, eb->current_rev));
          tracker_path_delete(eb->path_tracker, path);
        }

      svn_repos__dumpfile_header_push(
        headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "delete");

      /* we can leave this routine quietly now, don't need to dump
         any content. */
      must_dump_text = FALSE;
      must_dump_props = FALSE;
      break;

    case svn_node_action_replace:
      if (eb->path_tracker)
        SVN_ERR_W(node_must_exist(eb, path, eb->current_rev,
                                  svn_node_unknown, pool),
                  apr_psprintf(pool,
                               _("Replacing non-existent path '%s' in r%ld"),
                               path, eb->current_rev));

      if (! is_copy)
        {
          if (eb->path_tracker)
            tracker_path_replace(eb->path_tracker, path);

          /* a simple delete+add, implied by a single 'replace' action. */
          svn_repos__dumpfile_header_push(
            headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "replace");

          /* definitely need to dump all content for a replace. */
          if (kind == svn_node_file)
            must_dump_text = TRUE;
          must_dump_props = TRUE;
          break;
        }
      else
        {
          /* more complex:  delete original, then add-with-history.  */
          /* ### Why not write a 'replace' record? Don't know. */

          if (eb->path_tracker)
            {
              tracker_path_delete(eb->path_tracker, path);
            }

          /* ### Unusually, we end this 'delete' node record with only a single
                 blank line after the header block -- no extra blank line. */
          SVN_ERR(dump_node_delete(eb->stream, path, pool));

          /* The remaining action is a non-replacing add-with-history */
          /* action = svn_node_action_add; */
        }
      /* FALL THROUGH to 'add' */

    case svn_node_action_add:
      if (eb->path_tracker)
        SVN_ERR_W(node_must_not_exist(eb, path, eb->current_rev, pool),
                  apr_psprintf(pool,
                               _("Adding already existing path '%s' in r%ld"),
                               path, eb->current_rev));

      svn_repos__dumpfile_header_push(
        headers, SVN_REPOS_DUMPFILE_NODE_ACTION, "add");

      if (! is_copy)
        {
          if (eb->path_tracker)
            tracker_path_add(eb->path_tracker, path);

          /* Dump all contents for a simple 'add'. */
          if (kind == svn_node_file)
            must_dump_text = TRUE;
          must_dump_props = TRUE;
        }
      else
        {
          if (eb->path_tracker)
            {
              SVN_ERR_W(node_must_exist(eb, compare_path, compare_rev,
                                        kind, pool),
                        apr_psprintf(pool,
                                     _("Copying from invalid path to "
                                       "'%s' in r%ld"),
                                     path, eb->current_rev));
              tracker_path_copy(eb->path_tracker, path, compare_path,
                                compare_rev);
            }

          if (!eb->verify && cmp_rev < eb->oldest_dumped_rev
              && eb->notify_func)
            {
              notify_warning(pool, eb->notify_func, eb->notify_baton,
                             svn_repos_notify_warning_found_old_reference,
                             _("Referencing data in revision %ld,"
                               " which is older than the oldest"
                               " dumped revision (r%ld).  Loading this dump"
                               " into an empty repository"
                               " will fail."),
                             cmp_rev, eb->oldest_dumped_rev);
              if (eb->found_old_reference)
                *eb->found_old_reference = TRUE;
            }

          svn_repos__dumpfile_header_pushf(
            headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV, "%ld", cmp_rev);
          svn_repos__dumpfile_header_push(
            headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH, cmp_path);

          SVN_ERR(svn_fs_revision_root(&compare_root,
                                       svn_fs_root_fs(eb->fs_root),
                                       compare_rev, pool));

          /* Need to decide if the copied node had any extra textual or
             property mods as well.  */
          SVN_ERR(svn_fs_props_changed(&must_dump_props,
                                       compare_root, compare_path,
                                       eb->fs_root, path, pool));
          if (kind == svn_node_file)
            {
              svn_checksum_t *checksum;
              const char *hex_digest;
              SVN_ERR(svn_fs_contents_changed(&must_dump_text,
                                              compare_root, compare_path,
                                              eb->fs_root, path, pool));

              SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5,
                                           compare_root, compare_path,
                                           FALSE, pool));
              hex_digest = svn_checksum_to_cstring(checksum, pool);
              if (hex_digest)
                svn_repos__dumpfile_header_push(
                  headers, SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_MD5, hex_digest);

              SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
                                           compare_root, compare_path,
                                           FALSE, pool));
              hex_digest = svn_checksum_to_cstring(checksum, pool);
              if (hex_digest)
                svn_repos__dumpfile_header_push(
                  headers, SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_SHA1, hex_digest);
            }
        }
      break;
    }

  if ((! must_dump_text) && (! must_dump_props))
    {
      /* If we're not supposed to dump text or props, so be it, we can
         just go home.  However, if either one needs to be dumped,
         then our dumpstream format demands that at a *minimum*, we
         see a lone "PROPS-END" as a divider between text and props
         content within the content-block. */
      SVN_ERR(svn_repos__dump_headers(eb->stream, headers, pool));
      len = 1;
      return svn_stream_write(eb->stream, "\n", &len); /* ### needed? */
    }

  /*** Start prepping content to dump... ***/

  /* If we are supposed to dump properties, write out a property
     length header and generate a stringbuf that contains those
     property values here. */
  if (must_dump_props)
    {
      apr_hash_t *prophash, *oldhash = NULL;
      svn_stream_t *propstream;

      SVN_ERR(svn_fs_node_proplist(&prophash, eb->fs_root, path, pool));

      /* If this is a partial dump, then issue a warning if we dump mergeinfo
         properties that refer to revisions older than the first revision
         dumped. */
      if (!eb->verify && eb->notify_func && eb->oldest_dumped_rev > 1)
        {
          svn_string_t *mergeinfo_str = svn_hash_gets(prophash,
                                                      SVN_PROP_MERGEINFO);
          if (mergeinfo_str)
            {
              /* An error in verifying the mergeinfo must not prevent dumping
                 the data. Ignore any such error. */
              svn_error_clear(verify_mergeinfo_revisions(
                                eb->found_old_mergeinfo,
                                mergeinfo_str->data, eb->oldest_dumped_rev,
                                eb->notify_func, eb->notify_baton,
                                pool));
            }
        }

      /* If we're checking UCS normalization, also parse any changed
         mergeinfo and warn about denormalized paths and name
         collisions there. */
      if (eb->verify && eb->check_normalization && eb->notify_func)
        {
          /* N.B.: This hash lookup happens only once; the conditions
             for verifying historic mergeinfo references and checking
             UCS normalization are mutually exclusive. */
          svn_string_t *mergeinfo_str = svn_hash_gets(prophash,
                                                      SVN_PROP_MERGEINFO);
          if (mergeinfo_str)
            {
              svn_string_t *oldinfo_str = NULL;
              if (compare_root)
                {
                  SVN_ERR(svn_fs_node_proplist(&oldhash,
                                               compare_root, compare_path,
                                               pool));
                  oldinfo_str = svn_hash_gets(oldhash, SVN_PROP_MERGEINFO);
                }
              SVN_ERR(check_mergeinfo_normalization(
                          path, mergeinfo_str->data,
                          (oldinfo_str ? oldinfo_str->data : NULL),
                          eb->notify_func, eb->notify_baton, pool));
            }
        }

      if (eb->use_deltas && compare_root)
        {
          /* Fetch the old property hash to diff against and output a header
             saying that our property contents are a delta. */
          if (!oldhash)         /* May have been set for normalization check */
            SVN_ERR(svn_fs_node_proplist(&oldhash, compare_root, compare_path,
                                         pool));
          svn_repos__dumpfile_header_push(
            headers, SVN_REPOS_DUMPFILE_PROP_DELTA, "true");
        }
      else
        oldhash = apr_hash_make(pool);
      propstring = svn_stringbuf_create_ensure(0, pool);
      propstream = svn_stream_from_stringbuf(propstring, pool);
      SVN_ERR(svn_hash_write_incremental(prophash, oldhash, propstream,
                                         "PROPS-END", pool));
      SVN_ERR(svn_stream_close(propstream));
    }

  /* If we are supposed to dump text, write out a text length header
     here, and an MD5 checksum (if available). */
  if (must_dump_text && (kind == svn_node_file))
    {
      svn_checksum_t *checksum;
      const char *hex_digest;

      if (eb->use_deltas)
        {
          /* Compute the text delta now and write it into a temporary
             file, so that we can find its length.  Output a header
             saying our text contents are a delta. */
          SVN_ERR(store_delta(&delta_file, &textlen, compare_root,
                              compare_path, eb->fs_root, path, pool));
          svn_repos__dumpfile_header_push(
            headers, SVN_REPOS_DUMPFILE_TEXT_DELTA, "true");

          if (compare_root)
            {
              SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5,
                                           compare_root, compare_path,
                                           FALSE, pool));
              hex_digest = svn_checksum_to_cstring(checksum, pool);
              if (hex_digest)
                svn_repos__dumpfile_header_push(
                  headers, SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_MD5, hex_digest);

              SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
                                           compare_root, compare_path,
                                           FALSE, pool));
              hex_digest = svn_checksum_to_cstring(checksum, pool);
              if (hex_digest)
                svn_repos__dumpfile_header_push(
                  headers, SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_SHA1, hex_digest);
            }
        }
      else
        {
          /* Just fetch the length of the file. */
          SVN_ERR(svn_fs_file_length(&textlen, eb->fs_root, path, pool));
        }

      SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5,
                                   eb->fs_root, path, FALSE, pool));
      hex_digest = svn_checksum_to_cstring(checksum, pool);
      if (hex_digest)
        svn_repos__dumpfile_header_push(
          headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_MD5, hex_digest);

      SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
                                   eb->fs_root, path, FALSE, pool));
      hex_digest = svn_checksum_to_cstring(checksum, pool);
      if (hex_digest)
        svn_repos__dumpfile_header_push(
          headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_SHA1, hex_digest);
    }

  /* 'Content-length:' is the last header before we dump the content,
     and is the sum of the text and prop contents lengths.  We write
     this only for the benefit of non-Subversion RFC-822 parsers. */
  SVN_ERR(svn_repos__dump_node_record(eb->stream, headers,
                                      must_dump_props ? propstring : NULL,
                                      must_dump_text,
                                      must_dump_text ? textlen : 0,
                                      TRUE /*content_length_always*/,
                                      pool));

  /* Dump text content */
  if (must_dump_text && (kind == svn_node_file))
    {
      svn_stream_t *contents;

      if (delta_file)
        {
          /* Make sure to close the underlying file when the stream is
             closed. */
          contents = svn_stream_from_aprfile2(delta_file, FALSE, pool);
        }
      else
        SVN_ERR(svn_fs_file_contents(&contents, eb->fs_root, path, pool));

      SVN_ERR(svn_stream_copy3(contents, svn_stream_disown(eb->stream, pool),
                               NULL, NULL, pool));
    }

  len = 2;
  return svn_stream_write(eb->stream, "\n\n", &len); /* ### needed? */
}


static svn_error_t *
open_root(void *edit_baton,
          svn_revnum_t base_revision,
          apr_pool_t *pool,
          void **root_baton)
{
  return svn_error_trace(make_dir_baton((struct dir_baton **)root_baton,
                                        NULL, NULL, SVN_INVALID_REVNUM,
                                        edit_baton, NULL, pool));
}


static svn_error_t *
delete_entry(const char *path,
             svn_revnum_t revision,
             void *parent_baton,
             apr_pool_t *pool)
{
  struct dir_baton *pb = parent_baton;
  const char *mypath = apr_pstrdup(pb->pool, path);

  /* remember this path needs to be deleted. */
  svn_hash_sets(pb->deleted_entries, mypath, pb);

  return SVN_NO_ERROR;
}


static svn_error_t *
add_directory(const char *path,
              void *parent_baton,
              const char *copyfrom_path,
              svn_revnum_t copyfrom_rev,
              apr_pool_t *pool,
              void **child_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  void *was_deleted;
  svn_boolean_t is_copy = FALSE;
  struct dir_baton *new_db;

  SVN_ERR(make_dir_baton(&new_db, path, copyfrom_path, copyfrom_rev, eb,
                         pb, pool));

  /* This might be a replacement -- is the path already deleted? */
  was_deleted = svn_hash_gets(pb->deleted_entries, path);

  /* Detect an add-with-history. */
  is_copy = ARE_VALID_COPY_ARGS(copyfrom_path, copyfrom_rev);

  /* Dump the node. */
  SVN_ERR(dump_node(eb, path,
                    svn_node_dir,
                    was_deleted ? svn_node_action_replace : svn_node_action_add,
                    is_copy,
                    is_copy ? copyfrom_path : NULL,
                    is_copy ? copyfrom_rev : SVN_INVALID_REVNUM,
                    pool));

  if (was_deleted)
    /* Delete the path, it's now been dumped. */
    svn_hash_sets(pb->deleted_entries, path, NULL);

  /* Check for normalized name clashes, but only if this is actually a
     new name in the parent, not a replacement. */
  if (!was_deleted && eb->verify && eb->check_normalization && eb->notify_func)
    {
      pb->check_name_collision = TRUE;
    }

  new_db->written_out = TRUE;

  *child_baton = new_db;
  return SVN_NO_ERROR;
}


static svn_error_t *
open_directory(const char *path,
               void *parent_baton,
               svn_revnum_t base_revision,
               apr_pool_t *pool,
               void **child_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct dir_baton *new_db;
  const char *cmp_path = NULL;
  svn_revnum_t cmp_rev = SVN_INVALID_REVNUM;

  /* If the parent directory has explicit comparison path and rev,
     record the same for this one. */
  if (ARE_VALID_COPY_ARGS(pb->cmp_path, pb->cmp_rev))
    {
      cmp_path = svn_relpath_join(pb->cmp_path,
                                  svn_relpath_basename(path, pool), pool);
      cmp_rev = pb->cmp_rev;
    }

  SVN_ERR(make_dir_baton(&new_db, path, cmp_path, cmp_rev, eb, pb, pool));
  *child_baton = new_db;
  return SVN_NO_ERROR;
}


static svn_error_t *
close_directory(void *dir_baton,
                apr_pool_t *pool)
{
  struct dir_baton *db = dir_baton;
  struct edit_baton *eb = db->edit_baton;
  apr_pool_t *subpool = svn_pool_create(pool);
  int i;
  apr_array_header_t *sorted_entries;

  /* Sort entries lexically instead of as paths. Even though the entries
   * are full paths they're all in the same directory (see comment in struct
   * dir_baton definition). So we really want to sort by basename, in which
   * case the lexical sort function is more efficient. */
  sorted_entries = svn_sort__hash(db->deleted_entries,
                                  svn_sort_compare_items_lexically, pool);
  for (i = 0; i < sorted_entries->nelts; i++)
    {
      const char *path = APR_ARRAY_IDX(sorted_entries, i,
                                       svn_sort__item_t).key;

      svn_pool_clear(subpool);

      /* By sending 'svn_node_unknown', the Node-kind: header simply won't
         be written out.  No big deal at all, really.  The loader
         shouldn't care.  */
      SVN_ERR(dump_node(eb, path,
                        svn_node_unknown, svn_node_action_delete,
                        FALSE, NULL, SVN_INVALID_REVNUM, subpool));
    }

  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}


static svn_error_t *
add_file(const char *path,
         void *parent_baton,
         const char *copyfrom_path,
         svn_revnum_t copyfrom_rev,
         apr_pool_t *pool,
         void **file_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  void *was_deleted;
  svn_boolean_t is_copy = FALSE;

  /* This might be a replacement -- is the path already deleted? */
  was_deleted = svn_hash_gets(pb->deleted_entries, path);

  /* Detect add-with-history. */
  is_copy = ARE_VALID_COPY_ARGS(copyfrom_path, copyfrom_rev);

  /* Dump the node. */
  SVN_ERR(dump_node(eb, path,
                    svn_node_file,
                    was_deleted ? svn_node_action_replace : svn_node_action_add,
                    is_copy,
                    is_copy ? copyfrom_path : NULL,
                    is_copy ? copyfrom_rev : SVN_INVALID_REVNUM,
                    pool));

  if (was_deleted)
    /* delete the path, it's now been dumped. */
    svn_hash_sets(pb->deleted_entries, path, NULL);

  /* Check for normalized name clashes, but only if this is actually a
     new name in the parent, not a replacement. */
  if (!was_deleted && eb->verify && eb->check_normalization && eb->notify_func)
    {
      pb->check_name_collision = TRUE;
    }

  *file_baton = NULL;  /* muhahahaha */
  return SVN_NO_ERROR;
}


static svn_error_t *
open_file(const char *path,
          void *parent_baton,
          svn_revnum_t ancestor_revision,
          apr_pool_t *pool,
          void **file_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  const char *cmp_path = NULL;
  svn_revnum_t cmp_rev = SVN_INVALID_REVNUM;

  /* If the parent directory has explicit comparison path and rev,
     record the same for this one. */
  if (ARE_VALID_COPY_ARGS(pb->cmp_path, pb->cmp_rev))
    {
      cmp_path = svn_relpath_join(pb->cmp_path,
                                  svn_relpath_basename(path, pool), pool);
      cmp_rev = pb->cmp_rev;
    }

  SVN_ERR(dump_node(eb, path,
                    svn_node_file, svn_node_action_change,
                    FALSE, cmp_path, cmp_rev, pool));

  *file_baton = NULL;  /* muhahahaha again */
  return SVN_NO_ERROR;
}


static svn_error_t *
change_dir_prop(void *parent_baton,
                const char *name,
                const svn_string_t *value,
                apr_pool_t *pool)
{
  struct dir_baton *db = parent_baton;
  struct edit_baton *eb = db->edit_baton;

  /* This function is what distinguishes between a directory that is
     opened to merely get somewhere, vs. one that is opened because it
     *actually* changed by itself.

     Instead of recording the prop changes here, we just use this method
     to trigger writing the node; dump_node() finds all the changes. */
  if (! db->written_out)
    {
      SVN_ERR(dump_node(eb, db->path,
                        svn_node_dir, svn_node_action_change,
                        /* ### We pass is_copy=FALSE; this might be wrong
                           but the parameter isn't used when action=change. */
                        FALSE, db->cmp_path, db->cmp_rev, pool));
      db->written_out = TRUE;
    }
  return SVN_NO_ERROR;
}

static svn_error_t *
fetch_props_func(apr_hash_t **props,
                 void *baton,
                 const char *path,
                 svn_revnum_t base_revision,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
{
  struct edit_baton *eb = baton;
  svn_error_t *err;
  svn_fs_root_t *fs_root;

  if (!SVN_IS_VALID_REVNUM(base_revision))
    base_revision = eb->current_rev - 1;

  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));

  err = svn_fs_node_proplist(props, fs_root, path, result_pool);
  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
    {
      svn_error_clear(err);
      *props = apr_hash_make(result_pool);
      return SVN_NO_ERROR;
    }
  else if (err)
    return svn_error_trace(err);

  return SVN_NO_ERROR;
}

static svn_error_t *
fetch_kind_func(svn_node_kind_t *kind,
                void *baton,
                const char *path,
                svn_revnum_t base_revision,
                apr_pool_t *scratch_pool)
{
  struct edit_baton *eb = baton;
  svn_fs_root_t *fs_root;

  if (!SVN_IS_VALID_REVNUM(base_revision))
    base_revision = eb->current_rev - 1;

  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));

  SVN_ERR(svn_fs_check_path(kind, fs_root, path, scratch_pool));

  return SVN_NO_ERROR;
}

static svn_error_t *
fetch_base_func(const char **filename,
                void *baton,
                const char *path,
                svn_revnum_t base_revision,
                apr_pool_t *result_pool,
                apr_pool_t *scratch_pool)
{
  struct edit_baton *eb = baton;
  svn_stream_t *contents;
  svn_stream_t *file_stream;
  const char *tmp_filename;
  svn_error_t *err;
  svn_fs_root_t *fs_root;

  if (!SVN_IS_VALID_REVNUM(base_revision))
    base_revision = eb->current_rev - 1;

  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));

  err = svn_fs_file_contents(&contents, fs_root, path, scratch_pool);
  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
    {
      svn_error_clear(err);
      *filename = NULL;
      return SVN_NO_ERROR;
    }
  else if (err)
    return svn_error_trace(err);
  SVN_ERR(svn_stream_open_unique(&file_stream, &tmp_filename, NULL,
                                 svn_io_file_del_on_pool_cleanup,
                                 scratch_pool, scratch_pool));
  SVN_ERR(svn_stream_copy3(contents, file_stream, NULL, NULL, scratch_pool));

  *filename = apr_pstrdup(result_pool, tmp_filename);

  return SVN_NO_ERROR;
}


static svn_error_t *
get_dump_editor(const svn_delta_editor_t **editor,
                void **edit_baton,
                svn_fs_t *fs,
                svn_revnum_t to_rev,
                const char *root_path,
                svn_stream_t *stream,
                svn_boolean_t *found_old_reference,
                svn_boolean_t *found_old_mergeinfo,
                svn_error_t *(*custom_close_directory)(void *dir_baton,
                                  apr_pool_t *scratch_pool),
                svn_repos_notify_func_t notify_func,
                void *notify_baton,
                svn_revnum_t oldest_dumped_rev,
                svn_boolean_t use_deltas,
                svn_boolean_t verify,
                svn_boolean_t check_normalization,
                apr_pool_t *pool)
{
  /* Allocate an edit baton to be stored in every directory baton.
     Set it up for the directory baton we create here, which is the
     root baton. */
  struct edit_baton *eb = apr_pcalloc(pool, sizeof(*eb));
  svn_delta_editor_t *dump_editor = svn_delta_default_editor(pool);
  svn_delta_shim_callbacks_t *shim_callbacks =
                                svn_delta_shim_callbacks_default(pool);

  /* Set up the edit baton. */
  eb->stream = stream;
  eb->notify_func = notify_func;
  eb->notify_baton = notify_baton;
  eb->oldest_dumped_rev = oldest_dumped_rev;
  eb->path = apr_pstrdup(pool, root_path);
  SVN_ERR(svn_fs_revision_root(&(eb->fs_root), fs, to_rev, pool));
  eb->fs = fs;
  eb->current_rev = to_rev;
  eb->use_deltas = use_deltas;
  eb->verify = verify;
  eb->check_normalization = check_normalization;
  eb->found_old_reference = found_old_reference;
  eb->found_old_mergeinfo = found_old_mergeinfo;

  /* In non-verification mode, we will allow anything to be dumped because
     it might be an incremental dump with possible manual intervention.
     Also, this might be the last resort when it comes to data recovery.

     Else, make sure that all paths exists at their respective revisions.
  */
  eb->path_tracker = verify ? tracker_create(to_rev, pool) : NULL;

  /* Set up the editor. */
  dump_editor->open_root = open_root;
  dump_editor->delete_entry = delete_entry;
  dump_editor->add_directory = add_directory;
  dump_editor->open_directory = open_directory;
  if (custom_close_directory)
    dump_editor->close_directory = custom_close_directory;
  else
    dump_editor->close_directory = close_directory;
  dump_editor->change_dir_prop = change_dir_prop;
  dump_editor->add_file = add_file;
  dump_editor->open_file = open_file;

  *edit_baton = eb;
  *editor = dump_editor;

  shim_callbacks->fetch_kind_func = fetch_kind_func;
  shim_callbacks->fetch_props_func = fetch_props_func;
  shim_callbacks->fetch_base_func = fetch_base_func;
  shim_callbacks->fetch_baton = eb;

  SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
                                   NULL, NULL, shim_callbacks, pool, pool));

  return SVN_NO_ERROR;
}

/*----------------------------------------------------------------------*/

/** The main dumping routine, svn_repos_dump_fs. **/


/* Helper for svn_repos_dump_fs.

   Write a revision record of REV in REPOS to writable STREAM, using POOL.
   Dump revision properties as well if INCLUDE_REVPROPS has been set.
   AUTHZ_FUNC and AUTHZ_BATON are passed directly to the repos layer.
 */
static svn_error_t *
write_revision_record(svn_stream_t *stream,
                      svn_repos_t *repos,
                      svn_revnum_t rev,
                      svn_boolean_t include_revprops,
                      svn_repos_authz_func_t authz_func,
                      void *authz_baton,
                      apr_pool_t *pool)
{
  apr_hash_t *props;

  if (include_revprops)
    {
      SVN_ERR(svn_repos_fs_revision_proplist(&props, repos, rev,
                                             authz_func, authz_baton, pool));
    }
   else
    {
      /* Although we won't use it, we still need this container for the
         call below. */
      props = apr_hash_make(pool);
    }

  SVN_ERR(svn_repos__dump_revision_record(stream, rev, NULL, props,
                                          include_revprops,
                                          pool));
  return SVN_NO_ERROR;
}

/* Baton for dump_filter_authz_func(). */
typedef struct dump_filter_baton_t
{
  svn_repos_dump_filter_func_t filter_func;
  void *filter_baton;
} dump_filter_baton_t;

/* Implements svn_repos_authz_func_t. */
static svn_error_t *
dump_filter_authz_func(svn_boolean_t *allowed,
                       svn_fs_root_t *root,
                       const char *path,
                       void *baton,
                       apr_pool_t *pool)
{
  dump_filter_baton_t *b = baton;

  /* For some nodes (e.g. files under copied directory) PATH may be
   * non-canonical (missing leading '/').  Canonicalize PATH before
   * passing it to FILTER_FUNC. */
  path = svn_fspath__canonicalize(path, pool);

  return svn_error_trace(b->filter_func(allowed, root, path, b->filter_baton,
                                        pool));
}



/* The main dumper. */
svn_error_t *
svn_repos_dump_fs4(svn_repos_t *repos,
                   svn_stream_t *stream,
                   svn_revnum_t start_rev,
                   svn_revnum_t end_rev,
                   svn_boolean_t incremental,
                   svn_boolean_t use_deltas,
                   svn_boolean_t include_revprops,
                   svn_boolean_t include_changes,
                   svn_repos_notify_func_t notify_func,
                   void *notify_baton,
                   svn_repos_dump_filter_func_t filter_func,
                   void *filter_baton,
                   svn_cancel_func_t cancel_func,
                   void *cancel_baton,
                   apr_pool_t *pool)
{
  const svn_delta_editor_t *dump_editor;
  void *dump_edit_baton = NULL;
  svn_revnum_t rev;
  svn_fs_t *fs = svn_repos_fs(repos);
  apr_pool_t *iterpool = svn_pool_create(pool);
  svn_revnum_t youngest;
  const char *uuid;
  int version;
  svn_boolean_t found_old_reference = FALSE;
  svn_boolean_t found_old_mergeinfo = FALSE;
  svn_repos_notify_t *notify;
  svn_repos_authz_func_t authz_func;
  dump_filter_baton_t authz_baton = {0};

  /* Make sure we catch up on the latest revprop changes.  This is the only
   * time we will refresh the revprop data in this query. */
  SVN_ERR(svn_fs_refresh_revision_props(fs, pool));

  /* Determine the current youngest revision of the filesystem. */
  SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));

  /* Use default vals if necessary. */
  if (! SVN_IS_VALID_REVNUM(start_rev))
    start_rev = 0;
  if (! SVN_IS_VALID_REVNUM(end_rev))
    end_rev = youngest;
  if (! stream)
    stream = svn_stream_empty(pool);

  /* Validate the revisions. */
  if (start_rev > end_rev)
    return svn_error_createf(SVN_ERR_REPOS_BAD_ARGS, NULL,
                             _("Start revision %ld"
                               " is greater than end revision %ld"),
                             start_rev, end_rev);
  if (end_rev > youngest)
    return svn_error_createf(SVN_ERR_REPOS_BAD_ARGS, NULL,
                             _("End revision %ld is invalid "
                               "(youngest revision is %ld)"),
                             end_rev, youngest);

  /* We use read authz callback to implement dump filtering. If there is no
   * read access for some node, it will be excluded from dump as well as
   * references to it (e.g. copy source). */
  if (filter_func)
    {
      authz_func = dump_filter_authz_func;
      authz_baton.filter_func = filter_func;
      authz_baton.filter_baton = filter_baton;
    }
  else
    {
      authz_func = NULL;
    }

  /* Write out the UUID. */
  SVN_ERR(svn_fs_get_uuid(fs, &uuid, pool));

  /* If we're not using deltas, use the previous version, for
     compatibility with svn 1.0.x. */
  version = SVN_REPOS_DUMPFILE_FORMAT_VERSION;
  if (!use_deltas)
    version--;

  /* Write out "general" metadata for the dumpfile.  In this case, a
     magic header followed by a dumpfile format version. */
  SVN_ERR(svn_repos__dump_magic_header_record(stream, version, pool));
  SVN_ERR(svn_repos__dump_uuid_header_record(stream, uuid, pool));

  /* Create a notify object that we can reuse in the loop. */
  if (notify_func)
    notify = svn_repos_notify_create(svn_repos_notify_dump_rev_end,
                                     pool);

  /* Main loop:  we're going to dump revision REV.  */
  for (rev = start_rev; rev <= end_rev; rev++)
    {
      svn_fs_root_t *to_root;
      svn_boolean_t use_deltas_for_rev;

      svn_pool_clear(iterpool);

      /* Check for cancellation. */
      if (cancel_func)
        SVN_ERR(cancel_func(cancel_baton));

      /* Write the revision record. */
      SVN_ERR(write_revision_record(stream, repos, rev, include_revprops,
                                    authz_func, &authz_baton, iterpool));

      /* When dumping revision 0, we just write out the revision record.
         The parser might want to use its properties.
         If we don't want revision changes at all, skip in any case. */
      if (rev == 0 || !include_changes)
        goto loop_end;

      /* Fetch the editor which dumps nodes to a file.  Regardless of
         what we've been told, don't use deltas for the first rev of a
         non-incremental dump. */
      use_deltas_for_rev = use_deltas && (incremental || rev != start_rev);
      SVN_ERR(get_dump_editor(&dump_editor, &dump_edit_baton, fs, rev,
                              "", stream, &found_old_reference,
                              &found_old_mergeinfo, NULL,
                              notify_func, notify_baton,
                              start_rev, use_deltas_for_rev, FALSE, FALSE,
                              iterpool));

      /* Drive the editor in one way or another. */
      SVN_ERR(svn_fs_revision_root(&to_root, fs, rev, iterpool));

      /* If this is the first revision of a non-incremental dump,
         we're in for a full tree dump.  Otherwise, we want to simply
         replay the revision.  */
      if ((rev == start_rev) && (! incremental))
        {
          /* Compare against revision 0, so everything appears to be added. */
          svn_fs_root_t *from_root;
          SVN_ERR(svn_fs_revision_root(&from_root, fs, 0, iterpool));
          SVN_ERR(svn_repos_dir_delta2(from_root, "", "",
                                       to_root, "",
                                       dump_editor, dump_edit_baton,
                                       authz_func, &authz_baton,
                                       FALSE, /* don't send text-deltas */
                                       svn_depth_infinity,
                                       FALSE, /* don't send entry props */
                                       FALSE, /* don't ignore ancestry */
                                       iterpool));
        }
      else
        {
          /* The normal case: compare consecutive revs. */
          SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE,
                                    dump_editor, dump_edit_baton,
                                    authz_func, &authz_baton, iterpool));

          /* While our editor close_edit implementation is a no-op, we still
             do this for completeness. */
          SVN_ERR(dump_editor->close_edit(dump_edit_baton, iterpool));
        }

    loop_end:
      if (notify_func)
        {
          notify->revision = rev;
          notify_func(notify_baton, notify, iterpool);
        }
    }

  if (notify_func)
    {
      /* Did we issue any warnings about references to revisions older than
         the oldest dumped revision?  If so, then issue a final generic
         warning, since the inline warnings already issued might easily be
         missed. */

      notify = svn_repos_notify_create(svn_repos_notify_dump_end, iterpool);
      notify_func(notify_baton, notify, iterpool);

      if (found_old_reference)
        {
          notify_warning(iterpool, notify_func, notify_baton,
                         svn_repos_notify_warning_found_old_reference,
                         _("The range of revisions dumped "
                           "contained references to "
                           "copy sources outside that "
                           "range."));
        }

      /* Ditto if we issued any warnings about old revisions referenced
         in dumped mergeinfo. */
      if (found_old_mergeinfo)
        {
          notify_warning(iterpool, notify_func, notify_baton,
                         svn_repos_notify_warning_found_old_mergeinfo,
                         _("The range of revisions dumped "
                           "contained mergeinfo "
                           "which reference revisions outside "
                           "that range."));
        }
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}


/*----------------------------------------------------------------------*/

/* verify, based on dump */


/* Creating a new revision that changes /A/B/E/bravo means creating new
   directory listings for /, /A, /A/B, and /A/B/E in the new revision, with
   each entry not changed in the new revision a link back to the entry in a
   previous revision.  svn_repos_replay()ing a revision does not verify that
   those links are correct.

   For paths actually changed in the revision we verify, we get directory
   contents or file length twice: once in the dump editor, and once here.
   We could create a new verify baton, store in it the changed paths, and
   skip those here, but that means building an entire wrapper editor and
   managing two levels of batons.  The impact from checking these entries
   twice should be minimal, while the code to avoid it is not.
*/

static svn_error_t *
verify_directory_entry(void *baton, const void *key, apr_ssize_t klen,
                       void *val, apr_pool_t *pool)
{
  struct dir_baton *db = baton;
  svn_fs_dirent_t *dirent = (svn_fs_dirent_t *)val;
  char *path;
  svn_boolean_t right_kind;

  path = svn_relpath_join(db->path, (const char *)key, pool);

  /* since we can't access the directory entries directly by their ID,
     we need to navigate from the FS_ROOT to them (relatively expensive
     because we may start at a never rev than the last change to node).
     We check that the node kind stored in the noderev matches the dir
     entry.  This also ensures that all entries point to valid noderevs.
   */
  switch (dirent->kind) {
  case svn_node_dir:
    SVN_ERR(svn_fs_is_dir(&right_kind, db->edit_baton->fs_root, path, pool));
    if (!right_kind)
      return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                               _("Node '%s' is not a directory."),
                               path);

    break;
  case svn_node_file:
    SVN_ERR(svn_fs_is_file(&right_kind, db->edit_baton->fs_root, path, pool));
    if (!right_kind)
      return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                               _("Node '%s' is not a file."),
                               path);
    break;
  default:
    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                             _("Unexpected node kind %d for '%s'"),
                             dirent->kind, path);
  }

  return SVN_NO_ERROR;
}

/* Baton used by the check_name_collision hash iterator. */
struct check_name_collision_baton
{
  struct dir_baton *dir_baton;
  apr_hash_t *normalized;
  svn_membuf_t buffer;
};

/* Scan the directory and report all entry names that differ only in
   Unicode character representation. */
static svn_error_t *
check_name_collision(void *baton, const void *key, apr_ssize_t klen,
                     void *val, apr_pool_t *iterpool)
{
  struct check_name_collision_baton *const cb = baton;
  const char *name;
  const char *found;

  SVN_ERR(svn_utf__normalize(&name, key, klen, &cb->buffer));

  found = svn_hash_gets(cb->normalized, name);
  if (!found)
    svn_hash_sets(cb->normalized, apr_pstrdup(cb->buffer.pool, name),
                  normalized_unique);
  else if (found == normalized_collision)
    /* Skip already reported collision */;
  else
    {
      struct dir_baton *const db = cb->dir_baton;
      struct edit_baton *const eb = db->edit_baton;
      const char* normpath;

      svn_hash_sets(cb->normalized, apr_pstrdup(cb->buffer.pool, name),
                    normalized_collision);

      SVN_ERR(svn_utf__normalize(
                  &normpath, svn_relpath_join(db->path, name, iterpool),
                  SVN_UTF__UNKNOWN_LENGTH, &cb->buffer));
      notify_warning(iterpool, eb->notify_func, eb->notify_baton,
                     svn_repos_notify_warning_name_collision,
                     _("Duplicate representation of path '%s'"), normpath);
    }
  return SVN_NO_ERROR;
}


static svn_error_t *
verify_close_directory(void *dir_baton, apr_pool_t *pool)
{
  struct dir_baton *db = dir_baton;
  apr_hash_t *dirents;
  SVN_ERR(svn_fs_dir_entries(&dirents, db->edit_baton->fs_root,
                             db->path, pool));
  SVN_ERR(svn_iter_apr_hash(NULL, dirents, verify_directory_entry,
                            dir_baton, pool));

  if (db->check_name_collision)
    {
      struct check_name_collision_baton check_baton;
      check_baton.dir_baton = db;
      check_baton.normalized = apr_hash_make(pool);
      svn_membuf__create(&check_baton.buffer, 0, pool);
      SVN_ERR(svn_iter_apr_hash(NULL, dirents, check_name_collision,
                                &check_baton, pool));
    }

  return close_directory(dir_baton, pool);
}

/* Verify revision REV in file system FS. */
static svn_error_t *
verify_one_revision(svn_fs_t *fs,
                    svn_revnum_t rev,
                    svn_repos_notify_func_t notify_func,
                    void *notify_baton,
                    svn_revnum_t start_rev,
                    svn_boolean_t check_normalization,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    apr_pool_t *scratch_pool)
{
  const svn_delta_editor_t *dump_editor;
  void *dump_edit_baton;
  svn_fs_root_t *to_root;
  apr_hash_t *props;
  const svn_delta_editor_t *cancel_editor;
  void *cancel_edit_baton;

  /* Get cancellable dump editor, but with our close_directory handler.*/
  SVN_ERR(get_dump_editor(&dump_editor, &dump_edit_baton,
                          fs, rev, "",
                          svn_stream_empty(scratch_pool),
                          NULL, NULL,
                          verify_close_directory,
                          notify_func, notify_baton,
                          start_rev,
                          FALSE, TRUE, /* use_deltas, verify */
                          check_normalization,
                          scratch_pool));
  SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton,
                                            dump_editor, dump_edit_baton,
                                            &cancel_editor,
                                            &cancel_edit_baton,
                                            scratch_pool));
  SVN_ERR(svn_fs_revision_root(&to_root, fs, rev, scratch_pool));
  SVN_ERR(svn_fs_verify_root(to_root, scratch_pool));
  SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE,
                            cancel_editor, cancel_edit_baton,
                            NULL, NULL, scratch_pool));

  /* While our editor close_edit implementation is a no-op, we still
     do this for completeness. */
  SVN_ERR(cancel_editor->close_edit(cancel_edit_baton, scratch_pool));

  SVN_ERR(svn_fs_revision_proplist2(&props, fs, rev, FALSE, scratch_pool,
                                    scratch_pool));

  return SVN_NO_ERROR;
}

/* Baton type used for forwarding notifications from FS API to REPOS API. */
struct verify_fs_notify_func_baton_t
{
   /* notification function to call (must not be NULL) */
   svn_repos_notify_func_t notify_func;

   /* baton to use for it */
   void *notify_baton;

   /* type of notification to send (we will simply plug in the revision) */
   svn_repos_notify_t *notify;
};

/* Forward the notification to BATON. */
static void
verify_fs_notify_func(svn_revnum_t revision,
                       void *baton,
                       apr_pool_t *pool)
{
  struct verify_fs_notify_func_baton_t *notify_baton = baton;

  notify_baton->notify->revision = revision;
  notify_baton->notify_func(notify_baton->notify_baton,
                            notify_baton->notify, pool);
}

static svn_error_t *
report_error(svn_revnum_t revision,
             svn_error_t *verify_err,
             svn_repos_verify_callback_t verify_callback,
             void *verify_baton,
             apr_pool_t *pool)
{
  if (verify_callback)
    {
      svn_error_t *cb_err;

      /* The caller provided us with a callback, so make him responsible
         for what's going to happen with the error. */
      cb_err = verify_callback(verify_baton, revision, verify_err, pool);
      svn_error_clear(verify_err);
      SVN_ERR(cb_err);

      return SVN_NO_ERROR;
    }
  else
    {
      /* No callback -- no second guessing.  Just return the error. */
      return svn_error_trace(verify_err);
    }
}

svn_error_t *
svn_repos_verify_fs3(svn_repos_t *repos,
                     svn_revnum_t start_rev,
                     svn_revnum_t end_rev,
                     svn_boolean_t check_normalization,
                     svn_boolean_t metadata_only,
                     svn_repos_notify_func_t notify_func,
                     void *notify_baton,
                     svn_repos_verify_callback_t verify_callback,
                     void *verify_baton,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     apr_pool_t *pool)
{
  svn_fs_t *fs = svn_repos_fs(repos);
  svn_revnum_t youngest;
  svn_revnum_t rev;
  apr_pool_t *iterpool = svn_pool_create(pool);
  svn_repos_notify_t *notify;
  svn_fs_progress_notify_func_t verify_notify = NULL;
  struct verify_fs_notify_func_baton_t *verify_notify_baton = NULL;
  svn_error_t *err;

  /* Make sure we catch up on the latest revprop changes.  This is the only
   * time we will refresh the revprop data in this query. */
  SVN_ERR(svn_fs_refresh_revision_props(fs, pool));

  /* Determine the current youngest revision of the filesystem. */
  SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));

  /* Use default vals if necessary. */
  if (! SVN_IS_VALID_REVNUM(start_rev))
    start_rev = 0;
  if (! SVN_IS_VALID_REVNUM(end_rev))
    end_rev = youngest;

  /* Validate the revisions. */
  if (start_rev > end_rev)
    return svn_error_createf(SVN_ERR_REPOS_BAD_ARGS, NULL,
                             _("Start revision %ld"
                               " is greater than end revision %ld"),
                             start_rev, end_rev);
  if (end_rev > youngest)
    return svn_error_createf(SVN_ERR_REPOS_BAD_ARGS, NULL,
                             _("End revision %ld is invalid "
                               "(youngest revision is %ld)"),
                             end_rev, youngest);

  /* Create a notify object that we can reuse within the loop and a
     forwarding structure for notifications from inside svn_fs_verify(). */
  if (notify_func)
    {
      notify = svn_repos_notify_create(svn_repos_notify_verify_rev_end, pool);

      verify_notify = verify_fs_notify_func;
      verify_notify_baton = apr_palloc(pool, sizeof(*verify_notify_baton));
      verify_notify_baton->notify_func = notify_func;
      verify_notify_baton->notify_baton = notify_baton;
      verify_notify_baton->notify
        = svn_repos_notify_create(svn_repos_notify_verify_rev_structure, pool);
    }

  /* Verify global metadata and backend-specific data first. */
  err = svn_fs_verify(svn_fs_path(fs, pool), svn_fs_config(fs, pool),
                      start_rev, end_rev,
                      verify_notify, verify_notify_baton,
                      cancel_func, cancel_baton, pool);

  if (err && err->apr_err == SVN_ERR_CANCELLED)
    {
      return svn_error_trace(err);
    }
  else if (err)
    {
      SVN_ERR(report_error(SVN_INVALID_REVNUM, err, verify_callback,
                           verify_baton, iterpool));
    }

  if (!metadata_only)
    for (rev = start_rev; rev <= end_rev; rev++)
      {
        svn_pool_clear(iterpool);

        /* Wrapper function to catch the possible errors. */
        err = verify_one_revision(fs, rev, notify_func, notify_baton,
                                  start_rev, check_normalization,
                                  cancel_func, cancel_baton,
                                  iterpool);

        if (err && err->apr_err == SVN_ERR_CANCELLED)
          {
            return svn_error_trace(err);
          }
        else if (err)
          {
            SVN_ERR(report_error(rev, err, verify_callback, verify_baton,
                                 iterpool));
          }
        else if (notify_func)
          {
            /* Tell the caller that we're done with this revision. */
            notify->revision = rev;
            notify_func(notify_baton, notify, iterpool);
          }
      }

  /* We're done. */
  if (notify_func)
    {
      notify = svn_repos_notify_create(svn_repos_notify_verify_end, iterpool);
      notify_func(notify_baton, notify, iterpool);
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}
