/*
 * svndumpfilter.c: Subversion dump stream filtering tool main 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 <stdlib.h>

#include <apr_file_io.h>

#include "svn_private_config.h"
#include "svn_cmdline.h"
#include "svn_error.h"
#include "svn_string.h"
#include "svn_opt.h"
#include "svn_utf.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_hash.h"
#include "svn_repos.h"
#include "svn_fs.h"
#include "svn_pools.h"
#include "svn_sorts.h"
#include "svn_props.h"
#include "svn_mergeinfo.h"
#include "svn_version.h"

#include "private/svn_repos_private.h"
#include "private/svn_mergeinfo_private.h"
#include "private/svn_cmdline_private.h"
#include "private/svn_sorts_private.h"

/*** Code. ***/

/* Writes a property in dumpfile format to given stringbuf. */
static void
write_prop_to_stringbuf(svn_stringbuf_t *strbuf,
                        const char *name,
                        const svn_string_t *value)
{
  int bytes_used;
  size_t namelen;
  char buf[SVN_KEYLINE_MAXLEN];

  /* Output name length, then name. */
  namelen = strlen(name);
  svn_stringbuf_appendbytes(strbuf, "K ", 2);

  bytes_used = apr_snprintf(buf, sizeof(buf), "%" APR_SIZE_T_FMT, namelen);
  svn_stringbuf_appendbytes(strbuf, buf, bytes_used);
  svn_stringbuf_appendbyte(strbuf, '\n');

  svn_stringbuf_appendbytes(strbuf, name, namelen);
  svn_stringbuf_appendbyte(strbuf, '\n');

  /* Output value length, then value. */
  svn_stringbuf_appendbytes(strbuf, "V ", 2);

  bytes_used = apr_snprintf(buf, sizeof(buf), "%" APR_SIZE_T_FMT, value->len);
  svn_stringbuf_appendbytes(strbuf, buf, bytes_used);
  svn_stringbuf_appendbyte(strbuf, '\n');

  svn_stringbuf_appendbytes(strbuf, value->data, value->len);
  svn_stringbuf_appendbyte(strbuf, '\n');
}


/* Writes a property deletion in dumpfile format to given stringbuf. */
static void
write_propdel_to_stringbuf(svn_stringbuf_t **strbuf,
                           const char *name)
{
  int bytes_used;
  size_t namelen;
  char buf[SVN_KEYLINE_MAXLEN];

  /* Output name length, then name. */
  namelen = strlen(name);
  svn_stringbuf_appendbytes(*strbuf, "D ", 2);

  bytes_used = apr_snprintf(buf, sizeof(buf), "%" APR_SIZE_T_FMT, namelen);
  svn_stringbuf_appendbytes(*strbuf, buf, bytes_used);
  svn_stringbuf_appendbyte(*strbuf, '\n');

  svn_stringbuf_appendbytes(*strbuf, name, namelen);
  svn_stringbuf_appendbyte(*strbuf, '\n');
}


/* Compare the node-path PATH with the (const char *) prefixes in PFXLIST.
 * Return TRUE if any prefix is a prefix of PATH (matching whole path
 * components); FALSE otherwise.
 * PATH starts with a '/', as do the (const char *) paths in PREFIXES. */
static svn_boolean_t
ary_prefix_match(const apr_array_header_t *pfxlist, const char *path)
{
  int i;
  size_t path_len = strlen(path);

  for (i = 0; i < pfxlist->nelts; i++)
    {
      const char *pfx = APR_ARRAY_IDX(pfxlist, i, const char *);
      size_t pfx_len = strlen(pfx);

      if (path_len < pfx_len)
        continue;
      if (strncmp(path, pfx, pfx_len) == 0
          && (pfx_len == 1 || path[pfx_len] == '\0' || path[pfx_len] == '/'))
        return TRUE;
    }

  return FALSE;
}


/* Check whether we need to skip this PATH based on its presence in
   the PREFIXES list, and the DO_EXCLUDE option.
   PATH starts with a '/', as do the (const char *) paths in PREFIXES. */
static APR_INLINE svn_boolean_t
skip_path(const char *path, const apr_array_header_t *prefixes,
          svn_boolean_t do_exclude, svn_boolean_t glob)
{
  const svn_boolean_t matches =
    (glob
     ? svn_cstring_match_glob_list(path, prefixes)
     : ary_prefix_match(prefixes, path));

  /* NXOR */
  return (matches ? do_exclude : !do_exclude);
}



/* Note: the input stream parser calls us with events.
   Output of the filtered dump occurs for the most part streamily with the
   event callbacks, to avoid caching large quantities of data in memory.
   The exceptions this are:
   - All revision data (headers and props) must be cached until a non-skipped
     node within the revision is found, or the revision is closed.
   - Node headers and props must be cached until all props have been received
     (to allow the Prop-content-length to be found). This is signalled either
     by the node text arriving, or the node being closed.
   The writing_begun members of the associated object batons track the state.
   output_revision() and output_node() are called to cause this flushing of
   cached data to occur.
*/


/* Filtering batons */

struct revmap_t
{
  svn_revnum_t rev; /* Last non-dropped revision to which this maps. */
  svn_boolean_t was_dropped; /* Was this revision dropped? */
};

struct parse_baton_t
{
  /* Command-line options values. */
  svn_boolean_t do_exclude;
  svn_boolean_t quiet;
  svn_boolean_t glob;
  svn_boolean_t drop_empty_revs;
  svn_boolean_t drop_all_empty_revs;
  svn_boolean_t do_renumber_revs;
  svn_boolean_t preserve_revprops;
  svn_boolean_t skip_missing_merge_sources;
  svn_boolean_t allow_deltas;
  apr_array_header_t *prefixes;

  /* Input and output streams. */
  svn_stream_t *in_stream;
  svn_stream_t *out_stream;

  /* State for the filtering process. */
  apr_int32_t rev_drop_count;
  apr_hash_t *dropped_nodes;
  apr_hash_t *renumber_history;  /* svn_revnum_t -> struct revmap_t */
  svn_revnum_t last_live_revision;
  /* The oldest original revision, greater than r0, in the input
     stream which was not filtered. */
  svn_revnum_t oldest_original_rev;
};

struct revision_baton_t
{
  /* Reference to the global parse baton. */
  struct parse_baton_t *pb;

  /* Does this revision have node or prop changes? */
  svn_boolean_t has_nodes;

  /* Did we drop any nodes? */
  svn_boolean_t had_dropped_nodes;

  /* Written to output stream? */
  svn_boolean_t writing_begun;

  /* The original and new (re-mapped) revision numbers. */
  svn_revnum_t rev_orig;
  svn_revnum_t rev_actual;

  /* Pointers to dumpfile data. */
  apr_hash_t *original_headers;
  apr_hash_t *props;
};

struct node_baton_t
{
  /* Reference to the current revision baton. */
  struct revision_baton_t *rb;

  /* Are we skipping this node? */
  svn_boolean_t do_skip;

  /* Have we been instructed to change or remove props on, or change
     the text of, this node? */
  svn_boolean_t has_props;
  svn_boolean_t has_text;

  /* Written to output stream? */
  svn_boolean_t writing_begun;

  /* The text content length according to the dumpfile headers, because we
     need the length before we have the actual text. */
  svn_filesize_t tcl;

  /* Pointers to dumpfile data. */
  svn_repos__dumpfile_headers_t *headers;
  svn_stringbuf_t *props;

  /* Expect deltas? */
  svn_boolean_t has_prop_delta;
  svn_boolean_t has_text_delta;

  /* We might need the node path in a parse error message. */
  char *node_path;

  apr_pool_t *node_pool;
};



/* Filtering vtable members */

/* File-format stamp. */
static svn_error_t *
magic_header_record(int version, void *parse_baton, apr_pool_t *pool)
{
  struct parse_baton_t *pb = parse_baton;

  if (version >= SVN_REPOS_DUMPFILE_FORMAT_VERSION_DELTAS)
    pb->allow_deltas = TRUE;

  SVN_ERR(svn_stream_printf(pb->out_stream, pool,
                            SVN_REPOS_DUMPFILE_MAGIC_HEADER ": %d\n\n",
                            version));

  return SVN_NO_ERROR;
}


/* Return a deep copy of a (char * -> char *) hash. */
static apr_hash_t *
headers_dup(apr_hash_t *headers,
            apr_pool_t *pool)
{
  apr_hash_t *new_hash = apr_hash_make(pool);
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(pool, headers); hi; hi = apr_hash_next(hi))
    {
      const char *key = apr_hash_this_key(hi);
      const char *val = apr_hash_this_val(hi);

      svn_hash_sets(new_hash, apr_pstrdup(pool, key), apr_pstrdup(pool, val));
    }
  return new_hash;
}

/* New revision: set up revision_baton, decide if we skip it. */
static svn_error_t *
new_revision_record(void **revision_baton,
                    apr_hash_t *headers,
                    void *parse_baton,
                    apr_pool_t *pool)
{
  struct revision_baton_t *rb;
  const char *rev_orig;

  *revision_baton = apr_palloc(pool, sizeof(struct revision_baton_t));
  rb = *revision_baton;
  rb->pb = parse_baton;
  rb->has_nodes = FALSE;
  rb->had_dropped_nodes = FALSE;
  rb->writing_begun = FALSE;
  rb->props = apr_hash_make(pool);
  rb->original_headers = headers_dup(headers, pool);

  rev_orig = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER);
  rb->rev_orig = SVN_STR_TO_REV(rev_orig);

  if (rb->pb->do_renumber_revs)
    rb->rev_actual = rb->rev_orig - rb->pb->rev_drop_count;
  else
    rb->rev_actual = rb->rev_orig;

  return SVN_NO_ERROR;
}


/* Output revision to dumpstream
   This may be called by new_node_record(), iff rb->has_nodes has been set
   to TRUE, or by close_revision() otherwise. This must only be called
   if rb->writing_begun is FALSE. */
static svn_error_t *
output_revision(struct revision_baton_t *rb)
{
  svn_boolean_t write_out_rev = FALSE;
  apr_pool_t *hash_pool = apr_hash_pool_get(rb->props);
  apr_pool_t *subpool = svn_pool_create(hash_pool);

  rb->writing_begun = TRUE;

  /* If this revision has no nodes left because the ones it had were
     dropped, and we are not dropping empty revisions, and we were not
     told to preserve revision props, then we want to fixup the
     revision props to only contain:
       - the date
       - a log message that reports that this revision is just stuffing. */
  if ((! rb->pb->preserve_revprops)
      && (! rb->has_nodes)
      && rb->had_dropped_nodes
      && (! rb->pb->drop_empty_revs)
      && (! rb->pb->drop_all_empty_revs))
    {
      apr_hash_t *old_props = rb->props;
      rb->props = apr_hash_make(hash_pool);
      svn_hash_sets(rb->props, SVN_PROP_REVISION_DATE,
                    svn_hash_gets(old_props, SVN_PROP_REVISION_DATE));
      svn_hash_sets(rb->props, SVN_PROP_REVISION_LOG,
                    svn_string_create(_("This is an empty revision for "
                                        "padding."), hash_pool));
    }

  /* write out the revision */
  /* Revision is written out in the following cases:
     1. If the revision has nodes or
     it is revision 0 (Special case: To preserve the props on r0).
     2. --drop-empty-revs has been supplied,
     but revision has not all nodes dropped.
     3. If no --drop-empty-revs or --drop-all-empty-revs have been supplied,
     write out the revision which has no nodes to begin with.
  */
  if (rb->has_nodes || (rb->rev_orig == 0))
    write_out_rev = TRUE;
  else if (rb->pb->drop_empty_revs)
    write_out_rev = ! rb->had_dropped_nodes;
  else if (! rb->pb->drop_all_empty_revs)
    write_out_rev = TRUE;

  if (write_out_rev)
    {
      /* This revision is a keeper. */
      SVN_ERR(svn_repos__dump_revision_record(rb->pb->out_stream,
                                              rb->rev_actual,
                                              rb->original_headers,
                                              rb->props,
                                              FALSE /*props_section_always*/,
                                              subpool));

      /* Stash the oldest original rev not dropped. */
      if (rb->rev_orig > 0
          && !SVN_IS_VALID_REVNUM(rb->pb->oldest_original_rev))
        rb->pb->oldest_original_rev = rb->rev_orig;

      if (rb->pb->do_renumber_revs)
        {
          svn_revnum_t *rr_key;
          struct revmap_t *rr_val;
          apr_pool_t *rr_pool = apr_hash_pool_get(rb->pb->renumber_history);
          rr_key = apr_palloc(rr_pool, sizeof(*rr_key));
          rr_val = apr_palloc(rr_pool, sizeof(*rr_val));
          *rr_key = rb->rev_orig;
          rr_val->rev = rb->rev_actual;
          rr_val->was_dropped = FALSE;
          apr_hash_set(rb->pb->renumber_history, rr_key,
                       sizeof(*rr_key), rr_val);
          rb->pb->last_live_revision = rb->rev_actual;
        }

      if (! rb->pb->quiet)
        SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
                                    _("Revision %ld committed as %ld.\n"),
                                    rb->rev_orig, rb->rev_actual));
    }
  else
    {
      /* We're dropping this revision. */
      rb->pb->rev_drop_count++;
      if (rb->pb->do_renumber_revs)
        {
          svn_revnum_t *rr_key;
          struct revmap_t *rr_val;
          apr_pool_t *rr_pool = apr_hash_pool_get(rb->pb->renumber_history);
          rr_key = apr_palloc(rr_pool, sizeof(*rr_key));
          rr_val = apr_palloc(rr_pool, sizeof(*rr_val));
          *rr_key = rb->rev_orig;
          rr_val->rev = rb->pb->last_live_revision;
          rr_val->was_dropped = TRUE;
          apr_hash_set(rb->pb->renumber_history, rr_key,
                       sizeof(*rr_key), rr_val);
        }

      if (! rb->pb->quiet)
        SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
                                    _("Revision %ld skipped.\n"),
                                    rb->rev_orig));
    }
  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}


/* UUID record here: dump it, as we do not filter them. */
static svn_error_t *
uuid_record(const char *uuid, void *parse_baton, apr_pool_t *pool)
{
  struct parse_baton_t *pb = parse_baton;
  SVN_ERR(svn_stream_printf(pb->out_stream, pool,
                            SVN_REPOS_DUMPFILE_UUID ": %s\n\n", uuid));
  return SVN_NO_ERROR;
}


/* New node here. Set up node_baton by copying headers. */
static svn_error_t *
new_node_record(void **node_baton,
                apr_hash_t *headers,
                void *rev_baton,
                apr_pool_t *pool)
{
  struct parse_baton_t *pb;
  struct node_baton_t *nb;
  char *node_path, *copyfrom_path;
  apr_hash_index_t *hi;
  const char *tcl;

  *node_baton = apr_palloc(pool, sizeof(struct node_baton_t));
  nb          = *node_baton;
  nb->rb      = rev_baton;
  nb->node_pool = pool;
  pb          = nb->rb->pb;

  node_path = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_PATH);
  copyfrom_path = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH);

  /* Ensure that paths start with a leading '/'. */
  if (node_path[0] != '/')
    node_path = apr_pstrcat(pool, "/", node_path, SVN_VA_NULL);
  if (copyfrom_path && copyfrom_path[0] != '/')
    copyfrom_path = apr_pstrcat(pool, "/", copyfrom_path, SVN_VA_NULL);

  nb->do_skip = skip_path(node_path, pb->prefixes,
                          pb->do_exclude, pb->glob);

  /* If we're skipping the node, take note of path, discarding the
     rest.  */
  if (nb->do_skip)
    {
      svn_hash_sets(pb->dropped_nodes,
                    apr_pstrdup(apr_hash_pool_get(pb->dropped_nodes),
                                node_path),
                    (void *)1);
      nb->rb->had_dropped_nodes = TRUE;
    }
  else
    {
      const char *kind;
      const char *action;

      tcl = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH);

      /* Test if this node was copied from dropped source. */
      if (copyfrom_path &&
          skip_path(copyfrom_path, pb->prefixes, pb->do_exclude, pb->glob))
        {
          /* This node was copied from a dropped source.
             We have a problem, since we did not want to drop this node too.

             However, there is one special case we'll handle.  If the node is
             a file, and this was a copy-and-modify operation, then the
             dumpfile should contain the new contents of the file.  In this
             scenario, we'll just do an add without history using the new
             contents.  */
          kind = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_KIND);

          /* If there is a Text-content-length header, and the kind is
             "file", we just fallback to an add without history. */
          if (tcl && (strcmp(kind, "file") == 0))
            {
              svn_hash_sets(headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH,
                            NULL);
              svn_hash_sets(headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV,
                            NULL);
              copyfrom_path = NULL;
            }
          /* Else, this is either a directory or a file whose contents we
             don't have readily available.  */
          else
            {
              return svn_error_createf
                (SVN_ERR_INCOMPLETE_DATA, 0,
                 _("Invalid copy source path '%s'"), copyfrom_path);
            }
        }

      nb->has_props = FALSE;
      nb->has_text = FALSE;
      nb->has_prop_delta = FALSE;
      nb->has_text_delta = FALSE;
      nb->writing_begun = FALSE;
      nb->tcl = tcl ? svn__atoui64(tcl) : 0;
      nb->headers = svn_repos__dumpfile_headers_create(pool);
      nb->props = svn_stringbuf_create_empty(pool);
      nb->node_path = apr_pstrdup(pool, node_path);

      /* Now we know for sure that we have a node that will not be
         skipped, flush the revision if it has not already been done. */
      nb->rb->has_nodes = TRUE;
      if (! nb->rb->writing_begun)
        SVN_ERR(output_revision(nb->rb));

      /* A node record is required to begin with 'Node-path', skip the
         leading '/' to match the form used by 'svnadmin dump'. */
      svn_repos__dumpfile_header_push(
        nb->headers, SVN_REPOS_DUMPFILE_NODE_PATH, node_path + 1);

      /* Node-kind is next and is optional. */
      kind = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_KIND);
      if (kind)
        svn_repos__dumpfile_header_push(
          nb->headers, SVN_REPOS_DUMPFILE_NODE_KIND, kind);

      /* Node-action is next and required. */
      action = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_NODE_ACTION);
      if (action)
        svn_repos__dumpfile_header_push(
          nb->headers, SVN_REPOS_DUMPFILE_NODE_ACTION, action);
      else
        return svn_error_createf(SVN_ERR_INCOMPLETE_DATA, 0,
                                 _("Missing Node-action for path '%s'"),
                                 node_path);

      for (hi = apr_hash_first(pool, headers); hi; hi = apr_hash_next(hi))
        {
          const char *key = apr_hash_this_key(hi);
          const char *val = apr_hash_this_val(hi);

          if ((!strcmp(key, SVN_REPOS_DUMPFILE_PROP_DELTA))
              && (!strcmp(val, "true")))
            nb->has_prop_delta = TRUE;

          if ((!strcmp(key, SVN_REPOS_DUMPFILE_TEXT_DELTA))
              && (!strcmp(val, "true")))
            nb->has_text_delta = TRUE;

          if ((!strcmp(key, SVN_REPOS_DUMPFILE_CONTENT_LENGTH))
              || (!strcmp(key, SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH))
              || (!strcmp(key, SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH))
              || (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_PATH))
              || (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_KIND))
              || (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_ACTION)))
            continue;

          /* Rewrite Node-Copyfrom-Rev if we are renumbering revisions.
             The number points to some revision in the past. We keep track
             of revision renumbering in an apr_hash, which maps original
             revisions to new ones. Dropped revision are mapped to -1.
             This should never happen here.
          */
          if (pb->do_renumber_revs
              && (!strcmp(key, SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV)))
            {
              svn_revnum_t cf_orig_rev;
              struct revmap_t *cf_renum_val;

              cf_orig_rev = SVN_STR_TO_REV(val);
              cf_renum_val = apr_hash_get(pb->renumber_history,
                                          &cf_orig_rev,
                                          sizeof(cf_orig_rev));
              if (! (cf_renum_val && SVN_IS_VALID_REVNUM(cf_renum_val->rev)))
                return svn_error_createf
                  (SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                   _("No valid copyfrom revision in filtered stream"));
              svn_repos__dumpfile_header_pushf(
                nb->headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV,
                "%ld", cf_renum_val->rev);
              continue;
            }

          /* passthru: put header straight to output */
          svn_repos__dumpfile_header_push(nb->headers, key, val);
        }
    }

  return SVN_NO_ERROR;
}


/* Examine the mergeinfo in INITIAL_VAL, omitting missing merge
   sources or renumbering revisions in rangelists as appropriate, and
   return the (possibly new) mergeinfo in *FINAL_VAL (allocated from
   POOL). */
static svn_error_t *
adjust_mergeinfo(svn_string_t **final_val, const svn_string_t *initial_val,
                 struct revision_baton_t *rb, apr_pool_t *pool)
{
  apr_hash_t *mergeinfo;
  apr_hash_t *final_mergeinfo = apr_hash_make(pool);
  apr_hash_index_t *hi;
  apr_pool_t *subpool = svn_pool_create(pool);

  SVN_ERR(svn_mergeinfo_parse(&mergeinfo, initial_val->data, subpool));

  /* Issue #3020: If we are skipping missing merge sources, then also
     filter mergeinfo ranges as old or older than the oldest revision in the
     dump stream.  Those older than the oldest obviously refer to history
     outside of the dump stream.  The oldest rev itself is present in the
     dump, but cannot be a valid merge source revision since it is the
     start of all history.  E.g. if we dump -r100:400 then dumpfilter the
     result with --skip-missing-merge-sources, any mergeinfo with revision
     100 implies a change of -r99:100, but r99 is part of the history we
     want filtered.

     If the oldest rev is r0 then there is nothing to filter. */

  /* ### This seems to cater only for use cases where the revisions being
         processed are not following on from revisions that will already
         exist in the destination repository. If the revisions being
         processed do follow on, then we might want to keep the mergeinfo
         that refers to those older revisions. */

  if (rb->pb->skip_missing_merge_sources && rb->pb->oldest_original_rev > 0)
    SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
      &mergeinfo, mergeinfo,
      rb->pb->oldest_original_rev, 0,
      FALSE, subpool, subpool));

  for (hi = apr_hash_first(subpool, mergeinfo); hi; hi = apr_hash_next(hi))
    {
      const char *merge_source = apr_hash_this_key(hi);
      svn_rangelist_t *rangelist = apr_hash_this_val(hi);
      struct parse_baton_t *pb = rb->pb;

      /* Determine whether the merge_source is a part of the prefix. */
      if (skip_path(merge_source, pb->prefixes, pb->do_exclude, pb->glob))
        {
          if (pb->skip_missing_merge_sources)
            continue;
          else
            return svn_error_createf(SVN_ERR_INCOMPLETE_DATA, 0,
                                     _("Missing merge source path '%s'; try "
                                       "with --skip-missing-merge-sources"),
                                     merge_source);
        }

      /* Possibly renumber revisions in merge source's rangelist. */
      if (pb->do_renumber_revs)
        {
          int i;

          for (i = 0; i < rangelist->nelts; i++)
            {
              struct revmap_t *revmap_start;
              struct revmap_t *revmap_end;
              svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, i,
                                                       svn_merge_range_t *);

              revmap_start = apr_hash_get(pb->renumber_history,
                                          &range->start, sizeof(range->start));
              if (! (revmap_start && SVN_IS_VALID_REVNUM(revmap_start->rev)))
                return svn_error_createf
                  (SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                   _("No valid revision range 'start' in filtered stream"));

              revmap_end = apr_hash_get(pb->renumber_history,
                                        &range->end, sizeof(range->end));
              if (! (revmap_end && SVN_IS_VALID_REVNUM(revmap_end->rev)))
                return svn_error_createf
                  (SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
                   _("No valid revision range 'end' in filtered stream"));

              range->start = revmap_start->rev;
              range->end = revmap_end->rev;
            }
        }
      svn_hash_sets(final_mergeinfo, merge_source, rangelist);
    }

  SVN_ERR(svn_mergeinfo__canonicalize_ranges(final_mergeinfo, subpool));
  SVN_ERR(svn_mergeinfo_to_string(final_val, final_mergeinfo, pool));
  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}


static svn_error_t *
set_revision_property(void *revision_baton,
                      const char *name,
                      const svn_string_t *value)
{
  struct revision_baton_t *rb = revision_baton;
  apr_pool_t *hash_pool = apr_hash_pool_get(rb->props);

  svn_hash_sets(rb->props,
                apr_pstrdup(hash_pool, name),
                svn_string_dup(value, hash_pool));
  return SVN_NO_ERROR;
}


static svn_error_t *
set_node_property(void *node_baton,
                  const char *name,
                  const svn_string_t *value)
{
  struct node_baton_t *nb = node_baton;
  struct revision_baton_t *rb = nb->rb;

  if (nb->do_skip)
    return SVN_NO_ERROR;

  /* Try to detect if a delta-mode property occurs unexpectedly. HAS_PROPS
     can be false here only if the parser didn't call remove_node_props(),
     so this may indicate a bug rather than bad data. */
  if (! (nb->has_props || nb->has_prop_delta))
    return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
                             _("Delta property block detected, but deltas "
                               "are not enabled for node '%s' in original "
                               "revision %ld"),
                             nb->node_path, rb->rev_orig);

  if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
    {
      svn_string_t *filtered_mergeinfo;  /* Avoid compiler warning. */
      apr_pool_t *pool = apr_hash_pool_get(rb->props);
      SVN_ERR(adjust_mergeinfo(&filtered_mergeinfo, value, rb, pool));
      value = filtered_mergeinfo;
    }

  nb->has_props = TRUE;
  write_prop_to_stringbuf(nb->props, name, value);

  return SVN_NO_ERROR;
}


static svn_error_t *
delete_node_property(void *node_baton, const char *name)
{
  struct node_baton_t *nb = node_baton;
  struct revision_baton_t *rb = nb->rb;

  if (nb->do_skip)
    return SVN_NO_ERROR;

  if (!nb->has_prop_delta)
    return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
                             _("Delta property block detected, but deltas "
                               "are not enabled for node '%s' in original "
                               "revision %ld"),
                             nb->node_path, rb->rev_orig);

  nb->has_props = TRUE;
  write_propdel_to_stringbuf(&(nb->props), name);

  return SVN_NO_ERROR;
}


/* The parser calls this method if the node record has a non-delta
 * property content section, before any calls to set_node_property().
 * If the node record uses property deltas, this is not called.
 */
static svn_error_t *
remove_node_props(void *node_baton)
{
  struct node_baton_t *nb = node_baton;

  /* In this case, not actually indicating that the node *has* props,
     rather that it has a property content section. */
  nb->has_props = TRUE;

  return SVN_NO_ERROR;
}


static svn_error_t *
set_fulltext(svn_stream_t **stream, void *node_baton)
{
  struct node_baton_t *nb = node_baton;

  if (!nb->do_skip)
    {
      nb->has_text = TRUE;
      if (! nb->writing_begun)
        {
          nb->writing_begun = TRUE;
          if (nb->has_props)
            {
              svn_stringbuf_appendcstr(nb->props, "PROPS-END\n");
            }
          SVN_ERR(svn_repos__dump_node_record(nb->rb->pb->out_stream,
                                              nb->headers,
                                              nb->has_props ? nb->props : NULL,
                                              nb->has_text,
                                              nb->tcl,
                                              TRUE /*content_length_always*/,
                                              nb->node_pool));
        }
      *stream = nb->rb->pb->out_stream;
    }

  return SVN_NO_ERROR;
}


/* Finalize node */
static svn_error_t *
close_node(void *node_baton)
{
  struct node_baton_t *nb = node_baton;
  apr_size_t len = 2;

  /* Get out of here if we can. */
  if (nb->do_skip)
    return SVN_NO_ERROR;

  /* If the node was not flushed already to output its text, do it now. */
  if (! nb->writing_begun)
    {
      nb->writing_begun = TRUE;
      if (nb->has_props)
        {
          svn_stringbuf_appendcstr(nb->props, "PROPS-END\n");
        }
      SVN_ERR(svn_repos__dump_node_record(nb->rb->pb->out_stream,
                                          nb->headers,
                                          nb->has_props ? nb->props : NULL,
                                          nb->has_text,
                                          nb->tcl,
                                          TRUE /*content_length_always*/,
                                          nb->node_pool));
    }

  /* put an end to node. */
  SVN_ERR(svn_stream_write(nb->rb->pb->out_stream, "\n\n", &len));

  return SVN_NO_ERROR;
}


/* Finalize revision */
static svn_error_t *
close_revision(void *revision_baton)
{
  struct revision_baton_t *rb = revision_baton;

  /* If no node has yet flushed the revision, do it now. */
  if (! rb->writing_begun)
    return output_revision(rb);
  else
    return SVN_NO_ERROR;
}


/* Filtering vtable */
static svn_repos_parse_fns3_t filtering_vtable =
  {
    magic_header_record,
    uuid_record,
    new_revision_record,
    new_node_record,
    set_revision_property,
    set_node_property,
    delete_node_property,
    remove_node_props,
    set_fulltext,
    NULL,
    close_node,
    close_revision
  };



/** Subcommands. **/

static svn_opt_subcommand_t
  subcommand_help,
  subcommand_exclude,
  subcommand_include;

enum
  {
    svndumpfilter__drop_empty_revs = SVN_OPT_FIRST_LONGOPT_ID,
    svndumpfilter__drop_all_empty_revs,
    svndumpfilter__renumber_revs,
    svndumpfilter__preserve_revprops,
    svndumpfilter__skip_missing_merge_sources,
    svndumpfilter__targets,
    svndumpfilter__quiet,
    svndumpfilter__glob,
    svndumpfilter__version
  };

/* Option codes and descriptions.
 *
 * The entire list must be terminated with an entry of nulls.
 */
static const apr_getopt_option_t options_table[] =
  {
    {"help",          'h', 0,
     N_("show help on a subcommand")},

    {NULL,            '?', 0,
     N_("show help on a subcommand")},

    {"version",            svndumpfilter__version, 0,
     N_("show program version information") },
    {"quiet",              svndumpfilter__quiet, 0,
     N_("Do not display filtering statistics.") },
    {"pattern",            svndumpfilter__glob, 0,
     N_("Treat the path prefixes as file glob patterns.") },
    {"drop-empty-revs",    svndumpfilter__drop_empty_revs, 0,
     N_("Remove revisions emptied by filtering.")},
    {"drop-all-empty-revs",    svndumpfilter__drop_all_empty_revs, 0,
     N_("Remove all empty revisions found in dumpstream\n"
        "                             except revision 0.")},
    {"renumber-revs",      svndumpfilter__renumber_revs, 0,
     N_("Renumber revisions left after filtering.") },
    {"skip-missing-merge-sources",
     svndumpfilter__skip_missing_merge_sources, 0,
     N_("Skip missing merge sources.") },
    {"preserve-revprops",  svndumpfilter__preserve_revprops, 0,
     N_("Don't filter revision properties.") },
    {"targets", svndumpfilter__targets, 1,
     N_("Read additional prefixes, one per line, from\n"
        "                             file ARG.")},
    {NULL}
  };


/* Array of available subcommands.
 * The entire list must be terminated with an entry of nulls.
 */
static const svn_opt_subcommand_desc2_t cmd_table[] =
  {
    {"exclude", subcommand_exclude, {0},
     N_("Filter out nodes with given prefixes from dumpstream.\n"
        "usage: svndumpfilter exclude PATH_PREFIX...\n"),
     {svndumpfilter__drop_empty_revs, svndumpfilter__drop_all_empty_revs,
      svndumpfilter__renumber_revs,
      svndumpfilter__skip_missing_merge_sources, svndumpfilter__targets,
      svndumpfilter__preserve_revprops, svndumpfilter__quiet,
      svndumpfilter__glob} },

    {"include", subcommand_include, {0},
     N_("Filter out nodes without given prefixes from dumpstream.\n"
        "usage: svndumpfilter include PATH_PREFIX...\n"),
     {svndumpfilter__drop_empty_revs, svndumpfilter__drop_all_empty_revs,
      svndumpfilter__renumber_revs,
      svndumpfilter__skip_missing_merge_sources, svndumpfilter__targets,
      svndumpfilter__preserve_revprops, svndumpfilter__quiet,
      svndumpfilter__glob} },

    {"help", subcommand_help, {"?", "h"},
     N_("Describe the usage of this program or its subcommands.\n"
        "usage: svndumpfilter help [SUBCOMMAND...]\n"),
     {0} },

    { NULL, NULL, {0}, NULL, {0} }
  };


/* Baton for passing option/argument state to a subcommand function. */
struct svndumpfilter_opt_state
{
  svn_opt_revision_t start_revision;     /* -r X[:Y] is         */
  svn_opt_revision_t end_revision;       /* not implemented.    */
  svn_boolean_t quiet;                   /* --quiet             */
  svn_boolean_t glob;                    /* --pattern           */
  svn_boolean_t version;                 /* --version           */
  svn_boolean_t drop_empty_revs;         /* --drop-empty-revs   */
  svn_boolean_t drop_all_empty_revs;     /* --drop-all-empty-revs */
  svn_boolean_t help;                    /* --help or -?        */
  svn_boolean_t renumber_revs;           /* --renumber-revs     */
  svn_boolean_t preserve_revprops;       /* --preserve-revprops */
  svn_boolean_t skip_missing_merge_sources;
                                         /* --skip-missing-merge-sources */
  const char *targets_file;              /* --targets-file       */
  apr_array_header_t *prefixes;          /* mainargs.           */
};


static svn_error_t *
parse_baton_initialize(struct parse_baton_t **pb,
                       struct svndumpfilter_opt_state *opt_state,
                       svn_boolean_t do_exclude,
                       apr_pool_t *pool)
{
  struct parse_baton_t *baton = apr_palloc(pool, sizeof(*baton));

  /* Read the stream from STDIN.  Users can redirect a file. */
  SVN_ERR(svn_stream_for_stdin2(&baton->in_stream, TRUE, pool));

  /* Have the parser dump results to STDOUT. Users can redirect a file. */
  SVN_ERR(svn_stream_for_stdout(&baton->out_stream, pool));

  baton->do_exclude = do_exclude;

  /* Ignore --renumber-revs if there can't possibly be
     anything to renumber. */
  baton->do_renumber_revs =
    (opt_state->renumber_revs && (opt_state->drop_empty_revs
                                  || opt_state->drop_all_empty_revs));

  baton->drop_empty_revs = opt_state->drop_empty_revs;
  baton->drop_all_empty_revs = opt_state->drop_all_empty_revs;
  baton->preserve_revprops = opt_state->preserve_revprops;
  baton->quiet = opt_state->quiet;
  baton->glob = opt_state->glob;
  baton->prefixes = opt_state->prefixes;
  baton->skip_missing_merge_sources = opt_state->skip_missing_merge_sources;
  baton->rev_drop_count = 0; /* used to shift revnums while filtering */
  baton->dropped_nodes = apr_hash_make(pool);
  baton->renumber_history = apr_hash_make(pool);
  baton->last_live_revision = SVN_INVALID_REVNUM;
  baton->oldest_original_rev = SVN_INVALID_REVNUM;
  baton->allow_deltas = FALSE;

  *pb = baton;
  return SVN_NO_ERROR;
}

/* This implements `help` subcommand. */
static svn_error_t *
subcommand_help(apr_getopt_t *os, void *baton, apr_pool_t *pool)
{
  struct svndumpfilter_opt_state *opt_state = baton;
  const char *header =
    _("general usage: svndumpfilter SUBCOMMAND [ARGS & OPTIONS ...]\n"
      "Subversion repository dump filtering tool.\n"
      "Type 'svndumpfilter help <subcommand>' for help on a "
      "specific subcommand.\n"
      "Type 'svndumpfilter --version' to see the program version.\n"
      "\n"
      "Available subcommands:\n");

  SVN_ERR(svn_opt_print_help4(os, "svndumpfilter",
                              opt_state ? opt_state->version : FALSE,
                              opt_state ? opt_state->quiet : FALSE,
                              /*###opt_state ? opt_state->verbose :*/ FALSE,
                              NULL, header, cmd_table, options_table,
                              NULL, NULL, pool));

  return SVN_NO_ERROR;
}


/* Version compatibility check */
static svn_error_t *
check_lib_versions(void)
{
  static const svn_version_checklist_t checklist[] =
    {
      { "svn_subr",  svn_subr_version },
      { "svn_repos", svn_repos_version },
      { "svn_delta", svn_delta_version },
      { NULL, NULL }
    };
  SVN_VERSION_DEFINE(my_version);

  return svn_ver_check_list2(&my_version, checklist, svn_ver_equal);
}


/* Do the real work of filtering. */
static svn_error_t *
do_filter(apr_getopt_t *os,
          void *baton,
          svn_boolean_t do_exclude,
          apr_pool_t *pool)
{
  struct svndumpfilter_opt_state *opt_state = baton;
  struct parse_baton_t *pb;
  apr_hash_index_t *hi;
  apr_array_header_t *keys;
  int i, num_keys;

  if (! opt_state->quiet)
    {
      apr_pool_t *subpool = svn_pool_create(pool);

      if (opt_state->glob)
        {
          SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
                                      do_exclude
                                      ? (opt_state->drop_empty_revs
                                         || opt_state->drop_all_empty_revs)
                                        ? _("Excluding (and dropping empty "
                                            "revisions for) prefix patterns:\n")
                                        : _("Excluding prefix patterns:\n")
                                      : (opt_state->drop_empty_revs
                                         || opt_state->drop_all_empty_revs)
                                        ? _("Including (and dropping empty "
                                            "revisions for) prefix patterns:\n")
                                        : _("Including prefix patterns:\n")));
        }
      else
        {
          SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
                                      do_exclude
                                      ? (opt_state->drop_empty_revs
                                         || opt_state->drop_all_empty_revs)
                                        ? _("Excluding (and dropping empty "
                                            "revisions for) prefixes:\n")
                                        : _("Excluding prefixes:\n")
                                      : (opt_state->drop_empty_revs
                                         || opt_state->drop_all_empty_revs)
                                        ? _("Including (and dropping empty "
                                            "revisions for) prefixes:\n")
                                        : _("Including prefixes:\n")));
        }

      for (i = 0; i < opt_state->prefixes->nelts; i++)
        {
          svn_pool_clear(subpool);
          SVN_ERR(svn_cmdline_fprintf
                  (stderr, subpool, "   '%s'\n",
                   APR_ARRAY_IDX(opt_state->prefixes, i, const char *)));
        }

      SVN_ERR(svn_cmdline_fputs("\n", stderr, subpool));
      svn_pool_destroy(subpool);
    }

  SVN_ERR(parse_baton_initialize(&pb, opt_state, do_exclude, pool));
  SVN_ERR(svn_repos_parse_dumpstream3(pb->in_stream, &filtering_vtable, pb,
                                      TRUE, NULL, NULL, pool));

  /* The rest of this is just reporting.  If we aren't reporting, get
     outta here. */
  if (opt_state->quiet)
    return SVN_NO_ERROR;

  SVN_ERR(svn_cmdline_fputs("\n", stderr, pool));

  if (pb->rev_drop_count)
    SVN_ERR(svn_cmdline_fprintf(stderr, pool,
                                Q_("Dropped %d revision.\n\n",
                                   "Dropped %d revisions.\n\n",
                                   pb->rev_drop_count),
                                pb->rev_drop_count));

  if (pb->do_renumber_revs)
    {
      apr_pool_t *subpool = svn_pool_create(pool);
      SVN_ERR(svn_cmdline_fputs(_("Revisions renumbered as follows:\n"),
                                stderr, subpool));

      /* Get the keys of the hash, sort them, then print the hash keys
         and values, sorted by keys. */
      num_keys = apr_hash_count(pb->renumber_history);
      keys = apr_array_make(pool, num_keys + 1, sizeof(svn_revnum_t));
      for (hi = apr_hash_first(pool, pb->renumber_history);
           hi;
           hi = apr_hash_next(hi))
        {
          const svn_revnum_t *revnum = apr_hash_this_key(hi);

          APR_ARRAY_PUSH(keys, svn_revnum_t) = *revnum;
        }
      svn_sort__array(keys, svn_sort_compare_revisions);
      for (i = 0; i < keys->nelts; i++)
        {
          svn_revnum_t this_key;
          struct revmap_t *this_val;

          svn_pool_clear(subpool);
          this_key = APR_ARRAY_IDX(keys, i, svn_revnum_t);
          this_val = apr_hash_get(pb->renumber_history, &this_key,
                                  sizeof(this_key));
          if (this_val->was_dropped)
            SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
                                        _("   %ld => (dropped)\n"),
                                        this_key));
          else
            SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
                                        "   %ld => %ld\n",
                                        this_key, this_val->rev));
        }
      SVN_ERR(svn_cmdline_fputs("\n", stderr, subpool));
      svn_pool_destroy(subpool);
    }

  if ((num_keys = apr_hash_count(pb->dropped_nodes)))
    {
      apr_pool_t *subpool = svn_pool_create(pool);
      SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
                                  Q_("Dropped %d node:\n",
                                     "Dropped %d nodes:\n",
                                     num_keys),
                                  num_keys));

      /* Get the keys of the hash, sort them, then print the hash keys
         and values, sorted by keys. */
      keys = apr_array_make(pool, num_keys + 1, sizeof(const char *));
      for (hi = apr_hash_first(pool, pb->dropped_nodes);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *path = apr_hash_this_key(hi);

          APR_ARRAY_PUSH(keys, const char *) = path;
        }
      svn_sort__array(keys, svn_sort_compare_paths);
      for (i = 0; i < keys->nelts; i++)
        {
          svn_pool_clear(subpool);
          SVN_ERR(svn_cmdline_fprintf
                  (stderr, subpool, "   '%s'\n",
                   (const char *)APR_ARRAY_IDX(keys, i, const char *)));
        }
      SVN_ERR(svn_cmdline_fputs("\n", stderr, subpool));
      svn_pool_destroy(subpool);
    }

  return SVN_NO_ERROR;
}

/* This implements `exclude' subcommand. */
static svn_error_t *
subcommand_exclude(apr_getopt_t *os, void *baton, apr_pool_t *pool)
{
  return do_filter(os, baton, TRUE, pool);
}


/* This implements `include` subcommand. */
static svn_error_t *
subcommand_include(apr_getopt_t *os, void *baton, apr_pool_t *pool)
{
  return do_filter(os, baton, FALSE, pool);
}



/** Main. **/

/*
 * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
 * either return an error to be displayed, or set *EXIT_CODE to non-zero and
 * return SVN_NO_ERROR.
 */
static svn_error_t *
sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
{
  svn_error_t *err;
  apr_status_t apr_err;

  const svn_opt_subcommand_desc2_t *subcommand = NULL;
  struct svndumpfilter_opt_state opt_state;
  apr_getopt_t *os;
  int opt_id;
  apr_array_header_t *received_opts;
  int i;

  /* Check library versions */
  SVN_ERR(check_lib_versions());

  received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));

  /* Initialize the FS library. */
  SVN_ERR(svn_fs_initialize(pool));

  if (argc <= 1)
    {
      SVN_ERR(subcommand_help(NULL, NULL, pool));
      *exit_code = EXIT_FAILURE;
      return SVN_NO_ERROR;
    }

  /* Initialize opt_state. */
  memset(&opt_state, 0, sizeof(opt_state));
  opt_state.start_revision.kind = svn_opt_revision_unspecified;
  opt_state.end_revision.kind = svn_opt_revision_unspecified;

  /* Parse options. */
  SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));

  os->interleave = 1;
  while (1)
    {
      const char *opt_arg;

      /* Parse the next option. */
      apr_err = apr_getopt_long(os, options_table, &opt_id, &opt_arg);
      if (APR_STATUS_IS_EOF(apr_err))
        break;
      else if (apr_err)
        {
          SVN_ERR(subcommand_help(NULL, NULL, pool));
          *exit_code = EXIT_FAILURE;
          return SVN_NO_ERROR;
        }

      /* Stash the option code in an array before parsing it. */
      APR_ARRAY_PUSH(received_opts, int) = opt_id;

      switch (opt_id)
        {
        case 'h':
        case '?':
          opt_state.help = TRUE;
          break;
        case svndumpfilter__version:
          opt_state.version = TRUE;
          break;
        case svndumpfilter__quiet:
          opt_state.quiet = TRUE;
          break;
        case svndumpfilter__glob:
          opt_state.glob = TRUE;
          break;
        case svndumpfilter__drop_empty_revs:
          opt_state.drop_empty_revs = TRUE;
          break;
        case svndumpfilter__drop_all_empty_revs:
          opt_state.drop_all_empty_revs = TRUE;
          break;
        case svndumpfilter__renumber_revs:
          opt_state.renumber_revs = TRUE;
          break;
        case svndumpfilter__preserve_revprops:
          opt_state.preserve_revprops = TRUE;
          break;
        case svndumpfilter__skip_missing_merge_sources:
          opt_state.skip_missing_merge_sources = TRUE;
          break;
        case svndumpfilter__targets:
          opt_state.targets_file = opt_arg;
          break;
        default:
          {
            SVN_ERR(subcommand_help(NULL, NULL, pool));
            *exit_code = EXIT_FAILURE;
            return SVN_NO_ERROR;
          }
        }  /* close `switch' */
    }  /* close `while' */

  /* Disallow simultaneous use of both --drop-empty-revs and
     --drop-all-empty-revs. */
  if (opt_state.drop_empty_revs && opt_state.drop_all_empty_revs)
    {
      return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS,
                              NULL,
                              _("--drop-empty-revs cannot be used with "
                                "--drop-all-empty-revs"));
    }

  /* If the user asked for help, then the rest of the arguments are
     the names of subcommands to get help on (if any), or else they're
     just typos/mistakes.  Whatever the case, the subcommand to
     actually run is subcommand_help(). */
  if (opt_state.help)
    subcommand = svn_opt_get_canonical_subcommand2(cmd_table, "help");

  /* If we're not running the `help' subcommand, then look for a
     subcommand in the first argument. */
  if (subcommand == NULL)
    {
      if (os->ind >= os->argc)
        {
          if (opt_state.version)
            {
              /* Use the "help" subcommand to handle the "--version" option. */
              static const svn_opt_subcommand_desc2_t pseudo_cmd =
                { "--version", subcommand_help, {0}, "",
                  {svndumpfilter__version,  /* must accept its own option */
                   svndumpfilter__quiet,
                  } };

              subcommand = &pseudo_cmd;
            }
          else
            {
              svn_error_clear(svn_cmdline_fprintf
                              (stderr, pool,
                               _("Subcommand argument required\n")));
              SVN_ERR(subcommand_help(NULL, NULL, pool));
              *exit_code = EXIT_FAILURE;
              return SVN_NO_ERROR;
            }
        }
      else
        {
          const char *first_arg = os->argv[os->ind++];
          subcommand = svn_opt_get_canonical_subcommand2(cmd_table, first_arg);
          if (subcommand == NULL)
            {
              const char* first_arg_utf8;
              SVN_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg,
                                              pool));

              svn_error_clear(
                svn_cmdline_fprintf(stderr, pool,
                                    _("Unknown subcommand: '%s'\n"),
                                    first_arg_utf8));
              SVN_ERR(subcommand_help(NULL, NULL, pool));
              *exit_code = EXIT_FAILURE;
              return SVN_NO_ERROR;
            }
        }
    }

  /* If there's a second argument, it's probably [one of] prefixes.
     Every subcommand except `help' requires at least one, so we parse
     them out here and store in opt_state. */

  if (subcommand->cmd_func != subcommand_help)
    {

      opt_state.prefixes = apr_array_make(pool, os->argc - os->ind,
                                          sizeof(const char *));
      for (i = os->ind ; i< os->argc; i++)
        {
          const char *prefix;

          /* Ensure that each prefix is UTF8-encoded, in internal
             style, and absolute. */
          SVN_ERR(svn_utf_cstring_to_utf8(&prefix, os->argv[i], pool));
          prefix = svn_relpath__internal_style(prefix, pool);
          if (prefix[0] != '/')
            prefix = apr_pstrcat(pool, "/", prefix, SVN_VA_NULL);
          APR_ARRAY_PUSH(opt_state.prefixes, const char *) = prefix;
        }

      if (opt_state.targets_file)
        {
          svn_stringbuf_t *buffer, *buffer_utf8;
          const char *utf8_targets_file;
          apr_array_header_t *targets = apr_array_make(pool, 0,
                                                       sizeof(const char *));

          /* We need to convert to UTF-8 now, even before we divide
             the targets into an array, because otherwise we wouldn't
             know what delimiter to use for svn_cstring_split().  */

          SVN_ERR(svn_utf_cstring_to_utf8(&utf8_targets_file,
                                          opt_state.targets_file, pool));

          SVN_ERR(svn_stringbuf_from_file2(&buffer, utf8_targets_file,
                                           pool));
          SVN_ERR(svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool));

          targets = apr_array_append(pool,
                         svn_cstring_split(buffer_utf8->data, "\n\r",
                                           TRUE, pool),
                         targets);

          for (i = 0; i < targets->nelts; i++)
            {
              const char *prefix = APR_ARRAY_IDX(targets, i, const char *);
              if (prefix[0] != '/')
                prefix = apr_pstrcat(pool, "/", prefix, SVN_VA_NULL);
              APR_ARRAY_PUSH(opt_state.prefixes, const char *) = prefix;
            }
        }

      if (apr_is_empty_array(opt_state.prefixes))
        {
          svn_error_clear(svn_cmdline_fprintf
                          (stderr, pool,
                           _("\nError: no prefixes supplied.\n")));
          *exit_code = EXIT_FAILURE;
          return SVN_NO_ERROR;
        }
    }


  /* Check that the subcommand wasn't passed any inappropriate options. */
  for (i = 0; i < received_opts->nelts; i++)
    {
      opt_id = APR_ARRAY_IDX(received_opts, i, int);

      /* All commands implicitly accept --help, so just skip over this
         when we see it. Note that we don't want to include this option
         in their "accepted options" list because it would be awfully
         redundant to display it in every commands' help text. */
      if (opt_id == 'h' || opt_id == '?')
        continue;

      if (! svn_opt_subcommand_takes_option3(subcommand, opt_id, NULL))
        {
          const char *optstr;
          const apr_getopt_option_t *badopt =
            svn_opt_get_option_from_code2(opt_id, options_table, subcommand,
                                          pool);
          svn_opt_format_option(&optstr, badopt, FALSE, pool);
          if (subcommand->name[0] == '-')
            SVN_ERR(subcommand_help(NULL, NULL, pool));
          else
            svn_error_clear(svn_cmdline_fprintf
                            (stderr, pool,
                             _("Subcommand '%s' doesn't accept option '%s'\n"
                               "Type 'svndumpfilter help %s' for usage.\n"),
                             subcommand->name, optstr, subcommand->name));
          *exit_code = EXIT_FAILURE;
          return SVN_NO_ERROR;
        }
    }

  /* Run the subcommand. */
  err = (*subcommand->cmd_func)(os, &opt_state, pool);
  if (err)
    {
      /* For argument-related problems, suggest using the 'help'
         subcommand. */
      if (err->apr_err == SVN_ERR_CL_INSUFFICIENT_ARGS
          || err->apr_err == SVN_ERR_CL_ARG_PARSING_ERROR)
        {
          err = svn_error_quick_wrap(err,
                                     _("Try 'svndumpfilter help' for more "
                                       "info"));
        }
      return err;
    }

  return SVN_NO_ERROR;
}

int
main(int argc, const char *argv[])
{
  apr_pool_t *pool;
  int exit_code = EXIT_SUCCESS;
  svn_error_t *err;

  /* Initialize the app. */
  if (svn_cmdline_init("svndumpfilter", stderr) != EXIT_SUCCESS)
    return EXIT_FAILURE;

  /* Create our top-level pool.  Use a separate mutexless allocator,
   * given this application is single threaded.
   */
  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));

  err = sub_main(&exit_code, argc, argv, pool);

  /* Flush stdout and report if it fails. It would be flushed on exit anyway
     but this makes sure that output is not silently lost if it fails. */
  err = svn_error_compose_create(err, svn_cmdline_fflush(stdout));

  if (err)
    {
      exit_code = EXIT_FAILURE;
      svn_cmdline_handle_exit_error(err, NULL, "svndumpfilter: ");
    }

  svn_pool_destroy(pool);
  return exit_code;
}
