/*
 * version.c: mod_dav_svn versioning provider functions for Subversion
 *
 * ====================================================================
 *    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 <apr_tables.h>
#include <apr_uuid.h>

#include <httpd.h>
#include <http_log.h>
#include <mod_dav.h>

#include "svn_hash.h"
#include "svn_fs.h"
#include "svn_xml.h"
#include "svn_repos.h"
#include "svn_dav.h"
#include "svn_time.h"
#include "svn_pools.h"
#include "svn_props.h"
#include "svn_dav.h"
#include "svn_base64.h"
#include "svn_version.h"
#include "private/svn_repos_private.h"
#include "private/svn_subr_private.h"
#include "private/svn_dav_protocol.h"
#include "private/svn_log.h"
#include "private/svn_fspath.h"

#include "dav_svn.h"


svn_error_t *
dav_svn__attach_auto_revprops(svn_fs_txn_t *txn,
                              const char *fs_path,
                              apr_pool_t *pool)
{
  const char *logmsg;
  svn_string_t *logval;
  svn_error_t *serr;

  logmsg = apr_psprintf(pool,
                        "Autoversioning commit:  a non-deltaV client made "
                        "a change to\n%s", fs_path);

  logval = svn_string_create(logmsg, pool);
  if ((serr = svn_repos_fs_change_txn_prop(txn, SVN_PROP_REVISION_LOG, logval,
                                           pool)))
    return serr;

  /* Notate that this revision was created by autoversioning.  (Tools
     like post-commit email scripts might not care to send an email
     for every autoversioning change.) */
  if ((serr = svn_repos_fs_change_txn_prop(txn,
                                           SVN_PROP_REVISION_AUTOVERSIONED,
                                           svn_string_create("*", pool),
                                           pool)))
    return serr;

  return SVN_NO_ERROR;
}


/* Helper: attach an auto-generated svn:log property to a txn within
   an auto-checked-out working resource. */
static dav_error *
set_auto_revprops(dav_resource *resource)
{
  svn_error_t *serr;

  if (! (resource->type == DAV_RESOURCE_TYPE_WORKING
         && resource->info->auto_checked_out))
    return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0, 0,
                              "Set_auto_revprops called on invalid resource.");

  if ((serr = dav_svn__attach_auto_revprops(resource->info->root.txn,
                                            resource->info->repos_path,
                                            resource->pool)))
    return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                "Error setting a revision property "
                                " on auto-checked-out resource's txn. ",
                                resource->pool);
  return NULL;
}


static dav_error *
open_txn(svn_fs_txn_t **ptxn,
         svn_fs_t *fs,
         const char *txn_name,
         apr_pool_t *pool)
{
  svn_error_t *serr;

  serr = svn_fs_open_txn(ptxn, fs, txn_name, pool);
  if (serr != NULL)
    {
      if (serr->apr_err == SVN_ERR_FS_NO_SUCH_TRANSACTION)
        {
          /* ### correct HTTP error? */
          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                      "The transaction specified by the "
                                      "activity does not exist",
                                      pool);
        }

      /* ### correct HTTP error? */
      return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                  "There was a problem opening the "
                                  "transaction specified by this "
                                  "activity.",
                                  pool);
    }

  return NULL;
}


static void
get_vsn_options(apr_pool_t *p, apr_text_header *phdr)
{
  /* Note: we append pieces with care for Web Folders's 63-char limit
     on the DAV: header */

  apr_text_append(p, phdr,
                  "version-control,checkout,working-resource");
  apr_text_append(p, phdr,
                  "merge,baseline,activity,version-controlled-collection");
  /* Send SVN_RA_CAPABILITY_* capabilities. */
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_DEPTH);
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_LOG_REVPROPS);
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS);
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY);
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_INHERITED_PROPS);
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_INLINE_PROPS);
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_REVERSE_FILE_REVS);
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_LIST);
  /* Mergeinfo is a special case: here we merely say that the server
   * knows how to handle mergeinfo -- whether the repository does too
   * is a separate matter.
   *
   * Think of it as offering the client an early out: if the server
   * can't do merge-tracking, there's no point finding out of the
   * repository can.  But if the server can, it may be worth expending
   * an extra round trip to find out if the repository can too (the
   * extra round trip being necessary because, sadly, we don't have
   * access to the repository yet here, so we can only announce the
   * server capability and remain agnostic about the repository).
   */
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_MERGEINFO);

  /* ### fork-control? */
}


static dav_error *
get_option(const dav_resource *resource,
           const apr_xml_elem *elem,
           apr_text_header *option)
{
  int i;
  request_rec *r = resource->info->r;
  const char *repos_root_uri =
    dav_svn__build_uri(resource->info->repos, DAV_SVN__BUILD_URI_PUBLIC,
                       SVN_IGNORED_REVNUM, "", FALSE /* add_href */,
                       resource->pool);
  svn_version_t *master_version = dav_svn__get_master_version(r);

  /* These capabilities are used during commit and when configured as
     a WebDAV slave (SVNMasterURI is set) their availability should
     depend on the master version (SVNMasterVersion is set) if it is
     older than our own version.  Also, although SVNDIFF1 is available
     before 1.10 none of those earlier servers advertised it so for
     consistency we don't advertise it for masters older than 1.10. */
  struct capability_versions_t {
    const char *capability_name;
    svn_version_t min_version;
  } capabilities[] = {
    { SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS,  { 1,  8, 0, ""} },
    { SVN_DAV_NS_DAV_SVN_SVNDIFF1,            { 1, 10, 0, ""} },
    { SVN_DAV_NS_DAV_SVN_SVNDIFF2,            { 1, 10, 0, ""} },
    { SVN_DAV_NS_DAV_SVN_PUT_RESULT_CHECKSUM, { 1, 10, 0, ""} },
  };

  /* ### DAV:version-history-collection-set */
  if (elem->ns != APR_XML_NS_DAV_ID
      || strcmp(elem->name, "activity-collection-set") != 0)
    {
       /* We don't know about other options (yet).

          If we ever add multiple option request keys we should
          just write the requested option value and make sure
          we set the headers *once*. */
      return NULL;
    }

  apr_text_append(resource->pool, option,
                  "<D:activity-collection-set>");

  apr_text_append(resource->pool, option,
                  dav_svn__build_uri(resource->info->repos,
                                     DAV_SVN__BUILD_URI_ACT_COLLECTION,
                                     SVN_INVALID_REVNUM, NULL,
                                     TRUE /* add_href */,
                                     resource->pool));
  apr_text_append(resource->pool, option,
                  "</D:activity-collection-set>");

  if (resource->info->repos->fs)
    {
      svn_error_t *serr;
      svn_revnum_t youngest;
      const char *uuid;

      /* Got youngest revision? */
      if ((serr = dav_svn__get_youngest_rev(&youngest, resource->info->repos,
                                            resource->pool)))
        {
          return dav_svn__convert_err
            (serr, HTTP_INTERNAL_SERVER_ERROR,
             "Error fetching youngest revision from repository",
             resource->pool);
        }
      if (SVN_IS_VALID_REVNUM(youngest))
        {
          apr_table_set(r->headers_out,
                        SVN_DAV_YOUNGEST_REV_HEADER,
                        apr_psprintf(resource->pool, "%ld", youngest));
        }

      /* Got repository UUID? */
      if ((serr = svn_fs_get_uuid(resource->info->repos->fs,
                                  &uuid, resource->pool)))
        {
          return dav_svn__convert_err
            (serr, HTTP_INTERNAL_SERVER_ERROR,
             "Error fetching repository UUID",
             resource->pool);
        }
      if (uuid)
        {
          apr_table_set(r->headers_out,
                        SVN_DAV_REPOS_UUID_HEADER, uuid);
        }
    }

  if (resource->info->repos->repos)
    {
        svn_error_t *serr;
        svn_boolean_t has;

        serr = svn_repos_has_capability(resource->info->repos->repos, &has,
                                        SVN_REPOS_CAPABILITY_MERGEINFO,
                                        r->pool);
        if (serr)
        return dav_svn__convert_err
                    (serr, HTTP_INTERNAL_SERVER_ERROR,
                    "Error fetching repository capabilities",
                    resource->pool);

        apr_table_set(r->headers_out, SVN_DAV_REPOSITORY_MERGEINFO,
                    has ? "yes" : "no");
    }

  /* Welcome to the 2nd generation of the svn HTTP protocol, now
     DeltaV-free!  If we're configured to advise this support, do so.  */
  if (resource->info->repos->v2_protocol)
    {
      dav_svn__bulk_upd_conf bulk_upd_conf = dav_svn__get_bulk_updates_flag(r);

      /* The list of Subversion's custom POSTs and which versions of
         Subversion support them.  We need this latter information
         when acting as a WebDAV slave -- we don't want to claim
         support for a POST type if the master server which will
         actually have to handle it won't recognize it.

         Keep this in sync with what's handled in handle_post_request().
      */
      struct posts_versions_t {
        const char *post_name;
        svn_version_t min_version;
      } posts_versions[] = {
        { "create-txn",             { 1, 7, 0, "" } },
        { "create-txn-with-props",  { 1, 8, 0, "" } },
      };

      /* Add the header which indicates that this server can handle
         replay REPORTs submitted against an HTTP v2 revision resource. */
      apr_table_addn(r->headers_out, "DAV",
                     SVN_DAV_NS_DAV_SVN_REPLAY_REV_RESOURCE);

      /* Add a bunch of HTTP v2 headers which carry resource and
         resource stub URLs that the client can use to naively build
         addressable resources. */
      apr_table_set(r->headers_out, SVN_DAV_ROOT_URI_HEADER, repos_root_uri);
      apr_table_set(r->headers_out, SVN_DAV_ME_RESOURCE_HEADER,
                    apr_pstrcat(r->pool, repos_root_uri, "/",
                                dav_svn__get_me_resource_uri(r), SVN_VA_NULL));
      apr_table_set(r->headers_out, SVN_DAV_REV_ROOT_STUB_HEADER,
                    apr_pstrcat(r->pool, repos_root_uri, "/",
                                dav_svn__get_rev_root_stub(r), SVN_VA_NULL));
      apr_table_set(r->headers_out, SVN_DAV_REV_STUB_HEADER,
                    apr_pstrcat(r->pool, repos_root_uri, "/",
                                dav_svn__get_rev_stub(r), SVN_VA_NULL));
      apr_table_set(r->headers_out, SVN_DAV_TXN_ROOT_STUB_HEADER,
                    apr_pstrcat(r->pool, repos_root_uri, "/",
                                dav_svn__get_txn_root_stub(r), SVN_VA_NULL));
      apr_table_set(r->headers_out, SVN_DAV_TXN_STUB_HEADER,
                    apr_pstrcat(r->pool, repos_root_uri, "/",
                                dav_svn__get_txn_stub(r), SVN_VA_NULL));
      apr_table_set(r->headers_out, SVN_DAV_VTXN_ROOT_STUB_HEADER,
                    apr_pstrcat(r->pool, repos_root_uri, "/",
                                dav_svn__get_vtxn_root_stub(r), SVN_VA_NULL));
      apr_table_set(r->headers_out, SVN_DAV_VTXN_STUB_HEADER,
                    apr_pstrcat(r->pool, repos_root_uri, "/",
                                dav_svn__get_vtxn_stub(r), SVN_VA_NULL));
      apr_table_set(r->headers_out, SVN_DAV_ALLOW_BULK_UPDATES,
                    bulk_upd_conf == CONF_BULKUPD_ON ? "On" :
                      bulk_upd_conf == CONF_BULKUPD_OFF ? "Off" : "Prefer");

      /* Report the supported POST types. */
      for (i = 0; i < sizeof(posts_versions)/sizeof(posts_versions[0]); ++i)
        {
          /* If we're proxying to a master server and its version
             number is declared, we can selectively filter out POST
             types that it doesn't support. */
          if (master_version
              && (! svn_version__at_least(master_version,
                                          posts_versions[i].min_version.major,
                                          posts_versions[i].min_version.minor,
                                          posts_versions[i].min_version.patch)))
            continue;

          apr_table_addn(r->headers_out, SVN_DAV_SUPPORTED_POSTS_HEADER,
                         apr_pstrdup(r->pool, posts_versions[i].post_name));
        }
    }

  /* Report commit capabilities. */
  for (i = 0; i < sizeof(capabilities)/sizeof(capabilities[0]); ++i)
    {
      /* If a master version is declared filter out unsupported
         capabilities. */
      if (master_version
          && (!svn_version__at_least(master_version,
                                     capabilities[i].min_version.major,
                                     capabilities[i].min_version.minor,
                                     capabilities[i].min_version.patch)))
        continue;

      apr_table_addn(r->headers_out, "DAV",
                     apr_pstrdup(r->pool, capabilities[i].capability_name));
    }

  return NULL;
}


static int
versionable(const dav_resource *resource)
{
  return 0;
}


static dav_auto_version
auto_versionable(const dav_resource *resource)
{
  /* The svn client attempts to proppatch a baseline when changing
     unversioned revision props.  Thus we allow baselines to be
     "auto-checked-out" by mod_dav.  See issue #916. */
  if (resource->type == DAV_RESOURCE_TYPE_VERSION
      && resource->baselined)
    return DAV_AUTO_VERSION_ALWAYS;

  /* No other autoversioning is allowed unless the SVNAutoversioning
     directive is used. */
  if (resource->info->repos->autoversioning)
    {
      /* This allows a straight-out PUT on a public file or collection
         VCR.  mod_dav's auto-versioning subsystem will check to see if
         it's possible to auto-checkout a regular resource. */
      if (resource->type == DAV_RESOURCE_TYPE_REGULAR)
        return DAV_AUTO_VERSION_ALWAYS;

      /* mod_dav's auto-versioning subsystem will also check to see if
         it's possible to auto-checkin a working resource that was
         auto-checked-out.  We *only* allow auto-versioning on a working
         resource if it was auto-checked-out. */
      if (resource->type == DAV_RESOURCE_TYPE_WORKING
          && resource->info->auto_checked_out)
        return DAV_AUTO_VERSION_ALWAYS;
    }

  /* Default:  whatever it is, assume it's not auto-versionable */
  return DAV_AUTO_VERSION_NEVER;
}


static dav_error *
vsn_control(dav_resource *resource, const char *target)
{
  /* All mod_dav_svn resources are versioned objects;  so it doesn't
     make sense to call vsn_control on a resource that exists . */
  if (resource->exists)
    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, 0,
                              "vsn_control called on already-versioned "
                              "resource.");

  /* Only allow a NULL target, which means an create an 'empty' VCR. */
  if (target != NULL)
    return dav_svn__new_error_svn(resource->pool, HTTP_NOT_IMPLEMENTED,
                                  SVN_ERR_UNSUPPORTED_FEATURE, 0,
                                  "vsn_control called with non-null target");

  /* This is kind of silly.  The docstring for this callback says it's
     supposed to "put a resource under version control".  But in
     Subversion, all REGULAR resources (bc's or public URIs) are
     already under version control. So we don't need to do a thing to
     the resource, just return. */
  return NULL;
}


dav_error *
dav_svn__checkout(dav_resource *resource,
                  int auto_checkout,
                  int is_unreserved,
                  int is_fork_ok,
                  int create_activity,
                  apr_array_header_t *activities,
                  dav_resource **working_resource)
{
  const char *txn_name;
  svn_error_t *serr;
  apr_status_t apr_err;
  dav_error *derr;
  dav_svn__uri_info parse;

  /* Auto-Versioning Stuff */
  if (auto_checkout)
    {
      const char *uuid_buf;
      void *data;
      const char *shared_activity, *shared_txn_name = NULL;

      /* Baselines can be auto-checked-out -- grudgingly -- so we can
         allow clients to proppatch unversioned rev props.  See issue
         #916. */
      if ((resource->type == DAV_RESOURCE_TYPE_VERSION)
          && resource->baselined)
        /* ### We're violating deltaV big time here, by allowing a
           dav_auto_checkout() on something that mod_dav assumes is a
           VCR, not a VR.  Anyway, mod_dav thinks we're checking out the
           resource 'in place', so that no working resource is returned.
           (It passes NULL as **working_resource.)  */
        return NULL;

      if (resource->type != DAV_RESOURCE_TYPE_REGULAR)
        return dav_svn__new_error_svn(resource->pool, HTTP_METHOD_NOT_ALLOWED,
                                      SVN_ERR_UNSUPPORTED_FEATURE, 0,
                                      "auto-checkout attempted on non-regular "
                                      "version-controlled resource");

      if (resource->baselined)
        return dav_svn__new_error_svn(resource->pool, HTTP_METHOD_NOT_ALLOWED,
                                      SVN_ERR_UNSUPPORTED_FEATURE, 0,
                                      "auto-checkout attempted on baseline "
                                      "collection, which is not supported");

      /* See if the shared activity already exists. */
      apr_err = apr_pool_userdata_get(&data,
                                      DAV_SVN__AUTOVERSIONING_ACTIVITY,
                                      resource->info->r->pool);
      if (apr_err)
        return dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
                                    HTTP_INTERNAL_SERVER_ERROR,
                                    "Error fetching pool userdata.",
                                    resource->pool);
      shared_activity = data;

      if (! shared_activity)
        {
          /* Build a shared activity for all auto-checked-out resources. */
          uuid_buf = svn_uuid_generate(resource->info->r->pool);
          shared_activity = apr_pstrdup(resource->info->r->pool, uuid_buf);

          derr = dav_svn__create_txn(resource->info->repos, &shared_txn_name,
                                     NULL, resource->info->r->pool);
          if (derr) return derr;

          derr = dav_svn__store_activity(resource->info->repos,
                                         shared_activity, shared_txn_name);
          if (derr) return derr;

          /* Save the shared activity in r->pool for others to use. */
          apr_err = apr_pool_userdata_set(shared_activity,
                                          DAV_SVN__AUTOVERSIONING_ACTIVITY,
                                          NULL, resource->info->r->pool);
          if (apr_err)
            return dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
                                        HTTP_INTERNAL_SERVER_ERROR,
                                        "Error setting pool userdata.",
                                        resource->pool);
        }

      if (! shared_txn_name)
        {
          shared_txn_name = dav_svn__get_txn(resource->info->repos,
                                             shared_activity);
          if (! shared_txn_name)
            return dav_svn__new_error(resource->pool,
                                      HTTP_INTERNAL_SERVER_ERROR, 0, 0,
                                      "Cannot look up a txn_name by activity");
        }

      /* Tweak the VCR in-place, making it into a WR.  (Ignore the
         NULL return value.) */
      dav_svn__create_working_resource(resource,
                                       shared_activity, shared_txn_name,
                                       TRUE /* tweak in place */);

      /* Remember that this resource was auto-checked-out, so that
         auto_versionable allows us to do an auto-checkin and
         can_be_activity will allow this resource to be an
         activity. */
      resource->info->auto_checked_out = TRUE;

      /* The txn and txn_root must be open and ready to go in the
         resource's root object.  Normally prep_resource() will do
         this automatically on a WR's root object.  We're
         converting a VCR to WR forcibly, so it's now our job to
         make sure it happens. */
      derr = open_txn(&resource->info->root.txn, resource->info->repos->fs,
                      resource->info->root.txn_name, resource->pool);
      if (derr) return derr;

      serr = svn_fs_txn_root(&resource->info->root.root,
                             resource->info->root.txn, resource->pool);
      if (serr != NULL)
        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                    "Could not open a (transaction) root "
                                    "in the repository",
                                    resource->pool);
      return NULL;
    }
  /* end of Auto-Versioning Stuff */

  if (resource->type != DAV_RESOURCE_TYPE_VERSION)
    {
      return dav_svn__new_error_svn(resource->pool, HTTP_METHOD_NOT_ALLOWED,
                                    SVN_ERR_UNSUPPORTED_FEATURE, 0,
                                    "CHECKOUT can only be performed on a "
                                    "version resource");
    }
  if (create_activity)
    {
      return dav_svn__new_error_svn(resource->pool, HTTP_NOT_IMPLEMENTED,
                                    SVN_ERR_UNSUPPORTED_FEATURE, 0,
                                    "CHECKOUT cannot create an activity at "
                                    "this time. Use MKACTIVITY first");
    }
  if (is_unreserved)
    {
      return dav_svn__new_error_svn(resource->pool, HTTP_NOT_IMPLEMENTED,
                                    SVN_ERR_UNSUPPORTED_FEATURE, 0,
                                    "Unreserved checkouts are not yet "
                                    "available. A version history may not be "
                                    "checked out more than once, into a "
                                    "specific activity");
    }
  if (activities == NULL)
    {
      return dav_svn__new_error_svn(resource->pool, HTTP_CONFLICT,
                                    SVN_ERR_INCOMPLETE_DATA, 0,
                                    "An activity must be provided for "
                                    "checkout");
    }
  /* assert: nelts > 0.  the below check effectively means > 1. */
  if (activities->nelts != 1)
    {
      return dav_svn__new_error_svn(resource->pool, HTTP_CONFLICT,
                                    SVN_ERR_INCORRECT_PARAMS, 0,
                                    "Only one activity may be specified within "
                                    "the CHECKOUT");
    }

  serr = dav_svn__simple_parse_uri(&parse, resource,
                                   APR_ARRAY_IDX(activities, 0, const char *),
                                   resource->pool);
  if (serr != NULL)
    {
      /* ### is BAD_REQUEST proper? */
      return dav_svn__convert_err(serr, HTTP_CONFLICT,
                                  "The activity href could not be parsed "
                                  "properly.",
                                  resource->pool);
    }
  if (parse.activity_id == NULL)
    {
      return dav_svn__new_error_svn(resource->pool, HTTP_CONFLICT,
                                    SVN_ERR_INCORRECT_PARAMS, 0,
                                    "The provided href is not an activity URI");
    }

  if ((txn_name = dav_svn__get_txn(resource->info->repos,
                                   parse.activity_id)) == NULL)
    {
      return dav_svn__new_error_svn(resource->pool, HTTP_CONFLICT,
                                    SVN_ERR_APMOD_ACTIVITY_NOT_FOUND, 0,
                                    "The specified activity does not exist");
    }

  /* verify the specified version resource is the "latest", thus allowing
     changes to be made. */
  if (resource->baselined || resource->info->root.rev == SVN_INVALID_REVNUM)
    {
      /* a Baseline, or a standard Version Resource which was accessed
         via a Label against a VCR within a Baseline Collection. */
      /* ### at the moment, this branch is only reached for baselines */

      svn_revnum_t youngest;

      /* make sure the baseline being checked out is the latest */
      serr = dav_svn__get_youngest_rev(&youngest, resource->info->repos,
                                       resource->pool);
      if (serr != NULL)
        {
          /* ### correct HTTP error? */
          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                      "Could not determine the youngest "
                                      "revision for verification against "
                                      "the baseline being checked out.",
                                      resource->pool);
        }

      if (resource->info->root.rev != youngest)
        {
          return dav_svn__new_error_svn(resource->pool, HTTP_CONFLICT,
                                        SVN_ERR_APMOD_BAD_BASELINE, 0,
                                        "The specified baseline is not the "
                                        "latest baseline, so it may not be "
                                        "checked out");
        }

      /* ### hmm. what if the transaction root's revision is different
         ### from this baseline? i.e. somebody created a new revision while
         ### we are processing this commit.
         ###
         ### first question: what does the client *do* with a working
         ### baseline? knowing that, and how it maps to our backend, then
         ### we can figure out what to do here. */
    }
  else
    {
      /* standard Version Resource */

      svn_fs_txn_t *txn;
      svn_fs_root_t *txn_root;
      svn_revnum_t txn_created_rev;
      dav_error *err;

      /* open the specified transaction so that we can verify this version
         resource corresponds to the current/latest in the transaction. */
      if ((err = open_txn(&txn, resource->info->repos->fs, txn_name,
                          resource->pool)) != NULL)
        return err;

      serr = svn_fs_txn_root(&txn_root, txn, resource->pool);
      if (serr != NULL)
        {
          /* ### correct HTTP error? */
          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                     "Could not open the transaction tree.",
                                     resource->pool);
        }

      /* assert: repos_path != NULL (for this type of resource) */


      /* Out-of-dateness check:  compare the created-rev of the item
         in the txn against the created-rev of the version resource
         being changed. */
      serr = svn_fs_node_created_rev(&txn_created_rev,
                                     txn_root, resource->info->repos_path,
                                     resource->pool);
      if (serr != NULL)
        {
          /* ### correct HTTP error? */
          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                      "Could not get created-rev of "
                                      "transaction node.",
                                      resource->pool);
        }

      /* If txn_created_rev is invalid, that means it's already
         mutable in the txn... which means it has already passed this
         out-of-dateness check.  (Usually, this happens when looking
         at a parent directory of an already checked-out
         resource.)

         Now, we come down to it.  If the created revision of the node
         in the transaction is different from the revision parsed from
         the version resource URL, we're in a bit of a quandry, and
         one of a few things could be true.

         - The client is trying to modify an old (out-of-date)
           revision of the resource.  This is, of course,
           unacceptable!

         - The client is trying to modify a *newer* revision.  If the
           version resource is *newer* than the transaction root, then
           the client started a commit, a new revision was created
           within the repository, the client fetched the new resource
           from that new revision, changed it (or merged in a prior
           change), and then attempted to incorporate that into the
           commit that was initially started.  We could copy that new
           node into our transaction and then modify it, but why
           bother?  We can stop the commit, and everything will be
           fine again if the user simply restarts it (because we'll
           use that new revision as the transaction root, thus
           incorporating the new resource, which they will then
           modify).

         - The path/revision that client is wishing to edit and the
           path/revision in the current transaction are actually the
           same node, and thus this created-rev comparison didn't
           really solidify anything after all. :-)
      */

      if (SVN_IS_VALID_REVNUM( txn_created_rev ))
        {
          if (resource->info->root.rev < txn_created_rev)
            {
              /* The item being modified is older than the one in the
                 transaction.  The client is out of date.  */
              return dav_svn__new_error_svn
                (resource->pool, HTTP_CONFLICT, SVN_ERR_FS_CONFLICT, 0,
                 "resource out of date; try updating");
            }
          else if (resource->info->root.rev > txn_created_rev)
            {
              /* The item being modified is being accessed via a newer
                 revision than the one in the transaction.  We'll
                 check to see if they are still the same node, and if
                 not, return an error. */
              svn_fs_node_relation_t node_relation;
              if ((serr = svn_fs_node_relation(&node_relation, txn_root,
                                               resource->info->repos_path,
                                               resource->info->root.root,
                                               resource->info->repos_path,
                                               resource->pool)))
                {
                  err = dav_svn__new_error_svn
                    (resource->pool, HTTP_CONFLICT, serr->apr_err, 0,
                     "Unable to fetch the node revision id of the version "
                     "resource within the revision");
                  svn_error_clear(serr);
                  return err;
                }
              if (node_relation != svn_fs_node_unchanged)
                {
                  return dav_svn__new_error_svn
                    (resource->pool, HTTP_CONFLICT, SVN_ERR_FS_CONFLICT, 0,
                     "version resource newer than txn (restart the commit)");
                }
            }
        }
    }
  *working_resource = dav_svn__create_working_resource(resource,
                                                       parse.activity_id,
                                                       txn_name,
                                                       FALSE);
  return NULL;
}


static dav_error *
uncheckout(dav_resource *resource)
{
  if (resource->type != DAV_RESOURCE_TYPE_WORKING)
    return dav_svn__new_error_svn(resource->pool, HTTP_INTERNAL_SERVER_ERROR,
                                  SVN_ERR_UNSUPPORTED_FEATURE, 0,
                                  "UNCHECKOUT called on non-working resource");

  /* Try to abort the txn if it exists;  but don't try too hard.  :-)  */
  if (resource->info->root.txn)
    svn_error_clear(svn_fs_abort_txn(resource->info->root.txn,
                                     resource->pool));

  /* Attempt to destroy the shared activity. */
  if (resource->info->root.activity_id)
    {
      dav_svn__delete_activity(resource->info->repos,
                               resource->info->root.activity_id);
      apr_pool_userdata_set(NULL, DAV_SVN__AUTOVERSIONING_ACTIVITY,
                            NULL, resource->info->r->pool);
    }

  resource->info->root.txn_name = NULL;
  resource->info->root.txn = NULL;

  /* We're no longer checked out. */
  resource->info->auto_checked_out = FALSE;

  /* Convert the working resource back into a regular one, in-place. */
  return dav_svn__working_to_regular_resource(resource);
}


/* Closure object for cleanup_deltify. */
struct cleanup_deltify_baton
{
  /* The repository in which to deltify.  We use a path instead of an
     object, because it's difficult to obtain a repos or fs object
     with the right lifetime guarantees. */
  const char *repos_path;

  /* The revision number against which to deltify. */
  svn_revnum_t revision;

  /* The pool to use for all temporary allocation while working.  This
     may or may not be the same as the pool on which the cleanup is
     registered, but obviously it must have a lifetime at least as
     long as that pool. */
  apr_pool_t *pool;
};


/* APR pool cleanup function to deltify against a just-committed
   revision.  DATA is a 'struct cleanup_deltify_baton *'.

   If any errors occur, log them in the httpd server error log, but
   return APR_SUCCESS no matter what, as this is a pool cleanup
   function and deltification is not a matter of correctness
   anyway. */
static apr_status_t
cleanup_deltify(void *data)
{
  struct cleanup_deltify_baton *cdb = data;
  svn_repos_t *repos;
  svn_error_t *err;

  /* It's okay to allocate in the pool that's being cleaned up, and
     it's also okay to register new cleanups against that pool.  But
     if you create subpools of it, you must make sure to destroy them
     at the end of the cleanup.  So we do all our work in this
     subpool, then destroy it before exiting. */
  apr_pool_t *subpool = svn_pool_create(cdb->pool);

  err = svn_repos_open3(&repos, cdb->repos_path, NULL, subpool, subpool);
  if (err)
    {
      ap_log_perror(APLOG_MARK, APLOG_ERR, err->apr_err, cdb->pool,
                    "cleanup_deltify: error opening repository '%s'",
                    cdb->repos_path);
      svn_error_clear(err);
      goto cleanup;
    }

  err = svn_fs_deltify_revision(svn_repos_fs(repos),
                                cdb->revision, subpool);
  if (err)
    {
      ap_log_perror(APLOG_MARK, APLOG_ERR, err->apr_err, cdb->pool,
                    "cleanup_deltify: error deltifying against revision %ld"
                    " in repository '%s'",
                    cdb->revision, cdb->repos_path);
      svn_error_clear(err);
    }

 cleanup:
  svn_pool_destroy(subpool);

  return APR_SUCCESS;
}


/* Register the cleanup_deltify function on POOL, which should be the
   connection pool for the request.  This way the time needed for
   deltification won't delay the response to the client.

   REPOS is the repository in which deltify, and REVISION is the
   revision against which to deltify.  POOL is both the pool on which
   to register the cleanup function and the pool that will be used for
   temporary allocations while deltifying. */
static void
register_deltification_cleanup(svn_repos_t *repos,
                               svn_revnum_t revision,
                               apr_pool_t *pool)
{
  struct cleanup_deltify_baton *cdb = apr_palloc(pool, sizeof(*cdb));

  cdb->repos_path = svn_repos_path(repos, pool);
  cdb->revision = revision;
  cdb->pool = pool;

  apr_pool_cleanup_register(pool, cdb, cleanup_deltify, apr_pool_cleanup_null);
}


dav_error *
dav_svn__checkin(dav_resource *resource,
                 int keep_checked_out,
                 dav_resource **version_resource)
{
  svn_error_t *serr;
  dav_error *err;
  apr_status_t apr_err;
  const char *uri;
  const char *shared_activity;
  void *data;

  /* ### mod_dav has a flawed architecture, in the sense that it first
     tries to auto-checkin the modified resource, then attempts to
     auto-checkin the parent resource (if the parent resource was
     auto-checked-out).  Instead, the provider should be in charge:
     mod_dav should provide a *set* of resources that need
     auto-checkin, and the provider can decide how to do it.  (One
     txn?  Many txns?  Etc.) */

  if (resource->type != DAV_RESOURCE_TYPE_WORKING)
    return dav_svn__new_error_svn(resource->pool, HTTP_INTERNAL_SERVER_ERROR,
                                  SVN_ERR_UNSUPPORTED_FEATURE, 0,
                                  "CHECKIN called on non-working resource");

  /* If the global autoversioning activity still exists, that means
     nobody's committed it yet. */
  apr_err = apr_pool_userdata_get(&data,
                                  DAV_SVN__AUTOVERSIONING_ACTIVITY,
                                  resource->info->r->pool);
  if (apr_err)
    return dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
                                HTTP_INTERNAL_SERVER_ERROR,
                                "Error fetching pool userdata.",
                                resource->pool);
  shared_activity = data;

  /* Try to commit the txn if it exists. */
  if (shared_activity
      && (strcmp(shared_activity, resource->info->root.activity_id) == 0))
    {
      const char *shared_txn_name;
      const char *conflict_msg;
      svn_revnum_t new_rev;

      shared_txn_name = dav_svn__get_txn(resource->info->repos,
                                         shared_activity);
      if (! shared_txn_name)
        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR,
                                  0, 0,
                                  "Cannot look up a txn_name by activity");

      /* Sanity checks */
      if (resource->info->root.txn_name
          && (strcmp(shared_txn_name, resource->info->root.txn_name) != 0))
        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR,
                                  0, 0,
                                  "Internal txn_name doesn't match "
                                  "autoversioning transaction.");

      if (! resource->info->root.txn)
        /* should already be open by checkout */
        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR,
                                  0, 0,
                                  "Autoversioning txn isn't open "
                                  "when it should be.");

      err = set_auto_revprops(resource);
      if (err)
        return err;

      serr = svn_repos_fs_commit_txn(&conflict_msg,
                                     resource->info->repos->repos,
                                     &new_rev,
                                     resource->info->root.txn,
                                     resource->pool);

      if (SVN_IS_VALID_REVNUM(new_rev))
        {
          if (serr)
            {
              const char *post_commit_err = svn_repos__post_commit_error_str
                                              (serr, resource->pool);
              ap_log_perror(APLOG_MARK, APLOG_ERR, APR_EGENERAL,
                            resource->pool,
                            "commit of r%ld succeeded, but an error occurred "
                            "after the commit: '%s'",
                            new_rev,
                            post_commit_err);
              svn_error_clear(serr);
              serr = SVN_NO_ERROR;
            }
        }
      else
        {
          const char *msg;
          svn_error_clear(svn_fs_abort_txn(resource->info->root.txn,
                                           resource->pool));

          /* Attempt to destroy the shared activity. */
          dav_svn__delete_activity(resource->info->repos, shared_activity);
          apr_pool_userdata_set(NULL, DAV_SVN__AUTOVERSIONING_ACTIVITY,
                                NULL, resource->info->r->pool);

          if (serr)
            {
              int status;

              if (serr->apr_err == SVN_ERR_FS_CONFLICT)
                {
                  status = HTTP_CONFLICT;
                  msg = apr_psprintf(resource->pool,
                                     "A conflict occurred during the CHECKIN "
                                     "processing. The problem occurred with  "
                                     "the \"%s\" resource.",
                                     conflict_msg);
                }
              else
                {
                  status = HTTP_INTERNAL_SERVER_ERROR;
                  msg = "An error occurred while committing the transaction.";
                }

              return dav_svn__convert_err(serr, status, msg, resource->pool);
            }
          else
            {
              return dav_svn__new_error(resource->pool,
                                        HTTP_INTERNAL_SERVER_ERROR,
                                        0, 0,
                                        "Commit failed but there was no error "
                                        "provided.");
            }
        }

      /* Attempt to destroy the shared activity. */
      dav_svn__delete_activity(resource->info->repos, shared_activity);
      apr_pool_userdata_set(NULL, DAV_SVN__AUTOVERSIONING_ACTIVITY,
                            NULL, resource->info->r->pool);

      /* Commit was successful, so schedule deltification. */
      register_deltification_cleanup(resource->info->repos->repos,
                                     new_rev,
                                     resource->info->r->connection->pool);

      /* If caller wants it, return the new VR that was created by
         the checkin. */
      if (version_resource)
        {
          uri = dav_svn__build_uri(resource->info->repos,
                                   DAV_SVN__BUILD_URI_VERSION,
                                   new_rev, resource->info->repos_path,
                                   FALSE /* add_href */, resource->pool);

          err = dav_svn__create_version_resource(version_resource, uri,
                                                 resource->pool);
          if (err)
            return err;
        }
    } /* end of commit stuff */

  /* The shared activity was either nonexistent to begin with, or it's
     been committed and is only now nonexistent.  The resource needs
     to forget about it. */
  resource->info->root.txn_name = NULL;
  resource->info->root.txn = NULL;

  /* Convert the working resource back into an regular one. */
  if (! keep_checked_out)
    {
      resource->info->auto_checked_out = FALSE;
      return dav_svn__working_to_regular_resource(resource);
    }

  return NULL;
}


static dav_error *
avail_reports(const dav_resource *resource, const dav_report_elem **reports)
{
  /* ### further restrict to the public space? */
  if (resource->type != DAV_RESOURCE_TYPE_REGULAR) {
    *reports = NULL;
    return NULL;
  }

  *reports = dav_svn__reports_list;
  return NULL;
}


static int
report_label_header_allowed(const apr_xml_doc *doc)
{
  return 0;
}


static dav_error *
deliver_report(request_rec *r,
               const dav_resource *resource,
               const apr_xml_doc *doc,
               ap_filter_t *unused)
{
  int ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);

  if (doc->root->ns == ns)
    {
      dav_svn__output *output;

      output = dav_svn__output_create(resource->info->r, resource->pool);

      /* ### note that these report names should have symbols... */

      if (strcmp(doc->root->name, "update-report") == 0)
        {
          return dav_svn__update_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, "log-report") == 0)
        {
          return dav_svn__log_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, "dated-rev-report") == 0)
        {
          return dav_svn__dated_rev_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, "get-locations") == 0)
        {
          return dav_svn__get_locations_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, "get-location-segments") == 0)
        {
          return dav_svn__get_location_segments_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, "file-revs-report") == 0)
        {
          return dav_svn__file_revs_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, "get-locks-report") == 0)
        {
          return dav_svn__get_locks_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, "replay-report") == 0)
        {
          return dav_svn__replay_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, SVN_DAV__MERGEINFO_REPORT) == 0)
        {
          return dav_svn__get_mergeinfo_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, "get-deleted-rev-report") == 0)
        {
          return dav_svn__get_deleted_rev_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, SVN_DAV__INHERITED_PROPS_REPORT) == 0)
        {
          return dav_svn__get_inherited_props_report(resource, doc, output);
        }
      else if (strcmp(doc->root->name, "list-report") == 0)
        {
          return dav_svn__list_report(resource, doc, output);
        }
      /* NOTE: if you add a report, don't forget to add it to the
       *       dav_svn__reports_list[] array.
       */
    }

  /* ### what is a good error for an unknown report? */
  return dav_svn__new_error_svn(resource->pool, HTTP_NOT_IMPLEMENTED,
                                SVN_ERR_UNSUPPORTED_FEATURE, 0,
                                "The requested report is unknown");
}


static int
can_be_activity(const dav_resource *resource)
{
  /* If our resource is marked as auto_checked_out'd, then we allow this to
   * be an activity URL.  Otherwise, it must be a real activity URL that
   * doesn't already exist.
   */
  return (resource->info->auto_checked_out ||
          (resource->type == DAV_RESOURCE_TYPE_ACTIVITY &&
           !resource->exists));
}


static dav_error *
make_activity(dav_resource *resource)
{
  const char *activity_id = resource->info->root.activity_id;
  const char *txn_name;
  dav_error *err;

  /* sanity check:  make sure the resource is a valid activity, in
     case an older mod_dav doesn't do the check for us. */
  if (! can_be_activity(resource))
    return dav_svn__new_error_svn(resource->pool, HTTP_FORBIDDEN,
                                  SVN_ERR_APMOD_MALFORMED_URI, 0,
                                  "Activities cannot be created at that "
                                  "location; query the "
                                  "DAV:activity-collection-set property");

  err = dav_svn__create_txn(resource->info->repos, &txn_name,
                            NULL, resource->pool);
  if (err != NULL)
    return err;

  err = dav_svn__store_activity(resource->info->repos, activity_id, txn_name);
  if (err != NULL)
    return err;

  /* everything is happy. update the resource */
  resource->info->root.txn_name = txn_name;
  resource->exists = 1;
  return NULL;
}


dav_error *
dav_svn__build_lock_hash(apr_hash_t **locks,
                         request_rec *r,
                         const char *path_prefix,
                         apr_pool_t *pool)
{
  apr_status_t apr_err;
  dav_error *derr;
  void *data = NULL;
  apr_xml_doc *doc = NULL;
  apr_xml_elem *child, *lockchild;
  int ns;
  apr_hash_t *hash = apr_hash_make(pool);

  /* Grab the request body out of r->pool, as it contains all of the
     lock tokens.  It should have been stashed already by our custom
     input filter. */
  apr_err = apr_pool_userdata_get(&data, "svn-request-body", r->pool);
  if (apr_err)
    return dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
                                HTTP_INTERNAL_SERVER_ERROR,
                                "Error fetching pool userdata.",
                                pool);
  doc = data;
  if (! doc)
    {
      *locks = hash;
      return NULL;
    }

  /* Sanity check. */
  ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
  if (ns == -1)
    {
      /* If there's no svn: namespace in the body, then there are
         definitely no lock-tokens to harvest.  This is likely a
         request from an old client. */
      *locks = hash;
      return NULL;
    }

  if ((doc->root->ns == ns)
      && (strcmp(doc->root->name, "lock-token-list") == 0))
    {
      child = doc->root;
    }
  else
    {
      /* Search doc's children until we find the <lock-token-list>. */
      for (child = doc->root->first_child; child != NULL; child = child->next)
        {
          /* if this element isn't one of ours, then skip it */
          if (child->ns != ns)
            continue;

          if (strcmp(child->name, "lock-token-list") == 0)
            break;
        }
    }

  /* Did we find what we were looking for? */
  if (! child)
    {
      *locks = hash;
      return NULL;
    }

  /* Then look for N different <lock> structures within. */
  for (lockchild = child->first_child; lockchild != NULL;
       lockchild = lockchild->next)
    {
      const char *lockpath = NULL, *locktoken = NULL;
      apr_xml_elem *lfchild;

      if (strcmp(lockchild->name, "lock") != 0)
        continue;

      for (lfchild = lockchild->first_child; lfchild != NULL;
           lfchild = lfchild->next)
        {
          if (strcmp(lfchild->name, "lock-path") == 0)
            {
              const char *cdata = dav_xml_get_cdata(lfchild, pool, 0);
              if ((derr = dav_svn__test_canonical(cdata, pool)))
                return derr;

              /* Create an absolute fs-path */
              lockpath = svn_fspath__join(path_prefix, cdata, pool);
              if (lockpath && locktoken)
                {
                  svn_hash_sets(hash, lockpath, locktoken);
                  lockpath = NULL;
                  locktoken = NULL;
                }
            }
          else if (strcmp(lfchild->name, "lock-token") == 0)
            {
              locktoken = dav_xml_get_cdata(lfchild, pool, 1);
              if (lockpath && *locktoken)
                {
                  svn_hash_sets(hash, lockpath, locktoken);
                  lockpath = NULL;
                  locktoken = NULL;
                }
            }
        }
    }

  *locks = hash;
  return NULL;
}


dav_error *
dav_svn__push_locks(dav_resource *resource,
                    apr_hash_t *locks,
                    apr_pool_t *pool)
{
  svn_fs_access_t *fsaccess;
  apr_hash_index_t *hi;
  svn_error_t *serr;

  serr = svn_fs_get_access(&fsaccess, resource->info->repos->fs);
  if (serr || !fsaccess)
    {
      /* If an authenticated user name was attached to the request,
         then dav_svn_get_resource() should have already noticed and
         created an fs_access_t in the filesystem.  */
      if (serr == NULL)
        serr = svn_error_create(SVN_ERR_FS_LOCK_OWNER_MISMATCH, NULL, NULL);
      return dav_svn__sanitize_error(serr, "Lock token(s) in request, but "
                                     "missing an user name", HTTP_BAD_REQUEST,
                                     resource->info->r);
    }

  for (hi = apr_hash_first(pool, locks); hi; hi = apr_hash_next(hi))
    {
      const char *path, *token;
      const void *key;
      void *val;
      apr_hash_this(hi, &key, NULL, &val);
      path = key, token = val;

      serr = svn_fs_access_add_lock_token2(fsaccess, path, token);
      if (serr)
        return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                    "Error pushing token into filesystem.",
                                    pool);
    }

  return NULL;
}

/* Implements svn_fs_lock_callback_t. */
static svn_error_t *
unlock_many_cb(void *lock_baton,
               const char *path,
               const svn_lock_t *lock,
               svn_error_t *fs_err,
               apr_pool_t *pool)
{
  request_rec *r = lock_baton;

  if (fs_err)
    ap_log_rerror(APLOG_MARK, APLOG_ERR, fs_err->apr_err, r,
                  "%s", fs_err->message);

  return SVN_NO_ERROR;
}


/* Helper for merge().  Free every lock in LOCKS.  The locks
   live in REPOS.  Log any errors for REQUEST.  Use POOL for temporary
   work.*/
static svn_error_t *
release_locks(apr_hash_t *locks,
              svn_repos_t *repos,
              request_rec *r,
              apr_pool_t *pool)
{
  apr_pool_t *subpool = svn_pool_create(pool);
  svn_error_t *err;

  err = svn_repos_fs_unlock_many(repos, locks, FALSE, unlock_many_cb, r,
                                 subpool, subpool);

  if (err) /* If we got an error, just log it and move along. */
    ap_log_rerror(APLOG_MARK, APLOG_ERR, err->apr_err, r,
                  "%s", err->message);
  svn_error_clear(err);

  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}


static dav_error *
merge(dav_resource *target,
      dav_resource *source,
      int no_auto_merge,
      int no_checkout,
      apr_xml_elem *prop_elem,
      ap_filter_t *unused)
{
  apr_pool_t *pool;
  dav_error *err;
  svn_fs_txn_t *txn;
  const char *conflict;
  svn_error_t *serr;
  const char *post_commit_err = NULL;
  svn_revnum_t new_rev;
  apr_hash_t *locks;
  svn_boolean_t disable_merge_response = FALSE;
  dav_svn__output *output;

  /* We'll use the target's pool for our operation. We happen to know that
     it matches the request pool, which (should) have the proper lifetime. */
  pool = target->pool;

  /* ### what to verify on the target? */

  /* ### anything else for the source? */
  if (! (source->type == DAV_RESOURCE_TYPE_ACTIVITY
         || (source->type == DAV_RESOURCE_TYPE_PRIVATE
             && source->info->restype == DAV_SVN_RESTYPE_TXN_COLLECTION)))
    {
      return dav_svn__new_error_svn(pool, HTTP_METHOD_NOT_ALLOWED,
                                    SVN_ERR_INCORRECT_PARAMS, 0,
                                    "MERGE can only be performed using an "
                                    "activity or transaction resource as the "
                                    "source");
    }
  if (! source->exists)
    {
      return dav_svn__new_error_svn(pool, HTTP_METHOD_NOT_ALLOWED,
                                    SVN_ERR_INCORRECT_PARAMS, 0,
                                    "MERGE activity or transaction resource "
                                    "does not exist");
    }

  /* Before attempting the final commit, we need to push any incoming
     lock-tokens into the filesystem's access_t.   Normally they come
     in via 'If:' header, and dav_svn_get_resource() automatically
     notices them and does this work for us.  In the case of MERGE,
     however, svn clients are sending them in the request body. */

  err = dav_svn__build_lock_hash(&locks, target->info->r,
                                 target->info->repos_path,
                                 pool);
  if (err != NULL)
    return err;

  if (apr_hash_count(locks))
    {
      err = dav_svn__push_locks(source, locks, pool);
      if (err != NULL)
        return err;
    }

  /* We will ignore no_auto_merge and no_checkout. We can't do those, but the
     client has no way to assert that we *should* do them. This should be fine
     because, presumably, the client has no way to do the various checkouts
     and things that would necessitate an auto-merge or checkout during the
     MERGE processing. */

  /* open the transaction that we're going to commit. */
  if ((err = open_txn(&txn, source->info->repos->fs,
                      source->info->root.txn_name, pool)) != NULL)
    return err;

  /* all righty... commit the bugger. */
  serr = svn_repos_fs_commit_txn(&conflict, source->info->repos->repos,
                                 &new_rev, txn, pool);

  /* ### TODO: Figure out if the MERGE response can grow a means by
     which to marshal back both the success of the commit (and its
     commit info) and the failure of the post-commit hook.  */
  if (SVN_IS_VALID_REVNUM(new_rev))
    {
      if (serr)
        {
          /* ### Any error from svn_fs_commit_txn() itself, and not
             ### the post-commit script, should be reported to the
             ### client some other way than hijacking the post-commit
             ### error message.*/
          post_commit_err = svn_repos__post_commit_error_str(serr, pool);
          ap_log_perror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, pool,
                        "commit of r%ld succeeded, but an error occurred "
                        "after the commit: '%s'",
                        new_rev,
                        post_commit_err);
          svn_error_clear(serr);
          serr = SVN_NO_ERROR;
        }

      /* HTTPv2 doesn't send DELETE after a successful MERGE so if
         using the optional vtxn name mapping then delete it here. */
      if (source->info->root.vtxn_name)
        dav_svn__delete_activity(source->info->repos,
                                 source->info->root.vtxn_name);
    }
  else
    {
      svn_error_clear(svn_fs_abort_txn(txn, pool));

      if (serr)
        {
          const char *msg;
          int status;

          if (serr->apr_err == SVN_ERR_FS_CONFLICT)
            {
              status = HTTP_CONFLICT;
              /* ### we need to convert the conflict path into a URI */
              msg = apr_psprintf(pool,
                                 "A conflict occurred during the MERGE "
                                 "processing. The problem occurred with the "
                                 "\"%s\" resource.",
                                 conflict);
            }
          else
            {
              status = HTTP_INTERNAL_SERVER_ERROR;
              msg = "An error occurred while committing the transaction.";
            }

          return dav_svn__convert_err(serr, status, msg, pool);
        }
      else
        {
          return dav_svn__new_error(pool,
                                    HTTP_INTERNAL_SERVER_ERROR,
                                    0, 0,
                                    "Commit failed but there was no error "
                                    "provided.");
        }
    }

  /* Commit was successful, so schedule deltification. */
  register_deltification_cleanup(source->info->repos->repos, new_rev,
                                 source->info->r->connection->pool);

  /* We've detected a 'high level' svn action to log. */
  dav_svn__operational_log(target->info,
                           svn_log__commit(new_rev, target->info->r->pool));

  /* Since the commit was successful, the txn ID is no longer valid.
     If we're using activities, store an empty txn ID in the activity
     database so that when the client deletes the activity, we don't
     try to open and abort the transaction. */
  if (source->type == DAV_RESOURCE_TYPE_ACTIVITY)
    {
      err = dav_svn__store_activity(source->info->repos,
                                    source->info->root.activity_id, "");
      if (err != NULL)
        return err;
    }

  /* Check the dav_resource->info area for information about the
     special X-SVN-Options: header that may have come in the http
     request. */
  if (source->info->svn_client_options != NULL)
    {
      /* The client might want us to release all locks sent in the
         MERGE request. */
      if ((NULL != (ap_strstr_c(source->info->svn_client_options,
                                SVN_DAV_OPTION_RELEASE_LOCKS)))
          && apr_hash_count(locks))
        {
          serr = release_locks(locks, source->info->repos->repos,
                               source->info->r, pool);
          if (serr != NULL)
            return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
                                        "Error releasing locks", pool);
        }

      /* The client might want us to disable the merge response altogether. */
      if (NULL != (ap_strstr_c(source->info->svn_client_options,
                               SVN_DAV_OPTION_NO_MERGE_RESPONSE)))
        disable_merge_response = TRUE;
    }

  /* process the response for the new revision. */
  output = dav_svn__output_create(target->info->r, pool);
  return dav_svn__merge_response(output, source->info->repos, new_rev,
                                 post_commit_err, prop_elem,
                                 disable_merge_response, pool);
}


const dav_hooks_vsn dav_svn__hooks_vsn = {
  get_vsn_options,
  get_option,
  versionable,
  auto_versionable,
  vsn_control,
  dav_svn__checkout,
  uncheckout,
  dav_svn__checkin,
  avail_reports,
  report_label_header_allowed,
  deliver_report,
  NULL,                 /* update */
  NULL,                 /* add_label */
  NULL,                 /* remove_label */
  NULL,                 /* can_be_workspace */
  NULL,                 /* make_workspace */
  can_be_activity,
  make_activity,
  merge,
};
