/*
 * mergeinfo.c :  merge history functions for the libsvn_client library
 *
 * ====================================================================
 *    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_pools.h>
#include <apr_strings.h>

#include "svn_pools.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_string.h"
#include "svn_opt.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_props.h"
#include "svn_mergeinfo.h"
#include "svn_sorts.h"
#include "svn_ra.h"
#include "svn_client.h"
#include "svn_hash.h"

#include "private/svn_client_private.h"
#include "private/svn_opt_private.h"
#include "private/svn_mergeinfo_private.h"
#include "private/svn_ra_private.h"
#include "private/svn_sorts_private.h"
#include "private/svn_wc_private.h"
#include "private/svn_fspath.h"
#include "client.h"
#include "mergeinfo.h"
#include "svn_private_config.h"



svn_client__merge_path_t *
svn_client__merge_path_dup(const svn_client__merge_path_t *old,
                           apr_pool_t *pool)
{
  svn_client__merge_path_t *new = apr_pmemdup(pool, old, sizeof(*old));

  new->abspath = apr_pstrdup(pool, old->abspath);
  if (new->remaining_ranges)
    new->remaining_ranges = svn_rangelist_dup(old->remaining_ranges, pool);
  if (new->pre_merge_mergeinfo)
    new->pre_merge_mergeinfo = svn_mergeinfo_dup(old->pre_merge_mergeinfo,
                                                 pool);
  if (new->implicit_mergeinfo)
    new->implicit_mergeinfo = svn_mergeinfo_dup(old->implicit_mergeinfo,
                                                pool);

  return new;
}

svn_client__merge_path_t *
svn_client__merge_path_create(const char *abspath,
                              apr_pool_t *pool)
{
  svn_client__merge_path_t *result = apr_pcalloc(pool, sizeof(*result));

  result->abspath = apr_pstrdup(pool, abspath);
  return result;
}

svn_error_t *
svn_client__parse_mergeinfo(svn_mergeinfo_t *mergeinfo,
                            svn_wc_context_t *wc_ctx,
                            const char *local_abspath,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
{
  const svn_string_t *propval;

  *mergeinfo = NULL;

  /* ### Use svn_wc_prop_get() would actually be sufficient for now.
     ### DannyB thinks that later we'll need behavior more like
     ### svn_client__get_prop_from_wc(). */
  SVN_ERR(svn_wc_prop_get2(&propval, wc_ctx, local_abspath, SVN_PROP_MERGEINFO,
                           scratch_pool, scratch_pool));
  if (propval)
    SVN_ERR(svn_mergeinfo_parse(mergeinfo, propval->data, result_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__record_wc_mergeinfo(const char *local_abspath,
                                svn_mergeinfo_t mergeinfo,
                                svn_boolean_t do_notification,
                                svn_client_ctx_t *ctx,
                                apr_pool_t *scratch_pool)
{
  svn_string_t *mergeinfo_str = NULL;
  svn_boolean_t mergeinfo_changes = FALSE;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));

  /* Convert MERGEINFO (if any) into text for storage as a property value. */
  if (mergeinfo)
    SVN_ERR(svn_mergeinfo_to_string(&mergeinfo_str, mergeinfo, scratch_pool));

  if (do_notification && ctx->notify_func2)
    SVN_ERR(svn_client__mergeinfo_status(&mergeinfo_changes, ctx->wc_ctx,
                                         local_abspath, scratch_pool));

  /* Record the new mergeinfo in the WC. */
  /* ### Later, we'll want behavior more analogous to
     ### svn_client__get_prop_from_wc(). */
  SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, local_abspath, SVN_PROP_MERGEINFO,
                           mergeinfo_str, svn_depth_empty,
                           TRUE /* skip checks */, NULL,
                           NULL, NULL /* cancellation */,
                           NULL, NULL /* notification */,
                           scratch_pool));

  if (do_notification && ctx->notify_func2)
    {
      svn_wc_notify_t *notify =
        svn_wc_create_notify(local_abspath,
                             svn_wc_notify_merge_record_info,
                             scratch_pool);
      if (mergeinfo_changes)
        notify->prop_state = svn_wc_notify_state_merged;
      else
        notify->prop_state = svn_wc_notify_state_changed;

      ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__record_wc_mergeinfo_catalog(apr_hash_t *result_catalog,
                                        svn_client_ctx_t *ctx,
                                        apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);

  if (apr_hash_count(result_catalog))
    {
      int i;
      apr_array_header_t *sorted_cat =
        svn_sort__hash(result_catalog, svn_sort_compare_items_as_paths,
                       scratch_pool);

      /* Write the mergeinfo out in sorted order of the paths (presumably just
       * so that the notifications are in a predictable, convenient order). */
      for (i = 0; i < sorted_cat->nelts; i++)
        {
          svn_sort__item_t elt = APR_ARRAY_IDX(sorted_cat, i,
                                               svn_sort__item_t);
          svn_error_t *err;

          svn_pool_clear(iterpool);
          err = svn_client__record_wc_mergeinfo(elt.key, elt.value, TRUE,
                                                ctx, iterpool);

          if (err && err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
            {
              /* PATH isn't just missing, it's not even versioned as far
                 as this working copy knows.  But it was included in
                 MERGES, which means that the server knows about it.
                 Likely we don't have access to the source due to authz
                 restrictions.  For now just clear the error and
                 continue... */
              svn_error_clear(err);
            }
          else
            {
              SVN_ERR(err);
            }
        }
    }
  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/*-----------------------------------------------------------------------*/

/*** Retrieving mergeinfo. ***/

svn_error_t *
svn_client__get_wc_mergeinfo(svn_mergeinfo_t *mergeinfo,
                             svn_boolean_t *inherited_p,
                             svn_mergeinfo_inheritance_t inherit,
                             const char *local_abspath,
                             const char *limit_abspath,
                             const char **walked_path,
                             svn_boolean_t ignore_invalid_mergeinfo,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
{
  const char *walk_relpath = "";
  svn_mergeinfo_t wc_mergeinfo;
  svn_revnum_t base_revision;
  apr_pool_t *iterpool;
  svn_boolean_t inherited;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
  if (limit_abspath)
    SVN_ERR_ASSERT(svn_dirent_is_absolute(limit_abspath));

  SVN_ERR(svn_wc__node_get_base(NULL, &base_revision, NULL, NULL, NULL, NULL,
                                ctx->wc_ctx, local_abspath,
                                TRUE /* ignore_enoent */,
                                scratch_pool, scratch_pool));

  iterpool = svn_pool_create(scratch_pool);
  while (TRUE)
    {
      svn_pool_clear(iterpool);

      /* Don't look for explicit mergeinfo on LOCAL_ABSPATH if we are only
         interested in inherited mergeinfo. */
      if (inherit == svn_mergeinfo_nearest_ancestor)
        {
          wc_mergeinfo = NULL;
          inherit = svn_mergeinfo_inherited;
        }
      else
        {
          /* Look for mergeinfo on LOCAL_ABSPATH.  If there isn't any and we
             want inherited mergeinfo, walk towards the root of the WC until
             we encounter either (a) an unversioned directory, or
             (b) mergeinfo.  If we encounter (b), use that inherited
             mergeinfo as our baseline. */
          svn_error_t *err = svn_client__parse_mergeinfo(&wc_mergeinfo,
                                                         ctx->wc_ctx,
                                                         local_abspath,
                                                         result_pool,
                                                         iterpool);
          if ((ignore_invalid_mergeinfo || walk_relpath [0] != '\0')
              && err
              && err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
            {
              svn_error_clear(err);
              wc_mergeinfo = apr_hash_make(result_pool);
              break;
            }
          else
            {
              SVN_ERR(err);
            }
        }

      if (wc_mergeinfo == NULL &&
          inherit != svn_mergeinfo_explicit &&
          !svn_dirent_is_root(local_abspath, strlen(local_abspath)))
        {
          svn_boolean_t is_wc_root;
          svn_boolean_t is_switched;
          svn_revnum_t parent_base_rev;
          svn_revnum_t parent_changed_rev;

          /* Don't look any higher than the limit path. */
          if (limit_abspath && strcmp(limit_abspath, local_abspath) == 0)
            break;

          /* If we've reached the root of the working copy don't look any
             higher. */
          SVN_ERR(svn_wc_check_root(&is_wc_root, &is_switched, NULL,
                                    ctx->wc_ctx, local_abspath, iterpool));
          if (is_wc_root || is_switched)
            break;

          /* No explicit mergeinfo on this path.  Look higher up the
             directory tree while keeping track of what we've walked. */
          walk_relpath = svn_relpath_join(svn_dirent_basename(local_abspath,
                                                              iterpool),
                                          walk_relpath, result_pool);
          local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);

          SVN_ERR(svn_wc__node_get_base(NULL, &parent_base_rev, NULL, NULL,
                                        NULL, NULL,
                                        ctx->wc_ctx, local_abspath,
                                        TRUE /* ignore_enoent */,
                                        scratch_pool, scratch_pool));

          /* ### This checks the WORKING changed_rev, so invalid on replacement
             ### not even reliable in case an ancestor was copied from a
             ### different location */
          SVN_ERR(svn_wc__node_get_changed_info(&parent_changed_rev,
                                                NULL, NULL,
                                                ctx->wc_ctx, local_abspath,
                                                scratch_pool,
                                                scratch_pool));

          /* Look in LOCAL_ABSPATH's parent for inherited mergeinfo if
             LOCAL_ABSPATH has no base revision because it is an uncommitted
             addition, or if its base revision falls within the inclusive
             range of its parent's last changed revision to the parent's base
             revision; otherwise stop looking for inherited mergeinfo. */
          if (SVN_IS_VALID_REVNUM(base_revision)
              && (base_revision < parent_changed_rev
                  || parent_base_rev < base_revision))
            break;

          /* We haven't yet risen above the root of the WC. */
          continue;
        }
      break;
    }

  svn_pool_destroy(iterpool);

  if (svn_path_is_empty(walk_relpath))
    {
      /* Mergeinfo is explicit. */
      inherited = FALSE;
      *mergeinfo = wc_mergeinfo;
    }
  else
    {
      /* Mergeinfo may be inherited. */
      if (wc_mergeinfo)
        {
          inherited = TRUE;
          SVN_ERR(svn_mergeinfo__add_suffix_to_mergeinfo(mergeinfo,
                                                         wc_mergeinfo,
                                                         walk_relpath,
                                                         result_pool,
                                                         scratch_pool));
        }
      else
        {
          inherited = FALSE;
          *mergeinfo = NULL;
        }
    }

  if (walked_path)
    *walked_path = walk_relpath;

  /* Remove non-inheritable mergeinfo and paths mapped to empty ranges
     which may occur if WCPATH's mergeinfo is not explicit. */
  if (inherited
      && apr_hash_count(*mergeinfo)) /* Nothing to do for empty mergeinfo. */
    {
      SVN_ERR(svn_mergeinfo_inheritable2(mergeinfo, *mergeinfo, NULL,
                                         SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
                                         TRUE, result_pool, scratch_pool));
      svn_mergeinfo__remove_empty_rangelists(*mergeinfo, scratch_pool);
    }

  if (inherited_p)
    *inherited_p = inherited;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__get_wc_mergeinfo_catalog(svn_mergeinfo_catalog_t *mergeinfo_cat,
                                     svn_boolean_t *inherited,
                                     svn_boolean_t include_descendants,
                                     svn_mergeinfo_inheritance_t inherit,
                                     const char *local_abspath,
                                     const char *limit_path,
                                     const char **walked_path,
                                     svn_boolean_t ignore_invalid_mergeinfo,
                                     svn_client_ctx_t *ctx,
                                     apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool)
{
  const char *target_repos_relpath;
  svn_mergeinfo_t mergeinfo;
  const char *repos_root;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
  *mergeinfo_cat = NULL;
  SVN_ERR(svn_wc__node_get_repos_info(NULL, &target_repos_relpath,
                                      &repos_root, NULL,
                                      ctx->wc_ctx, local_abspath,
                                      scratch_pool, scratch_pool));

  /* Get the mergeinfo for the LOCAL_ABSPATH target and set *INHERITED and
     *WALKED_PATH. */
  SVN_ERR(svn_client__get_wc_mergeinfo(&mergeinfo, inherited, inherit,
                                       local_abspath, limit_path,
                                       walked_path, ignore_invalid_mergeinfo,
                                       ctx, result_pool, scratch_pool));

  /* Add any explicit/inherited mergeinfo for LOCAL_ABSPATH to
     *MERGEINFO_CAT. */
  if (mergeinfo)
    {
      *mergeinfo_cat = apr_hash_make(result_pool);
      svn_hash_sets(*mergeinfo_cat,
                    apr_pstrdup(result_pool, target_repos_relpath), mergeinfo);
    }

  /* If LOCAL_ABSPATH is a directory and we want the subtree mergeinfo too,
     then get it.

     With WC-NG it is cheaper to do a single db transaction, than first
     looking if we really have a directory. */
  if (include_descendants)
    {
      apr_hash_t *mergeinfo_props;
      apr_hash_index_t *hi;

      SVN_ERR(svn_wc__prop_retrieve_recursive(&mergeinfo_props,
                                              ctx->wc_ctx, local_abspath,
                                              SVN_PROP_MERGEINFO,
                                              scratch_pool, scratch_pool));

      /* Convert *mergeinfo_props into a proper svn_mergeinfo_catalog_t */
      for (hi = apr_hash_first(scratch_pool, mergeinfo_props);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *node_abspath = apr_hash_this_key(hi);
          svn_string_t *propval = apr_hash_this_val(hi);
          svn_mergeinfo_t subtree_mergeinfo;
          const char *repos_relpath;

          if (strcmp(node_abspath, local_abspath) == 0)
            continue; /* Already parsed in svn_client__get_wc_mergeinfo */

          SVN_ERR(svn_wc__node_get_repos_info(NULL, &repos_relpath, NULL, NULL,
                                              ctx->wc_ctx, node_abspath,
                                              result_pool, scratch_pool));

          SVN_ERR(svn_mergeinfo_parse(&subtree_mergeinfo, propval->data,
                                      result_pool));

          /* If the target had no explicit/inherited mergeinfo and this is the
             first subtree with mergeinfo found, then the catalog will still
             be NULL. */
          if (*mergeinfo_cat == NULL)
            *mergeinfo_cat = apr_hash_make(result_pool);

          svn_hash_sets(*mergeinfo_cat, repos_relpath, subtree_mergeinfo);
        }
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__get_repos_mergeinfo(svn_mergeinfo_t *target_mergeinfo,
                                svn_ra_session_t *ra_session,
                                const char *url,
                                svn_revnum_t rev,
                                svn_mergeinfo_inheritance_t inherit,
                                svn_boolean_t squelch_incapable,
                                apr_pool_t *pool)
{
  svn_mergeinfo_catalog_t tgt_mergeinfo_cat;

  *target_mergeinfo = NULL;

  SVN_ERR(svn_client__get_repos_mergeinfo_catalog(&tgt_mergeinfo_cat,
                                                  ra_session,
                                                  url, rev, inherit,
                                                  squelch_incapable, FALSE,
                                                  pool, pool));

  if (tgt_mergeinfo_cat && apr_hash_count(tgt_mergeinfo_cat))
    {
      /* We asked only for the REL_PATH's mergeinfo, not any of its
         descendants.  So if there is anything in the catalog it is the
         mergeinfo for REL_PATH. */
      *target_mergeinfo =
        apr_hash_this_val(apr_hash_first(pool, tgt_mergeinfo_cat));

    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__get_repos_mergeinfo_catalog(svn_mergeinfo_catalog_t *mergeinfo_cat,
                                        svn_ra_session_t *ra_session,
                                        const char *url,
                                        svn_revnum_t rev,
                                        svn_mergeinfo_inheritance_t inherit,
                                        svn_boolean_t squelch_incapable,
                                        svn_boolean_t include_descendants,
                                        apr_pool_t *result_pool,
                                        apr_pool_t *scratch_pool)
{
  svn_error_t *err;
  svn_mergeinfo_catalog_t repos_mergeinfo_cat;
  apr_array_header_t *rel_paths = apr_array_make(scratch_pool, 1,
                                                 sizeof(const char *));
  const char *old_session_url;

  APR_ARRAY_PUSH(rel_paths, const char *) = "";

  /* Fetch the mergeinfo. */
  SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
                                            ra_session, url, scratch_pool));
  err = svn_ra_get_mergeinfo(ra_session, &repos_mergeinfo_cat, rel_paths,
                             rev, inherit, include_descendants, result_pool);
  err = svn_error_compose_create(
          err, svn_ra_reparent(ra_session, old_session_url, scratch_pool));
  if (err)
    {
      if (squelch_incapable && err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)
        {
          svn_error_clear(err);
          *mergeinfo_cat = NULL;
          return SVN_NO_ERROR;
        }
      else
        return svn_error_trace(err);
    }

  if (repos_mergeinfo_cat == NULL)
    {
      *mergeinfo_cat = NULL;
    }
  else
    {
      const char *session_relpath;

      SVN_ERR(svn_ra_get_path_relative_to_root(ra_session, &session_relpath,
                                               url, scratch_pool));

      if (session_relpath[0] == '\0')
        *mergeinfo_cat = repos_mergeinfo_cat;
      else
        SVN_ERR(svn_mergeinfo__add_prefix_to_catalog(mergeinfo_cat,
                                                     repos_mergeinfo_cat,
                                                     session_relpath,
                                                     result_pool,
                                                     scratch_pool));
    }
  return SVN_NO_ERROR;
}


svn_error_t *
svn_client__get_wc_or_repos_mergeinfo(svn_mergeinfo_t *target_mergeinfo,
                                      svn_boolean_t *inherited,
                                      svn_boolean_t *from_repos,
                                      svn_boolean_t repos_only,
                                      svn_mergeinfo_inheritance_t inherit,
                                      svn_ra_session_t *ra_session,
                                      const char *target_wcpath,
                                      svn_client_ctx_t *ctx,
                                      apr_pool_t *pool)
{
  svn_mergeinfo_catalog_t tgt_mergeinfo_cat;

  *target_mergeinfo = NULL;

  SVN_ERR(svn_client__get_wc_or_repos_mergeinfo_catalog(&tgt_mergeinfo_cat,
                                                        inherited, from_repos,
                                                        FALSE,
                                                        repos_only,
                                                        FALSE, inherit,
                                                        ra_session,
                                                        target_wcpath, ctx,
                                                        pool, pool));
  if (tgt_mergeinfo_cat && apr_hash_count(tgt_mergeinfo_cat))
    {
      /* We asked only for the TARGET_WCPATH's mergeinfo, not any of its
         descendants.  It this mergeinfo is in the catalog, it's keyed
         on TARGET_WCPATH's root-relative path.  We could dig that up
         so we can peek into our catalog, but it ought to be the only
         thing in the catalog, so we'll just fetch the first hash item. */
      *target_mergeinfo =
        apr_hash_this_val(apr_hash_first(pool, tgt_mergeinfo_cat));

    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__get_wc_or_repos_mergeinfo_catalog(
  svn_mergeinfo_catalog_t *target_mergeinfo_catalog,
  svn_boolean_t *inherited_p,
  svn_boolean_t *from_repos,
  svn_boolean_t include_descendants,
  svn_boolean_t repos_only,
  svn_boolean_t ignore_invalid_mergeinfo,
  svn_mergeinfo_inheritance_t inherit,
  svn_ra_session_t *ra_session,
  const char *target_wcpath,
  svn_client_ctx_t *ctx,
  apr_pool_t *result_pool,
  apr_pool_t *scratch_pool)
{
  const char *url;
  svn_revnum_t target_rev;
  const char *local_abspath;
  const char *repos_root;
  const char *repos_relpath;
  svn_mergeinfo_catalog_t target_mergeinfo_cat_wc = NULL;
  svn_mergeinfo_catalog_t target_mergeinfo_cat_repos = NULL;

  SVN_ERR(svn_dirent_get_absolute(&local_abspath, target_wcpath,
                                  scratch_pool));

  if (from_repos)
    *from_repos = FALSE;

  /* We may get an entry with abbreviated information from TARGET_WCPATH's
     parent if TARGET_WCPATH is missing.  These limited entries do not have
     a URL and without that we cannot get accurate mergeinfo for
     TARGET_WCPATH. */
  SVN_ERR(svn_wc__node_get_origin(NULL, &target_rev, &repos_relpath,
                                  &repos_root, NULL, NULL, NULL,
                                  ctx->wc_ctx, local_abspath, FALSE,
                                  scratch_pool, scratch_pool));

  if (repos_relpath)
    url = svn_path_url_add_component2(repos_root, repos_relpath, scratch_pool);
  else
    url = NULL;

  if (!repos_only)
    {
      svn_boolean_t inherited;
      SVN_ERR(svn_client__get_wc_mergeinfo_catalog(&target_mergeinfo_cat_wc,
                                                   &inherited,
                                                   include_descendants,
                                                   inherit,
                                                   local_abspath,
                                                   NULL, NULL,
                                                   ignore_invalid_mergeinfo,
                                                   ctx,
                                                   result_pool,
                                                   scratch_pool));
      if (inherited_p)
        *inherited_p = inherited;

      /* If we want LOCAL_ABSPATH's inherited mergeinfo, were we able to
         get it from the working copy?  If not, then we must ask the
         repository. */
      if (! (inherited
             || (inherit == svn_mergeinfo_explicit)
             || (repos_relpath
                 && target_mergeinfo_cat_wc
                 && svn_hash_gets(target_mergeinfo_cat_wc, repos_relpath))))
        {
          repos_only = TRUE;
          /* We already have any subtree mergeinfo from the working copy, no
             need to ask the server for it again. */
          include_descendants = FALSE;
        }
    }

  if (repos_only)
    {
      /* No need to check the repos if this is a local addition. */
      if (url != NULL)
        {
          apr_hash_t *original_props;

          /* Check to see if we have local modifications which removed all of
             TARGET_WCPATH's pristine mergeinfo.  If that is the case then
             TARGET_WCPATH effectively has no mergeinfo. */
          SVN_ERR(svn_wc_get_pristine_props(&original_props,
                                            ctx->wc_ctx, local_abspath,
                                            result_pool, scratch_pool));
          if (!svn_hash_gets(original_props, SVN_PROP_MERGEINFO))
            {
              apr_pool_t *sesspool = NULL;

              if (! ra_session)
                {
                  sesspool = svn_pool_create(scratch_pool);
                  SVN_ERR(svn_client_open_ra_session2(&ra_session, url, NULL,
                                                      ctx,
                                                      sesspool, sesspool));
                }

              SVN_ERR(svn_client__get_repos_mergeinfo_catalog(
                        &target_mergeinfo_cat_repos, ra_session,
                        url, target_rev, inherit,
                        TRUE, include_descendants,
                        result_pool, scratch_pool));

              if (target_mergeinfo_cat_repos
                  && svn_hash_gets(target_mergeinfo_cat_repos, repos_relpath))
                {
                  if (inherited_p)
                    *inherited_p = TRUE;
                  if (from_repos)
                    *from_repos = TRUE;
                }

              /* If we created an RA_SESSION above, destroy it.
                 Otherwise, if reparented an existing session, point
                 it back where it was when we were called. */
              if (sesspool)
                {
                  svn_pool_destroy(sesspool);
                }
            }
        }
    }

  /* Combine the mergeinfo from the working copy and repository as needed. */
  if (target_mergeinfo_cat_wc)
    {
      *target_mergeinfo_catalog = target_mergeinfo_cat_wc;
      if (target_mergeinfo_cat_repos)
        SVN_ERR(svn_mergeinfo_catalog_merge(*target_mergeinfo_catalog,
                                            target_mergeinfo_cat_repos,
                                            result_pool, scratch_pool));
    }
  else if (target_mergeinfo_cat_repos)
    {
      *target_mergeinfo_catalog = target_mergeinfo_cat_repos;
    }
  else
    {
      *target_mergeinfo_catalog = NULL;
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_client__get_history_as_mergeinfo(svn_mergeinfo_t *mergeinfo_p,
                                      svn_boolean_t *has_rev_zero_history,
                                      const svn_client__pathrev_t *pathrev,
                                      svn_revnum_t range_youngest,
                                      svn_revnum_t range_oldest,
                                      svn_ra_session_t *ra_session,
                                      svn_client_ctx_t *ctx,
                                      apr_pool_t *pool)
{
  apr_array_header_t *segments;

  /* Fetch the location segments for our URL@PEG_REVNUM. */
  if (! SVN_IS_VALID_REVNUM(range_youngest))
    range_youngest = pathrev->rev;
  if (! SVN_IS_VALID_REVNUM(range_oldest))
    range_oldest = 0;

  SVN_ERR(svn_client__repos_location_segments(&segments, ra_session,
                                              pathrev->url, pathrev->rev,
                                              range_youngest, range_oldest,
                                              ctx, pool));

  if (has_rev_zero_history)
    {
      *has_rev_zero_history = FALSE;
        if (segments->nelts)
          {
            svn_location_segment_t *oldest_segment =
              APR_ARRAY_IDX(segments, 0, svn_location_segment_t *);
            if (oldest_segment->range_start == 0)
              *has_rev_zero_history = TRUE;
          }
    }

  SVN_ERR(svn_mergeinfo__mergeinfo_from_segments(mergeinfo_p, segments, pool));

  return SVN_NO_ERROR;
}


/*-----------------------------------------------------------------------*/

/*** Eliding mergeinfo. ***/

/* Given the mergeinfo (CHILD_MERGEINFO) for a path, and the
   mergeinfo of its nearest ancestor with mergeinfo (PARENT_MERGEINFO), compare
   CHILD_MERGEINFO to PARENT_MERGEINFO to see if the former elides to
   the latter, following the elision rules described in
   svn_client__elide_mergeinfo()'s docstring.  Set *ELIDES to whether
   or not CHILD_MERGEINFO is redundant.

   Note: This function assumes that PARENT_MERGEINFO is definitive;
   i.e. if it is NULL then the caller not only walked the entire WC
   looking for inherited mergeinfo, but queried the repository if none
   was found in the WC.  This is rather important since this function
   says empty mergeinfo should be elided if PARENT_MERGEINFO is NULL,
   and we don't want to do that unless we are *certain* that the empty
   mergeinfo on PATH isn't overriding anything.

   If PATH_SUFFIX and PARENT_MERGEINFO are not NULL append PATH_SUFFIX
   to each path in PARENT_MERGEINFO before performing the comparison. */
static svn_error_t *
should_elide_mergeinfo(svn_boolean_t *elides,
                       svn_mergeinfo_t parent_mergeinfo,
                       svn_mergeinfo_t child_mergeinfo,
                       const char *path_suffix,
                       apr_pool_t *scratch_pool)
{
  /* Easy out: No child mergeinfo to elide. */
  if (child_mergeinfo == NULL)
    {
      *elides = FALSE;
    }
  else if (apr_hash_count(child_mergeinfo) == 0)
    {
      /* Empty mergeinfo elides to empty mergeinfo or to "nothing",
         i.e. it isn't overriding any parent. Otherwise it doesn't
         elide. */
      *elides = (!parent_mergeinfo || apr_hash_count(parent_mergeinfo) == 0);
    }
  else if (!parent_mergeinfo || apr_hash_count(parent_mergeinfo) == 0)
    {
      /* Non-empty mergeinfo never elides to empty mergeinfo
         or no mergeinfo. */
      *elides = FALSE;
    }
  else
    {
      /* Both CHILD_MERGEINFO and PARENT_MERGEINFO are non-NULL and
         non-empty. */
      svn_mergeinfo_t path_tweaked_parent_mergeinfo;

      /* If we need to adjust the paths in PARENT_MERGEINFO do it now. */
      if (path_suffix)
        SVN_ERR(svn_mergeinfo__add_suffix_to_mergeinfo(
                  &path_tweaked_parent_mergeinfo, parent_mergeinfo,
                  path_suffix, scratch_pool, scratch_pool));
      else
        path_tweaked_parent_mergeinfo = parent_mergeinfo;

      SVN_ERR(svn_mergeinfo__equals(elides,
                                    path_tweaked_parent_mergeinfo,
                                    child_mergeinfo, TRUE, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Helper for svn_client__elide_mergeinfo().

   Given a working copy LOCAL_ABSPATH, its mergeinfo hash CHILD_MERGEINFO, and
   the mergeinfo of LOCAL_ABSPATH's nearest ancestor PARENT_MERGEINFO, use
   should_elide_mergeinfo() to decide whether or not CHILD_MERGEINFO elides to
   PARENT_MERGEINFO; PATH_SUFFIX means the same as in that function.

   If elision does occur, then remove the mergeinfo for LOCAL_ABSPATH.

   If CHILD_MERGEINFO is NULL, do nothing.

   Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
elide_mergeinfo(svn_mergeinfo_t parent_mergeinfo,
                svn_mergeinfo_t child_mergeinfo,
                const char *local_abspath,
                svn_client_ctx_t *ctx,
                apr_pool_t *scratch_pool)
{
  svn_boolean_t elides;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));

  SVN_ERR(should_elide_mergeinfo(&elides,
                                 parent_mergeinfo, child_mergeinfo, NULL,
                                 scratch_pool));

  if (elides)
    {
      SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, local_abspath, SVN_PROP_MERGEINFO,
                               NULL, svn_depth_empty, TRUE, NULL,
                               NULL, NULL /* cancellation */,
                               NULL, NULL /* notification */,
                               scratch_pool));

      if (ctx->notify_func2)
        {
          svn_wc_notify_t *notify;

          notify = svn_wc_create_notify(local_abspath,
                                        svn_wc_notify_merge_elide_info,
                                        scratch_pool);
          ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);

          notify = svn_wc_create_notify(local_abspath,
                                        svn_wc_notify_update_update,
                                        scratch_pool);
          notify->prop_state = svn_wc_notify_state_changed;

          ctx->notify_func2(ctx->notify_baton2, notify, scratch_pool);
        }
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_client__elide_mergeinfo(const char *target_abspath,
                            const char *wc_elision_limit_abspath,
                            svn_client_ctx_t *ctx,
                            apr_pool_t *pool)
{
  const char *limit_abspath = wc_elision_limit_abspath;

  SVN_ERR_ASSERT(svn_dirent_is_absolute(target_abspath));
  SVN_ERR_ASSERT(!wc_elision_limit_abspath || svn_dirent_is_absolute(wc_elision_limit_abspath));

  /* Check for first easy out: We are already at the limit path. */
  if (!limit_abspath
      || strcmp(target_abspath, limit_abspath) != 0)
    {
      svn_mergeinfo_t target_mergeinfo;
      svn_mergeinfo_t mergeinfo = NULL;
      svn_error_t *err;

      /* Get the TARGET_WCPATH's explicit mergeinfo. */
      err = svn_client__get_wc_mergeinfo(&target_mergeinfo, NULL,
                                         svn_mergeinfo_explicit,
                                         target_abspath,
                                         NULL, NULL, FALSE,
                                         ctx, pool, pool);
      if (err)
        {
          if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
            {
              /* Issue #3896: If we attempt elision because invalid
                 mergeinfo is present on TARGET_WCPATH, then don't let
                 the merge fail, just skip the elision attempt. */
              svn_error_clear(err);
              return SVN_NO_ERROR;
            }
          else
            {
              return svn_error_trace(err);
            }
        }

     /* If TARGET_WCPATH has no explicit mergeinfo, there's nothing to
         elide, we're done. */
      if (target_mergeinfo == NULL)
        return SVN_NO_ERROR;

      /* Get TARGET_WCPATH's inherited mergeinfo from the WC. */
      err = svn_client__get_wc_mergeinfo(&mergeinfo, NULL,
                                         svn_mergeinfo_nearest_ancestor,
                                         target_abspath,
                                         limit_abspath,
                                         NULL, FALSE, ctx, pool, pool);
      if (err)
        {
          if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
            {
              /* Issue #3896 again, but invalid mergeinfo is inherited. */
              svn_error_clear(err);
              return SVN_NO_ERROR;
            }
          else
            {
              return svn_error_trace(err);
            }
        }

      /* If TARGET_WCPATH inherited no mergeinfo from the WC and we are
         not limiting our search to the working copy then check if it
         inherits any from the repos. */
      if (!mergeinfo && !wc_elision_limit_abspath)
        {
          err = svn_client__get_wc_or_repos_mergeinfo(
            &mergeinfo, NULL, NULL, TRUE,
            svn_mergeinfo_nearest_ancestor,
            NULL, target_abspath, ctx, pool);
          if (err)
            {
              if (err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
                {
                  /* Issue #3896 again, but invalid mergeinfo is inherited
                     from the repository. */
                  svn_error_clear(err);
                  return SVN_NO_ERROR;
                }
              else
                {
                  return svn_error_trace(err);
                }
            }
        }

      /* If there is nowhere to elide TARGET_WCPATH's mergeinfo to and
         the elision is limited, then we are done.*/
      if (!mergeinfo && wc_elision_limit_abspath)
        return SVN_NO_ERROR;

      SVN_ERR(elide_mergeinfo(mergeinfo, target_mergeinfo, target_abspath,
                              ctx, pool));
    }
  return SVN_NO_ERROR;
}


/* Set *MERGEINFO_CATALOG to the explicit or inherited mergeinfo for
   PATH_OR_URL@PEG_REVISION.  If INCLUDE_DESCENDANTS is true, also
   store in *MERGEINFO_CATALOG the explicit mergeinfo on any subtrees
   under PATH_OR_URL.  Key all mergeinfo in *MERGEINFO_CATALOG on
   repository relpaths.

   If no mergeinfo is found then set *MERGEINFO_CATALOG to NULL.

   Set *REPOS_ROOT to the root URL of the repository associated with
   PATH_OR_URL.

   If RA_SESSION is NOT NULL and PATH_OR_URL refers to a URL, RA_SESSION
   (which must be of the repository containing PATH_OR_URL) will be used
   instead of a temporary RA session. Caller is responsible for reparenting
   the session if it wants to use it after the call.

   Allocate *MERGEINFO_CATALOG and all its contents in RESULT_POOL.  Use
   SCRATCH_POOL for all temporary allocations.

   Return SVN_ERR_UNSUPPORTED_FEATURE if the server does not support
   Merge Tracking.  */
static svn_error_t *
get_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo_catalog,
              const char **repos_root,
              const char *path_or_url,
              const svn_opt_revision_t *peg_revision,
              svn_boolean_t include_descendants,
              svn_boolean_t ignore_invalid_mergeinfo,
              svn_client_ctx_t *ctx,
              svn_ra_session_t *ra_session,
              apr_pool_t *result_pool,
              apr_pool_t *scratch_pool)
{
  const char *local_abspath;
  svn_boolean_t use_url = svn_path_is_url(path_or_url);
  svn_client__pathrev_t *peg_loc;

  if (ra_session && svn_path_is_url(path_or_url))
    {
      SVN_ERR(svn_ra_reparent(ra_session, path_or_url, scratch_pool));
      SVN_ERR(svn_client__resolve_rev_and_url(&peg_loc, ra_session,
                                              path_or_url,
                                              peg_revision,
                                              peg_revision,
                                              ctx, scratch_pool));
    }
  else
    {
      SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &peg_loc,
                                                path_or_url, NULL,
                                                peg_revision,
                                                peg_revision, ctx, scratch_pool));
    }

  /* If PATH_OR_URL is as working copy path determine if we will need to
     contact the repository for the requested PEG_REVISION. */
  if (!use_url)
    {
      svn_client__pathrev_t *origin;
      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url,
                                      scratch_pool));

      SVN_ERR(svn_client__wc_node_get_origin(&origin, local_abspath, ctx,
                                             scratch_pool, scratch_pool));
      if (!origin
          || strcmp(origin->url, peg_loc->url) != 0
          || peg_loc->rev != origin->rev)
      {
        use_url = TRUE; /* Don't rely on local mergeinfo */
      }
    }

  SVN_ERR(svn_ra_get_repos_root2(ra_session, repos_root, result_pool));

  if (use_url)
    {
      SVN_ERR(svn_client__get_repos_mergeinfo_catalog(
        mergeinfo_catalog, ra_session, peg_loc->url, peg_loc->rev,
        svn_mergeinfo_inherited, FALSE, include_descendants,
        result_pool, scratch_pool));
    }
  else /* ! svn_path_is_url() */
    {
      SVN_ERR(svn_client__get_wc_or_repos_mergeinfo_catalog(
        mergeinfo_catalog, NULL, NULL, include_descendants, FALSE,
        ignore_invalid_mergeinfo, svn_mergeinfo_inherited,
        ra_session, path_or_url, ctx,
        result_pool, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/*** In-memory mergeinfo elision ***/
svn_error_t *
svn_client__elide_mergeinfo_catalog(svn_mergeinfo_catalog_t mergeinfo_catalog,
                                    apr_pool_t *scratch_pool)
{
  apr_array_header_t *sorted_hash;
  apr_array_header_t *elidable_paths = apr_array_make(scratch_pool, 1,
                                                      sizeof(const char *));
  apr_array_header_t *dir_stack = apr_array_make(scratch_pool, 1,
                                                 sizeof(const char *));
  apr_pool_t *iterpool;
  int i;

  /* Here's the general algorithm:
     Walk through the paths sorted in tree order.  For each path, pop
     the dir_stack until it is either empty or the top item contains a parent
     of the current path. Check to see if that mergeinfo is then elidable,
     and build the list of elidable mergeinfo based upon that determination.
     Finally, push the path of interest onto the stack, and continue. */
  sorted_hash = svn_sort__hash(mergeinfo_catalog,
                               svn_sort_compare_items_as_paths,
                               scratch_pool);
  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; i < sorted_hash->nelts; i++)
    {
      svn_sort__item_t *item = &APR_ARRAY_IDX(sorted_hash, i,
                                              svn_sort__item_t);
      const char *path = item->key;

      if (dir_stack->nelts > 0)
        {
          const char *top;
          const char *path_suffix;
          svn_boolean_t elides = FALSE;

          svn_pool_clear(iterpool);

          /* Pop off any paths which are not ancestors of PATH. */
          do
            {
              top = APR_ARRAY_IDX(dir_stack, dir_stack->nelts - 1,
                                          const char *);
              path_suffix = svn_dirent_is_child(top, path, NULL);

              if (!path_suffix)
                apr_array_pop(dir_stack);
            }
          while (dir_stack->nelts > 0 && !path_suffix);

          /* If we have a path suffix, it means we haven't popped the stack
             clean. */
          if (path_suffix)
            {
              SVN_ERR(should_elide_mergeinfo(&elides,
                                         svn_hash_gets(mergeinfo_catalog, top),
                                         svn_hash_gets(mergeinfo_catalog, path),
                                         path_suffix,
                                         iterpool));

              if (elides)
                APR_ARRAY_PUSH(elidable_paths, const char *) = path;
            }
        }

      APR_ARRAY_PUSH(dir_stack, const char *) = path;
    }
  svn_pool_destroy(iterpool);

  /* Now remove the elidable paths from the catalog. */
  for (i = 0; i < elidable_paths->nelts; i++)
    {
      const char *path = APR_ARRAY_IDX(elidable_paths, i, const char *);
      svn_hash_sets(mergeinfo_catalog, path, NULL);
    }

  return SVN_NO_ERROR;
}


/* Helper for filter_log_entry_with_rangelist().

   DEPTH_FIRST_CATALOG_INDEX is an array of svn_sort__item_t's.  The keys are
   repository-absolute const char *paths, the values are svn_mergeinfo_t for
   each path.

   Return a pointer to the mergeinfo value of the nearest path-wise ancestor
   of FSPATH in DEPTH_FIRST_CATALOG_INDEX.  A path is considered its
   own ancestor, so if a key exactly matches FSPATH, return that
   key's mergeinfo and set *ANCESTOR_IS_SELF to true (set it to false in all
   other cases).

   If DEPTH_FIRST_CATALOG_INDEX is NULL, empty, or no ancestor is found, then
   return NULL. */
static svn_mergeinfo_t
find_nearest_ancestor(const apr_array_header_t *depth_first_catalog_index,
                      svn_boolean_t *ancestor_is_self,
                      const char *fspath)
{
  int ancestor_index = -1;

  *ancestor_is_self = FALSE;

  if (depth_first_catalog_index)
    {
      int i;

      for (i = 0; i < depth_first_catalog_index->nelts; i++)
        {
          svn_sort__item_t item = APR_ARRAY_IDX(depth_first_catalog_index, i,
                                                svn_sort__item_t);
          if (svn_fspath__skip_ancestor(item.key, fspath))
            {
              ancestor_index = i;

              /* There's no nearer ancestor than FSPATH itself. */
              if (strcmp(item.key, fspath) == 0)
                {
                  *ancestor_is_self = TRUE;
                  break;
                }
            }

        }
    }

  if (ancestor_index == -1)
    return NULL;
  else
    return (APR_ARRAY_IDX(depth_first_catalog_index,
                          ancestor_index,
                          svn_sort__item_t)).value;
}

/* Baton for use with the filter_log_entry_with_rangelist()
   svn_log_entry_receiver_t callback. */
struct filter_log_entry_baton_t
{
  /* Is TRUE if RANGELIST describes potentially merged revisions, is FALSE
     if RANGELIST describes potentially eligible revisions. */
  svn_boolean_t filtering_merged;

  /* Unsorted array of repository relative paths representing the merge
     sources.  There will be more than one source  */
  const apr_array_header_t *merge_source_fspaths;

  /* The repository-absolute path we are calling svn_client_log5() on. */
  const char *target_fspath;

  /* Mergeinfo catalog for the tree rooted at TARGET_FSPATH.
     The path keys must be repository-absolute. */
  svn_mergeinfo_catalog_t target_mergeinfo_catalog;

  /* Depth first sorted array of svn_sort__item_t's for
     TARGET_MERGEINFO_CATALOG. */
  apr_array_header_t *depth_first_catalog_index;

  /* A rangelist describing all the revisions potentially merged or
     potentially eligible for merging (see FILTERING_MERGED) based on
     the target's explicit or inherited mergeinfo. */
  const svn_rangelist_t *rangelist;

  /* The wrapped svn_log_entry_receiver_t callback and baton which
     filter_log_entry_with_rangelist() is acting as a filter for. */
  svn_log_entry_receiver_t log_receiver;
  void *log_receiver_baton;

  svn_client_ctx_t *ctx;
};

/* Implements the svn_log_entry_receiver_t interface.  BATON is a
   `struct filter_log_entry_baton_t *'.

   Call the wrapped log receiver BATON->log_receiver (with
   BATON->log_receiver_baton) if:

   BATON->FILTERING_MERGED is FALSE and the changes represented by LOG_ENTRY
   have been fully merged from BATON->merge_source_fspaths to the WC target
   based on the mergeinfo for the WC contained in BATON->TARGET_MERGEINFO_CATALOG.

   Or

   BATON->FILTERING_MERGED is TRUE and the changes represented by LOG_ENTRY
   have not been merged, or only partially merged, from
   BATON->merge_source_fspaths to the WC target based on the mergeinfo for the
   WC contained in BATON->TARGET_MERGEINFO_CATALOG. */
static svn_error_t *
filter_log_entry_with_rangelist(void *baton,
                                svn_log_entry_t *log_entry,
                                apr_pool_t *pool)
{
  struct filter_log_entry_baton_t *fleb = baton;
  svn_rangelist_t *intersection, *this_rangelist;

  if (fleb->ctx->cancel_func)
    SVN_ERR(fleb->ctx->cancel_func(fleb->ctx->cancel_baton));

  /* Ignore r0 because there can be no "change 0" in a merge range. */
  if (log_entry->revision == 0)
    return SVN_NO_ERROR;

  this_rangelist = svn_rangelist__initialize(log_entry->revision - 1,
                                             log_entry->revision,
                                             TRUE, pool);

  /* Don't consider inheritance yet, see if LOG_ENTRY->REVISION is
     fully or partially represented in BATON->RANGELIST. */
  SVN_ERR(svn_rangelist_intersect(&intersection, fleb->rangelist,
                                  this_rangelist, FALSE, pool));
  if (! (intersection && intersection->nelts))
    return SVN_NO_ERROR;

  SVN_ERR_ASSERT(intersection->nelts == 1);

  /* Ok, we know LOG_ENTRY->REVISION is represented in BATON->RANGELIST,
     but is it only partially represented, i.e. is the corresponding range in
     BATON->RANGELIST non-inheritable?  Ask for the same intersection as
     above but consider inheritance this time, if the intersection is empty
     we know the range in BATON->RANGELIST is non-inheritable. */
  SVN_ERR(svn_rangelist_intersect(&intersection, fleb->rangelist,
                                  this_rangelist, TRUE, pool));
  log_entry->non_inheritable = !intersection->nelts;

  /* If the paths changed by LOG_ENTRY->REVISION are provided we can determine
     if LOG_ENTRY->REVISION, while only partially represented in
     BATON->RANGELIST, is in fact completely applied to all affected paths.
     ### And ... what if it is, or if it isn't? What do we do with the answer?
         And how do we cope if the changed paths are not provided? */
  if ((log_entry->non_inheritable || !fleb->filtering_merged)
      && log_entry->changed_paths2)
    {
      apr_hash_index_t *hi;
      svn_boolean_t all_subtrees_have_this_rev = TRUE;
      svn_rangelist_t *this_rev_rangelist =
        svn_rangelist__initialize(log_entry->revision - 1,
                                  log_entry->revision, TRUE, pool);
      apr_pool_t *iterpool = svn_pool_create(pool);

      for (hi = apr_hash_first(pool, log_entry->changed_paths2);
           hi;
           hi = apr_hash_next(hi))
        {
          int i;
          const char *path = apr_hash_this_key(hi);
          svn_log_changed_path2_t *change = apr_hash_this_val(hi);
          const char *target_fspath_affected;
          svn_mergeinfo_t nearest_ancestor_mergeinfo;
          svn_boolean_t found_this_revision = FALSE;
          const char *merge_source_rel_target;
          const char *merge_source_fspath;
          svn_boolean_t ancestor_is_self;

          svn_pool_clear(iterpool);

          /* Check that PATH is a subtree of at least one of the
             merge sources.  If not then ignore this path.  */
          for (i = 0; i < fleb->merge_source_fspaths->nelts; i++)
            {
              merge_source_fspath = APR_ARRAY_IDX(fleb->merge_source_fspaths,
                                                  i, const char *);

              merge_source_rel_target
                = svn_fspath__skip_ancestor(merge_source_fspath, path);
              if (merge_source_rel_target)
                {
                  /* If MERGE_SOURCE was itself deleted, replaced, or added
                     in LOG_ENTRY->REVISION then ignore this PATH since you
                     can't merge a addition or deletion of yourself. */
                  if (merge_source_rel_target[0] == '\0'
                      && (change->action != 'M'))
                    i = fleb->merge_source_fspaths->nelts;
                  break;
                }
            }
          /* If we examined every merge source path and PATH is a child of
             none of them then we can ignore this PATH. */
          if (i == fleb->merge_source_fspaths->nelts)
            continue;

          /* Calculate the target path which PATH would affect if merged. */
          target_fspath_affected = svn_fspath__join(fleb->target_fspath,
                                                    merge_source_rel_target,
                                                    iterpool);

          nearest_ancestor_mergeinfo =
            find_nearest_ancestor(fleb->depth_first_catalog_index,
                                  &ancestor_is_self,
                                  target_fspath_affected);

          /* Issue #3791: A path should never have explicit mergeinfo
             describing its own addition (that's self-referential).  Nor will
             it have explicit mergeinfo describing its own deletion (we
             obviously can't add new mergeinfo to a path we are deleting).

             This lack of explicit mergeinfo should not cause such revisions
             to show up as eligible however.  If PATH was deleted, replaced,
             or added in LOG_ENTRY->REVISION, but the corresponding
             TARGET_PATH_AFFECTED already exists and has explicit mergeinfo
             describing merges from PATH *after* LOG_ENTRY->REVISION, then
             ignore this PATH.  If it was deleted in LOG_ENTRY->REVISION it's
             obviously back.  If it was added or replaced it's still around
             possibly it was replaced one or more times, but it's back now.
             Regardless, LOG_ENTRY->REVISION is *not* an eligible revision! */
          if (nearest_ancestor_mergeinfo &&
              ancestor_is_self /* Explicit mergeinfo on TARGET_PATH_AFFECTED */
              && (change->action != 'M'))
            {
              svn_rangelist_t *rangelist =
                  svn_hash_gets(nearest_ancestor_mergeinfo, path);
              if (rangelist)
                {
                  svn_merge_range_t *youngest_range = APR_ARRAY_IDX(
                    rangelist, rangelist->nelts - 1, svn_merge_range_t *);

                  if (youngest_range
                      && (youngest_range->end > log_entry->revision))
                    continue;
                }
            }

          if (nearest_ancestor_mergeinfo)
            {
              apr_hash_index_t *hi2;

              for (hi2 = apr_hash_first(iterpool, nearest_ancestor_mergeinfo);
                   hi2;
                   hi2 = apr_hash_next(hi2))
                {
                  const char *mergeinfo_path = apr_hash_this_key(hi2);
                  svn_rangelist_t *rangelist = apr_hash_this_val(hi2);

                  /* Does the mergeinfo for PATH reflect if
                     LOG_ENTRY->REVISION was previously merged
                     from MERGE_SOURCE_FSPATH? */
                  if (svn_fspath__skip_ancestor(merge_source_fspath,
                                                mergeinfo_path))
                    {
                      /* Something was merged from MERGE_SOURCE_FSPATH, does
                         it include LOG_ENTRY->REVISION? */
                      SVN_ERR(svn_rangelist_intersect(&intersection,
                                                      rangelist,
                                                      this_rev_rangelist,
                                                      FALSE,
                                                      iterpool));
                      if (intersection->nelts)
                        {
                          if (ancestor_is_self)
                            {
                              /* TARGET_PATH_AFFECTED has explicit mergeinfo,
                                 so we don't need to worry if that mergeinfo
                                 is inheritable or not. */
                              found_this_revision = TRUE;
                              break;
                            }
                          else
                            {
                              /* TARGET_PATH_AFFECTED inherited its mergeinfo,
                                 so we have to ignore non-inheritable
                                 ranges. */
                              SVN_ERR(svn_rangelist_intersect(
                                &intersection,
                                rangelist,
                                this_rev_rangelist,
                                TRUE, iterpool));
                              if (intersection->nelts)
                                {
                                  found_this_revision = TRUE;
                                  break;
                                }
                            }
                        }
                    }
                }
            }

          if (!found_this_revision)
            {
              /* As soon as any PATH is found that is not fully merged for
                 LOG_ENTRY->REVISION then we can stop. */
              all_subtrees_have_this_rev = FALSE;
              break;
            }
        }

      svn_pool_destroy(iterpool);

      if (all_subtrees_have_this_rev)
        {
          if (fleb->filtering_merged)
            log_entry->non_inheritable = FALSE;
          else
            return SVN_NO_ERROR;
        }
    }

  /* Call the wrapped log receiver which this function is filtering for. */
  return fleb->log_receiver(fleb->log_receiver_baton, log_entry, pool);
}

static svn_error_t *
logs_for_mergeinfo_rangelist(const char *source_url,
                             const apr_array_header_t *merge_source_fspaths,
                             svn_boolean_t filtering_merged,
                             const svn_rangelist_t *rangelist,
                             svn_boolean_t oldest_revs_first,
                             svn_mergeinfo_catalog_t target_mergeinfo_catalog,
                             const char *target_fspath,
                             svn_boolean_t discover_changed_paths,
                             const apr_array_header_t *revprops,
                             svn_log_entry_receiver_t log_receiver,
                             void *log_receiver_baton,
                             svn_client_ctx_t *ctx,
                             svn_ra_session_t *ra_session,
                             apr_pool_t *scratch_pool)
{
  svn_merge_range_t *oldest_range, *youngest_range;
  svn_revnum_t oldest_rev, youngest_rev;
  struct filter_log_entry_baton_t fleb;

  if (! rangelist->nelts)
    return SVN_NO_ERROR;

  /* Calculate and construct the bounds of our log request. */
  youngest_range = APR_ARRAY_IDX(rangelist, rangelist->nelts - 1,
                                 svn_merge_range_t *);
  youngest_rev = youngest_range->end;
  oldest_range = APR_ARRAY_IDX(rangelist, 0, svn_merge_range_t *);
  oldest_rev = oldest_range->start;

  if (! target_mergeinfo_catalog)
    target_mergeinfo_catalog = apr_hash_make(scratch_pool);

  /* FILTER_LOG_ENTRY_BATON_T->TARGET_MERGEINFO_CATALOG's keys are required
     to be repository-absolute. */
  SVN_ERR(svn_mergeinfo__add_prefix_to_catalog(&target_mergeinfo_catalog,
                                               target_mergeinfo_catalog, "/",
                                               scratch_pool, scratch_pool));

  /* Build the log filtering callback baton. */
  fleb.filtering_merged = filtering_merged;
  fleb.merge_source_fspaths = merge_source_fspaths;
  fleb.target_mergeinfo_catalog = target_mergeinfo_catalog;
  fleb.depth_first_catalog_index =
    svn_sort__hash(target_mergeinfo_catalog,
                   svn_sort_compare_items_as_paths,
                   scratch_pool);
  fleb.target_fspath = target_fspath;
  fleb.rangelist = rangelist;
  fleb.log_receiver = log_receiver;
  fleb.log_receiver_baton = log_receiver_baton;
  fleb.ctx = ctx;

  if (!ra_session)
    SVN_ERR(svn_client__open_ra_session_internal(&ra_session, NULL, source_url,
                                                 NULL, NULL, FALSE, FALSE, ctx,
                                                 scratch_pool, scratch_pool));
  else
    SVN_ERR(svn_ra_reparent(ra_session, source_url, scratch_pool));

  {
    apr_array_header_t *target;
    target = apr_array_make(scratch_pool, 1, sizeof(const char *));
    APR_ARRAY_PUSH(target, const char *) = "";

    SVN_ERR(svn_ra_get_log2(ra_session, target,
                            oldest_revs_first ? oldest_rev : youngest_rev,
                            oldest_revs_first ? youngest_rev : oldest_rev,
                            0 /* limit */,
                            discover_changed_paths,
                            FALSE /* strict_node_history */,
                            FALSE /* include_merged_revisions */,
                            revprops,
                            filter_log_entry_with_rangelist, &fleb,
                            scratch_pool));
  }

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

  return SVN_NO_ERROR;
}

/* Set *OUT_MERGEINFO to a shallow copy of MERGEINFO with each source path
   converted to a (URI-encoded) URL based on REPOS_ROOT_URL. *OUT_MERGEINFO
   is declared as 'apr_hash_t *' because its key do not obey the rules of
   'svn_mergeinfo_t'.

   Allocate *OUT_MERGEINFO and the new keys in RESULT_POOL.  Use
   SCRATCH_POOL for any temporary allocations. */
static svn_error_t *
mergeinfo_relpaths_to_urls(apr_hash_t **out_mergeinfo,
                           svn_mergeinfo_t mergeinfo,
                           const char *repos_root_url,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
{
  *out_mergeinfo = NULL;
  if (mergeinfo)
    {
      apr_hash_index_t *hi;
      apr_hash_t *full_path_mergeinfo = apr_hash_make(result_pool);

      for (hi = apr_hash_first(scratch_pool, mergeinfo);
           hi; hi = apr_hash_next(hi))
        {
          const char *key = apr_hash_this_key(hi);
          void *val = apr_hash_this_val(hi);

          svn_hash_sets(full_path_mergeinfo,
                        svn_path_url_add_component2(repos_root_url, key + 1,
                                                    result_pool),
                        val);
        }
      *out_mergeinfo = full_path_mergeinfo;
    }

  return SVN_NO_ERROR;
}


/*** Public APIs ***/

svn_error_t *
svn_client_mergeinfo_get_merged(apr_hash_t **mergeinfo_p,
                                const char *path_or_url,
                                const svn_opt_revision_t *peg_revision,
                                svn_client_ctx_t *ctx,
                                apr_pool_t *pool)
{
  const char *repos_root;
  svn_mergeinfo_catalog_t mergeinfo_cat;
  svn_mergeinfo_t mergeinfo;

  SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
                        peg_revision, FALSE, FALSE, ctx, NULL, pool, pool));
  if (mergeinfo_cat)
    {
      const char *repos_relpath;

      if (! svn_path_is_url(path_or_url))
        {
          SVN_ERR(svn_dirent_get_absolute(&path_or_url, path_or_url, pool));
          SVN_ERR(svn_wc__node_get_repos_info(NULL, &repos_relpath, NULL, NULL,
                                              ctx->wc_ctx, path_or_url,
                                              pool, pool));
        }
      else
        {
          repos_relpath = svn_uri_skip_ancestor(repos_root, path_or_url, pool);

          SVN_ERR_ASSERT(repos_relpath != NULL); /* Or get_mergeinfo failed */
        }

      mergeinfo = svn_hash_gets(mergeinfo_cat, repos_relpath);
    }
  else
    {
      mergeinfo = NULL;
    }

  SVN_ERR(mergeinfo_relpaths_to_urls(mergeinfo_p, mergeinfo,
                                     repos_root, pool, pool));
  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__mergeinfo_log(svn_boolean_t finding_merged,
                          const char *target_path_or_url,
                          const svn_opt_revision_t *target_peg_revision,
                          svn_mergeinfo_catalog_t *target_mergeinfo_catalog,
                          const char *source_path_or_url,
                          const svn_opt_revision_t *source_peg_revision,
                          const svn_opt_revision_t *source_start_revision,
                          const svn_opt_revision_t *source_end_revision,
                          svn_log_entry_receiver_t log_receiver,
                          void *log_receiver_baton,
                          svn_boolean_t discover_changed_paths,
                          svn_depth_t depth,
                          const apr_array_header_t *revprops,
                          svn_client_ctx_t *ctx,
                          svn_ra_session_t *ra_session,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
{
  const char *log_target = NULL;
  const char *repos_root;
  const char *target_repos_relpath;
  svn_mergeinfo_catalog_t target_mergeinfo_cat;
  svn_ra_session_t *target_session = NULL;
  svn_client__pathrev_t *pathrev;

  /* A hash of paths, at or under TARGET_PATH_OR_URL, mapped to
     rangelists.  Not technically mergeinfo, so not using the
     svn_mergeinfo_t type. */
  apr_hash_t *inheritable_subtree_merges;

  svn_mergeinfo_t source_history;
  svn_mergeinfo_t target_history;
  svn_rangelist_t *master_noninheritable_rangelist;
  svn_rangelist_t *master_inheritable_rangelist;
  apr_array_header_t *merge_source_fspaths =
    apr_array_make(scratch_pool, 1, sizeof(const char *));
  apr_hash_index_t *hi_catalog;
  apr_hash_index_t *hi;
  apr_pool_t *iterpool;
  svn_boolean_t oldest_revs_first = TRUE;
  apr_pool_t *subpool;

  /* We currently only support depth = empty | infinity. */
  if (depth != svn_depth_infinity && depth != svn_depth_empty)
    return svn_error_create(
      SVN_ERR_UNSUPPORTED_FEATURE, NULL,
      _("Only depths 'infinity' and 'empty' are currently supported"));

  /* Validate and sanitize the incoming source operative revision range. */
  if (!((source_start_revision->kind == svn_opt_revision_unspecified) ||
        (source_start_revision->kind == svn_opt_revision_number) ||
        (source_start_revision->kind == svn_opt_revision_date) ||
        (source_start_revision->kind == svn_opt_revision_head)))
    return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
  if (!((source_end_revision->kind == svn_opt_revision_unspecified) ||
        (source_end_revision->kind == svn_opt_revision_number) ||
        (source_end_revision->kind == svn_opt_revision_date) ||
        (source_end_revision->kind == svn_opt_revision_head)))
    return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
  if ((source_end_revision->kind != svn_opt_revision_unspecified)
      && (source_start_revision->kind == svn_opt_revision_unspecified))
    return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
  if ((source_end_revision->kind == svn_opt_revision_unspecified)
      && (source_start_revision->kind != svn_opt_revision_unspecified))
    return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);

  subpool = svn_pool_create(scratch_pool);

  if (ra_session)
    target_session = ra_session;

  /* We need the union of TARGET_PATH_OR_URL@TARGET_PEG_REVISION's mergeinfo
     and MERGE_SOURCE_URL's history.  It's not enough to do path
     matching, because renames in the history of MERGE_SOURCE_URL
     throw that all in a tizzy.  Of course, if there's no mergeinfo on
     the target, that vastly simplifies matters (we'll have nothing to
     do). */
  /* This get_mergeinfo() call doubles as a mergeinfo capabilities check. */
  if (target_mergeinfo_catalog)
    {
      if (*target_mergeinfo_catalog)
        {
          /* The caller provided the mergeinfo catalog for
             TARGET_PATH_OR_URL, so we don't need to acquire
             it ourselves.  We do need to get the repos_root
             though, because get_mergeinfo() won't do it for us. */
          target_mergeinfo_cat = *target_mergeinfo_catalog;

          if (ra_session && svn_path_is_url(target_path_or_url))
            {
              SVN_ERR(svn_ra_reparent(ra_session, target_path_or_url, subpool));
              SVN_ERR(svn_client__resolve_rev_and_url(&pathrev, ra_session,
                                                      target_path_or_url,
                                                      target_peg_revision,
                                                      target_peg_revision,
                                                      ctx, subpool));
              target_session = ra_session;
            }
          else
            {
              SVN_ERR(svn_client__ra_session_from_path2(&target_session,
                                                        &pathrev,
                                                        target_path_or_url,
                                                        NULL,
                                                        target_peg_revision,
                                                        target_peg_revision,
                                                        ctx, subpool));
            }
          SVN_ERR(svn_ra_get_repos_root2(target_session, &repos_root,
                                         scratch_pool));
        }
      else
        {
          /* The caller didn't provide the mergeinfo catalog for
             TARGET_PATH_OR_URL, but wants us to pass a copy back
             when we get it, so use RESULT_POOL. */
          SVN_ERR(get_mergeinfo(target_mergeinfo_catalog, &repos_root,
                                target_path_or_url, target_peg_revision,
                                depth == svn_depth_infinity, TRUE,
                                ctx, ra_session, result_pool, scratch_pool));
          target_mergeinfo_cat = *target_mergeinfo_catalog;
        }
    }
  else
    {
      /* The caller didn't provide the mergeinfo catalog for
         TARGET_PATH_OR_URL, nor does it want a copy, so we can use
         nothing but SCRATCH_POOL. */
      SVN_ERR(get_mergeinfo(&target_mergeinfo_cat, &repos_root,
                            target_path_or_url, target_peg_revision,
                            depth == svn_depth_infinity, TRUE,
                            ctx, ra_session, scratch_pool, scratch_pool));
    }

  if (!svn_path_is_url(target_path_or_url))
    {
      SVN_ERR(svn_dirent_get_absolute(&target_path_or_url,
                                      target_path_or_url, scratch_pool));
      SVN_ERR(svn_wc__node_get_repos_info(NULL, &target_repos_relpath,
                                          NULL, NULL,
                                          ctx->wc_ctx, target_path_or_url,
                                          scratch_pool, scratch_pool));
    }
  else
    {
      target_repos_relpath = svn_uri_skip_ancestor(repos_root,
                                                   target_path_or_url,
                                                   scratch_pool);

      /* TARGET_REPOS_REL should be non-NULL, else get_mergeinfo
         should have failed.  */
      SVN_ERR_ASSERT(target_repos_relpath != NULL);
    }

  if (!target_mergeinfo_cat)
    {
      /* If we are looking for what has been merged and there is no
         mergeinfo then we already know the answer.  If we are looking
         for eligible revisions then create a catalog with empty mergeinfo
         on the target.  This is semantically equivalent to no mergeinfo
         and gives us something to combine with MERGE_SOURCE_URL's
         history. */
      if (finding_merged)
        {
          svn_pool_destroy(subpool);
          return SVN_NO_ERROR;
        }
      else
        {
          target_mergeinfo_cat = apr_hash_make(scratch_pool);
          svn_hash_sets(target_mergeinfo_cat, target_repos_relpath,
                        apr_hash_make(scratch_pool));
        }
    }

  /* Fetch the location history as mergeinfo, for the source branch
   * (between the given start and end revisions), and, if we're finding
   * merged revisions, then also for the entire target branch.
   *
   * ### TODO: As the source and target must be in the same repository, we
   * should share a single session, tracking the two URLs separately. */
  {
    svn_ra_session_t *source_session;
    svn_revnum_t start_rev, end_rev, youngest_rev = SVN_INVALID_REVNUM;

    if (! finding_merged)
      {
        if (!target_session)
          SVN_ERR(svn_client__ra_session_from_path2(&target_session, &pathrev,
                                                    target_path_or_url, NULL,
                                                    target_peg_revision,
                                                    target_peg_revision,
                                                    ctx, subpool));
        SVN_ERR(svn_client__get_history_as_mergeinfo(&target_history, NULL,
                                                     pathrev,
                                                     SVN_INVALID_REVNUM,
                                                     SVN_INVALID_REVNUM,
                                                     target_session, ctx,
                                                     scratch_pool));
      }

    if (target_session
        && svn_path_is_url(source_path_or_url)
        && repos_root
        && svn_uri_skip_ancestor(repos_root, source_path_or_url, subpool))
      {
        /* We can re-use the existing session */
        source_session = target_session;
        SVN_ERR(svn_ra_reparent(source_session, source_path_or_url, subpool));
        SVN_ERR(svn_client__resolve_rev_and_url(&pathrev, source_session,
                                                source_path_or_url,
                                                source_peg_revision,
                                                source_peg_revision,
                                                ctx, subpool));
      }
    else
      {
        SVN_ERR(svn_client__ra_session_from_path2(&source_session, &pathrev,
                                                  source_path_or_url, NULL,
                                                  source_peg_revision,
                                                  source_peg_revision,
                                                  ctx, subpool));
      }
    SVN_ERR(svn_client__get_revision_number(&start_rev, &youngest_rev,
                                            ctx->wc_ctx, source_path_or_url,
                                            source_session,
                                            source_start_revision,
                                            subpool));
    SVN_ERR(svn_client__get_revision_number(&end_rev, &youngest_rev,
                                            ctx->wc_ctx, source_path_or_url,
                                            source_session,
                                            source_end_revision,
                                            subpool));
    SVN_ERR(svn_client__get_history_as_mergeinfo(&source_history, NULL,
                                                 pathrev,
                                                 MAX(end_rev, start_rev),
                                                 MIN(end_rev, start_rev),
                                                 source_session, ctx,
                                                 scratch_pool));
    if (start_rev > end_rev)
      oldest_revs_first = FALSE;
  }

  /* Separate the explicit or inherited mergeinfo on TARGET_PATH_OR_URL,
     and possibly its explicit subtree mergeinfo, into their
     inheritable and non-inheritable parts. */
  master_noninheritable_rangelist = apr_array_make(scratch_pool, 64,
                                                   sizeof(svn_merge_range_t *));
  master_inheritable_rangelist = apr_array_make(scratch_pool, 64,
                                                sizeof(svn_merge_range_t *));
  inheritable_subtree_merges = apr_hash_make(scratch_pool);

  iterpool = svn_pool_create(scratch_pool);

  for (hi_catalog = apr_hash_first(scratch_pool, target_mergeinfo_cat);
       hi_catalog;
       hi_catalog = apr_hash_next(hi_catalog))
    {
      svn_mergeinfo_t subtree_mergeinfo = apr_hash_this_val(hi_catalog);
      svn_mergeinfo_t subtree_history;
      svn_mergeinfo_t subtree_source_history;
      svn_mergeinfo_t subtree_inheritable_mergeinfo;
      svn_mergeinfo_t subtree_noninheritable_mergeinfo;
      svn_mergeinfo_t merged_noninheritable;
      svn_mergeinfo_t merged;
      const char *subtree_path = apr_hash_this_key(hi_catalog);
      svn_boolean_t is_subtree = strcmp(subtree_path,
                                        target_repos_relpath) != 0;
      svn_pool_clear(iterpool);

      if (is_subtree)
        {
          /* If SUBTREE_PATH is a proper subtree of TARGET_PATH_OR_URL
             then make a copy of SOURCE_HISTORY that is path adjusted
             for the subtree.  */
          const char *subtree_rel_path =
            subtree_path + strlen(target_repos_relpath) + 1;

          SVN_ERR(svn_mergeinfo__add_suffix_to_mergeinfo(
            &subtree_source_history, source_history,
            subtree_rel_path, scratch_pool, iterpool));

          if (!finding_merged)
            SVN_ERR(svn_mergeinfo__add_suffix_to_mergeinfo(
                    &subtree_history, target_history,
                    subtree_rel_path, scratch_pool, iterpool));
        }
      else
        {
          subtree_source_history = source_history;
          if (!finding_merged)
            subtree_history = target_history;
        }

      if (!finding_merged)
        {
          svn_mergeinfo_t merged_via_history;
          SVN_ERR(svn_mergeinfo_intersect2(&merged_via_history,
                                           subtree_history,
                                           subtree_source_history, TRUE,
                                           scratch_pool, iterpool));
          SVN_ERR(svn_mergeinfo_merge2(subtree_mergeinfo,
                                       merged_via_history,
                                       scratch_pool, iterpool));
        }

      SVN_ERR(svn_mergeinfo_inheritable2(&subtree_inheritable_mergeinfo,
                                         subtree_mergeinfo, NULL,
                                         SVN_INVALID_REVNUM,
                                         SVN_INVALID_REVNUM,
                                         TRUE, scratch_pool, iterpool));
      SVN_ERR(svn_mergeinfo_inheritable2(&subtree_noninheritable_mergeinfo,
                                         subtree_mergeinfo, NULL,
                                         SVN_INVALID_REVNUM,
                                         SVN_INVALID_REVNUM,
                                         FALSE, scratch_pool, iterpool));

      /* Find the intersection of the non-inheritable part of
         SUBTREE_MERGEINFO and SOURCE_HISTORY.  svn_mergeinfo_intersect2()
         won't consider non-inheritable and inheritable ranges
         intersecting unless we ignore inheritance, but in doing so the
         resulting intersections have all inheritable ranges.  To get
         around this we set the inheritance on the result to all
         non-inheritable. */
      SVN_ERR(svn_mergeinfo_intersect2(&merged_noninheritable,
                                       subtree_noninheritable_mergeinfo,
                                       subtree_source_history, FALSE,
                                       scratch_pool, iterpool));
      svn_mergeinfo__set_inheritance(merged_noninheritable, FALSE,
                                     iterpool);

      /* Keep track of all ranges partially merged to any and all
         subtrees. */
      SVN_ERR(svn_rangelist__merge_many(master_noninheritable_rangelist,
                                        merged_noninheritable,
                                        scratch_pool, iterpool));

      /* Find the intersection of the inheritable part of TGT_MERGEINFO
         and SOURCE_HISTORY. */
      SVN_ERR(svn_mergeinfo_intersect2(&merged,
                                       subtree_inheritable_mergeinfo,
                                       subtree_source_history, FALSE,
                                       scratch_pool, iterpool));

      /* Keep track of all ranges fully merged to any and all
         subtrees. */
      if (apr_hash_count(merged))
        {
          /* The inheritable rangelist merged from SUBTREE_SOURCE_HISTORY
             to SUBTREE_PATH. */
          svn_rangelist_t *subtree_merged_rangelist =
            apr_array_make(scratch_pool, 1, sizeof(svn_merge_range_t *));

          SVN_ERR(svn_rangelist__merge_many(master_inheritable_rangelist,
                                            merged, scratch_pool, iterpool));
          SVN_ERR(svn_rangelist__merge_many(subtree_merged_rangelist,
                                            merged, scratch_pool, iterpool));

          svn_hash_sets(inheritable_subtree_merges, subtree_path,
                        subtree_merged_rangelist);
        }
      else
        {
          /* Map SUBTREE_PATH to an empty rangelist if there was nothing
             fully merged. e.g. Only empty or non-inheritable mergeinfo
             on the subtree or mergeinfo unrelated to the source. */
          svn_hash_sets(inheritable_subtree_merges, subtree_path,
                        apr_array_make(scratch_pool, 0,
                                       sizeof(svn_merge_range_t *)));
        }
    }

  /* Make sure every range in MASTER_INHERITABLE_RANGELIST is fully merged to
     each subtree (including the target itself).  Any revisions which don't
     exist in *every* subtree are *potentially* only partially merged to the
     tree rooted at TARGET_PATH_OR_URL, so move those revisions to
     MASTER_NONINHERITABLE_RANGELIST.  It may turn out that that a revision
     was merged to the only subtree it affects, but we need to examine the
     logs to make this determination (which will be done by
     logs_for_mergeinfo_rangelist). */
  if (master_inheritable_rangelist->nelts)
    {
      for (hi = apr_hash_first(scratch_pool, inheritable_subtree_merges);
           hi;
           hi = apr_hash_next(hi))
        {
          svn_rangelist_t *deleted_rangelist;
          svn_rangelist_t *added_rangelist;
          svn_rangelist_t *subtree_merged_rangelist = apr_hash_this_val(hi);

          svn_pool_clear(iterpool);

          SVN_ERR(svn_rangelist_diff(&deleted_rangelist, &added_rangelist,
                                     master_inheritable_rangelist,
                                     subtree_merged_rangelist, TRUE,
                                     iterpool));

          if (deleted_rangelist->nelts)
            {
              svn_rangelist__set_inheritance(deleted_rangelist, FALSE);
              SVN_ERR(svn_rangelist_merge2(master_noninheritable_rangelist,
                                           deleted_rangelist,
                                           scratch_pool, iterpool));
              SVN_ERR(svn_rangelist_remove(&master_inheritable_rangelist,
                                           deleted_rangelist,
                                           master_inheritable_rangelist,
                                           FALSE,
                                           scratch_pool));
            }
        }
    }

  if (finding_merged)
    {
      /* Roll all the merged revisions into one rangelist. */
      SVN_ERR(svn_rangelist_merge2(master_inheritable_rangelist,
                                   master_noninheritable_rangelist,
                                   scratch_pool, scratch_pool));

    }
  else
    {
      /* Create the starting rangelist for what might be eligible. */
      svn_rangelist_t *source_master_rangelist =
        apr_array_make(scratch_pool, 1, sizeof(svn_merge_range_t *));

      SVN_ERR(svn_rangelist__merge_many(source_master_rangelist,
                                        source_history,
                                        scratch_pool, scratch_pool));

      /* From what might be eligible subtract what we know is
         partially merged and then merge that back. */
      SVN_ERR(svn_rangelist_remove(&source_master_rangelist,
                                   master_noninheritable_rangelist,
                                   source_master_rangelist,
                                   FALSE, scratch_pool));
      SVN_ERR(svn_rangelist_merge2(source_master_rangelist,
                                   master_noninheritable_rangelist,
                                   scratch_pool, scratch_pool));
      SVN_ERR(svn_rangelist_remove(&master_inheritable_rangelist,
                                   master_inheritable_rangelist,
                                   source_master_rangelist,
                                   TRUE, scratch_pool));
    }

  /* Nothing merged?  Not even when considering shared history if
     looking for eligible revisions (i.e. !FINDING_MERGED)?  Then there
     is nothing more to do. */
  if (! master_inheritable_rangelist->nelts)
    {
      svn_pool_destroy(iterpool);
      return SVN_NO_ERROR;
    }
  else
    {
      /* Determine the correct (youngest) target for 'svn log'. */
      svn_merge_range_t *youngest_range
        = APR_ARRAY_IDX(master_inheritable_rangelist,
                        master_inheritable_rangelist->nelts - 1,
                        svn_merge_range_t *);
      svn_rangelist_t *youngest_rangelist =
        svn_rangelist__initialize(youngest_range->end - 1,
                                  youngest_range->end,
                                  youngest_range->inheritable,
                                  scratch_pool);

      for (hi = apr_hash_first(scratch_pool, source_history);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *key = apr_hash_this_key(hi);
          svn_rangelist_t *subtree_merged_rangelist = apr_hash_this_val(hi);
          svn_rangelist_t *intersecting_rangelist;

          svn_pool_clear(iterpool);
          SVN_ERR(svn_rangelist_intersect(&intersecting_rangelist,
                                          youngest_rangelist,
                                          subtree_merged_rangelist,
                                          FALSE, iterpool));

          APR_ARRAY_PUSH(merge_source_fspaths, const char *) = key;

          if (intersecting_rangelist->nelts)
            log_target = key;
        }
    }

  svn_pool_destroy(iterpool);

  /* Step 4: Finally, we run 'svn log' to drive our log receiver, but
     using a receiver filter to only allow revisions to pass through
     that are in our rangelist. */
  log_target = svn_path_url_add_component2(repos_root, log_target + 1,
                                           scratch_pool);

  {
    svn_error_t *err;

    err = logs_for_mergeinfo_rangelist(log_target, merge_source_fspaths,
                                       finding_merged,
                                       master_inheritable_rangelist,
                                       oldest_revs_first,
                                       target_mergeinfo_cat,
                                       svn_fspath__join("/",
                                                        target_repos_relpath,
                                                        scratch_pool),
                                       discover_changed_paths,
                                       revprops,
                                       log_receiver, log_receiver_baton,
                                       ctx, target_session, scratch_pool);

    /* Close the source and target sessions. */
    svn_pool_destroy(subpool); /* For SVN_ERR_CEASE_INVOCATION */

    return svn_error_trace(err);
  }
}

svn_error_t *
svn_client_mergeinfo_log2(svn_boolean_t finding_merged,
                          const char *target_path_or_url,
                          const svn_opt_revision_t *target_peg_revision,
                          const char *source_path_or_url,
                          const svn_opt_revision_t *source_peg_revision,
                          const svn_opt_revision_t *source_start_revision,
                          const svn_opt_revision_t *source_end_revision,
                          svn_log_entry_receiver_t log_receiver,
                          void *log_receiver_baton,
                          svn_boolean_t discover_changed_paths,
                          svn_depth_t depth,
                          const apr_array_header_t *revprops,
                          svn_client_ctx_t *ctx,
                          apr_pool_t *scratch_pool)
{
  return svn_error_trace(
         svn_client__mergeinfo_log(finding_merged, target_path_or_url,
                                   target_peg_revision, NULL,
                                   source_path_or_url, source_peg_revision,
                                   source_start_revision, source_end_revision,
                                   log_receiver, log_receiver_baton,
                                   discover_changed_paths, depth, revprops,
                                   ctx, NULL,
                                   scratch_pool, scratch_pool));
}

svn_error_t *
svn_client_suggest_merge_sources(apr_array_header_t **suggestions,
                                 const char *path_or_url,
                                 const svn_opt_revision_t *peg_revision,
                                 svn_client_ctx_t *ctx,
                                 apr_pool_t *pool)
{
  const char *repos_root;
  const char *copyfrom_path;
  apr_array_header_t *list;
  svn_revnum_t copyfrom_rev;
  svn_mergeinfo_catalog_t mergeinfo_cat;
  svn_mergeinfo_t mergeinfo;
  apr_hash_index_t *hi;
  apr_pool_t *session_pool = svn_pool_create(pool);
  svn_ra_session_t *ra_session;

  list = apr_array_make(pool, 1, sizeof(const char *));

  /* In our ideal algorithm, the list of recommendations should be
     ordered by:

        1. The most recent existing merge source.
        2. The copyfrom source (which will also be listed as a merge
           source if the copy was made with a 1.5+ client and server).
        3. All other merge sources, most recent to least recent.

     However, determining the order of application of merge sources
     requires a new RA API.  Until such an API is available, our
     algorithm will be:

        1. The copyfrom source.
        2. All remaining merge sources (unordered).
  */
  SVN_ERR(svn_client__ra_session_from_path2(&ra_session, NULL, path_or_url,
                                            NULL, peg_revision, peg_revision,
                                            ctx, session_pool));

  SVN_ERR(get_mergeinfo(&mergeinfo_cat, &repos_root, path_or_url,
                        peg_revision, FALSE, FALSE,
                        ctx, ra_session, session_pool, session_pool));

  if (mergeinfo_cat && apr_hash_count(mergeinfo_cat))
    {
      /* We asked only for the PATH_OR_URL's mergeinfo, not any of its
         descendants.  So if there is anything in the catalog it is the
         mergeinfo for PATH_OR_URL. */
      mergeinfo = apr_hash_this_val(apr_hash_first(session_pool,
                                                   mergeinfo_cat));
    }
  else
    {
      mergeinfo = NULL;
    }

  /* ### Should we only add the last source or all copy sources back to
         the origin? */
  SVN_ERR(svn_client__get_copy_source(&copyfrom_path, &copyfrom_rev,
                                      path_or_url, peg_revision, ra_session,
                                      ctx, session_pool, session_pool));
  if (copyfrom_path)
    {
      APR_ARRAY_PUSH(list, const char *) =
        svn_path_url_add_component2(repos_root, copyfrom_path, pool);
    }

  if (mergeinfo)
    {
      for (hi = apr_hash_first(session_pool, mergeinfo);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *rel_path = apr_hash_this_key(hi);

          if (copyfrom_path == NULL || strcmp(rel_path, copyfrom_path) != 0)
            APR_ARRAY_PUSH(list, const char *) = \
              svn_path_url_add_component2(repos_root, rel_path + 1, pool);
        }
    }

  svn_pool_destroy(session_pool);

  *suggestions = list;
  return SVN_NO_ERROR;
}

svn_error_t *
svn_client__mergeinfo_status(svn_boolean_t *mergeinfo_changes,
                             svn_wc_context_t *wc_ctx,
                             const char *local_abspath,
                             apr_pool_t *scratch_pool)
{
  apr_array_header_t *propchanges;
  int i;

  *mergeinfo_changes = FALSE;

  SVN_ERR(svn_wc_get_prop_diffs2(&propchanges, NULL, wc_ctx,
                                 local_abspath, scratch_pool, scratch_pool));

  for (i = 0; i < propchanges->nelts; i++)
    {
      svn_prop_t prop = APR_ARRAY_IDX(propchanges, i, svn_prop_t);
      if (strcmp(prop.name, SVN_PROP_MERGEINFO) == 0)
        {
          *mergeinfo_changes = TRUE;
          break;
        }
    }

  return SVN_NO_ERROR;
}
